diff --git a/bin/docs.php b/bin/docs.php index 790549d99b..0f91b93a58 100755 --- a/bin/docs.php +++ b/bin/docs.php @@ -57,6 +57,7 @@ public function execute(InputInterface $input, OutputInterface $output): int $paths = [ __DIR__ . '/../src/core/etl/src/Flow/ETL/DSL/functions.php', __DIR__ . '/../src/core/etl/src/Flow/Floe/DSL/functions.php', + __DIR__ . '/../src/core/etl/src/Flow/Serializer/DSL/functions.php', __DIR__ . '/../src/adapter/etl-adapter-avro/src/Flow/ETL/Adapter/Avro/functions.php', __DIR__ . '/../src/adapter/etl-adapter-chartjs/src/Flow/ETL/Adapter/ChartJS/functions.php', __DIR__ . '/../src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/functions.php', diff --git a/composer.json b/composer.json index be7b19fa08..bad9b81f65 100644 --- a/composer.json +++ b/composer.json @@ -247,6 +247,7 @@ "src/cli/src/Flow/CLI/DSL/functions.php", "src/core/etl/src/Flow/ETL/DSL/functions.php", "src/core/etl/src/Flow/Floe/DSL/functions.php", + "src/core/etl/src/Flow/Serializer/DSL/functions.php", "src/functions.php", "src/lib/array-dot/src/Flow/ArrayDot/array_dot.php", "src/lib/azure-sdk/src/Flow/Azure/SDK/DSL/functions.php", diff --git a/documentation/components/core/building-blocks.md b/documentation/components/core/building-blocks.md index 7cd730ef8e..1920c316bf 100644 --- a/documentation/components/core/building-blocks.md +++ b/documentation/components/core/building-blocks.md @@ -41,7 +41,7 @@ $rows = array_to_rows([ ['id' => 2, 'name' => 'user_02', 'active' => false], ['id' => 3, 'name' => 'user_03', 'active' => true], ['id' => 4, 'name' => 'user_04', 'active' => false], -], flow_context(config())->entryFactory()); +]); ``` ## Entry Types @@ -56,6 +56,7 @@ $rows = array_to_rows([ - [Json](/src/core/etl/src/Flow/ETL/Row/Entry/JsonEntry.php) - [List](/src/core/etl/src/Flow/ETL/Row/Entry/ListEntry.php) - [Map](/src/core/etl/src/Flow/ETL/Row/Entry/MapEntry.php) +- [Null](/src/core/etl/src/Flow/ETL/Row/Entry/NullEntry.php) - [String](/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php) - [Structure](/src/core/etl/src/Flow/ETL/Row/Entry/StructureEntry.php) - [Uuid](/src/core/etl/src/Flow/ETL/Row/Entry/UuidEntry.php) @@ -64,7 +65,8 @@ $rows = array_to_rows([ - [XML](/src/core/etl/src/Flow/ETL/Row/Entry/XMLEntry.php) - [XMLElement](/src/core/etl/src/Flow/ETL/Row/Entry/XMLElementEntry.php) -Internally, Flow is using [EntryFactory](/src/core/etl/src/Flow/ETL/Row/EntryFactory.php) to create entries. -It will try to detect and create the most appropriate entry type based on the value. +Internally, Flow is using a [Hydrator](/src/core/etl/src/Flow/ETL/Row/Hydrator.php) to turn raw values +into rows and an [EntryFactory](/src/core/etl/src/Flow/ETL/Row/EntryFactory.php) to create single entries. +Both will try to detect and create the most appropriate entry type based on the value. Flow Entries are based on [Flow Types Library](/documentation/components/libs/types.md) diff --git a/documentation/components/core/caching.md b/documentation/components/core/caching.md index 37aad8fdec..8bca2abc07 100644 --- a/documentation/components/core/caching.md +++ b/documentation/components/core/caching.md @@ -63,33 +63,40 @@ but it does not come with any out of the box. ## Serialization -Cache entries are stored as [Floe](/documentation/components/core/floe.md) files, streamed in both -directions: writes go straight to the cache file batch by batch (the payload string is never -materialized), reads decode one batch at a time. The batch size (default 1000 rows) bounds how many -rows cross the engine at once: +Persisting caches (`FilesystemCache`, `PSRSimpleCache`) turn `Rows` into bytes through a +[`Serializer`](/src/core/etl/src/Flow/Serializer/Serializer.php). The default is +[`FloeSerializer`](/src/core/etl/src/Flow/Floe/FloeSerializer.php), which encodes to the +[Floe](/documentation/components/core/floe.md) binary format. + +`Cache::get()` returns one fully materialized `Rows` per key. The caching processor writes exactly +one batch per cache key, so each key holds a single batch bounded by `DataFrame::cache(cacheBatchSize:)` +(falling back to `DataFrame::batchSize()`): ```php cacheSerializerBatchSize(1000); +use function Flow\ETL\DSL\{data_frame, from_array}; -// or constructing the cache directly -filesystem_cache(serializer_batch_size: 1000); +data_frame() + ->read(from_array($data)) + ->cache('my-dataset', cacheBatchSize: 1000) + ->run(); ``` -`Cache::get()` always returns a fully materialized `Rows` — the raw payload bytes are never held -next to the decoded rows, but the decoded rows themselves are unbounded. To keep the decoded side -bounded too, use `Cache::read()`: +A `Serializer` writes to and reads from streams, so the default `FilesystemCache` streams the payload +directly to and from the cache file. `PSRSimpleCache` materializes the payload string — its PSR-16 +backend stores string values — bounded by `cacheBatchSize`. + +You can swap the serializer per cache; the default `FilesystemCache` shares the same serializer as the +rest of the pipeline (so it uses the context hydrator): ```php read('my-dataset') as $rows) { - // FilesystemCache: one batch of Rows at a time - // InMemory/PSRSimpleCache: the whole value, yielded once -} -``` \ No newline at end of file +use function Flow\ETL\DSL\filesystem_cache; + +filesystem_cache(serializer: new MyCustomSerializer()); +``` + +`FilesystemCache` stores each entry in a file named after the cache key, with no extension — the +on-disk bytes are whatever the configured serializer produced. \ No newline at end of file diff --git a/documentation/components/core/floe.md b/documentation/components/core/floe.md index 72ee2cbc8a..5720649815 100644 --- a/documentation/components/core/floe.md +++ b/documentation/components/core/floe.md @@ -38,6 +38,11 @@ data_frame() ->run(); ``` +When the [`flow_php` extension](/documentation/components/extensions/flow-php-ext.md) is loaded, the +strict read and the write fuse frame-split + value decode/encode + hydrate/dehydrate into one native +call per batch. It is transparent — the on-disk format is unchanged and the rows are byte-for-byte +identical to the pure-PHP engine; the salvage path (`FloeStreamReader::recover()`) always stays pure PHP. + ## Save Modes `to_floe()` honors every [Save Mode](/documentation/components/core/save-mode.md) through the same @@ -68,9 +73,11 @@ data_frame() ->run(); ``` -> Floe additionally supports appending seamlessly into a **single** file with schema evolution -> through the low-level `Flow\Floe\FloeWriter::append()` API; the DataFrame `Append` save mode uses -> the sibling-file behavior for consistency with the rest of Flow. +> Floe additionally supports appending into a **single** file through the low-level +> `Flow\Floe\FloeWriter::append()` API — appended batches must match the file's schema (a drifted +> batch throws `IncompatibleSchemaException`; schema evolution is only available through +> `merge_floe()`). The DataFrame `Append` save mode uses the sibling-file behavior for consistency +> with the rest of Flow. ## Partitioning @@ -174,19 +181,21 @@ merge_floe( ); ``` -All sources must share one partition combination and evolve the running merged schema cleanly — -otherwise `IncompatibleSchemaException` is thrown before anything is written. `merge_floe()` works on -the local filesystem; for other filesystems use `Flow\Floe\FloeMerger` directly. +Sources must evolve the running merged schema cleanly — otherwise `IncompatibleSchemaException` is +thrown before anything is written. Each source's per-section partition combinations are preserved +(deduped into the merged footer table), so sources with differing combinations merge without error. +`merge_floe()` works on the local filesystem; for other filesystems use `Flow\Floe\FloeMerger` directly. ## Whole-Value Serialization The whole-value serialization paths — the [cache](/documentation/components/core/caching.md) and -`Flow\Floe\FloeSerializer` (the config default serializer) — stream: encode goes through -`FloeWriter` and decode through `FloeFile::recover()` in batches of `batchSize` rows (default -1000), so the engine holds one batch at a time. The batch size never changes the produced bytes — -only the memory bound. A whole-value decode verifies the recovered row count against the footer -and rejects torn payloads. Numbers and guidance live in the -[caching documentation](/documentation/components/core/caching.md). +`Flow\Floe\FloeSerializer` (the config default serializer) — stream: `serialize(Rows, DestinationStream)` +goes through `FloeStreamWriter` and `unserialize(SourceStream)` through the strict `FloeStreamReader::rows()` +read in batches of `batchSize` rows (default 1000), so the engine holds one batch at a time. The batch size +never changes the produced bytes — only the memory bound. String payloads round-trip through the +`Flow\Serializer\DSL` helpers `serialize_to_string()` / `unserialize_from_string()`. A whole-value +`unserialize()` verifies the decoded row count against the footer and rejects torn payloads. Numbers and +guidance live in the [caching documentation](/documentation/components/core/caching.md). ## On-Disk Layout @@ -199,8 +208,8 @@ reader can locate from the last 8 bytes without scanning the body. All multi-byt │ HEADER 6 bytes │ ├──────────────────────────────────────────────────────────┤ │ FRAMES (repeated, in write order) │ -│ PARTITIONS (0x03) once, partitioned files only │ -│ SCHEMA (0x01) emitted when the schema changes │ +│ PARTITIONS (0x03) emitted when combination changes │ +│ SCHEMA (0x01) written once, before first ROW │ │ ROW (0x02) one frame per row │ │ ROW (0x02) │ │ … │ @@ -234,19 +243,23 @@ Every frame — `SCHEMA`, `ROW`, `PARTITIONS`, `FOOTER` — shares the same enve 0x01 SCHEMA 0x02 ROW 0x03 PARTITIONS 0x06 FOOTER ``` -- **SCHEMA (`0x01`)** — body is the JSON schema for the section that follows. A section's schema is - **grow-only**: it starts as the first row's schema and a new `SCHEMA` frame is written only when a row - introduces a new column or an incompatible type. Rows narrower than the section ride it (see the ROW - absent flag), so a heterogeneous stream needs far fewer sections than one frame per distinct shape. -- **ROW (`0x02`)** — one row encoded **by column** against the current section schema: for each section +- **SCHEMA (`0x01`)** — body is the JSON schema for the file. A file carries **exactly one schema**, + fixed at session start (explicit, or the first batch's union), written once before the first section. + Rows narrower than the schema ride it (see the ROW absent flag). A later batch that introduces a new + column or an incompatible type throws `IncompatibleSchemaException` — schema evolution lives only in + `merge_floe()`. +- **ROW (`0x02`)** — one row encoded **by column** against the file schema: for each schema column, in order, a one-byte presence flag — `0x01` present (followed by the value encoded per the column's schema type, no per-value tag), `0x00` null, `0x02` null-from-null, or `0x03` **absent** (the row has no such column). Only dynamically typed values (mixed/union columns, dynamic map keys) carry a one-byte type tag (`NULL`, `INTEGER`, `FLOAT`, `BOOLEAN`, `STRING`, `ARRAY`, `DATETIME`, `UUID`, `JSON`). A row whose columns exactly match the section produces the same bytes as a plain positional encode. One frame per row. -- **PARTITIONS (`0x03`)** — for a partitioned file, the partition key/value pairs, written once before - the first section: a 4-byte count followed by repeated `[nameLen(4), name, valueLen(4), value]`. +- **PARTITIONS (`0x03`)** — the partition key/value pairs for the section that follows: a 4-byte count + followed by repeated `[nameLen(4), name, valueLen(4), value]`. Written at the start of every section + whose combination differs from the previous one (mirror of the `SCHEMA`-frame dedup); the reader + starts at the empty combination, so an unpartitioned first section emits none and a later change back + to unpartitioned emits a `count=0` frame. - **FOOTER (`0x06`)** — the footer JSON followed by the trailer (below). ### Footer @@ -258,23 +271,24 @@ scanning rows**: { "version": 1, "writer": "1.x-dev", - "schemas": [ /* schema body per schemaId */ ], - "fileSchema": { /* merged schema of every section */ }, - "sections": [ { "offset": 6, "schemaId": 0, "rowCount": 2 } ], - "partitions": { "country": "PL" }, + "schema": { /* the file's single schema */ }, + "sections": [ { "offset": 6, "partitionsId": 0, "rowCount": 2 } ], + "partitions": [ { "country": "PL" } ], "totalRows": 2, "metadata": { /* typed key/value, Schema\Metadata */ } } ``` -- **`sections`** map a byte `offset` → `schemaId` + `rowCount`, so a reader can skip whole sections - (offset/limit pushdown) and know each section's schema up front. -- **`schemas`** is the deduplicated list of every schema written; **`fileSchema`** is their merge — - the source schema, available from the footer alone. On a seamless read, a row narrower than - `fileSchema` (an absent column, or a column added by a later section) is padded with null entries so - every yielded row conforms; `recover()` reads rows exactly as written, absent columns omitted. -- A new column or incompatible type grows the section (new `SCHEMA` frame); this is also how a single - file evolves its schema across appended sections. +- **`sections`** map a byte `offset` → `partitionsId` + `rowCount`, so a reader can skip whole sections + (offset/limit pushdown) and know each section's partition combination up front. Sections bound + partition combinations and appends only; every section shares the file's one schema. +- **`partitions`** is the deduplicated, order-preserving table of partition combinations, indexed by + `partitionsId`; the unpartitioned combination is an empty object at its own id. A file can hold many + combinations (one per section). +- **`schema`** is the file's single schema, available from the footer alone. On a seamless read, a row + narrower than it (an absent column) is padded with null entries so every yielded row conforms; + `recover()` reads rows exactly as written, absent columns omitted. `merge_floe()` re-encodes drifted + sources to their union, so a merged file is still one schema. ### Trailer (last 8 bytes) diff --git a/documentation/components/core/group-by.md b/documentation/components/core/group-by.md index 3fb0bb409c..b0691d35c0 100644 --- a/documentation/components/core/group-by.md +++ b/documentation/components/core/group-by.md @@ -41,4 +41,27 @@ However, the result of this operation is not very useful. It will just return a To make it more useful, you need to use one of the aggregation functions. -[➡️ Aggregations](/documentation/components/core/aggregations.md) \ No newline at end of file +[➡️ Aggregations](/documentation/components/core/aggregations.md) + +## Buckets Storage + +`groupBy()` partitions grouping state into buckets through a `BucketsCache` — the same abstraction +used by [external sort](/documentation/components/core/sort.md) and +[join](/documentation/components/core/join.md). The default is `FilesystemBucketsCache`: buckets are +spilled to the local filesystem cache directory (as Floe files), so memory usage is bounded by the +largest bucket instead of the whole grouped dataset. + +```php +groupingBucketsCount(64) // number of buckets (default 64) + ->groupingBatchSize(1000) // rows per batch when reading buckets back (default 1000) + ->groupingCache(new InMemoryBucketsCache()) // keep buckets in memory instead of on disk +) + ->read(from_parquet('orders.parquet')) + ->groupBy(ref('country')) + ->aggregate(sum(ref('total'))) + ->run(); +``` \ No newline at end of file diff --git a/documentation/components/core/join.md b/documentation/components/core/join.md index b73f25652c..c8c244c59e 100644 --- a/documentation/components/core/join.md +++ b/documentation/components/core/join.md @@ -12,7 +12,7 @@ rows from the left DataFrame. ### join() -Main join method that loads the right DataFrame into memory as a hash table for efficient lookups. +Main join method that partitions the right DataFrame into buckets and probes them with left rows through a hash table. ### crossJoin() - Cartesian Product @@ -33,7 +33,44 @@ Flow PHP supports four join types with specific behaviors: | **Right Join** (`Join::right`) | Returns all rows from right DataFrame with matching rows from left (or NULL) | | **Left Anti Join** (`Join::left_anti`) | Returns rows from left DataFrame that have NO match in right DataFrame | -> Flow uses hash join implementation where hashes are stored in sorted buckets to optimize memory usage and performance. +Joins follow SQL semantics - every matching pair of rows produces one output row, so a left row +that matches multiple right rows is emitted multiple times. + +> Flow uses hash join implementation where hashes are stored in buckets to optimize memory usage and performance. +> Rows are bucketed by the values of the join columns and every candidate pair is verified against +> the join expression, so non-equality expressions (like `compare_any()`) are supported as well. + +## Buckets Storage + +Like group by, `join()` always partitions the right DataFrame into buckets through a `BucketsCache` - +the same abstraction used by external sort and group by - and the configured implementation decides +how the join executes: + +| Buckets cache | Behavior | +|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `FilesystemBucketsCache` - **Default** | Both sides are partitioned by join key into buckets spilled to disk (Floe files), then joined bucket by bucket. Memory usage is bounded by the largest bucket, left row order is not preserved. | +| `InMemoryBucketsCache` | Right DataFrame is held in memory, left rows are streamed through a hash table and keep their order. Memory usage is bounded by the right side. | + +The implementation is swapped with `config_builder()->joinCache(BucketsCache $cache)`; any cache +implementing `ResidentBucketsCache` (like `InMemoryBucketsCache`) enables the streaming, +order-preserving execution: + +```php +joinCache(new InMemoryBucketsCache()) // right side fits in memory, keep left row order + ->joinBucketsCount(64) // number of disk buckets + ->joinBatchSize(1000) // rows per batch when reading buckets back +) + ->read(from_parquet('orders.parquet')) + ->join( + data_frame()->read(from_parquet('sellers.parquet')), + join_on(['seller_id' => 'id'], join_prefix: 'seller_'), + ) + ->run(); +``` ## Example diff --git a/documentation/components/core/partitioning.md b/documentation/components/core/partitioning.md index a5b2f03f14..b3954e774b 100644 --- a/documentation/components/core/partitioning.md +++ b/documentation/components/core/partitioning.md @@ -279,6 +279,10 @@ data_frame() ->run(); ``` +Partition values from the path become regular row columns. When the extractor is given a schema that +does not declare a partition column, the column is appended to the schema as a **string** column — +declare it explicitly (e.g. `int_schema('date')`) to read partition values as a different type. + ### Partition Pruning Skip entire partitions without reading their contents using `filterPartitions()`: diff --git a/documentation/components/extensions/flow-php-ext.md b/documentation/components/extensions/flow-php-ext.md index 7b02e0f9d0..9f9b5e339d 100644 --- a/documentation/components/extensions/flow-php-ext.md +++ b/documentation/components/extensions/flow-php-ext.md @@ -9,9 +9,9 @@ package: flow-php/flow-php-ext [TOC] Flow stores durable datasets (`to_floe()`) and caches intermediate ones (`DataFrame::cache()`, -external-sort spill buckets) using the native **Floe** binary format (`.floe`) — the schema is written -once per section and rows carry raw values only, which makes both the payload and the hydration -dramatically cheaper than native PHP `serialize()`/`unserialize()`. +sort / join / group-by spill buckets) using the native **Floe** binary format (`.floe`) — the schema +is written once per file and rows carry raw values only, which makes both the payload and the +hydration dramatically cheaper than native PHP `serialize()`/`unserialize()`. This extension encodes and decodes Floe **frames** natively in Rust via [ext-php-rs](https://github.com/extphprs/ext-php-rs). The pure-PHP implementation in `Flow\Floe` @@ -19,8 +19,8 @@ This extension encodes and decodes Floe **frames** natively in Rust via purely an optimization. File header and footer assembly always stay in PHP. > You never need to call this extension directly. `Flow\Floe\FloeReader`/`FloeWriter` — used by -> `from_floe()`/`to_floe()`, the cache and the external-sort buckets cache — route ROW/SCHEMA frame -> bodies to it automatically when `extension_loaded('flow_php')` is true. +> `from_floe()`/`to_floe()`, the cache and the sort / join / group-by buckets caches — route whole +> batches to it automatically when `extension_loaded('flow_php')` is true. ## Loading the Extension @@ -52,26 +52,24 @@ df() ->run(); ``` -The low-level API works on bare frame bodies (`FloeReader`/`FloeWriter` add the framing): - -```php -schema($schemaFrameBody); -$row = $decoder->row($rowFrameBody); // Flow\ETL\Row -$rows = $decoder->rows([$rowFrameBody, ...]); // batched: Flow\ETL\Rows - -$encoder = new RowsEncoder(); -$encoder->schema($schemaFrameBody); -$rowFrameBody = $encoder->row($row); // byte-identical to Flow\Floe\RowEncoder - -$segments = (new RowsEncoder())->rows($rows); // batched: framed ROW frames per section segment, - // list of Flow\Floe\FrameSegment -``` +The extension registers two native classes; the PHP side (`FloeStreamWriter`/`FloeStreamReader`) owns +file framing, sectioning, partitions, footer and — on read — skip/limit/padding, and picks the native +implementation automatically: + +- **`Flow\Floe\RustFloeEncoderNative`** — the Floe ROW frame-body codec: + `encode(list, schemaBody)` returns the encoded frame bodies, + `decode(list, schemaBody)` returns `list`. The userland wrapper + `Flow\Floe\NativeFloeEncoder` carries the `Flow\ETL\Row\Encoder` interface, and + `Flow\Floe\AdaptiveFloeEncoder` — built by every writer/reader — selects it over + `Flow\Floe\PhpFloeEncoder` when the extension is loaded. +- **`Flow\ETL\Row\RustRowHydratorNative`** — the native `hydrate`/`cast`/`dehydrate` behind + `Flow\ETL\Row\NativeRowHydrator`, which `Flow\ETL\Row\AdaptiveRowHydrator` (the config default) + selects when the extension is loaded — used by adapter loaders and raw-scalar extractors such as + CSV, JSON or XML. `cast(batch, Schema)` casts raw scalars and builds entries in a single native + pass; values outside the proven native subset (and every exotic type such as enum, xml or time) + cast per value through the schema's PHP `Type::cast`, so results and exceptions match + `PhpRowHydrator` exactly. Schema-less `cast` (type inference) stays PHP. Hydrate and cast plans are + cached on the `Schema` object identity and rebuilt only when a different schema arrives. All extension failures throw `Flow\Floe\Exception\ExtensionException`; `FloeReader`/`FloeWriter` wrap it as `Flow\Floe\Exception\FloeException`. There is no silent fallback to the PHP engine. diff --git a/documentation/upgrading.md b/documentation/upgrading.md index 2d7a3d5305..65289dd380 100644 --- a/documentation/upgrading.md +++ b/documentation/upgrading.md @@ -268,31 +268,37 @@ built from the missing, mismatched (`MismatchedDefinition`), and unexpected defi `{name}` in a path is now a partition placeholder resolved from `partitionBy()` columns; strip braces from partition values before partitioning. -### 19) `flow-php/etl` - `Cache` stores only `Rows` and gained `read()`; cache indexes are stored as `Rows` +### 19) `flow-php/etl` - `Cache` stores only `Rows`; cache indexes are stored as `Rows` -| Before | After | -|---------------------------------------------------|---------------------------------------------------------------| -| `Cache::get(string): Row\|Rows\|CacheIndex` | `Cache::get(string): Rows` | -| `Cache::set(string, Row\|Rows\|CacheIndex): void` | `Cache::set(string, Rows): void` | -| — | `Cache::read(string $key): Generator` (yields `Rows` batches) | -| `$cache->set($id, $row)` | `$cache->set($id, rows($row))` | -| `$cache->set($id, $cacheIndex)` | `$cache->set($id, $cacheIndex->toRows())` | -| `$cache->get($id)` returning `CacheIndex` | `CacheIndex::fromRows($id, $cache->get($id))` | +| Before | After | +|---------------------------------------------------|-----------------------------------------------| +| `Cache::get(string): Row\|Rows\|CacheIndex` | `Cache::get(string): Rows` | +| `Cache::set(string, Row\|Rows\|CacheIndex): void` | `Cache::set(string, Rows): void` | +| `$cache->set($id, $row)` | `$cache->set($id, rows($row))` | +| `$cache->set($id, $cacheIndex)` | `$cache->set($id, $cacheIndex->toRows())` | +| `$cache->get($id)` returning `CacheIndex` | `CacheIndex::fromRows($id, $cache->get($id))` | -Custom `Cache` implementations must adopt the `Rows`-only signatures and add `read()`; the minimal -implementation is `yield $this->get($key);`. +Custom `Cache` implementations must adopt the `Rows`-only signatures. ### 20) `flow-php/etl` - cache and serialization use the Floe (`.floe`) binary format; datetime subclasses rejected -| Before | After | -|----------------------------------------------------------------------------------------|-----------------------------------------------| -| `config_builder()->serializer()` default `Base64Serializer(new NativePHPSerializer())` | `Flow\Floe\FloeSerializer` | -| `filesystem_cache($cache_dir, $filesystem, $serializer)` | `filesystem_cache($cache_dir, $filesystem)` | -| `new FilesystemCache($filesystem, $serializer, $cacheDir)` | `new FilesystemCache($filesystem, $cacheDir)` | -| `CacheConfigBuilder::build($fstab, $serializer, …)` | `CacheConfigBuilder::build($fstab, …)` | -| caching or serializing a `DateTime`/`DateTimeImmutable` subclass (e.g. Carbon) | throws `Flow\Floe\Exception\FloeException` | +| Before | After | +|----------------------------------------------------------------------------------------|------------------------------------------------------------------------| +| `config_builder()->serializer()` default `Base64Serializer(new NativePHPSerializer())` | `Flow\Floe\FloeSerializer` | +| `filesystem_cache(..., Serializer $serializer = new NativePHPSerializer())` | `filesystem_cache(..., Serializer $serializer = new FloeSerializer())` | +| `new FilesystemCache($filesystem, $serializer, $cacheDir)` | `new FilesystemCache($filesystem, $cacheDir, $serializer)` | +| caching or serializing a `DateTime`/`DateTimeImmutable` subclass (e.g. Carbon) | throws `Flow\Floe\Exception\FloeException` | -Convert `DateTime`/`DateTimeImmutable` subclasses to `DateTime`/`DateTimeImmutable` before caching or serializing. +Delete cache directories written by 0.41 — the old serialized payloads are unreadable. Convert +`DateTime`/`DateTimeImmutable` subclasses to `DateTime`/`DateTimeImmutable` before caching or serializing. + +A Floe file carries exactly one schema, and sort / join / group-by spill batches through it — a pipeline with a +drifting or schemaless source must declare column types at the source so nullable columns carry a concrete type +(`DataFrame::match($schema)` validates but does not retype values): + +```php +->read(from_array($data, schema(str_schema('email'), float_schema('discount', nullable: true)))) +``` ### 21) `flow-php/symfony-telemetry-bundle` - `HttpKernelSpanSubscriber` takes a @@ -330,6 +336,119 @@ $config->sort->algorithm(SortAlgorithms::MEMORY_SORT); data_frame($config)->read(...)->sortBy(ref('id'))->run(); ``` +### 23) `flow-php/etl` - joins emit every matching right row and follow SQL semantics + +| Before | After | +|-----------------------------------------------------------------------|------------------------------------------------------------------------| +| inner/left/right join: first matching row per probe row | one output row per matching pair | +| left/left_anti join: left row dropped on hash collision without match | left row kept | +| duplicated right side rows collapsed into one | preserved | +| `DataFrame::join(..., Join::inner)`: duplicated join columns kept | duplicated join columns dropped (empty prefix) | +| `Equal` on object values (Uuid, etc.): always `false` | compared with `==` | +| `Flow\ETL\Processor\HashJoin\HashTable` | `Flow\ETL\Join\HashJoin\HashTable` | +| `Flow\ETL\Processor\HashJoin\Bucket` | removed | +| — | `Expression::comparison()`, `All::comparisons()`, `Any::comparisons()` | + +`Rows::joinRight()` emits matched rows in left-probe order and unmatched right rows last. + +### 24) `flow-php/etl` - join buckets storage is configurable, spills to disk by default + +| Before | After | +|----------------------------------------------------|-----------------------------------------------------------------------------| +| `join()` holds right side in memory, keeps left row order | join buckets spilled to disk (Floe files), left row order not preserved | +| — | `ConfigBuilder::joinCache(BucketsCache)` (default `FilesystemBucketsCache`) | +| — | `ConfigBuilder::joinBucketsCount(int)` (default `64`) | +| — | `ConfigBuilder::joinBatchSize(int)` (default `1000`) | +| — | `Flow\ETL\Sort\ExternalSort\ResidentBucketsCache` | +| — | `Flow\ETL\Sort\ExternalSort\BucketsCache\InMemoryBucketsCache` | + +To keep the right side in memory and preserve left row order: + +```php +data_frame(config_builder()->joinCache(new InMemoryBucketsCache())) + ->read(...) + ->join(...) + ->run(); +``` + +### 25) `flow-php/etl` - `Serializer` works on `Rows` and filesystem streams + +| Before | After | +|-------------------------------------------------------------------------------------------|---------------------------------------------------------------------------| +| `Serializer::serialize(object $serializable): string` | `Serializer::serialize(Rows $rows, DestinationStream $destination): void` | +| `Serializer::unserialize(string $serialized, array $classes): object` | `Serializer::unserialize(SourceStream $source): Rows` | +| `CompressingSerializer`/`NativePHPSerializer` throw `Flow\ETL\Exception\RuntimeException` | throw `Flow\Serializer\Exception\SerializationException` | +| — | `Flow\Floe\FloeSerializer` (the default) | + +### 26) `flow-php/etl` - `EntryFactory` API reshaped + +| Before | After | +|---------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------| +| `EntryFactory::create(string $entryName, mixed $value, Schema\|Definition\|null $schema = null)` | `EntryFactory::create(string $name, mixed $value, ?Type $type = null, ?Metadata $metadata = null)` | +| `EntryFactory::createAs(string $entryName, mixed $value, Type $type, ?Metadata $metadata = null)` | `EntryFactory::cast(string $name, mixed $value, Type $type, ?Metadata $metadata = null)` | +| — | `EntryFactory::fromDefinition(Definition $definition, mixed $value): Entry` | +| `to_entry($name, $data, EntryFactory $entryFactory)` | `to_entry($name, $data, EntryFactory $entryFactory = new EntryFactory())` | +| `ConfigBuilder::build(EntryFactory $entryFactory = new EntryFactory())` | `ConfigBuilder::build()` | + +### 27) `flow-php/etl` - `Encoder`/`Hydrator` contracts; hydrator configured on the context + +| Before | After | +|---------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| — | `Flow\ETL\Row\Encoder`: `encode(list): list`, `decode(list): list` | +| — | `Flow\ETL\Row\Hydrator`: `cast(list, ?Schema): Rows`, `hydrate(list, ?Schema): Rows`, `dehydrate(Rows): list` | +| — | `Flow\ETL\Row\RawRowValues`, `Flow\ETL\Row\TypedRowValues` | +| — | `Flow\ETL\Row\PhpRowHydrator`, `NativeRowHydrator`, `AdaptiveRowHydrator` (the default) | +| — | `ConfigBuilder::hydrator(Hydrator)`, `Config::hydrator()`, `FlowContext::hydrator()` | +| `array_to_row($data, EntryFactory $entryFactory, ...)` | `array_to_row($data, Hydrator $hydrator = new AdaptiveRowHydrator(), ...)` | +| `array_to_rows($data, EntryFactory $entryFactory, ...)` | `array_to_rows($data, Hydrator $hydrator = new AdaptiveRowHydrator(), ...)` | + +`cast()` coerces untrusted values through the schema (`null` schema infers types); `hydrate()` instantiates trusted, +already-typed values and requires a schema. A custom extractor reading raw values (CSV, JSON, XML, Excel, Text, +Google Sheet, PostgreSQL, Doctrine) calls `$context->hydrator()->cast(...)`; a self-describing source (Parquet, Floe) +calls `$context->hydrator()->hydrate(...)`. + +Under a schema, entries emit in schema-definition order (was data-key order with missing columns appended); a schema +column missing from the source hydrates as a typed null (was a `StringEntry` null); a column absent from the schema is +dropped. When the `flow_php` extension is loaded, `AdaptiveRowHydrator` runs hydration natively — pin the pure-PHP +engine with `config_builder()->hydrator(new PhpRowHydrator())`. + +### 28) `flow-php/etl-adapter-csv`, `-json`, `-parquet`, `-xml`, `-excel`, `-doctrine`, `-postgresql`, `-seal`, `-text`, + +`-google-sheet` - per-format `Encoder`s replace normalizers + +| Before | After | +|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------| +| `Flow\ETL\Adapter\CSV\RowsNormalizer`, `RowsNormalizer\EntryNormalizer`, `RowsNormalizer\ScalarCast` | `Flow\ETL\Adapter\CSV\CSVEncoder` | +| `Flow\ETL\Adapter\JSON\RowsNormalizer`, `RowsNormalizer\EntryNormalizer` | `Flow\ETL\Adapter\JSON\JSONEncoder` | +| `Flow\ETL\Adapter\Parquet\RowsNormalizer` | `Flow\ETL\Adapter\Parquet\ParquetEncoder` | +| `Flow\ETL\Adapter\XML\RowsNormalizer`, `RowsNormalizer\EntryNormalizer`, `RowsNormalizer\EntryNormalizer\PHPValueNormalizer` | `Flow\ETL\Adapter\XML\XMLEncoder` | +| `Flow\ETL\Adapter\Excel\RowsNormalizer\ExcelRowsNormalizer` | `Flow\ETL\Adapter\Excel\ExcelEncoder` | +| `Flow\ETL\Adapter\Doctrine\RowsNormalizer` | `Flow\ETL\Adapter\Doctrine\DbalEncoder` | +| `Flow\ETL\Adapter\Seal\RowsNormalizer`, `RowsNormalizer\EntryNormalizer` | `Flow\ETL\Adapter\Seal\SealEncoder` | +| — | `Flow\ETL\Adapter\Text\TextEncoder`, `Flow\ETL\Adapter\PostgreSql\PostgreSqlEncoder`, `Flow\ETL\Adapter\GoogleSheet\GoogleSheetEncoder` | +| `Flow\ETL\Adapter\Doctrine\TypesMap::flowRowTypes(Row)` | `TypesMap::flowSchemaTypes(Schema)` | +| `Flow\ETL\Adapter\PostgreSql\EntryTypesMap::mapEntry(Entry)` | `EntryTypesMap::map(string $column, Type $type, mixed $value)` | +| `InsertQueryBuilder::build(Rows, ...)` | `InsertQueryBuilder::build(array $values, Schema, ...)` | +| `UpdateQueryBuilder::build(Row, ...)`, `DeleteQueryBuilder::build(Row, ...)` | `build(array $value, Schema, ...)` | +| CSV/JSON/XML/Excel/Seal writers (no `dateFormat`) | `dateFormat = 'Y-m-d'` encoder constructor param | +| Excel `timeFormat = 'H:i:s'` | `timeFormat = '%H:%I:%S'` | +| — | `withDateFormat()` on `CSVLoader`, `JsonLoader`, `JsonLinesLoader`, `XMLLoader`, `ExcelLoader`, `SealLoader`; `SealLoader::withDateTimeFormat()` | + +Behavioural changes: CSV/JSON/XML/Excel/Seal `date` columns render with `dateFormat` (`Y-m-d`, was `dateTimeFormat`); +XML `date`/`time` columns render (was `InvalidArgumentException`); Seal `time` columns render as microseconds (was +`null`); Google Sheet `_spread_sheet_id`/`_sheet_name` are appended to the schema under `putInputIntoRows()` (were +dropped when a schema was set); Excel now appends `_input_file_uri` under `putInputIntoRows()`. + +### 29) `flow-php/etl` - null is a first-class `NullEntry`/`NullDefinition`; `from_null` metadata removed + +| Before | After | +|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------| +| `null_entry($name)` → `StringEntry` (type `string`, `from_null` metadata) | `null_entry($name)` → `Flow\ETL\Row\Entry\NullEntry` (type `null`) | +| `null_schema($name)` → `StringDefinition` + `from_null` metadata | `null_schema($name)` → `Flow\ETL\Schema\Definition\NullDefinition` (always nullable) | +| `Flow\ETL\Row\Entry\StringEntry::fromNull($name, $metadata)` | `null_entry($name, $metadata)` | +| `new StringEntry($name, $value, $metadata, fromNull: true)` | `$fromNull` constructor flag removed | +| `Flow\ETL\Schema\Metadata::FROM_NULL` | removed | + --- ## Upgrading from 0.40.x to 0.41.x diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0a5d5c2f9f..e320126b61 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -285,6 +285,9 @@ src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Integration + + src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Unit + src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Integration diff --git a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVEncoder.php b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVEncoder.php new file mode 100644 index 0000000000..3f68815117 --- /dev/null +++ b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVEncoder.php @@ -0,0 +1,271 @@ + + */ +final class CSVEncoder implements Encoder +{ + /** + * @var null|resource + */ + private $buffer = null; + + private readonly CSVRowNormalizer $rowNormalizer; + + /** + * @var null|list + */ + private ?array $headers = null; + + public function __construct( + private readonly bool $withHeader = true, + private readonly string $separator = ',', + private readonly string $enclosure = '"', + private readonly string $escape = '\\', + bool $emptyToNull = true, + private readonly string $dateTimeFormat = DateTimeInterface::ATOM, + private readonly string $dateFormat = 'Y-m-d', + private readonly string $newLineSeparator = PHP_EOL, + ) { + $this->rowNormalizer = new CSVRowNormalizer($emptyToNull); + } + + public function decode(array $batch): array + { + $maps = []; + + foreach ($batch as $line) { + $fields = array_values(array_map( + static fn(mixed $field): ?string => is_string($field) ? $field : null, + str_getcsv($line, $this->separator, $this->enclosure, $this->escape), + )); + + if ($this->headers === null) { + if ($this->withHeader) { + $this->headers = $this->mapHeaders($fields); + + continue; + } + + $this->headers = $this->generateAutoHeaders(count($fields)); + } + + $maps[] = new RawRowValues(array_combine( + $this->headers, + $this->rowNormalizer->normalize($fields, count($this->headers)), + )); + } + + return $maps; + } + + public function encode(array $batch): array + { + $lines = []; + + foreach ($batch as $rowValues) { + $fields = []; + + /** @var mixed $value */ + foreach ($rowValues->values as $name => $value) { + $fields[] = $this->renderValue($rowValues->types[$name], $value); + } + + $lines[] = $this->line($fields); + } + + return $lines; + } + + /** + * @param list $headers + */ + public function encodeHeader(array $headers): string + { + return $this->line($headers); + } + + /** + * @return list + */ + private function generateAutoHeaders(int $count): array + { + $headers = []; + + for ($i = 0; $i < $count; $i++) { + $headers[] = 'e' . str_pad((string) $i, 2, '0', STR_PAD_LEFT); + } + + return $headers; + } + + /** + * @param array $headers + * + * @return list + */ + private function mapHeaders(array $headers): array + { + $headers = array_map(static fn(mixed $header): string => trim(match (true) { + is_string($header) => $header, + is_numeric($header) => (string) $header, + $header === null => '', + default => is_scalar($header) ? (string) $header : '', + }), $headers); + + return array_values(array_map( + static fn(string $header, int|string $index): string => $header !== '' + ? $header + : 'e' . str_pad((string) $index, 2, '0', STR_PAD_LEFT), + $headers, + array_keys($headers), + )); + } + + /** + * @param list $fields + */ + private function line(array $fields): string + { + $buffer = $this->buffer(); + ftruncate($buffer, 0); + rewind($buffer); + + fputcsv( + stream: $buffer, + fields: $fields, + separator: $this->separator, + enclosure: $this->enclosure, + escape: $this->escape, + eol: $this->newLineSeparator, + ); + + $line = stream_get_contents($buffer, offset: 0); + + if ($line === false) { + throw new RuntimeException('Failed to render a CSV line'); + } + + return $line; + } + + private function renderValue(Type $type, mixed $value): string|float|int|bool|null + { + if ($value === null) { + return null; + } + + return match ($type::class) { + DateTimeType::class => $value instanceof DateTimeInterface ? $value->format($this->dateTimeFormat) : '', + DateType::class => $value instanceof DateTimeInterface ? $value->format($this->dateFormat) : '', + TimeType::class => $value instanceof DateInterval ? date_interval_to_microseconds($value) : '', + EnumType::class => $value instanceof UnitEnum ? $value->name : '', + JsonType::class => $value instanceof Json ? $value->toString() : '', + UuidType::class => $value instanceof Uuid ? $value->toString() : '', + XMLType::class, XMLElementType::class => $this->xmlToString($value), + ListType::class, MapType::class, StructureType::class, ArrayType::class => is_array($value) + ? json_encode($value, JSON_THROW_ON_ERROR) + : '', + default => $this->scalar($value), + }; + } + + private function scalar(mixed $value): string|float|int|bool + { + return match (true) { + is_string($value), is_int($value), is_float($value), is_bool($value) => $value, + is_resource($value), $value instanceof Stringable => (string) $value, + default => '', + }; + } + + private function xmlToString(mixed $value): string + { + return match (true) { + $value instanceof DOMDocument => $this->domString($value->saveXML($value->documentElement)), + $value instanceof XMLDocument => $this->domString($value->saveXml($value->documentElement)), + $value instanceof DOMElement => $this->domString($value->C14N()), + $value instanceof Element => $this->domString($value->c14n()), + default => '', + }; + } + + private function domString(string|false $serialized): string + { + if ($serialized === false) { + throw new RuntimeException('Failed to serialize XML document.'); + } + + return $serialized; + } + + /** + * @return resource + */ + private function buffer() + { + if (is_resource($this->buffer)) { + return $this->buffer; + } + + $buffer = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'rb+'); + + if ($buffer === false) { + throw new RuntimeException('Failed to open a temporary CSV buffer'); + } + + return $this->buffer = $buffer; + } +} diff --git a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVExtractor.php b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVExtractor.php index adf00e8df2..32719d6170 100644 --- a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVExtractor.php +++ b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVExtractor.php @@ -12,22 +12,14 @@ use Flow\ETL\Extractor\PathFiltering; use Flow\ETL\Extractor\Signal; use Flow\ETL\FlowContext; +use Flow\ETL\Row\RawRowValues; use Flow\ETL\Rows; use Flow\ETL\Schema; use Flow\Filesystem\Path; use Generator; -use function array_combine; -use function array_keys; -use function array_map; use function count; -use function Flow\ETL\DSL\array_to_rows; -use function is_numeric; -use function is_scalar; -use function is_string; -use function str_getcsv; -use function str_pad; -use function trim; +use function Flow\ETL\DSL\str_schema; final class CSVExtractor implements Extractor, FileExtractor, LimitableExtractor { @@ -65,6 +57,17 @@ public function __construct( public function extract(FlowContext $context): Generator { $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); + $baseSchema = $this->schema; + + if ( + $baseSchema !== null + && $shouldPutInputIntoRows + && $baseSchema->findDefinition('_input_file_uri') === null + ) { + $baseSchema = $baseSchema->add(str_schema('_input_file_uri')); + } foreach ($context->streams()->list($this->path, $this->filter()) as $stream) { $option = csv_detect_separator($stream); @@ -72,44 +75,93 @@ public function extract(FlowContext $context): Generator $separator = $this->separator ?? $option->separator; $enclosure = $this->enclosure ?? $option->enclosure; $escape = $this->escape ?? $option->escape; - $uri = $stream->path()->uri(); + $streamUri = $shouldPutInputIntoRows ? $stream->path()->uri() : null; $partitions = $stream->path()->partitions(); - $headers = []; - $headersCount = 0; - $streamUri = $shouldPutInputIntoRows ? $uri : null; + $schema = $baseSchema; + + if ($schema !== null) { + foreach ($partitions as $partition) { + if ($schema->findDefinition($partition->name) === null) { + $schema = $schema->add(str_schema($partition->name)); + } + } + } + + $lines = (new CSVLineReader($enclosure, $this->charactersReadInLine, $this->removeBOM))->readLines($stream); + + if (!$lines->valid()) { + $stream->close(); + + continue; + } + + $encoder = new CSVEncoder( + withHeader: $this->withHeader, + separator: $separator, + enclosure: $enclosure, + escape: $escape, + emptyToNull: $this->emptyToNull, + ); - $csvLineReader = new CSVLineReader($enclosure, $this->charactersReadInLine, $this->removeBOM); - $rowNormalizer = new CSVRowNormalizer($this->emptyToNull); + $rawLines = []; - foreach ($csvLineReader->readLines($stream) as $csvLine) { - $rowData = array_values(array_map( - static fn(mixed $field): ?string => is_string($field) ? $field : null, - str_getcsv($csvLine, $separator, $enclosure, $escape), - )); - $rowDataCount = count($rowData); + while (($line = $lines->current()) !== null) { + $rawLines[] = $line; - if ([] === $headers) { - if ($this->withHeader) { - $headers = $this->mapHeaders($rowData); - $headersCount = $rowDataCount; + if (count($rawLines) >= $batchSize) { + $batch = []; - continue; + foreach ($encoder->decode($rawLines) as $rowValues) { + $row = $rowValues->values; + + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($row); } - $headers = $this->generateAutoHeaders($rowDataCount); - $headersCount = $rowDataCount; + $rawLines = []; + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + + return; + } + } } - $rowData = $rowNormalizer->normalize($rowData, $headersCount); + $lines->next(); + } + + $batch = []; - $row = array_combine($headers, $rowData); + foreach ($encoder->decode($rawLines) as $rowValues) { + $row = $rowValues->values; if ($streamUri !== null) { $row['_input_file_uri'] = $streamUri; } - $signal = yield array_to_rows($row, $context->entryFactory(), $partitions, $this->schema); + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($row); + } + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); $this->incrementReturnedRows(); @@ -175,9 +227,6 @@ public function withHeader(bool $withHeader): self return $this; } - /** - * @param Schema $schema - */ public function withSchema(Schema $schema): self { $this->schema = $schema; @@ -191,41 +240,4 @@ public function withSeparator(string $separator): self return $this; } - - /** - * @return array - */ - private function generateAutoHeaders(int $count): array - { - $headers = []; - - for ($i = 0; $i < $count; $i++) { - $headers[$i] = 'e' . str_pad((string) $i, 2, '0', STR_PAD_LEFT); - } - - return $headers; - } - - /** - * @param array $headers - * - * @return array - */ - private function mapHeaders(array $headers): array - { - $headers = array_map(static fn(mixed $header): string => trim(match (true) { - is_string($header) => $header, - is_numeric($header) => (string) $header, - $header === null => '', - default => is_scalar($header) ? (string) $header : '', - }), $headers); - - return array_values(array_map( - static fn(string $header, int|string $index): string => $header !== '' - ? $header - : 'e' . str_pad((string) $index, 2, '0', STR_PAD_LEFT), - $headers, - array_keys($headers), - )); - } } diff --git a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVLoader.php b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVLoader.php index b52b69e5e4..77bf00065c 100644 --- a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVLoader.php +++ b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/CSVLoader.php @@ -5,34 +5,29 @@ namespace Flow\ETL\Adapter\CSV; use DateTimeInterface; -use Flow\ETL\Adapter\CSV\RowsNormalizer\EntryNormalizer; use Flow\ETL\Config\Telemetry\TelemetryAttributes; -use Flow\ETL\Exception\RuntimeException; use Flow\ETL\FlowContext; use Flow\ETL\Loader; use Flow\ETL\Loader\Closure; use Flow\ETL\Loader\FileLoader; -use Flow\ETL\Row\Entry; use Flow\ETL\Rows; -use Flow\Filesystem\DestinationStream; use Flow\Filesystem\Partition; use Flow\Filesystem\Path; use Flow\Filesystem\Path\Option; use Flow\Filesystem\Path\Option\ContentType; use Throwable; -use function fclose; -use function fopen; -use function fputcsv; -use function ftruncate; -use function is_resource; -use function rewind; -use function stream_get_contents; +use function array_values; +use function implode; final class CSVLoader implements Closure, FileLoader, Loader { + private string $dateFormat = 'Y-m-d'; + private string $dateTimeFormat = DateTimeInterface::ATOM; + private ?CSVEncoder $encoder = null; + private string $enclosure = '"'; private string $escape = '\\'; @@ -43,11 +38,6 @@ final class CSVLoader implements Closure, FileLoader, Loader private readonly Path $path; - /** - * @var null|closed-resource|resource - */ - private $rowBuffer = null; - private string $separator = ','; public function __construct(Path $path) @@ -57,12 +47,6 @@ public function __construct(Path $path) public function closure(FlowContext $context): void { - if (is_resource($this->rowBuffer)) { - fclose($this->rowBuffer); - } - - $this->rowBuffer = null; - $context->streams()->closeStreams($this->path); } @@ -82,17 +66,12 @@ public function load(Rows $rows, FlowContext $context): void ]); try { - $normalizer = new RowsNormalizer(new EntryNormalizer($this->dateTimeFormat)); - - $headers = $rows - ->first() - ->entries() - ->map(static fn(Entry $entry) => $entry->name()); + $headers = array_values($rows->first()->entries()->names()); if ($rows->partitions()->count()) { - $this->write($rows, $headers, $context, $rows->partitions()->toArray(), $normalizer); + $this->write($rows, $headers, $context, $rows->partitions()->toArray()); } else { - $this->write($rows, $headers, $context, [], $normalizer); + $this->write($rows, $headers, $context, []); } $context->telemetry()->loadingCompleted($this, [TelemetryAttributes::ATTR_LOADING_ROWS => $rows->count()]); @@ -103,6 +82,13 @@ public function load(Rows $rows, FlowContext $context): void } } + public function withDateFormat(string $dateFormat): self + { + $this->dateFormat = $dateFormat; + + return $this; + } + public function withDateTimeFormat(string $dateTimeFormat): self { $this->dateTimeFormat = $dateTimeFormat; @@ -146,70 +132,35 @@ public function withSeparator(string $separator): self } /** - * @param array $headers + * @param list $headers * @param array $partitions */ - public function write( - Rows $nextRows, - array $headers, - FlowContext $context, - array $partitions, - RowsNormalizer $normalizer, - ): void { + public function write(Rows $nextRows, array $headers, FlowContext $context, array $partitions): void + { $streams = $context->streams(); - if ($this->header && !$streams->isOpen($this->path, $partitions)) { - $this->writeCSV([$headers], $streams->writeTo($this->path, $partitions)); - } - - $this->writeCSV($normalizer->normalize($nextRows), $streams->writeTo($this->path, $partitions)); - } - - /** - * @param iterable> $rows - */ - private function writeCSV(iterable $rows, DestinationStream $stream): void - { - $buffer = $this->rowBuffer(); - - ftruncate($buffer, 0); - rewind($buffer); - - foreach ($rows as $row) { - fputcsv( - stream: $buffer, - fields: $row, - separator: $this->separator, - enclosure: $this->enclosure, - escape: $this->escape, - eol: $this->newLineSeparator, - ); - } + $encoder = $this->encoder(); - $csvData = stream_get_contents($buffer, offset: 0); + $writeHeader = $this->header && !$streams->isOpen($this->path, $partitions); + $stream = $streams->writeTo($this->path, $partitions); - if ($csvData === false) { - throw new RuntimeException('Failed to read temporary stream for CSV rows'); + if ($writeHeader) { + $stream->append($encoder->encodeHeader($headers)); } - $stream->append($csvData); + $stream->append(implode('', $encoder->encode($context->hydrator()->dehydrate($nextRows)))); } - /** - * @return resource - */ - private function rowBuffer() + private function encoder(): CSVEncoder { - if (!is_resource($this->rowBuffer)) { - $handle = fopen('php://temp/maxmemory:' . (5 * 1024 * 1024), 'rb+'); - - if ($handle === false) { - throw new RuntimeException('Failed to open temporary stream for CSV rows'); - } - - $this->rowBuffer = $handle; - } - - return $this->rowBuffer; + return $this->encoder ??= new CSVEncoder( + withHeader: $this->header, + separator: $this->separator, + enclosure: $this->enclosure, + escape: $this->escape, + dateTimeFormat: $this->dateTimeFormat, + dateFormat: $this->dateFormat, + newLineSeparator: $this->newLineSeparator, + ); } } diff --git a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer.php b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer.php deleted file mode 100644 index 2721fc0961..0000000000 --- a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer.php +++ /dev/null @@ -1,32 +0,0 @@ -> - */ - public function normalize(Rows $rows): Generator - { - foreach ($rows as $row) { - $normalizedRow = []; - - foreach ($row->entries() as $entry) { - $normalizedRow[] = $this->entryNormalizer->normalize($entry); - } - - yield $normalizedRow; - } - } -} diff --git a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/EntryNormalizer.php b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/EntryNormalizer.php deleted file mode 100644 index 0b4bbd55f8..0000000000 --- a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/EntryNormalizer.php +++ /dev/null @@ -1,53 +0,0 @@ - $entry - */ - public function normalize(Entry $entry): string|float|int|bool|null - { - return match ($entry::class) { - UuidEntry::class, XMLElementEntry::class, XMLEntry::class, JsonEntry::class => $entry->toString(), - DateTimeEntry::class => $entry->value()?->format($this->dateTimeFormat), - DateEntry::class => $entry->value()?->format($this->dateFormat), - TimeEntry::class => ($timeValue = $entry->value()) !== null - ? date_interval_to_microseconds($timeValue) - : null, - EnumEntry::class => $entry->value()?->name, - ListEntry::class, MapEntry::class, StructureEntry::class => json_encode( - $entry->value(), - JSON_THROW_ON_ERROR, - ), - default => ScalarCast::fromMixed($entry->value()), - }; - } -} diff --git a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/ScalarCast.php b/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/ScalarCast.php deleted file mode 100644 index ebe2c0f926..0000000000 --- a/src/adapter/etl-adapter-csv/src/Flow/ETL/Adapter/CSV/RowsNormalizer/ScalarCast.php +++ /dev/null @@ -1,54 +0,0 @@ -withSchema(schema( + int_schema('id', nullable: true), + str_schema('name', nullable: true), + bool_schema('active'), + )); + + $actual = []; + + foreach ($extractor->extract(flow_context(Config::builder()->putInputIntoRows()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + static::assertSame( + [ + ['id' => null, 'name' => null, 'active' => false, '_input_file_uri' => $path->uri()], + ['id' => 1, 'name' => 'Norbert', 'active' => null, '_input_file_uri' => $path->uri()], + ], + $actual, + ); + } + + public function test_honours_a_hydrator_configured_on_the_context(): void + { + $extractor = from_csv(path_real(__DIR__ . '/../Fixtures/file_with_empty_columns.csv')) + ->withSchema(schema( + int_schema('id', nullable: true), + str_schema('name', nullable: true), + bool_schema('active'), + )); + + $actual = []; + + foreach ($extractor->extract( + flow_context(Config::builder()->hydrator(new AdaptiveRowHydrator())->build()), + ) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + static::assertSame( + [ + ['id' => null, 'name' => null, 'active' => false], + ['id' => 1, 'name' => 'Norbert', 'active' => null], + ], + $actual, + ); + } + + public function test_reads_partitioned_files_with_schema_typed_partition_values(): void + { + $extractor = from_csv(__DIR__ . '/../Fixtures/partitioned/group=*/*.csv')->withSchema(schema( + int_schema('group'), + int_schema('id'), + str_schema('value'), + )); + + $actual = []; + $partitions = []; + + foreach ($extractor->extract(flow_context(Config::builder()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + + foreach ($rows->partitions() as $partition) { + $partitions[$partition->name] = true; + } + } + + usort($actual, static fn(array $a, array $b): int => (int) $a['id'] <=> (int) $b['id']); + + static::assertSame( + [ + ['group' => 1, 'id' => 1, 'value' => 'a'], + ['group' => 1, 'id' => 2, 'value' => 'b'], + ['group' => 1, 'id' => 3, 'value' => 'c'], + ['group' => 1, 'id' => 4, 'value' => 'd'], + ['group' => 2, 'id' => 5, 'value' => 'e'], + ['group' => 2, 'id' => 6, 'value' => 'f'], + ['group' => 2, 'id' => 7, 'value' => 'g'], + ['group' => 2, 'id' => 8, 'value' => 'h'], + ], + $actual, + ); + static::assertArrayHasKey('group', $partitions); + } + + public function test_appends_partition_columns_absent_from_the_schema(): void + { + $extractor = from_csv(__DIR__ . '/../Fixtures/partitioned/group=1/file_01.csv')->withSchema(schema( + int_schema('id'), + str_schema('value'), + )); + + $actual = []; + + foreach ($extractor->extract(flow_context(Config::builder()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + usort($actual, static fn(array $a, array $b): int => (int) $a['id'] <=> (int) $b['id']); + + static::assertSame( + [ + ['id' => 1, 'value' => 'a', 'group' => '1'], + ['id' => 2, 'value' => 'b', 'group' => '1'], + ], + $actual, + ); + } +} diff --git a/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Integration/CSVLineReaderTest.php b/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Integration/CSVLineReaderTest.php index 7de111238f..eefee60676 100644 --- a/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Integration/CSVLineReaderTest.php +++ b/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Integration/CSVLineReaderTest.php @@ -15,28 +15,6 @@ final class CSVLineReaderTest extends FlowTestCase { use OperatingSystem; - public function test_memory_usage_with_large_multiline_csv(): void - { - $path = __DIR__ . '/../Fixtures/large_multiline_csv.csv'; - $memoryBefore = memory_get_usage(true); - - $stream = NativeLocalSourceStream::open(path_real($path)); - $reader = new CSVLineReader('"'); - $lines = iterator_to_array($reader->readLines($stream)); - - $memoryAfter = memory_get_usage(true); - $memoryUsed = $memoryAfter - $memoryBefore; - - static::assertCount(11, $lines); - - static::assertLessThan(50 * 1024 * 1024, $memoryUsed, 'Memory usage should be reasonable'); - - static::assertSame('"id","content"', $lines[0]); - static::assertStringStartsWith('"0","Line 0 content', $lines[1]); - - $stream->close(); - } - public function test_reading_csv_with_custom_character_limit(): void { $path = __DIR__ . '/../Fixtures/more_than_1000_characters_per_line.csv'; @@ -87,28 +65,6 @@ public function test_reading_csv_with_escaped_quotes_file(): void $stream->close(); } - public function test_reading_large_csv_file_performance(): void - { - $path = __DIR__ . '/../Fixtures/large_performance_csv.csv'; - $startTime = microtime(true); - - $stream = NativeLocalSourceStream::open(path_real($path)); - $reader = new CSVLineReader('"'); - $lines = iterator_to_array($reader->readLines($stream)); - - $endTime = microtime(true); - $executionTime = $endTime - $startTime; - - static::assertCount(10001, $lines); - - static::assertLessThan(1.0, $executionTime, 'Reading 10,000 rows should complete in less than 1 second'); - - static::assertSame('id,name,value,description', $lines[0]); - static::assertSame('9999,name_9999,value_9999,description_9999', $lines[10000]); - - $stream->close(); - } - public function test_reading_multiline_csv_file(): void { $path = __DIR__ . '/../Fixtures/multiline_strings.csv'; diff --git a/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/CSVEncoderTest.php b/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/CSVEncoderTest.php new file mode 100644 index 0000000000..a1d25c9830 --- /dev/null +++ b/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/CSVEncoderTest.php @@ -0,0 +1,150 @@ +decode(['id,name'])); + static::assertSame(['id' => '1', 'name' => 'Norbert'], $encoder->decode(['1,Norbert'])[0]->values); + } + + public function test_decode_generates_auto_headers_when_header_is_disabled(): void + { + static::assertSame( + ['e00' => '1', 'e01' => 'Norbert'], + (new CSVEncoder(withHeader: false))->decode(['1,Norbert'])[0]->values, + ); + } + + public function test_decode_keeps_empty_fields_when_empty_to_null_is_disabled(): void + { + static::assertSame( + ['id' => '1', 'name' => ''], + (new CSVEncoder(emptyToNull: false))->decode(['id,name', '1,'])[0]->values, + ); + } + + public function test_decode_maps_fields_to_headers(): void + { + static::assertSame( + ['id' => '1', 'name' => 'Norbert'], + (new CSVEncoder())->decode(['id,name', '1,Norbert'])[0]->values, + ); + } + + public function test_decode_pads_short_rows_with_null(): void + { + static::assertSame(['id' => '1', 'name' => null], (new CSVEncoder())->decode(['id,name', '1'])[0]->values); + } + + public function test_decode_truncates_rows_longer_than_the_headers(): void + { + static::assertSame( + ['id' => '1', 'name' => 'Norbert'], + (new CSVEncoder())->decode(['id,name', '1,Norbert,extra'])[0]->values, + ); + } + + public function test_decode_turns_empty_fields_into_null_by_default(): void + { + static::assertSame(['id' => '1', 'name' => null], (new CSVEncoder())->decode(['id,name', '1,'])[0]->values); + } + + public function test_encode_renders_array_values_as_json(): void + { + static::assertSame( + ["\"[1,2,3]\"\n"], + (new CSVEncoder(newLineSeparator: "\n"))->encode([ + new TypedRowValues(['tags' => [1, 2, 3]], ['tags' => type_array()]), + ]), + ); + } + + public function test_encode_renders_date_with_the_date_format(): void + { + static::assertSame( + ["2023-10-01\n"], + (new CSVEncoder(newLineSeparator: "\n"))->encode([ + new TypedRowValues(['at' => new DateTimeImmutable('2023-10-01 12:02:01 UTC')], ['at' => type_date()]), + ]), + ); + } + + public function test_encode_renders_datetime_with_the_datetime_format(): void + { + static::assertSame( + ["2023-10-01T12:02:01+00:00\n"], + (new CSVEncoder(newLineSeparator: "\n"))->encode([ + new TypedRowValues(['at' => new DateTimeImmutable('2023-10-01 12:02:01 UTC')], [ + 'at' => type_datetime(), + ]), + ]), + ); + } + + public function test_encode_renders_null_as_an_empty_field(): void + { + static::assertSame( + ["\n"], + (new CSVEncoder(newLineSeparator: "\n"))->encode([ + new TypedRowValues(['name' => null], ['name' => type_string()]), + ]), + ); + } + + public function test_encode_renders_scalars_verbatim_in_value_order(): void + { + static::assertSame( + ["9.99,1,Norbert\n"], + (new CSVEncoder(newLineSeparator: "\n"))->encode([ + new TypedRowValues(['price' => 9.99, 'id' => 1, 'name' => 'Norbert'], [ + 'price' => type_float(), + 'id' => type_integer(), + 'name' => type_string(), + ]), + ]), + ); + } + + public function test_encode_renders_time_as_microseconds(): void + { + static::assertSame( + ["3600000000\n"], + (new CSVEncoder(newLineSeparator: "\n"))->encode([ + new TypedRowValues(['duration' => new DateInterval('PT1H')], ['duration' => type_time()]), + ]), + ); + } + + public function test_encode_renders_uuid_as_string(): void + { + static::assertSame( + ["f47ac10b-58cc-4372-a567-0e02b2c3d479\n"], + (new CSVEncoder(newLineSeparator: "\n"))->encode([ + new TypedRowValues(['id' => new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479')], ['id' => type_uuid()]), + ]), + ); + } +} diff --git a/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/EntryNormalizerTest.php b/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/EntryNormalizerTest.php deleted file mode 100644 index 0f78a8c43b..0000000000 --- a/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/EntryNormalizerTest.php +++ /dev/null @@ -1,62 +0,0 @@ - [str_entry('string', null), null]; - yield 'string' => [str_entry('string', 'value'), 'value']; - yield 'int' => [int_entry('integer', 1), 1]; - yield 'int_nullable' => [int_entry('integer', null), null]; - yield 'float' => [float_entry('float', 1.1), 1.1]; - yield 'float_nullable' => [float_entry('float', null), null]; - yield 'bool' => [bool_entry('bool', true), 'true']; - yield 'bool_nullable' => [bool_entry('bool', null), null]; - yield 'null' => [null_entry('null'), null]; - yield 'date' => [date_entry('date', new DateTimeImmutable('2023-10-01 12:02:01')), '2023-10-01']; - yield 'date_nullable' => [date_entry('date', null), null]; - yield 'datetime' => [ - datetime_entry('datetime', new DateTimeImmutable('2023-10-01 12:02:01')), - '2023-10-01T12:02:01+00:00', - ]; - yield 'datetime_nullable' => [datetime_entry('datetime', null), null]; - yield 'time' => [time_entry('time', new DateInterval('PT1H')), 3600000000]; - yield 'time_nullable' => [time_entry('time', null), null]; - yield 'uuid' => [ - uuid_entry('uuid', 'f47ac10b-58cc-4372-a567-0e02b2c3d479'), - 'f47ac10b-58cc-4372-a567-0e02b2c3d479', - ]; - yield 'uuid_nullable' => [uuid_entry('uuid', null), null]; - } - - /** - * @param Entry $entry - */ - #[DataProvider('entries_provider')] - public function test_normalizing_entries(Entry $entry, mixed $expected): void - { - static::assertEquals($expected, (new EntryNormalizer())->normalize($entry)); - } -} diff --git a/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/ScalarCastTest.php b/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/ScalarCastTest.php deleted file mode 100644 index 7fb2b7261f..0000000000 --- a/src/adapter/etl-adapter-csv/tests/Flow/ETL/Adapter/CSV/Tests/Unit/ScalarCastTest.php +++ /dev/null @@ -1,86 +0,0 @@ -> + */ +final class DbalEncoder implements Encoder +{ + public function decode(array $batch): array + { + $decoded = []; + + foreach ($batch as $values) { + $decoded[] = new RawRowValues($values); + } + + return $decoded; + } + + public function encode(array $batch): array + { + $normalized = []; + + foreach ($batch as $rowValues) { + $values = $rowValues->values; + $row = []; + + /** @var mixed $value */ + foreach ($values as $name => $value) { + $row[$name] = $this->renderValue($value); + } + + $normalized[] = $row; + } + + return $normalized; + } + + private function renderValue(mixed $value): mixed + { + if ($value instanceof XMLDocument) { + return $this->domString($value->saveXml($value->documentElement)); + } + + if ($value instanceof DOMDocument) { + return $this->domString($value->saveXML($value->documentElement)); + } + + if ($value instanceof Element || $value instanceof DOMElement) { + return $this->elementToString($value); + } + + return $value; + } + + private function elementToString(Element|DOMElement $value): string + { + $ownerDocument = $value->ownerDocument; + + if ($ownerDocument === null) { + return ''; + } + + if ($ownerDocument instanceof XMLDocument) { + // @mago-ignore analysis:possibly-invalid-argument + return $this->domString($ownerDocument->saveXml($value)); + } + + /** @var false|string $serialized */ + // @mago-ignore analysis:possibly-invalid-argument,non-existent-method + $serialized = $ownerDocument->saveXML($value); + + return $this->domString($serialized); + } + + private function domString(string|false $serialized): string + { + if ($serialized === false) { + throw new RuntimeException('Failed to serialize XML document.'); + } + + return $serialized; + } +} diff --git a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalKeySetExtractor.php b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalKeySetExtractor.php index 6461ac2610..ac0c2f6404 100644 --- a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalKeySetExtractor.php +++ b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalKeySetExtractor.php @@ -19,7 +19,6 @@ use function array_key_exists; use function count; -use function Flow\ETL\DSL\array_to_rows; use function sha1; /** @@ -65,6 +64,7 @@ public function extract(FlowContext $context): Generator { $totalFetched = 0; $lastRow = null; + $encoder = new DbalEncoder(); while (true) { $qb = clone $this->queryBuilder; @@ -129,6 +129,7 @@ public function extract(FlowContext $context): Generator $stmt = $this->connection->executeQuery($qb->getSQL(), $qb->getParameters(), $qb->getParameterTypes()); $hasRows = false; + $rawBatch = []; while ($row = $stmt->fetchAssociative()) { $hasRows = true; @@ -142,7 +143,11 @@ public function extract(FlowContext $context): Generator } } - $signal = yield array_to_rows($row, $context->entryFactory(), [], $this->schema); + $rawBatch[] = $row; + } + + foreach ($context->hydrator()->cast($encoder->decode($rawBatch), $this->schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); $totalFetched++; diff --git a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLimitOffsetExtractor.php b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLimitOffsetExtractor.php index 52a1e86d8f..a240348fe4 100644 --- a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLimitOffsetExtractor.php +++ b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLimitOffsetExtractor.php @@ -15,7 +15,6 @@ use Generator; use function count; -use function Flow\ETL\DSL\array_to_rows; use function is_numeric; final class DbalLimitOffsetExtractor implements Extractor @@ -97,6 +96,7 @@ public function extract(FlowContext $context): Generator } $totalFetched = 0; + $encoder = new DbalEncoder(); for ($page = 0; $page < (new Pages($total, $this->pageSize))->pages(); $page++) { $offset = ($page * $this->pageSize) + $this->offset; @@ -107,8 +107,14 @@ public function extract(FlowContext $context): Generator ->executeQuery($pageQuery->getSQL(), $pageQuery->getParameters(), $pageQuery->getParameterTypes()) ->fetchAllAssociative(); + $rawBatch = []; + foreach ($pageResults as $row) { - $signal = yield array_to_rows($row, $context->entryFactory(), [], $this->schema); + $rawBatch[] = $row; + } + + foreach ($context->hydrator()->cast($encoder->decode($rawBatch), $this->schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); $totalFetched++; diff --git a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLoader.php b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLoader.php index c1e67ab68b..533bccb9fb 100644 --- a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLoader.php +++ b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalLoader.php @@ -29,6 +29,8 @@ final class DbalLoader implements Loader private ?Connection $connection = null; + private ?DbalEncoder $encoder = null; + private string $operation = 'insert'; private InsertOptions|UpdateOptions|null $operationOptions = null; @@ -80,13 +82,15 @@ public function load(Rows $rows, FlowContext $context): void try { $sortedRows = $rows->sortEntries(); - $normalizedData = (new RowsNormalizer())->normalize($sortedRows); // @mago-expect analysis:string-member-selector $this->bulk()->{$this->operation}( $this->connection(), $this->tableName, - new BulkData($normalizedData, $this->typesMap()->flowRowTypes($sortedRows->first())), + new BulkData( + $this->encoder()->encode($context->hydrator()->dehydrate($sortedRows)), + $this->typesMap()->flowSchemaTypes($sortedRows->schema()), + ), $this->operationOptions, ); @@ -138,6 +142,11 @@ private function bulk(): Bulk return $this->bulk; } + private function encoder(): DbalEncoder + { + return $this->encoder ??= new DbalEncoder(); + } + private function connection(): Connection { if ($this->connection === null) { diff --git a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalQueryExtractor.php b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalQueryExtractor.php index 5e5ec2cb68..1da60a9fe4 100644 --- a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalQueryExtractor.php +++ b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/DbalQueryExtractor.php @@ -15,8 +15,6 @@ use Flow\ETL\Schema; use Generator; -use function Flow\ETL\DSL\array_to_rows; - final class DbalQueryExtractor implements Extractor { private ParametersSet $parametersSet; @@ -63,9 +61,18 @@ public static function single( */ public function extract(FlowContext $context): Generator { + $hydrator = $context->hydrator(); + $encoder = new DbalEncoder(); + foreach ($this->parametersSet->all() as $parameters) { + $rawBatch = []; + foreach ($this->connection->fetchAllAssociative($this->query, $parameters, $this->types) as $row) { - $signal = yield array_to_rows($row, $context->entryFactory(), [], $this->schema); + $rawBatch[] = $row; + } + + foreach ($hydrator->cast($encoder->decode($rawBatch), $this->schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); if ($signal === Signal::STOP) { return; diff --git a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/RowsNormalizer.php b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/RowsNormalizer.php deleted file mode 100644 index 1b46608cef..0000000000 --- a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/RowsNormalizer.php +++ /dev/null @@ -1,38 +0,0 @@ -> - */ - public function normalize(Rows $rows): array - { - $normalizedData = []; - - foreach ($rows as $row) { - $normalizedRow = []; - - foreach ($row->entries() as $entry) { - if ($entry instanceof XMLEntry || $entry instanceof XMLElementEntry) { - $normalizedRow[$entry->name()] = $entry->toString(); - } else { - $normalizedRow[$entry->name()] = $entry->value(); - } - } - - $normalizedData[] = $normalizedRow; - } - - return $normalizedData; - } -} diff --git a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/TypesMap.php b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/TypesMap.php index 54da12fad5..f0f236e784 100644 --- a/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/TypesMap.php +++ b/src/adapter/etl-adapter-doctrine/src/Flow/ETL/Adapter/Doctrine/TypesMap.php @@ -26,7 +26,7 @@ use Doctrine\DBAL\Types\TimeType as DoctrineTimeType; use Doctrine\DBAL\Types\Type as DbalType; use Flow\ETL\Exception\InvalidArgumentException; -use Flow\ETL\Row; +use Flow\ETL\Schema; use Flow\Types\Type as FlowType; use Flow\Types\Type\Logical\DateTimeType; use Flow\Types\Type\Logical\DateType; @@ -133,23 +133,23 @@ public function __construct(array $map) } /** - * Build DBAL types array from a row's entries. + * Build DBAL types array from a schema's definitions. * * @return array Column name => DBAL Type instance */ - public function flowRowTypes(Row $row): array + public function flowSchemaTypes(Schema $schema): array { $types = []; $typeClassToName = array_flip(DbalType::getTypesMap()); - foreach ($row->entries() as $entry) { - $dbalTypeClass = $this->toDbalType($entry->type()::class); + foreach ($schema->definitions() as $definition) { + $dbalTypeClass = $this->toDbalType($definition->type()::class); if (!array_key_exists($dbalTypeClass, $typeClassToName)) { throw new BaseInvalidArgumentException(sprintf('DBAL type "%s" is not registered.', $dbalTypeClass)); } - $types[$entry->name()] = DbalType::getType($typeClassToName[$dbalTypeClass]); + $types[$definition->entry()->name()] = DbalType::getType($typeClassToName[$dbalTypeClass]); } return $types; diff --git a/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/DbalEncoderTest.php b/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/DbalEncoderTest.php new file mode 100644 index 0000000000..c92dc3bb48 --- /dev/null +++ b/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/DbalEncoderTest.php @@ -0,0 +1,72 @@ +encode([new TypedRowValues(['id' => 1, 'name' => 'Norbert', 'active' => true], [ + 'id' => type_integer(), + 'name' => type_string(), + 'active' => type_boolean(), + ])]); + + static::assertSame([['id' => 1, 'name' => 'Norbert', 'active' => true]], $encoded); + static::assertSame(['id', 'name', 'active'], array_keys($encoded[0])); + } + + public function test_renders_a_dom_document_value_to_an_xml_string(): void + { + $doc = new DOMDocument(); + $doc->loadXML('Software Engineer'); + + $encoded = (new DbalEncoder())->encode([new TypedRowValues(['id' => 1, 'profile' => $doc], [ + 'id' => type_integer(), + 'profile' => type_xml(), + ])]); + + static::assertSame(1, $encoded[0]['id']); + static::assertIsString($encoded[0]['profile']); + static::assertStringContainsString('Software Engineer', $encoded[0]['profile']); + } + + public function test_renders_a_dom_element_value_to_an_xml_string(): void + { + $doc = new DOMDocument(); + $doc->loadXML('John Doe'); + $element = $doc->getElementsByTagName('user')->item(0); + + $encoded = (new DbalEncoder())->encode([new TypedRowValues(['user_element' => $element], [ + 'user_element' => type_xml_element(), + ])]); + + static::assertIsString($encoded[0]['user_element']); + static::assertStringContainsString('John Doe', $encoded[0]['user_element']); + } + + public function test_passes_null_through_unchanged(): void + { + static::assertSame( + [['id' => 1, 'body' => null]], + (new DbalEncoder())->encode([new TypedRowValues(['id' => 1, 'body' => null], [ + 'id' => type_integer(), + 'body' => type_string(), + ])]), + ); + } +} diff --git a/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/RowsNormalizerTest.php b/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/RowsNormalizerTest.php deleted file mode 100644 index f4a2c67f7a..0000000000 --- a/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/RowsNormalizerTest.php +++ /dev/null @@ -1,159 +0,0 @@ -normalizer = new RowsNormalizer(); - } - - public function test_normalize_empty_rows(): void - { - $rows = rows(); - $result = $this->normalizer->normalize($rows); - - static::assertSame([], $result); - } - - public function test_normalize_preserves_entry_order(): void - { - $xmlContent = 'John'; - $doc = new DOMDocument(); - $doc->loadXML($xmlContent); - - $rows = rows(row( - string_entry('first', 'value1'), - xml_entry('xml_data', $doc), - integer_entry('number', 42), - string_entry('last', 'value2'), - )); - - $result = $this->normalizer->normalize($rows); - - static::assertCount(1, $result); - $keys = array_keys($result[0]); - static::assertSame(['first', 'xml_data', 'number', 'last'], $keys); - } - - public function test_normalize_rows_with_mixed_xml_entries(): void - { - $xmlContent = 'John Doe'; - $doc = new DOMDocument(); - $doc->loadXML($xmlContent); - $element = $doc->getElementsByTagName('user')[0]; - - $xmlContent2 = 'Software Engineer'; - $doc2 = new DOMDocument(); - $doc2->loadXML($xmlContent2); - - $rows = rows(row( - integer_entry('id', 1), - xml_entry('profile', $doc2), - xml_element_entry('user_element', $element), - string_entry('status', 'active'), - )); - - $result = $this->normalizer->normalize($rows); - - static::assertCount(1, $result); - static::assertSame(1, $result[0]['id']); - static::assertSame('active', $result[0]['status']); - - // Both XML entries should be converted to strings - static::assertIsString($result[0]['profile']); - static::assertIsString($result[0]['user_element']); - static::assertStringContainsString('', $result[0]['profile']); - static::assertStringContainsString('Software Engineer', $result[0]['profile']); - static::assertStringContainsString('', $result[0]['user_element']); - static::assertStringContainsString('John Doe', $result[0]['user_element']); - } - - public function test_normalize_rows_with_null_xml_entry(): void - { - $rows = rows(row(integer_entry('id', 1), xml_entry('user_data', null), string_entry('status', 'active'))); - - $result = $this->normalizer->normalize($rows); - - static::assertCount(1, $result); - static::assertSame(1, $result[0]['id']); - static::assertSame('active', $result[0]['status']); - static::assertSame('', $result[0]['user_data']); // null XML entry should become empty string - } - - public function test_normalize_rows_with_xml_element_entry(): void - { - $xmlContent = 'John Doe'; - $doc = new DOMDocument(); - $doc->loadXML($xmlContent); - $element = $doc->getElementsByTagName('user')[0]; - - $rows = rows(row( - integer_entry('id', 1), - xml_element_entry('user_element', $element), - string_entry('status', 'active'), - )); - - $result = $this->normalizer->normalize($rows); - - static::assertCount(1, $result); - static::assertSame(1, $result[0]['id']); - static::assertSame('active', $result[0]['status']); - static::assertIsString($result[0]['user_element']); - static::assertStringContainsString('', $result[0]['user_element']); - static::assertStringContainsString('John Doe', $result[0]['user_element']); - } - - public function test_normalize_rows_with_xml_entry(): void - { - $xmlContent = 'John Doejohn@example.com'; - $doc = new DOMDocument(); - $doc->loadXML($xmlContent); - - $rows = rows(row(integer_entry('id', 1), xml_entry('user_data', $doc), string_entry('status', 'active'))); - - $result = $this->normalizer->normalize($rows); - - static::assertCount(1, $result); - static::assertSame(1, $result[0]['id']); - static::assertSame('active', $result[0]['status']); - static::assertIsString($result[0]['user_data']); - static::assertStringContainsString('', $result[0]['user_data']); - static::assertStringContainsString('John Doe', $result[0]['user_data']); - static::assertStringContainsString('john@example.com', $result[0]['user_data']); - } - - public function test_normalize_rows_without_xml_entries(): void - { - $rows = rows( - row(integer_entry('id', 1), string_entry('name', 'John Doe'), string_entry('email', 'john@example.com')), - row(integer_entry('id', 2), string_entry('name', 'Jane Smith'), string_entry('email', 'jane@example.com')), - ); - - $result = $this->normalizer->normalize($rows); - - static::assertSame( - [ - ['id' => 1, 'name' => 'John Doe', 'email' => 'john@example.com'], - ['id' => 2, 'name' => 'Jane Smith', 'email' => 'jane@example.com'], - ], - $result, - ); - } -} diff --git a/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/TypesMapTest.php b/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/TypesMapTest.php index ba83923387..ca8260abb0 100644 --- a/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/TypesMapTest.php +++ b/src/adapter/etl-adapter-doctrine/tests/Flow/ETL/Adapter/Doctrine/Tests/Unit/TypesMapTest.php @@ -47,6 +47,12 @@ use PHPUnit\Framework\TestCase; use stdClass; +use function array_keys; +use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\string_schema; +use function Flow\ETL\DSL\xml_schema; + final class TypesMapTest extends TestCase { public function test_complete_dbal_to_flow_type_conversion_workflow(): void @@ -346,4 +352,18 @@ public function test_type_map_preserves_mapping_order(): void static::assertSame(TextType::class, $typesMap->toDbalType(StringType::class)); static::assertSame(BigIntType::class, $typesMap->toDbalType(IntegerType::class)); } + + public function test_flow_schema_types_maps_schema_definitions_to_dbal_types(): void + { + $types = (new TypesMap([]))->flowSchemaTypes(schema( + int_schema('id'), + string_schema('name'), + xml_schema('body'), + )); + + static::assertSame(['id', 'name', 'body'], array_keys($types)); + static::assertInstanceOf(DoctrineIntegerType::class, $types['id']); + static::assertInstanceOf(DoctrineStringType::class, $types['name']); + static::assertInstanceOf(DoctrineStringType::class, $types['body']); + } } diff --git a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelEncoder.php b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelEncoder.php new file mode 100644 index 0000000000..59587430eb --- /dev/null +++ b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelEncoder.php @@ -0,0 +1,191 @@ +> + */ +final class ExcelEncoder implements Encoder +{ + /** + * @var null|list + */ + private ?array $headers = null; + + public function __construct( + private readonly bool $withHeader = true, + private readonly bool $convertEmptyToNull = true, + private readonly string $dateTimeFormat = 'Y-m-d H:i:s', + private readonly string $dateFormat = 'Y-m-d', + private readonly string $timeFormat = '%H:%I:%S', + ) {} + + public function decode(array $batch): array + { + $decoded = []; + + foreach ($batch as $cells) { + if ($this->headers === null) { + if ($this->withHeader) { + $this->headers = $this->mapHeaders($cells); + + continue; + } + + $this->headers = $this->generateAutoHeaders(count($cells)); + } + + $values = []; + + foreach ($this->headers as $index => $name) { + // @mago-ignore analysis:mixed-assignment + $cell = $cells[$index] ?? null; + $values[$name] = $this->convertEmptyToNull && '' === $cell ? null : $cell; + } + + $decoded[] = new RawRowValues($values); + } + + return $decoded; + } + + public function encode(array $batch): array + { + $rows = []; + + foreach ($batch as $rowValues) { + $cells = []; + + /** @var mixed $value */ + foreach ($rowValues->values as $name => $value) { + $cells[] = $this->renderValue($rowValues->types[$name], $value); + } + + $rows[] = $cells; + } + + return $rows; + } + + /** + * @param list $headers + * + * @return list + */ + public function encodeHeader(array $headers): array + { + return array_values($headers); + } + + /** + * @return list + */ + private function generateAutoHeaders(int $count): array + { + $headers = []; + + for ($i = 0; $i < $count; $i++) { + $headers[] = 'e' . str_pad((string) $i, 2, '0', STR_PAD_LEFT); + } + + return $headers; + } + + /** + * @param array $cells + * + * @return list + */ + private function mapHeaders(array $cells): array + { + return array_values(array_map(static fn(mixed $header): string => is_scalar($header) + ? (string) $header + : '', $cells)); + } + + private function renderValue(Type $type, mixed $value): bool|float|int|string|null + { + if ($value === null) { + return null; + } + + return match ($type::class) { + DateTimeType::class => $value instanceof DateTimeInterface ? $value->format($this->dateTimeFormat) : null, + DateType::class => $value instanceof DateTimeInterface ? $value->format($this->dateFormat) : null, + TimeType::class => $value instanceof DateInterval ? $value->format($this->timeFormat) : null, + EnumType::class => match (true) { + $value instanceof BackedEnum => (string) $value->value, + $value instanceof UnitEnum => $value->name, + default => null, + }, + JsonType::class => $value instanceof Json ? $value->toString() : null, + UuidType::class => $value instanceof Uuid ? $value->toString() : null, + XMLType::class => $value instanceof XMLDocument || $value instanceof DOMDocument + ? $this->xmlToString($value) + : null, + ListType::class, MapType::class, StructureType::class, ArrayType::class => is_array($value) + ? json_encode($value, JSON_THROW_ON_ERROR) + : null, + default => $this->scalar($value), + }; + } + + private function scalar(mixed $value): bool|float|int|string|null + { + return match (true) { + is_scalar($value) => $value, + $value instanceof Stringable => (string) $value, + default => null, + }; + } + + private function xmlToString(XMLDocument|DOMDocument $value): string + { + $serialized = $value instanceof XMLDocument + ? $value->saveXml($value->documentElement) + : $value->saveXML($value->documentElement); + + if ($serialized === false) { + throw new RuntimeException('Failed to serialize XML document.'); + } + + return $serialized; + } +} diff --git a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelExtractor.php b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelExtractor.php index 895c9212b9..f25ecbb31b 100644 --- a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelExtractor.php +++ b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelExtractor.php @@ -14,6 +14,8 @@ use Flow\ETL\Extractor\PathFiltering; use Flow\ETL\Extractor\Signal; use Flow\ETL\FlowContext; +use Flow\ETL\Row\RawRowValues; +use Flow\ETL\Rows; use Flow\ETL\Schema; use Flow\Filesystem\Path; use Flow\Filesystem\SourceStream; @@ -25,11 +27,9 @@ use Throwable; use ZipArchive; -use function array_combine; use function array_map; use function count; -use function Flow\ETL\DSL\array_to_rows; -use function is_scalar; +use function Flow\ETL\DSL\str_schema; use function str_starts_with; final class ExcelExtractor implements Extractor, FileExtractor, LimitableExtractor @@ -68,16 +68,94 @@ public function __construct( */ public function extract(FlowContext $context): Generator { - $headers = []; - // Offset must be a positive number $offset = $this->offset ?? 1; + $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); + + $baseSchema = $this->schema; + + if ( + $baseSchema !== null + && $shouldPutInputIntoRows + && $baseSchema->findDefinition('_input_file_uri') === null + ) { + $baseSchema = $baseSchema->add(str_schema('_input_file_uri')); + } + foreach ($context->streams()->list($this->path, $this->filter()) as $stream) { + $streamUri = $shouldPutInputIntoRows ? $stream->path()->uri() : null; $partitions = $stream->path()->partitions(); - foreach ($this->extractRows($stream, $headers, $offset) as $row) { - $signal = yield array_to_rows($row, $context->entryFactory(), $partitions, $this->schema); + $schema = $baseSchema; + + if ($schema !== null) { + foreach ($partitions as $partition) { + if ($schema->findDefinition($partition->name) === null) { + $schema = $schema->add(str_schema($partition->name)); + } + } + } + + $encoder = new ExcelEncoder(withHeader: $this->withHeader, convertEmptyToNull: $this->convertEmptyToNull); + $rawCells = []; + + foreach ($this->extractRows($stream, $offset) as $cells) { + $rawCells[] = $cells; + + if (count($rawCells) >= $batchSize) { + $batch = []; + + foreach ($encoder->decode($rawCells) as $rowValues) { + $row = $rowValues->values; + + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($row); + } + + $rawCells = []; + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $stream->close(); + + return; + } + } + } + } + + $batch = []; + + foreach ($encoder->decode($rawCells) as $rowValues) { + $row = $rowValues->values; + + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($row); + } + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); $this->incrementReturnedRows(); @@ -153,11 +231,7 @@ public function withSheetName(string $sheetName): self */ private function createRowsFromCells(Row $row, int $previousRowDataCount = 0): array { - $rowData = array_map( - // Convert empty values to nullables if allowed - fn(Cell $cell) => $this->convertEmptyToNull && '' === $cell->getValue() ? null : $cell->getValue(), - $row->cells, - ); + $rowData = array_map(static fn(Cell $cell) => $cell->getValue(), $row->cells); // Expand columns to the size of the previous row for ($i = count($rowData); $i < $previousRowDataCount; $i++) { @@ -168,11 +242,9 @@ private function createRowsFromCells(Row $row, int $previousRowDataCount = 0): a } /** - * @param array $headers - * - * @return Generator> + * @return Generator> */ - private function extractRows(SourceStream $stream, array $headers, int $offset): Generator + private function extractRows(SourceStream $stream, int $offset): Generator { $reader = $this->reader($stream); @@ -191,9 +263,7 @@ private function extractRows(SourceStream $stream, array $headers, int $offset): $rowIndex++; if (1 === $rowIndex && $this->withHeader) { - $headersRaw = $this->createRowsFromCells($sheetRow); - // Convert headers to strings for array_combine compatibility - $headers = array_map(static fn($header) => is_scalar($header) ? (string) $header : '', $headersRaw); + yield $this->createRowsFromCells($sheetRow); continue; } @@ -207,11 +277,7 @@ private function extractRows(SourceStream $stream, array $headers, int $offset): $row = $this->createRowsFromCells($sheetRow, $previousRowDataCount); $previousRowDataCount = count($row); - if ($this->withHeader) { - yield array_combine($headers, $row); - } else { - yield $row; - } + yield $row; } $reader->close(); diff --git a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php index 0d704c574f..b831d6db3c 100644 --- a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php +++ b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/ExcelLoader.php @@ -4,7 +4,6 @@ namespace Flow\ETL\Adapter\Excel; -use Flow\ETL\Adapter\Excel\RowsNormalizer\ExcelRowsNormalizer; use Flow\ETL\Adapter\Excel\Sheet\SheetNameAssertion; use Flow\ETL\Config\Telemetry\TelemetryAttributes; use Flow\ETL\Exception\InvalidArgumentException; @@ -13,6 +12,7 @@ use Flow\ETL\Loader\Closure; use Flow\ETL\Loader\FileLoader; use Flow\ETL\Row; +use Flow\ETL\Row\TypedRowValues; use Flow\ETL\Rows; use Flow\Filesystem\Path; use OpenSpout\Common\Entity\Style\Style; @@ -20,6 +20,7 @@ use OpenSpout\Writer\XLSX\Options as XlsxOptions; use Throwable; +use function array_keys; use function is_string; final class ExcelLoader implements Closure, FileLoader, Loader @@ -30,6 +31,8 @@ final class ExcelLoader implements Closure, FileLoader, Loader private string $dateTimeFormat = 'Y-m-d H:i:s'; + private ?ExcelEncoder $encoder = null; + private ?Style $headerStyle = null; private readonly Path $path; @@ -38,7 +41,7 @@ final class ExcelLoader implements Closure, FileLoader, Loader private ?string $sheetNameEntryName = null; - private string $timeFormat = 'H:i:s'; + private string $timeFormat = '%H:%I:%S'; private bool $withHeader = true; @@ -85,11 +88,8 @@ public function load(Rows $rows, FlowContext $context): void ]); try { - $normalizer = new ExcelRowsNormalizer( - dateFormat: $this->dateFormat, - dateTimeFormat: $this->dateTimeFormat, - timeFormat: $this->timeFormat, - ); + $dehydrated = $context->hydrator()->dehydrate($rows); + $encoder = $this->encoder(); $stream = $context->streams()->writeTo($this->path, $rows->partitions()->toArray()); @@ -103,14 +103,27 @@ public function load(Rows $rows, FlowContext $context): void ? $row->remove($this->sheetNameEntryName) : $row; + $typed = $dehydrated[$rowIndex]; + $values = $typed->values; + $types = $typed->types; + $metadata = $typed->metadata; + + if ($this->sheetNameEntryName !== null) { + unset( + $values[$this->sheetNameEntryName], + $types[$this->sheetNameEntryName], + $metadata[$this->sheetNameEntryName], + ); + } + if ($this->withHeader && !$manager->isHeaderWritten($sheetName)) { - $headers = $normalizer->headers($rowForExcel); - $manager->writeHeader($sheetName, $headers, $this->headerStyle); + $manager->writeHeader($sheetName, $encoder->encodeHeader(array_keys($values)), $this->headerStyle); } - $values = $normalizer->normalize($rowForExcel); $styles = $this->resolveCellStyles($rowForExcel, $rowIndex, $sheetName); - $manager->writeRow($sheetName, $values, $styles); + /** @var array $cells */ + $cells = $encoder->encode([new TypedRowValues($values, $types, $metadata)])[0]; + $manager->writeRow($sheetName, $cells, $styles); } $context->telemetry()->loadingCompleted($this, [TelemetryAttributes::ATTR_LOADING_ROWS => $rows->count()]); @@ -207,6 +220,15 @@ public function withWriterOptions(OdsOptions|XlsxOptions $options): self return $this; } + private function encoder(): ExcelEncoder + { + return $this->encoder ??= new ExcelEncoder( + dateTimeFormat: $this->dateTimeFormat, + dateFormat: $this->dateFormat, + timeFormat: $this->timeFormat, + ); + } + private function getWorkbookManager(): WorkbookManager { if ($this->workbookManager === null) { diff --git a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/ExcelRowsNormalizer.php b/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/ExcelRowsNormalizer.php deleted file mode 100644 index 3dda2c109e..0000000000 --- a/src/adapter/etl-adapter-excel/src/Flow/ETL/Adapter/Excel/RowsNormalizer/ExcelRowsNormalizer.php +++ /dev/null @@ -1,109 +0,0 @@ - - */ - public function headers(Row $row): array - { - $headers = []; - - foreach ($row->entries() as $entry) { - $headers[] = $entry->name(); - } - - return $headers; - } - - /** - * @return array - */ - public function normalize(Row $row): array - { - $values = []; - - foreach ($row->entries() as $entry) { - $values[] = $this->normalizeEntry($entry); - } - - return $values; - } - - /** - * @param Entry $entry - */ - private function normalizeEntry(Entry $entry): bool|float|int|string|null - { - return match ($entry::class) { - BooleanEntry::class, IntegerEntry::class, FloatEntry::class, StringEntry::class => $entry->value(), - DateTimeEntry::class => $entry->value()?->format($this->dateTimeFormat), - DateEntry::class => $entry->value()?->format($this->dateFormat), - TimeEntry::class => $entry->value()?->format($this->timeFormat), - EnumEntry::class => $this->normalizeEnumEntry($entry), - JsonEntry::class, ListEntry::class, MapEntry::class, StructureEntry::class => $this->normalizeToJson( - $entry->value(), - ), - UuidEntry::class, - XMLEntry::class, - XMLElementEntry::class, - HTMLEntry::class, - HTMLElementEntry::class, - => $entry->toString(), - default => throw new InvalidArgumentException('Unknown entry type: ' . $entry::class), - }; - } - - /** - * @param EnumEntry<\UnitEnum|null> $entry - */ - private function normalizeEnumEntry(EnumEntry $entry): ?string - { - $value = $entry->value(); - - if ($value instanceof BackedEnum) { - return (string) $value->value; - } - - return $value?->name; - } - - private function normalizeToJson(mixed $value): ?string - { - return $value !== null ? json_encode($value, JSON_THROW_ON_ERROR) : null; - } -} diff --git a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Integration/ExcelHydratorParityTest.php b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Integration/ExcelHydratorParityTest.php new file mode 100644 index 0000000000..3c8fb748de --- /dev/null +++ b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Integration/ExcelHydratorParityTest.php @@ -0,0 +1,65 @@ +withSchema(schema(int_schema('id'), string_schema('name'), string_schema('email', nullable: true))); + + $count = 0; + + foreach ($extractor->extract(flow_context(Config::builder()->build())) as $rows) { + foreach ($rows as $row) { + static::assertInstanceOf(IntegerEntry::class, $row->get('id')); + $count++; + } + } + + static::assertSame(10, $count); + } + + public function test_appends_input_file_uri_when_put_input_into_rows_is_enabled(): void + { + $extractor = from_excel($path = path_real(__DIR__ . '/../Fixtures/fixture.xlsx')) + ->withSchema(schema(int_schema('id'), string_schema('name'), string_schema('email', nullable: true))); + + foreach ($extractor->extract(flow_context(Config::builder()->putInputIntoRows()->build())) as $rows) { + foreach ($rows as $row) { + static::assertTrue($row->has('_input_file_uri')); + static::assertSame($path->uri(), $row->valueOf('_input_file_uri')); + } + } + } + + public function test_honours_a_hydrator_configured_on_the_context(): void + { + $extractor = from_excel(path_real(__DIR__ . '/../Fixtures/fixture.xlsx')); + + $count = 0; + + foreach ($extractor->extract( + flow_context(Config::builder()->hydrator(new AdaptiveRowHydrator())->build()), + ) as $rows) { + $count += $rows->count(); + } + + static::assertSame(10, $count); + } +} diff --git a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Integration/ExcelLoaderTest.php b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Integration/ExcelLoaderTest.php index 17521817b9..e075903bf6 100644 --- a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Integration/ExcelLoaderTest.php +++ b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Integration/ExcelLoaderTest.php @@ -138,7 +138,7 @@ public function test_round_trip_with_basic_data(ExcelWriter $writer, string $ext ); } - public function test_round_trip_with_custom_date_formats(): void + public function test_round_trip_with_custom_datetime_and_time_formats(): void { $outputPath = __DIR__ . '/var/output_custom_formats.xlsx'; $date = new DateTimeImmutable('2024-06-15'); @@ -152,19 +152,14 @@ public function test_round_trip_with_custom_date_formats(): void time_entry('time_val', $time), )))) ->saveMode(overwrite()) - ->write( - to_excel($outputPath) - ->withDateFormat('d/m/Y') - ->withDateTimeFormat('d/m/Y H:i') - ->withTimeFormat('%H:%I'), - ) + ->write(to_excel($outputPath)->withDateTimeFormat('d/m/Y H:i')->withTimeFormat('%H:%I')) ->run(); $rows = df()->read(from_excel($outputPath))->fetch()->toArray(); static::assertEquals( [ - ['date_val' => '15/06/2024', 'datetime_val' => '15/06/2024 14:30', 'time_val' => '14:30'], + ['date_val' => '2024-06-15', 'datetime_val' => '15/06/2024 14:30', 'time_val' => '14:30'], ], $rows, ); diff --git a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/ExcelEncoderTest.php b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/ExcelEncoderTest.php new file mode 100644 index 0000000000..a0d3e3d42c --- /dev/null +++ b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/ExcelEncoderTest.php @@ -0,0 +1,146 @@ +decode([['id', 'name']])); + static::assertSame(['id' => 1, 'name' => 'Norbert'], $encoder->decode([[1, 'Norbert']])[0]->values); + } + + public function test_decode_generates_auto_headers_when_header_is_disabled(): void + { + static::assertSame( + ['e00' => 1, 'e01' => 'Norbert'], + (new ExcelEncoder(withHeader: false))->decode([[1, 'Norbert']])[0]->values, + ); + } + + public function test_decode_keeps_empty_cells_when_convert_empty_to_null_is_disabled(): void + { + static::assertSame( + ['id' => 1, 'name' => ''], + (new ExcelEncoder(convertEmptyToNull: false))->decode([['id', 'name'], [1, '']])[0]->values, + ); + } + + public function test_decode_maps_cells_to_headers(): void + { + static::assertSame( + ['id' => 1, 'name' => 'Norbert'], + (new ExcelEncoder())->decode([['id', 'name'], [1, 'Norbert']])[0]->values, + ); + } + + public function test_decode_turns_empty_cells_into_null_by_default(): void + { + static::assertSame( + ['id' => 1, 'name' => null], + (new ExcelEncoder())->decode([['id', 'name'], [1, '']])[0]->values, + ); + } + + public function test_encodes_scalars_as_a_flat_cell_list_in_value_order(): void + { + static::assertSame( + [[1, 'Norbert', 1.5, true]], + (new ExcelEncoder())->encode([new TypedRowValues([ + 'id' => 1, + 'name' => 'Norbert', + 'p' => 1.5, + 'a' => true, + ], ['id' => type_integer(), 'name' => type_string(), 'p' => type_float(), 'a' => type_boolean()])]), + ); + } + + public function test_encodes_dates_with_the_date_format_datetimes_with_the_datetime_format_and_intervals_with_the_time_format(): void + { + $encoder = new ExcelEncoder(dateTimeFormat: 'd/m/Y H:i', timeFormat: '%H:%I'); + + static::assertSame( + [['2024-08-01', '01/08/2024 10:30', '01:30']], + $encoder->encode([new TypedRowValues([ + 'd' => new DateTimeImmutable('2024-08-01'), + 'dt' => new DateTimeImmutable('2024-08-01 10:30:00'), + 't' => new DateInterval('PT1H30M'), + ], ['d' => type_date(), 'dt' => type_datetime(), 't' => type_time()])]), + ); + } + + public function test_encodes_time_with_the_default_time_format(): void + { + static::assertSame( + [['14:30:45']], + (new ExcelEncoder())->encode([ + new TypedRowValues(['t' => new DateInterval('PT14H30M45S')], ['t' => type_time()]), + ]), + ); + } + + public function test_encodes_backed_enum_as_its_backing_value(): void + { + static::assertSame( + [['1']], + (new ExcelEncoder())->encode([ + new TypedRowValues(['e' => BackedIntEnum::one], ['e' => type_enum(BackedIntEnum::class)]), + ]), + ); + } + + public function test_encodes_arrays_as_json(): void + { + static::assertSame( + [['["a","b"]', '{"x":1}', '{"city":"Krakow"}']], + (new ExcelEncoder())->encode([new TypedRowValues([ + 'tags' => ['a', 'b'], + 'm' => ['x' => 1], + 'addr' => ['city' => 'Krakow'], + ], ['tags' => type_array(), 'm' => type_array(), 'addr' => type_array()])]), + ); + } + + public function test_encodes_uuid_as_string(): void + { + static::assertSame( + [['f47ac10b-58cc-4372-a567-0e02b2c3d479']], + (new ExcelEncoder())->encode([new TypedRowValues([ + 'id' => new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'), + ], ['id' => type_uuid()])]), + ); + } + + public function test_encodes_null_values_as_null_cells(): void + { + static::assertSame( + [[null, null]], + (new ExcelEncoder())->encode([ + new TypedRowValues(['id' => null, 'd' => null], ['id' => type_integer(), 'd' => type_date()]), + ]), + ); + } +} diff --git a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/ExcelRowsNormalizerTest.php b/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/ExcelRowsNormalizerTest.php deleted file mode 100644 index 3b03183e14..0000000000 --- a/src/adapter/etl-adapter-excel/tests/Flow/ETL/Adapter/Excel/Tests/Unit/RowsNormalizer/ExcelRowsNormalizerTest.php +++ /dev/null @@ -1,169 +0,0 @@ -headers(row( - int_entry('id', 1), - string_entry('name', 'Test'), - float_entry('value', 1.5), - )); - - static::assertSame(['id', 'name', 'value'], $headers); - } - - public function test_normalize_backed_int_enum(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(enum_entry('count', BackedIntTestEnum::TWO))); - - static::assertSame(['2'], $result); - } - - public function test_normalize_backed_string_enum(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(enum_entry('status', BackedStringTestEnum::ACTIVE))); - - static::assertSame(['active'], $result); - } - - public function test_normalize_json_entry_with_null_value(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(json_entry('data', null))); - - static::assertSame([null], $result); - } - - public function test_normalize_json_entry_with_value(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(json_entry('data', ['key' => 'value']))); - - static::assertSame(['{"key":"value"}'], $result); - } - - public function test_normalize_list_entry(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(list_entry('items', [1, 2, 3], type_list(type_integer())))); - - static::assertSame(['[1,2,3]'], $result); - } - - public function test_normalize_map_entry(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(map_entry( - 'mapping', - ['a' => 1, 'b' => 2], - type_map(type_string(), type_integer()), - ))); - - static::assertSame(['{"a":1,"b":2}'], $result); - } - - public function test_normalize_mixed_row(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row( - int_entry('id', 42), - string_entry('name', 'Test'), - float_entry('price', 19.99), - enum_entry('status', BackedStringTestEnum::ACTIVE), - )); - - static::assertSame([42, 'Test', 19.99, 'active'], $result); - } - - public function test_normalize_null_enum_entry(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(enum_entry('status', null))); - - static::assertSame([null], $result); - } - - public function test_normalize_structure_entry(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(structure_entry('person', ['name' => 'John', 'age' => 30], type_structure([ - 'name' => type_string(), - 'age' => type_integer(), - ])))); - - static::assertSame(['{"name":"John","age":30}'], $result); - } - - public function test_normalize_unit_enum(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(enum_entry('status', UnitTestEnum::PENDING))); - - static::assertSame(['PENDING'], $result); - } - - public function test_normalize_xml_entry(): void - { - $normalizer = new ExcelRowsNormalizer(); - - $result = $normalizer->normalize(row(xml_entry('xml', 'value'))); - - static::assertSame(['value'], $result); - } -} diff --git a/src/adapter/etl-adapter-google-sheet/src/Flow/ETL/Adapter/GoogleSheet/GoogleSheetEncoder.php b/src/adapter/etl-adapter-google-sheet/src/Flow/ETL/Adapter/GoogleSheet/GoogleSheetEncoder.php new file mode 100644 index 0000000000..71acd7ef44 --- /dev/null +++ b/src/adapter/etl-adapter-google-sheet/src/Flow/ETL/Adapter/GoogleSheet/GoogleSheetEncoder.php @@ -0,0 +1,102 @@ +> + */ +final class GoogleSheetEncoder implements Encoder +{ + /** + * @var array + */ + private array $headers = []; + + private int $headersCount = 0; + + public function __construct( + private readonly bool $withHeader = true, + private readonly bool $dropExtraColumns = true, + ) {} + + public function decode(array $batch): array + { + $maps = []; + + foreach ($batch as $rowData) { + $rowDataCount = count($rowData); + + if ($this->withHeader) { + if ([] === $this->headers) { + if ([] === $rowData) { + continue; + } + + /** @var array $rowData */ + $this->headers = $rowData; + $this->headersCount = $rowDataCount; + + continue; + } + } elseif (0 === $this->headersCount) { + $this->headersCount = $rowDataCount; + } + + for ($i = $rowDataCount; $i < $this->headersCount; $i++) { + $rowData[$i] = null; + } + + if ($rowDataCount > $this->headersCount) { + if (!$this->dropExtraColumns) { + throw InvalidArgumentException::because( + 'Row has more columns (%d) than headers (%d)', + $rowDataCount, + $this->headersCount, + ); + } + + $rowData = array_slice($rowData, 0, $this->headersCount); + } + + $maps[] = new RawRowValues(array_combine( + $this->withHeader ? $this->headers : $this->generateAutoHeaders(count($rowData)), + $rowData, + )); + } + + return $maps; + } + + public function encode(array $batch): array + { + throw new RuntimeException( + 'Google Sheet adapter is read-only, encoding rows back to sheet values is not supported', + ); + } + + /** + * @return list + */ + private function generateAutoHeaders(int $count): array + { + $headers = []; + + for ($i = 0; $i < $count; $i++) { + $headers[] = 'e' . str_pad((string) $i, 2, '0', STR_PAD_LEFT); + } + + return $headers; + } +} diff --git a/src/adapter/etl-adapter-google-sheet/src/Flow/ETL/Adapter/GoogleSheet/GoogleSheetExtractor.php b/src/adapter/etl-adapter-google-sheet/src/Flow/ETL/Adapter/GoogleSheet/GoogleSheetExtractor.php index d4c03e728e..0a8b0bbc4a 100644 --- a/src/adapter/etl-adapter-google-sheet/src/Flow/ETL/Adapter/GoogleSheet/GoogleSheetExtractor.php +++ b/src/adapter/etl-adapter-google-sheet/src/Flow/ETL/Adapter/GoogleSheet/GoogleSheetExtractor.php @@ -10,15 +10,14 @@ use Flow\ETL\Extractor\LimitableExtractor; use Flow\ETL\Extractor\Signal; use Flow\ETL\FlowContext; +use Flow\ETL\Row\RawRowValues; use Flow\ETL\Rows; use Flow\ETL\Schema; use Generator; use Google\Service\Sheets; -use function array_combine; -use function array_slice; use function count; -use function Flow\ETL\DSL\array_to_rows; +use function Flow\ETL\DSL\str_schema; final class GoogleSheetExtractor implements Extractor, LimitableExtractor { @@ -81,10 +80,20 @@ public function extract(FlowContext $context): Generator } $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); - /** @var array $headers */ - $headers = []; - $headersCount = 0; + $schema = $this->schema; + + if ($schema !== null && $shouldPutInputIntoRows) { + if ($schema->findDefinition('_spread_sheet_id') === null) { + $schema = $schema->add(str_schema('_spread_sheet_id')); + } + + if ($schema->findDefinition('_sheet_name') === null) { + $schema = $schema->add(str_schema('_sheet_name')); + } + } /** @var Sheets\Resource\SpreadsheetsValues $valuesResource */ $valuesResource = $this->service->spreadsheets_values; @@ -93,60 +102,63 @@ public function extract(FlowContext $context): Generator 'ranges' => $ranges, ])); + $encoder = new GoogleSheetEncoder(withHeader: $this->withHeader, dropExtraColumns: $this->dropExtraColumns); + $rawRows = []; + foreach ($response->getValueRanges() as $valueRange) { // @mago-ignore analysis:redundant-null-coalesce foreach ($valueRange->getValues() ?? [] as $rowData) { - $rowDataCount = count($rowData); + $rawRows[] = $rowData; - if ($this->withHeader) { - if ([] === $headers) { - if ([] === $rowData) { - continue; - } + if (count($rawRows) >= $batchSize) { + $batch = []; - /** @var array $headers */ - $headers = $rowData; + foreach ($encoder->decode($rawRows) as $rowValues) { + $row = $rowValues->values; - $headersCount = $rowDataCount; + if ($shouldPutInputIntoRows) { + $row['_spread_sheet_id'] = $this->spreadsheetId; + $row['_sheet_name'] = $this->columnRange->sheetName; + } - continue; + $batch[] = new RawRowValues($row); } - } elseif (0 === $headersCount) { - $headersCount = $rowDataCount; - } - for ($i = $rowDataCount; $i < $headersCount; $i++) { - $rowData[$i] = null; - } + $rawRows = []; - if ($rowDataCount > $headersCount) { - if (!$this->dropExtraColumns) { - throw InvalidArgumentException::because( - 'Row has more columns (%d) than headers (%d)', - $rowDataCount, - $headersCount, - ); - } + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); - $rowData = array_slice($rowData, 0, $headersCount); - } + $this->incrementReturnedRows(); - if ($this->withHeader) { - $rowData = array_combine($headers, $rowData); + if ($signal === Signal::STOP || $this->reachedLimit()) { + return; + } + } } + } + } - if ($shouldPutInputIntoRows) { - $rowData['_spread_sheet_id'] = $this->spreadsheetId; - $rowData['_sheet_name'] = $this->columnRange->sheetName; - } + $batch = []; - $signal = yield array_to_rows($rowData, $context->entryFactory(), schema: $this->schema); + foreach ($encoder->decode($rawRows) as $rowValues) { + $row = $rowValues->values; - $this->incrementReturnedRows(); + if ($shouldPutInputIntoRows) { + $row['_spread_sheet_id'] = $this->spreadsheetId; + $row['_sheet_name'] = $this->columnRange->sheetName; + } - if ($signal === Signal::STOP || $this->reachedLimit()) { - return; - } + $batch[] = new RawRowValues($row); + } + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + return; } } } diff --git a/src/adapter/etl-adapter-google-sheet/tests/Flow/ETL/Adapter/GoogleSheet/Tests/Integration/GoogleSheetHydratorParityTest.php b/src/adapter/etl-adapter-google-sheet/tests/Flow/ETL/Adapter/GoogleSheet/Tests/Integration/GoogleSheetHydratorParityTest.php new file mode 100644 index 0000000000..3c014b927f --- /dev/null +++ b/src/adapter/etl-adapter-google-sheet/tests/Flow/ETL/Adapter/GoogleSheet/Tests/Integration/GoogleSheetHydratorParityTest.php @@ -0,0 +1,61 @@ +sheets(__DIR__ . '/../Fixtures/batch.json'), + '1234567890', + 'Sheet', + )->withSchema(schema(string_schema('Header 1'), string_schema('Header 2'), string_schema('Header 3'))); + + $rows = []; + + foreach ($extractor->extract(flow_context(Config::builder()->putInputIntoRows()->build())) as $batch) { + foreach ($batch as $row) { + $rows[] = $row->toArray(); + } + } + + static::assertNotEmpty($rows); + + foreach ($rows as $row) { + static::assertSame('1234567890', $row['_spread_sheet_id']); + static::assertSame('Sheet', $row['_sheet_name']); + } + } + + public function test_honours_a_hydrator_configured_on_the_context(): void + { + $extractor = from_google_sheet( + (new GoogleSheetsContext())->sheets(__DIR__ . '/../Fixtures/batch.json'), + '1234567890', + 'Sheet', + ); + + $count = 0; + + foreach ($extractor->extract( + flow_context(Config::builder()->hydrator(new AdaptiveRowHydrator())->build()), + ) as $batch) { + $count += $batch->count(); + } + + static::assertSame(19, $count); + } +} diff --git a/src/adapter/etl-adapter-google-sheet/tests/Flow/ETL/Adapter/GoogleSheet/Tests/Unit/GoogleSheetEncoderTest.php b/src/adapter/etl-adapter-google-sheet/tests/Flow/ETL/Adapter/GoogleSheet/Tests/Unit/GoogleSheetEncoderTest.php new file mode 100644 index 0000000000..7f98579d72 --- /dev/null +++ b/src/adapter/etl-adapter-google-sheet/tests/Flow/ETL/Adapter/GoogleSheet/Tests/Unit/GoogleSheetEncoderTest.php @@ -0,0 +1,134 @@ +decode([ + ['id', 'name'], + ['1', 'Norbert'], + ['2', 'Tomek'], + ]); + + static::assertSame( + [ + ['id' => '1', 'name' => 'Norbert'], + ['id' => '2', 'name' => 'Tomek'], + ], + array_map(static fn($rowValues): array => $rowValues->values, $decoded), + ); + } + + public function test_skips_empty_rows_before_headers(): void + { + $encoder = new GoogleSheetEncoder(); + + $decoded = $encoder->decode([ + [], + ['id', 'name'], + ['1', 'Norbert'], + ]); + + static::assertSame( + [['id' => '1', 'name' => 'Norbert']], + array_map(static fn($rowValues): array => $rowValues->values, $decoded), + ); + } + + public function test_keeps_headers_between_decode_calls(): void + { + $encoder = new GoogleSheetEncoder(); + + $encoder->decode([['id', 'name'], ['1', 'Norbert']]); + + static::assertSame( + [['id' => '2', 'name' => 'Tomek']], + array_map(static fn($rowValues): array => $rowValues->values, $encoder->decode([['2', 'Tomek']])), + ); + } + + public function test_pads_shorter_rows_with_nulls(): void + { + $encoder = new GoogleSheetEncoder(); + + $decoded = $encoder->decode([ + ['id', 'name'], + ['1'], + ]); + + static::assertSame( + [['id' => '1', 'name' => null]], + array_map(static fn($rowValues): array => $rowValues->values, $decoded), + ); + } + + public function test_drops_extra_columns(): void + { + $encoder = new GoogleSheetEncoder(); + + $decoded = $encoder->decode([ + ['id', 'name'], + ['1', 'Norbert', 'extra'], + ]); + + static::assertSame( + [['id' => '1', 'name' => 'Norbert']], + array_map(static fn($rowValues): array => $rowValues->values, $decoded), + ); + } + + public function test_throws_on_extra_columns_when_drop_is_disabled(): void + { + $encoder = new GoogleSheetEncoder(dropExtraColumns: false); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Row has more columns (3) than headers (2)'); + + $encoder->decode([ + ['id', 'name'], + ['1', 'Norbert', 'extra'], + ]); + } + + public function test_generates_auto_headers_without_header_row(): void + { + $encoder = new GoogleSheetEncoder(withHeader: false); + + $decoded = $encoder->decode([ + ['1', 'Norbert'], + ['2', 'Tomek'], + ]); + + static::assertSame( + [ + ['e00' => '1', 'e01' => 'Norbert'], + ['e00' => '2', 'e01' => 'Tomek'], + ], + array_map(static fn($rowValues): array => $rowValues->values, $decoded), + ); + } + + public function test_encode_is_not_supported(): void + { + $encoder = new GoogleSheetEncoder(); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Google Sheet adapter is read-only'); + + $encoder->encode([new TypedRowValues([], [])]); + } +} diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONEncoder.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONEncoder.php new file mode 100644 index 0000000000..fedb7d59aa --- /dev/null +++ b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONEncoder.php @@ -0,0 +1,154 @@ +> + */ +final class JSONEncoder implements Encoder +{ + public function __construct( + private readonly string $dateTimeFormat = DateTimeInterface::ATOM, + private readonly string $dateFormat = 'Y-m-d', + ) {} + + public function decode(array $batch): array + { + $decoded = []; + + foreach ($batch as $values) { + $decoded[] = new RawRowValues($values); + } + + return $decoded; + } + + public function encode(array $batch): array + { + $encoded = []; + + foreach ($batch as $rowValues) { + $row = []; + + /** @var mixed $value */ + foreach ($rowValues->values as $name => $value) { + $row[$name] = $this->renderValue($rowValues->types[$name], $value); + } + + $encoded[] = $row; + } + + return $encoded; + } + + /** + * @param Type $type + * + * @return null|array|bool|float|int|string + */ + private function renderValue(Type $type, mixed $value): string|float|int|bool|array|null + { + if ($value === null) { + return null; + } + + return match ($type::class) { + DateTimeType::class => $value instanceof DateTimeInterface ? $value->format($this->dateTimeFormat) : '', + DateType::class => $value instanceof DateTimeInterface ? $value->format($this->dateFormat) : '', + TimeType::class => $value instanceof DateInterval ? date_interval_to_microseconds($value) : '', + EnumType::class => $value instanceof UnitEnum ? $value->name : '', + JsonType::class => $value instanceof Json ? $this->normalizeJsonValue($value->toArray()) : null, + UuidType::class => $value instanceof Uuid ? $value->toString() : '', + XMLType::class, XMLElementType::class => $this->xmlToString($value), + ListType::class, MapType::class, StructureType::class, ArrayType::class => is_array($value) + ? json_encode($value, JSON_THROW_ON_ERROR) + : '', + default => $this->scalar($value), + }; + } + + private function scalar(mixed $value): string|float|int|bool + { + return match (true) { + is_string($value), is_int($value), is_float($value), is_bool($value) => $value, + $value instanceof Stringable => (string) $value, + default => '', + }; + } + + private function xmlToString(mixed $value): string + { + return match (true) { + $value instanceof DOMDocument => $this->domString($value->saveXML($value->documentElement)), + $value instanceof XMLDocument => $this->domString($value->saveXml($value->documentElement)), + $value instanceof DOMElement => $this->domString($value->C14N()), + $value instanceof Element => $this->domString($value->c14n()), + default => '', + }; + } + + /** + * @param array $value + * + * @return array + */ + private function normalizeJsonValue(array $value): array + { + return array_combine( + array_map(static fn(int|string $key): string => (string) $key, array_keys($value)), + array_values($value), + ); + } + + private function domString(string|false $serialized): string + { + if ($serialized === false) { + throw new RuntimeException('Failed to serialize XML document.'); + } + + return $serialized; + } +} diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonExtractor.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonExtractor.php index 7ed3a8e211..0cb43f6e58 100644 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonExtractor.php +++ b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonExtractor.php @@ -4,6 +4,7 @@ namespace Flow\ETL\Adapter\JSON\JSONMachine; +use Flow\ETL\Adapter\JSON\JSONEncoder; use Flow\ETL\Extractor; use Flow\ETL\Extractor\FileExtractor; use Flow\ETL\Extractor\Limitable; @@ -19,7 +20,7 @@ use JsonMachine\JsonDecoder\ExtJsonDecoder; use function count; -use function Flow\ETL\DSL\array_to_rows; +use function Flow\ETL\DSL\str_schema; final class JsonExtractor implements Extractor, FileExtractor, LimitableExtractor { @@ -44,21 +45,41 @@ public function __construct( public function extract(FlowContext $context): Generator { $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); + $encoder = new JSONEncoder(); + $baseSchema = $this->schema; + + if ( + $baseSchema !== null + && $shouldPutInputIntoRows + && $baseSchema->findDefinition('_input_file_uri') === null + ) { + $baseSchema = $baseSchema->add(str_schema('_input_file_uri')); + } foreach ($context->streams()->list($this->path, $this->filter()) as $stream) { - $uri = $stream->path()->uri(); + $streamUri = $shouldPutInputIntoRows ? $stream->path()->uri() : null; $partitions = $stream->path()->partitions(); + $schema = $baseSchema; + + if ($schema !== null) { + foreach ($partitions as $partition) { + if ($schema->findDefinition($partition->name) === null) { + $schema = $schema->add(str_schema($partition->name)); + } + } + } + + $rawBatch = []; + /** * @var array $rowData */ foreach ((new Items($stream->iterate(8 * 1024), $this->readerOptions()))->getIterator() as $rowData) { $row = $rowData; - if ($shouldPutInputIntoRows) { - $row['_input_file_uri'] = $uri; - } - if ($this->pointer !== null && $this->pointerToEntryName) { $row = [$this->pointer => $row]; } @@ -67,7 +88,35 @@ public function extract(FlowContext $context): Generator continue; } - $signal = yield array_to_rows([$row], $context->entryFactory(), $partitions, $this->schema); + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } + + $rawBatch[] = $row; + + if (count($rawBatch) >= $batchSize) { + foreach ($hydrator->cast($encoder->decode($rawBatch), $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + + return; + } + } + + $rawBatch = []; + } + } + + foreach ($hydrator->cast($encoder->decode($rawBatch), $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); $this->incrementReturnedRows(); diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonLinesExtractor.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonLinesExtractor.php index e9aad6f87c..e592fecb6d 100644 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonLinesExtractor.php +++ b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JSONMachine/JsonLinesExtractor.php @@ -4,6 +4,7 @@ namespace Flow\ETL\Adapter\JSON\JSONMachine; +use Flow\ETL\Adapter\JSON\JSONEncoder; use Flow\ETL\Extractor; use Flow\ETL\Extractor\FileExtractor; use Flow\ETL\Extractor\Limitable; @@ -19,7 +20,7 @@ use JsonMachine\JsonDecoder\ExtJsonDecoder; use function count; -use function Flow\ETL\DSL\array_to_rows; +use function Flow\ETL\DSL\str_schema; use function iterator_to_array; final class JsonLinesExtractor implements Extractor, FileExtractor, LimitableExtractor @@ -45,6 +46,18 @@ public function __construct( public function extract(FlowContext $context): Generator { $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); + $encoder = new JSONEncoder(); + $baseSchema = $this->schema; + + if ( + $baseSchema !== null + && $shouldPutInputIntoRows + && $baseSchema->findDefinition('_input_file_uri') === null + ) { + $baseSchema = $baseSchema->add(str_schema('_input_file_uri')); + } // JSONL iterator modes $lineIterator = match ($this->pointer) { @@ -60,9 +73,21 @@ public function extract(FlowContext $context): Generator }; foreach ($context->streams()->list($this->path, $this->filter()) as $stream) { - $uri = $stream->path()->uri(); + $streamUri = $shouldPutInputIntoRows ? $stream->path()->uri() : null; $partitions = $stream->path()->partitions(); + $schema = $baseSchema; + + if ($schema !== null) { + foreach ($partitions as $partition) { + if ($schema->findDefinition($partition->name) === null) { + $schema = $schema->add(str_schema($partition->name)); + } + } + } + + $rawBatch = []; + foreach ($stream->readLines() as $jsonLine) { /** * @var array $rowData @@ -70,10 +95,6 @@ public function extract(FlowContext $context): Generator foreach ($lineIterator($jsonLine) as $rowData) { $row = $rowData; - if ($shouldPutInputIntoRows) { - $row['_input_file_uri'] = $uri; - } - if ($this->pointer !== null && $this->pointerToEntryName) { $row = [$this->pointer => $row]; } @@ -82,18 +103,46 @@ public function extract(FlowContext $context): Generator continue; } - $signal = yield array_to_rows([$row], $context->entryFactory(), $partitions, $this->schema); + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; + } - $this->incrementReturnedRows(); + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } - if ($signal === Signal::STOP || $this->reachedLimit()) { - $context->streams()->closeStreams($this->path); + $rawBatch[] = $row; - return; + if (count($rawBatch) >= $batchSize) { + foreach ($hydrator->cast($encoder->decode($rawBatch), $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + + return; + } + } + + $rawBatch = []; } } } + foreach ($hydrator->cast($encoder->decode($rawBatch), $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + + return; + } + } + $stream->close(); } } diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLinesLoader.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLinesLoader.php index 1b4560fa1c..3670b2644d 100644 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLinesLoader.php +++ b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLinesLoader.php @@ -5,7 +5,6 @@ namespace Flow\ETL\Adapter\JSON; use DateTimeInterface; -use Flow\ETL\Adapter\JSON\RowsNormalizer\EntryNormalizer; use Flow\ETL\Config\Telemetry\TelemetryAttributes; use Flow\ETL\Exception\RuntimeException; use Flow\ETL\FlowContext; @@ -13,7 +12,6 @@ use Flow\ETL\Loader\Closure; use Flow\ETL\Loader\FileLoader; use Flow\ETL\Rows; -use Flow\Filesystem\DestinationStream; use Flow\Filesystem\Partition; use Flow\Filesystem\Path; use Flow\Filesystem\Path\Option; @@ -21,12 +19,14 @@ use JsonException; use Throwable; -use function count; - final class JsonLinesLoader implements Closure, FileLoader, Loader { + private string $dateFormat = 'Y-m-d'; + private string $dateTimeFormat = DateTimeInterface::ATOM; + private ?JSONEncoder $encoder = null; + private int $flags = JSON_THROW_ON_ERROR; private readonly Path $path; @@ -67,6 +67,13 @@ public function load(Rows $rows, FlowContext $context): void } } + public function withDateFormat(string $dateFormat): self + { + $this->dateFormat = $dateFormat; + + return $this; + } + public function withDateTimeFormat(string $dateTimeFormat): self { $this->dateTimeFormat = $dateTimeFormat; @@ -86,28 +93,9 @@ public function withFlags(int $flags): self */ public function write(Rows $nextRows, array $partitions, FlowContext $context): void { - $streams = $context->streams(); - $normalizer = new RowsNormalizer(new EntryNormalizer($this->dateTimeFormat)); + $stream = $context->streams()->writeTo($this->path, $partitions); - $stream = $streams->writeTo($this->path, $partitions); - - $this->writeJSON($nextRows, $stream, $normalizer); - } - - /** - * @param Rows $rows - * @param DestinationStream $stream - * - * @throws RuntimeException - * @throws \JsonException - */ - private function writeJSON(Rows $rows, DestinationStream $stream, RowsNormalizer $normalizer): void - { - if (!count($rows)) { - return; - } - - foreach ($normalizer->normalize($rows) as $normalizedRow) { + foreach ($this->encoder()->encode($context->hydrator()->dehydrate($nextRows)) as $normalizedRow) { try { $json = json_encode($normalizedRow, $this->flags); @@ -121,4 +109,9 @@ private function writeJSON(Rows $rows, DestinationStream $stream, RowsNormalizer $stream->append($json . "\n"); } } + + private function encoder(): JSONEncoder + { + return $this->encoder ??= new JSONEncoder($this->dateTimeFormat, $this->dateFormat); + } } diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLoader.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLoader.php index 48b6d945cf..cc867a44cb 100644 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLoader.php +++ b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/JsonLoader.php @@ -5,7 +5,6 @@ namespace Flow\ETL\Adapter\JSON; use DateTimeInterface; -use Flow\ETL\Adapter\JSON\RowsNormalizer\EntryNormalizer; use Flow\ETL\Config\Telemetry\TelemetryAttributes; use Flow\ETL\Exception\RuntimeException; use Flow\ETL\FlowContext; @@ -22,12 +21,15 @@ use Throwable; use function array_key_exists; -use function count; final class JsonLoader implements Closure, FileLoader, Loader { + private string $dateFormat = 'Y-m-d'; + private string $dateTimeFormat = DateTimeInterface::ATOM; + private ?JSONEncoder $encoder = null; + private int $flags = JSON_THROW_ON_ERROR; private readonly Path $path; @@ -81,6 +83,13 @@ public function load(Rows $rows, FlowContext $context): void } } + public function withDateFormat(string $dateFormat): self + { + $this->dateFormat = $dateFormat; + + return $this; + } + public function withDateTimeFormat(string $dateTimeFormat): self { $this->dateTimeFormat = $dateTimeFormat; @@ -108,7 +117,6 @@ public function withRowsInNewLines(bool $putRowsInNewLines): self public function write(Rows $nextRows, array $partitions, FlowContext $context): void { $streams = $context->streams(); - $normalizer = new RowsNormalizer(new EntryNormalizer($this->dateTimeFormat)); if (!$streams->isOpen($this->path, $partitions)) { $stream = $streams->writeTo($this->path, $partitions); @@ -122,25 +130,29 @@ public function write(Rows $nextRows, array $partitions, FlowContext $context): $stream = $streams->writeTo($this->path, $partitions); } - $this->writeJSON($nextRows, $stream, $normalizer); + $this->writeJSON($this->encoder()->encode($context->hydrator()->dehydrate($nextRows)), $stream); + } + + private function encoder(): JSONEncoder + { + return $this->encoder ??= new JSONEncoder($this->dateTimeFormat, $this->dateFormat); } /** - * @param Rows $rows - * @param DestinationStream $stream + * @param list> $encodedRows * * @throws RuntimeException * @throws \JsonException */ - private function writeJSON(Rows $rows, DestinationStream $stream, RowsNormalizer $normalizer): void + private function writeJSON(array $encodedRows, DestinationStream $stream): void { - if (!count($rows)) { + if ($encodedRows === []) { return; } $separator = $this->putRowsInNewLines ? ",\n" : ','; - foreach ($normalizer->normalize($rows) as $normalizedRow) { + foreach ($encodedRows as $normalizedRow) { try { $json = json_encode($normalizedRow, $this->flags); diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer.php deleted file mode 100644 index 1963189cff..0000000000 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer.php +++ /dev/null @@ -1,32 +0,0 @@ -|bool|float|int|string>> - */ - public function normalize(Rows $rows): Generator - { - foreach ($rows as $row) { - $normalizedRow = []; - - foreach ($row->entries() as $entry) { - $normalizedRow[$entry->name()] = $this->normalizer->normalize($entry); - } - - yield $normalizedRow; - } - } -} diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer/EntryNormalizer.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer/EntryNormalizer.php deleted file mode 100644 index 257d1554eb..0000000000 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/RowsNormalizer/EntryNormalizer.php +++ /dev/null @@ -1,94 +0,0 @@ - $entry - * - * @return null|array|bool|float|int|string - */ - public function normalize(Entry $entry): string|float|int|bool|array|null - { - return match ($entry::class) { - UuidEntry::class => $entry->toString(), - DateTimeEntry::class => $entry->value()?->format($this->dateTimeFormat), - DateEntry::class => $entry->value()?->format($this->dateFormat), - TimeEntry::class => ($timeValue = $entry->value()) !== null - ? date_interval_to_microseconds($timeValue) - : null, - EnumEntry::class => $entry->value()?->name, - JsonEntry::class => $this->normalizeJsonValue($entry->value()?->toArray()), - ListEntry::class, MapEntry::class, StructureEntry::class, XMLElementEntry::class => $entry->toString(), - XMLEntry::class => $entry->toString(), - default => $this->normalizeValue($entry->value()), - }; - } - - /** - * @return null|array|bool|float|int|string - */ - private function normalizeJsonValue(mixed $value): string|float|int|bool|array|null - { - if (is_array($value)) { - return array_combine( - array_map(static fn(int|string $key): string => (string) $key, array_keys($value)), - array_values($value), - ); - } - - return $this->normalizeValue($value); - } - - /** - * @return null|array|bool|float|int|string - */ - private function normalizeValue(mixed $value): string|float|int|bool|array|null - { - if (is_string($value) || is_float($value) || is_int($value) || is_bool($value) || $value === null) { - return $value; - } - - if (is_array($value)) { - return array_combine( - array_map(static fn(int|string $key): string => (string) $key, array_keys($value)), - array_values($value), - ); - } - - return ''; - } -} diff --git a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/SchemaConverter.php b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/SchemaConverter.php index 1509600015..db52e2dc1c 100644 --- a/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/SchemaConverter.php +++ b/src/adapter/etl-adapter-json/src/Flow/ETL/Adapter/JSON/SchemaConverter.php @@ -574,7 +574,7 @@ private function definitionToJsonSchema(Definition $definition): array|bool if ($metadata->has(JsonSchemaMetadata::ANY->value)) { $property = []; - } elseif ($metadata->has(Metadata::FROM_NULL)) { + } elseif ($definition->type() instanceof NullType) { $property = ['type' => 'null']; } else { $property = $metadata->has(JsonSchemaMetadata::PREFIX_ITEMS->value) diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_partitioned/group=1/data.json b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_partitioned/group=1/data.json new file mode 100644 index 0000000000..e140fc876e --- /dev/null +++ b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_partitioned/group=1/data.json @@ -0,0 +1 @@ +[{"id":1,"value":"a"}] \ No newline at end of file diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_partitioned/group=2/data.json b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_partitioned/group=2/data.json new file mode 100644 index 0000000000..3cbc521379 --- /dev/null +++ b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_partitioned/group=2/data.json @@ -0,0 +1 @@ +[{"id":2,"value":"b"}] \ No newline at end of file diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_people.json b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_people.json new file mode 100644 index 0000000000..cd45c1665a --- /dev/null +++ b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_people.json @@ -0,0 +1 @@ +[{"id":1,"name":"Alice","active":true},{"id":2,"active":false}] \ No newline at end of file diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_people.jsonl b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_people.jsonl new file mode 100644 index 0000000000..7aace54aae --- /dev/null +++ b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Fixtures/parity_people.jsonl @@ -0,0 +1,2 @@ +{"id":1,"name":"Alice","active":true} +{"id":2,"active":false} diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Integration/JSONMachine/JsonHydratorParityTest.php b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Integration/JSONMachine/JsonHydratorParityTest.php new file mode 100644 index 0000000000..8f426e1870 --- /dev/null +++ b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Integration/JSONMachine/JsonHydratorParityTest.php @@ -0,0 +1,97 @@ +extract(flow_context(Config::builder()->putInputIntoRows()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + static::assertSame( + [ + ['id' => 1, 'name' => 'Alice', 'active' => true, '_input_file_uri' => $path->uri()], + ['id' => 2, 'name' => null, 'active' => false, '_input_file_uri' => $path->uri()], + ], + $actual, + ); + } + + public function test_fast_path_reads_partitioned_files_with_partition_value_from_path(): void + { + $extractor = from_json(__DIR__ . '/../../Fixtures/parity_partitioned/group=*/data.json', schema: schema( + int_schema('group'), + int_schema('id'), + str_schema('value'), + )); + + $actual = []; + + foreach ($extractor->extract(flow_context(Config::builder()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + usort($actual, static fn(array $a, array $b): int => (int) $a['id'] <=> (int) $b['id']); + + static::assertSame( + [ + ['group' => 1, 'id' => 1, 'value' => 'a'], + ['group' => 2, 'id' => 2, 'value' => 'b'], + ], + $actual, + ); + } + + public function test_appends_partition_columns_absent_from_the_schema(): void + { + $extractor = from_json(__DIR__ . '/../../Fixtures/parity_partitioned/group=*/data.json', schema: schema( + int_schema('id'), + str_schema('value'), + )); + + $actual = []; + + foreach ($extractor->extract(flow_context(Config::builder()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + usort($actual, static fn(array $a, array $b): int => (int) $a['id'] <=> (int) $b['id']); + + static::assertSame( + [ + ['id' => 1, 'value' => 'a', 'group' => '1'], + ['id' => 2, 'value' => 'b', 'group' => '2'], + ], + $actual, + ); + } +} diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Integration/JSONMachine/JsonLinesHydratorParityTest.php b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Integration/JSONMachine/JsonLinesHydratorParityTest.php new file mode 100644 index 0000000000..62a458677a --- /dev/null +++ b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Integration/JSONMachine/JsonLinesHydratorParityTest.php @@ -0,0 +1,66 @@ +withSchema(schema(int_schema('id'), str_schema('name', nullable: true), bool_schema('active'))); + + $actual = []; + + foreach ($extractor->extract(flow_context(Config::builder()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + static::assertSame( + [ + ['id' => 1, 'name' => 'Alice', 'active' => true], + ['id' => 2, 'name' => null, 'active' => false], + ], + $actual, + ); + } + + public function test_honours_a_hydrator_configured_on_the_context(): void + { + $extractor = from_json_lines(path_real(__DIR__ . '/../../Fixtures/parity_people.jsonl')) + ->withSchema(schema(int_schema('id'), str_schema('name', nullable: true), bool_schema('active'))); + + $actual = []; + + foreach ($extractor->extract( + flow_context(Config::builder()->hydrator(new AdaptiveRowHydrator())->build()), + ) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + static::assertSame( + [ + ['id' => 1, 'name' => 'Alice', 'active' => true], + ['id' => 2, 'name' => null, 'active' => false], + ], + $actual, + ); + } +} diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Unit/EntryNormalizerTest.php b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Unit/EntryNormalizerTest.php deleted file mode 100644 index 5a9e65c87e..0000000000 --- a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Unit/EntryNormalizerTest.php +++ /dev/null @@ -1,62 +0,0 @@ - [str_entry('string', 'value'), 'value']; - yield 'string_nullable' => [str_entry('string', null), null]; - yield 'int' => [int_entry('integer', 1), 1]; - yield 'int_nullable' => [int_entry('integer', null), null]; - yield 'float' => [float_entry('float', 1.1), 1.1]; - yield 'float_nullable' => [float_entry('float', null), null]; - yield 'bool' => [bool_entry('bool', true), 'true']; - yield 'bool_nullable' => [bool_entry('bool', null), null]; - yield 'null' => [null_entry('null'), null]; - yield 'date' => [date_entry('date', new DateTimeImmutable('2023-10-01 12:02:01')), '2023-10-01']; - yield 'date_nullable' => [date_entry('date', null), null]; - yield 'datetime' => [ - datetime_entry('datetime', new DateTimeImmutable('2023-10-01 12:02:01')), - '2023-10-01T12:02:01+00:00', - ]; - yield 'datetime_nullable' => [datetime_entry('datetime', null), null]; - yield 'time' => [time_entry('time', new DateInterval('PT1H')), 3600000000]; - yield 'time_nullable' => [time_entry('time', null), null]; - yield 'uuid' => [ - uuid_entry('uuid', 'f47ac10b-58cc-4372-a567-0e02b2c3d479'), - 'f47ac10b-58cc-4372-a567-0e02b2c3d479', - ]; - yield 'uuid_nullable' => [uuid_entry('uuid', null), null]; - } - - /** - * @param Entry $entry - */ - #[DataProvider('entries_provider')] - public function test_normalizing_entries(Entry $entry, mixed $expected): void - { - static::assertEquals($expected, (new EntryNormalizer())->normalize($entry)); - } -} diff --git a/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Unit/JSONEncoderTest.php b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Unit/JSONEncoderTest.php new file mode 100644 index 0000000000..d2be798072 --- /dev/null +++ b/src/adapter/etl-adapter-json/tests/Flow/ETL/Adapter/JSON/Tests/Unit/JSONEncoderTest.php @@ -0,0 +1,119 @@ + 1, 'name' => 'Alice'], + (new JSONEncoder())->decode([['id' => 1, 'name' => 'Alice']])[0]->values, + ); + } + + public function test_encode_keeps_json_values_as_nested_structures(): void + { + static::assertSame( + [['data' => ['a' => 1, 'b' => 2]]], + (new JSONEncoder())->encode([ + new TypedRowValues(['data' => Json::fromArray(['a' => 1, 'b' => 2])], ['data' => type_json()]), + ]), + ); + } + + public function test_encode_passes_scalars_through(): void + { + static::assertSame( + [['id' => 1, 'name' => 'Alice', 'active' => true, 'score' => 9.5, 'missing' => null]], + (new JSONEncoder())->encode([ + new TypedRowValues([ + 'id' => 1, + 'name' => 'Alice', + 'active' => true, + 'score' => 9.5, + 'missing' => null, + ], [ + 'id' => type_integer(), + 'name' => type_string(), + 'active' => type_boolean(), + 'score' => type_float(), + 'missing' => type_string(), + ]), + ]), + ); + } + + public function test_encode_renders_date_with_the_date_format(): void + { + static::assertSame( + [['at' => '2023-10-01']], + (new JSONEncoder())->encode([ + new TypedRowValues(['at' => new DateTimeImmutable('2023-10-01 12:02:01 UTC')], ['at' => type_date()]), + ]), + ); + } + + public function test_encode_renders_datetime_with_the_datetime_format(): void + { + static::assertSame( + [['at' => '2023-10-01T12:02:01+00:00']], + (new JSONEncoder())->encode([ + new TypedRowValues(['at' => new DateTimeImmutable('2023-10-01 12:02:01 UTC')], [ + 'at' => type_datetime(), + ]), + ]), + ); + } + + public function test_encode_renders_list_map_structure_values_as_json_strings(): void + { + static::assertSame( + [['tags' => '[1,2,3]']], + (new JSONEncoder())->encode([ + new TypedRowValues(['tags' => [1, 2, 3]], ['tags' => type_array()]), + ]), + ); + } + + public function test_encode_renders_time_as_microseconds(): void + { + static::assertSame( + [['duration' => 3600000000]], + (new JSONEncoder())->encode([ + new TypedRowValues(['duration' => new DateInterval('PT1H')], ['duration' => type_time()]), + ]), + ); + } + + public function test_encode_renders_uuid_as_string(): void + { + static::assertSame( + [['id' => 'f47ac10b-58cc-4372-a567-0e02b2c3d479']], + (new JSONEncoder())->encode([ + new TypedRowValues(['id' => new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479')], ['id' => type_uuid()]), + ]), + ); + } +} diff --git a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetEncoder.php b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetEncoder.php new file mode 100644 index 0000000000..d9c97b2e61 --- /dev/null +++ b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetEncoder.php @@ -0,0 +1,98 @@ +> + */ +final class ParquetEncoder implements Encoder +{ + /** + * @var array> + */ + private array $decodePlan; + + /** + * @var array, bool}> + */ + private array $encodePlan; + + public function __construct(ParquetSchema $schema) + { + $converter = new SchemaConverter(); + $decodePlan = []; + $encodePlan = []; + + foreach ($schema->columns() as $column) { + $name = $column->name(); + $logicalType = $column instanceof FlatColumn ? $column->logicalType()?->name() : null; + + $encodePlan[$name] = [ + $converter->parquetToFlowType($column), + $logicalType === LogicalType::UUID || $logicalType === LogicalType::JSON, + ]; + + if ($logicalType === LogicalType::UUID) { + $decodePlan[$name] = type_uuid(); + } elseif ($logicalType === LogicalType::JSON) { + $decodePlan[$name] = type_json(); + } + } + + $this->decodePlan = $decodePlan; + $this->encodePlan = $encodePlan; + } + + public function decode(array $batch): array + { + $decoded = []; + + foreach ($batch as $values) { + foreach ($this->decodePlan as $name => $type) { + if (array_key_exists($name, $values) && $values[$name] !== null) { + $values[$name] = $type->cast($values[$name]); + } + } + + $decoded[] = new RawRowValues($values); + } + + return $decoded; + } + + public function encode(array $batch): array + { + $encoded = []; + + foreach ($batch as $rowValues) { + $values = $rowValues->values; + + foreach ($this->encodePlan as $name => [$type, $stringify]) { + if (array_key_exists($name, $values) && $values[$name] !== null) { + // @mago-ignore analysis:mixed-assignment + $cast = $type->cast($values[$name]); + $values[$name] = $stringify && is_object($cast) ? type_string()->cast($cast) : $cast; + } + } + + $encoded[] = $values; + } + + return $encoded; + } +} diff --git a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetExtractor.php b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetExtractor.php index 8b75a22a69..4e80a354ca 100644 --- a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetExtractor.php +++ b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetExtractor.php @@ -21,10 +21,9 @@ use Flow\Parquet\Reader; use Generator; -use function Flow\ETL\DSL\ref; -use function Flow\ETL\DSL\row; -use function Flow\ETL\DSL\rows; -use function Flow\Types\DSL\type_string; +use function count; +use function Flow\ETL\DSL\str_schema; +use function max; final class ParquetExtractor implements Extractor, FileExtractor, LimitableExtractor { @@ -44,8 +43,6 @@ final class ParquetExtractor implements Extractor, FileExtractor, LimitableExtra private SchemaConverter $schemaConverter; - private ValueHydrator $valueHydrator; - /** * @param Path $path */ @@ -54,7 +51,6 @@ public function __construct( ) { $this->resetLimit(); $this->schemaConverter = new SchemaConverter(); - $this->valueHydrator = new ValueHydrator(); $this->options = Options::default(); } @@ -64,6 +60,8 @@ public function __construct( public function extract(FlowContext $context): Generator { $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); $fileOffset = $this->offset ?? 0; @@ -78,34 +76,46 @@ public function extract(FlowContext $context): Generator } $flowSchema = $this->schemaConverter->toFlow($fileData['file']->schema()); + $streamUri = $shouldPutInputIntoRows ? $fileData['stream']->path()->uri() : null; if (count($this->columns)) { $flowSchema = $flowSchema->keep(...$this->columns); } - $uri = $fileData['stream']->path()->uri(); + if ($streamUri !== null && $flowSchema->findDefinition('_input_file_uri') === null) { + $flowSchema = $flowSchema->add(str_schema('_input_file_uri')); + } - foreach ($fileData['file']->values($this->columns, $this->limit(), $fileOffset) as $row) { - $entries = []; + $encoder = new ParquetEncoder($fileData['file']->schema()); - if ($shouldPutInputIntoRows) { - $entries[] = $context->entryFactory()->createAs('_input_file_uri', $uri, type_string()); + $rawBatch = []; + + foreach ($fileData['file']->values($this->columns, $this->limit(), $fileOffset) as $row) { + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; } - // @mago-ignore analysis:mixed-assignment - foreach ($row as $entryName => $entryValue) { - $definition = $flowSchema->get(ref($entryName)); + $rawBatch[] = $row; - $entries[] = $context->entryFactory()->instantiate( - $entryName, - $this->valueHydrator->hydrate($entryValue, $definition), - $definition, - ); - } + if (count($rawBatch) >= $batchSize) { + foreach ($hydrator->hydrate($encoder->decode($rawBatch), $flowSchema) as $hydratedRow) { + $this->incrementReturnedRows(); + $signal = yield new Rows($hydratedRow); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + + return; + } + } - $signal = yield rows(row(...$entries)); + $rawBatch = []; + } + } + foreach ($hydrator->hydrate($encoder->decode($rawBatch), $flowSchema) as $hydratedRow) { $this->incrementReturnedRows(); + $signal = yield new Rows($hydratedRow); if ($signal === Signal::STOP || $this->reachedLimit()) { $context->streams()->closeStreams($this->path); diff --git a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetLoader.php b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetLoader.php index f016849a28..3b37d83109 100644 --- a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetLoader.php +++ b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ParquetLoader.php @@ -29,9 +29,9 @@ final class ParquetLoader implements Closure, FileLoader, Loader private readonly SchemaConverter $converter; - private ?Schema $inferredSchema = null; + private ?ParquetEncoder $encoder = null; - private readonly RowsNormalizer $normalizer; + private ?Schema $inferredSchema = null; private Options $options; @@ -47,7 +47,6 @@ final class ParquetLoader implements Closure, FileLoader, Loader public function __construct(Path $path) { $this->converter = new SchemaConverter(); - $this->normalizer = new RowsNormalizer(); $this->options = Options::default(); $this->path = $path->setOptionWhenEmpty(Option::CONTENT_TYPE, ContentType::PARQUET); } @@ -80,6 +79,8 @@ public function load(Rows $rows, FlowContext $context): void $this->inferSchema($rows); } + $encoded = $this->encoder()->encode($context->hydrator()->dehydrate($rows)); + $streams = $context->streams(); if ($rows->partitions()->count()) { @@ -97,10 +98,7 @@ public function load(Rows $rows, FlowContext $context): void ); } - $this->writers[$stream->path()->uri()]->writeBatch($this->normalizer->normalize( - $rows, - $this->schema(), - )); + $this->writers[$stream->path()->uri()]->writeBatch($encoded); } else { $stream = $streams->writeTo($this->path); @@ -116,10 +114,7 @@ public function load(Rows $rows, FlowContext $context): void ); } - $this->writers[$stream->path()->uri()]->writeBatch($this->normalizer->normalize( - $rows, - $this->schema(), - )); + $this->writers[$stream->path()->uri()]->writeBatch($encoded); } $context->telemetry()->loadingCompleted($this, [TelemetryAttributes::ATTR_LOADING_ROWS => $rows->count()]); @@ -151,6 +146,11 @@ public function withSchema(Schema $schema): self return $this; } + private function encoder(): ParquetEncoder + { + return $this->encoder ??= new ParquetEncoder($this->converter->toParquet($this->schema())); + } + private function inferSchema(Rows $rows): void { if ($this->inferredSchema === null) { diff --git a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/RowsNormalizer.php b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/RowsNormalizer.php deleted file mode 100644 index d87d072b81..0000000000 --- a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/RowsNormalizer.php +++ /dev/null @@ -1,62 +0,0 @@ -> - */ - public function normalize(Rows $rows, Schema $schema): array - { - $normalizedRows = []; - - foreach ($rows as $row) { - $columns = []; - - foreach ($row->entries() as $entry) { - $definition = $schema->get($entry->ref()); - - if ($definition->isNullable() && $entry->value() === null) { - $columns[$entry->name()] = null; - - continue; - } - - if ($entry instanceof JsonEntry) { - $columns[$entry->name()] = $entry->toString(); - } elseif ($entry instanceof UuidEntry || $entry instanceof XMLEntry) { - $columns[$entry->name()] = type_string()->cast($entry->value()); - } else { - $type = $definition->type(); - $isJsonType = - $type instanceof JsonType || $type instanceof OptionalType && $type->base() instanceof JsonType; - - $columns[$entry->name()] = $isJsonType - ? type_string()->cast($type->cast($entry->value())) - : $type->cast($entry->value()); - } - } - - $normalizedRows[] = $columns; - } - - return $normalizedRows; - } -} diff --git a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/SchemaConverter.php b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/SchemaConverter.php index 7295ba61d1..a696016d89 100644 --- a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/SchemaConverter.php +++ b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/SchemaConverter.php @@ -29,6 +29,7 @@ use Flow\Types\Type\Native\BooleanType; use Flow\Types\Type\Native\FloatType; use Flow\Types\Type\Native\IntegerType; +use Flow\Types\Type\Native\NullType; use Flow\Types\Type\Native\StringType; use function array_keys; @@ -105,6 +106,7 @@ private function flowToParquet(string $name, Type $type, bool $nullable): Column XMLElementType::class, XMLType::class, StringType::class, + NullType::class, => FlatColumn::string($name, $repetition), BooleanType::class => FlatColumn::boolean($name, $repetition), TimeType::class => FlatColumn::time($name, $repetition), @@ -225,7 +227,7 @@ private function parquetToFlowDefinition(Column $column): Definition /** * @return Type */ - private function parquetToFlowType(Column $column): Type + public function parquetToFlowType(Column $column): Type { if ($column instanceof FlatColumn) { $logicalType = $column->logicalType(); diff --git a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ValueHydrator.php b/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ValueHydrator.php deleted file mode 100644 index ce2cada3dc..0000000000 --- a/src/adapter/etl-adapter-parquet/src/Flow/ETL/Adapter/Parquet/ValueHydrator.php +++ /dev/null @@ -1,37 +0,0 @@ - $definition - */ - public function hydrate(mixed $value, Definition $definition): mixed - { - if ($value === null) { - return null; - } - - $type = $definition->type(); - - if ($type instanceof OptionalType) { - $type = $type->base(); - } - - if ($type instanceof JsonType || $type instanceof UuidType) { - return $type->cast($value); - } - - return $value; - } -} diff --git a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/PaginationTest.php b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/PaginationTest.php index 49527cf8e9..36b513857f 100644 --- a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/PaginationTest.php +++ b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/PaginationTest.php @@ -11,7 +11,6 @@ use function Flow\ETL\DSL\config; use function Flow\ETL\DSL\flow_context; use function Flow\Filesystem\DSL\path_real; -use function iterator_to_array; final class PaginationTest extends FlowTestCase { @@ -77,6 +76,12 @@ public function test_reading_file_from_given_offset(): void $extractor = from_parquet(path_real(__DIR__ . '/Fixtures/orders_1k.parquet'))->withOffset($totalRows - 100); - static::assertCount(100, iterator_to_array($extractor->extract(flow_context(config())))); + $extractedRows = 0; + + foreach ($extractor->extract(flow_context(config())) as $batch) { + $extractedRows += $batch->count(); + } + + static::assertSame(100, $extractedRows); } } diff --git a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/ParquetExtractorTest.php b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/ParquetExtractorTest.php index 5f65d982ec..f3570d1093 100644 --- a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/ParquetExtractorTest.php +++ b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/ParquetExtractorTest.php @@ -13,7 +13,6 @@ use function Flow\ETL\DSL\flow_context; use function Flow\Filesystem\DSL\path; use function Flow\Filesystem\DSL\path_real; -use function iterator_to_array; final class ParquetExtractorTest extends FlowTestCase { @@ -22,7 +21,13 @@ public function test_limit(): void $extractor = from_parquet(path(__DIR__ . '/Fixtures/orders_1k.parquet')); $extractor->changeLimit(2); - static::assertCount(2, iterator_to_array($extractor->extract(flow_context(config())))); + $extractedRows = 0; + + foreach ($extractor->extract(flow_context(config())) as $batch) { + $extractedRows += $batch->count(); + } + + static::assertSame(2, $extractedRows); } public function test_reading_file_from_given_offset(): void @@ -34,17 +39,21 @@ public function test_reading_file_from_given_offset(): void $extractor = from_parquet(path_real(__DIR__ . '/Fixtures/orders_1k.parquet'))->withOffset($totalRows - 100); - static::assertCount(100, iterator_to_array($extractor->extract(flow_context(config())))); + $extractedRows = 0; + + foreach ($extractor->extract(flow_context(config())) as $batch) { + $extractedRows += $batch->count(); + } + + static::assertSame(100, $extractedRows); } public function test_signal_stop(): void { - $extractor = from_parquet(path(__DIR__ . '/Fixtures/orders_1k.parquet')); + $extractor = from_parquet(path(__DIR__ . '/Fixtures/Pagination/*.parquet')); $generator = $extractor->extract(flow_context(config())); - static::assertTrue($generator->valid()); - $generator->next(); static::assertTrue($generator->valid()); $generator->next(); static::assertTrue($generator->valid()); diff --git a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/ParquetHydratorParityTest.php b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/ParquetHydratorParityTest.php new file mode 100644 index 0000000000..1ab1440263 --- /dev/null +++ b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Integration/ParquetHydratorParityTest.php @@ -0,0 +1,67 @@ +path)) { + unlink($this->path); + } + } + + public function test_trusted_read_is_identical_to_a_casting_read(): void + { + data_frame(config()) + ->read(new FakeExtractor(50)) + ->drop('null', 'enum') + ->mode(overwrite()) + ->write(to_parquet(path($this->path))) + ->run(); + + $file = (new Reader())->read($this->path); + $flowSchema = (new SchemaConverter())->toFlow($file->schema()); + $rawRows = iterator_to_array($file->values(), false); + + $encoder = new ParquetEncoder($file->schema()); + $decodedRows = $encoder->decode($rawRows); + + $trusted = (new AdaptiveRowHydrator())->hydrate($decodedRows, $flowSchema); + $cast = (new AdaptiveRowHydrator())->cast( + array_map(static fn(array $values): RawRowValues => new RawRowValues($values), $rawRows), + $flowSchema, + ); + + static::assertSame(serialize($cast), serialize($trusted)); + } +} diff --git a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/ParquetEncoderTest.php b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/ParquetEncoderTest.php new file mode 100644 index 0000000000..3f5a197c20 --- /dev/null +++ b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/ParquetEncoderTest.php @@ -0,0 +1,118 @@ + null, 'payload' => null], + (new ParquetEncoder(ParquetSchema::with(FlatColumn::uuid('id'), FlatColumn::json('payload'))))->decode([[ + 'id' => null, + 'payload' => null, + ]])[0]->values, + ); + } + + public function test_decode_normalizes_json_columns_to_flow_native(): void + { + $decoded = (new ParquetEncoder(ParquetSchema::with(FlatColumn::json('payload'))))->decode([[ + 'payload' => '{"id":1,"status":"NEW"}', + ]]); + + static::assertInstanceOf(Json::class, $decoded[0]->values['payload']); + static::assertSame(['id' => 1, 'status' => 'NEW'], $decoded[0]->values['payload']->toArray()); + } + + public function test_decode_normalizes_uuid_columns_to_flow_native(): void + { + $decoded = (new ParquetEncoder(ParquetSchema::with(FlatColumn::uuid('id'))))->decode([[ + 'id' => 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + ]]); + + static::assertInstanceOf(Uuid::class, $decoded[0]->values['id']); + static::assertSame('f47ac10b-58cc-4372-a567-0e02b2c3d479', $decoded[0]->values['id']->toString()); + } + + public function test_decode_passes_scalar_value_maps_through_unchanged(): void + { + static::assertSame( + ['id' => 1, 'name' => 'Alice'], + (new ParquetEncoder(ParquetSchema::with(FlatColumn::int64('id'), FlatColumn::string('name'))))->decode([[ + 'id' => 1, + 'name' => 'Alice', + ]])[0]->values, + ); + } + + public function test_encode_coerces_values_to_the_column_type(): void + { + static::assertSame( + [['id' => '1', 'name' => 'test']], + (new ParquetEncoder(ParquetSchema::with( + FlatColumn::string('id'), + FlatColumn::string('name'), + )))->encode([new TypedRowValues(['id' => 1, 'name' => 'test'], [ + 'id' => type_integer(), + 'name' => type_string(), + ])]), + ); + } + + public function test_encode_keeps_datetime_and_scalar_values(): void + { + $at = new DateTimeImmutable('2024-01-01 12:00:00 UTC'); + + static::assertSame( + [['id' => 1, 'at' => $at]], + (new ParquetEncoder(ParquetSchema::with( + FlatColumn::int64('id'), + FlatColumn::datetime('at'), + )))->encode([new TypedRowValues(['id' => 1, 'at' => $at], [ + 'id' => type_integer(), + 'at' => type_datetime(), + ])]), + ); + } + + public function test_encode_leaves_null_values_untouched(): void + { + static::assertSame( + [['id' => null, 'name' => null]], + (new ParquetEncoder(ParquetSchema::with( + FlatColumn::int64('id'), + FlatColumn::string('name'), + )))->encode([new TypedRowValues(['id' => null, 'name' => null], [ + 'id' => type_integer(), + 'name' => type_string(), + ])]), + ); + } + + public function test_encode_renders_uuid_values_back_to_strings(): void + { + static::assertSame( + [['id' => 'f47ac10b-58cc-4372-a567-0e02b2c3d479']], + (new ParquetEncoder(ParquetSchema::with(FlatColumn::uuid('id'))))->encode([new TypedRowValues([ + 'id' => new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'), + ], ['id' => type_uuid()])]), + ); + } +} diff --git a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/RowsNormalizerTest.php b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/RowsNormalizerTest.php deleted file mode 100644 index bbf050da3e..0000000000 --- a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/RowsNormalizerTest.php +++ /dev/null @@ -1,129 +0,0 @@ - type_string(), - 'city' => type_string(), - 'zip' => type_string(), - 'country' => type_string(), - 'location' => type_structure([ - 'lat' => type_float(), - 'lon' => type_float(), - ]), - ])), - enum_entry('enum', null), - xml_entry('xml', null), - html_entry('html', null), - )); - $schema = schema( - int_schema('int', true), - float_schema('float', true), - bool_schema('bool', true), - datetime_schema('datetime', true), - string_schema('null', nullable: true), - uuid_schema('uuid', true), - json_schema('json', true), - list_schema('list', type_list(type_integer()), true), - list_schema('list_of_datetimes', type_list(type_datetime()), true), - map_schema('map', type_map(type_integer(), type_string()), true), - structure_schema( - 'struct', - type_structure([ - 'street' => type_string(), - 'city' => type_string(), - 'zip' => type_string(), - 'country' => type_string(), - 'location' => type_structure([ - 'lat' => type_float(), - 'lon' => type_float(), - ]), - ]), - true, - ), - enum_schema('enum', BackedStringEnum::class, true), - xml_schema('xml', true), - html_schema('html', true), - ); - - static::assertEquals( - [ - [ - 'int' => null, - 'float' => null, - 'bool' => null, - 'datetime' => null, - 'null' => null, - 'uuid' => null, - 'json' => null, - 'list' => null, - 'list_of_datetimes' => null, - 'map' => null, - 'struct' => null, - 'enum' => null, - 'xml' => null, - 'html' => null, - ], - ], - (new RowsNormalizer())->normalize($rows, $schema), - ); - } -} diff --git a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/ValueHydratorTest.php b/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/ValueHydratorTest.php deleted file mode 100644 index 6c2ec5bb2e..0000000000 --- a/src/adapter/etl-adapter-parquet/tests/Flow/ETL/Adapter/Parquet/Tests/Unit/ValueHydratorTest.php +++ /dev/null @@ -1,112 +0,0 @@ -hydrate($json, json_schema('json'))); - static::assertSame($uuid, (new ValueHydrator())->hydrate($uuid, uuid_schema('uuid'))); - } - - public function test_hydrating_json_string_into_json_value(): void - { - static::assertEquals( - new Json('{"id":1,"name":"flow"}'), - (new ValueHydrator())->hydrate('{"id":1,"name":"flow"}', json_schema('json')), - ); - } - - public function test_hydrating_json_string_into_json_value_for_nullable_definition(): void - { - static::assertEquals( - new Json('{"id":1}'), - (new ValueHydrator())->hydrate('{"id":1}', json_schema('json', true)), - ); - } - - public function test_hydrating_null(): void - { - static::assertNull((new ValueHydrator())->hydrate(null, int_schema('int', true))); - static::assertNull((new ValueHydrator())->hydrate(null, json_schema('json', true))); - static::assertNull((new ValueHydrator())->hydrate(null, uuid_schema('uuid', true))); - static::assertNull((new ValueHydrator())->hydrate(null, int_schema('int'))); - } - - public function test_hydrating_uuid_string_into_uuid_value(): void - { - static::assertEquals( - new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'), - (new ValueHydrator())->hydrate('f47ac10b-58cc-4372-a567-0e02b2c3d479', uuid_schema('uuid')), - ); - } - - public function test_hydrating_uuid_string_into_uuid_value_for_nullable_definition(): void - { - static::assertEquals( - new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'), - (new ValueHydrator())->hydrate('f47ac10b-58cc-4372-a567-0e02b2c3d479', uuid_schema('uuid', true)), - ); - } - - public function test_values_of_types_without_flow_value_objects_are_passed_through_without_casting(): void - { - $datetime = new DateTimeImmutable('2024-04-01 10:00:00 UTC'); - $time = new DateInterval('PT2H30M'); - $list = [1, 2, 3]; - $map = ['a' => 1, 'b' => 2]; - $structure = ['lat' => 1.5, 'lon' => 2.5]; - - static::assertSame(1, (new ValueHydrator())->hydrate(1, int_schema('int'))); - static::assertSame(1.5, (new ValueHydrator())->hydrate(1.5, float_schema('float'))); - static::assertTrue((new ValueHydrator())->hydrate(true, bool_schema('bool'))); - static::assertSame('flow', (new ValueHydrator())->hydrate('flow', string_schema('string'))); - static::assertSame($datetime, (new ValueHydrator())->hydrate($datetime, datetime_schema('datetime'))); - static::assertSame($datetime, (new ValueHydrator())->hydrate($datetime, date_schema('date'))); - static::assertSame($time, (new ValueHydrator())->hydrate($time, time_schema('time'))); - static::assertSame($list, (new ValueHydrator())->hydrate($list, list_schema( - 'list', - type_list(type_integer()), - ))); - static::assertSame($map, (new ValueHydrator())->hydrate($map, map_schema('map', type_map( - type_string(), - type_integer(), - )))); - static::assertSame($structure, (new ValueHydrator())->hydrate($structure, structure_schema('struct', type_structure([ - 'lat' => type_float(), - 'lon' => type_float(), - ])))); - } -} diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/EntryTypesMap.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/EntryTypesMap.php index 47b1fc9373..5cd7d302d5 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/EntryTypesMap.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/EntryTypesMap.php @@ -5,24 +5,6 @@ namespace Flow\ETL\Adapter\PostgreSql; use Flow\ETL\Adapter\PostgreSql\Exception\TypeMappingException; -use Flow\ETL\Row\Entry; -use Flow\ETL\Row\Entry\BooleanEntry; -use Flow\ETL\Row\Entry\DateEntry; -use Flow\ETL\Row\Entry\DateTimeEntry; -use Flow\ETL\Row\Entry\EnumEntry; -use Flow\ETL\Row\Entry\FloatEntry; -use Flow\ETL\Row\Entry\HTMLElementEntry; -use Flow\ETL\Row\Entry\HTMLEntry; -use Flow\ETL\Row\Entry\IntegerEntry; -use Flow\ETL\Row\Entry\JsonEntry; -use Flow\ETL\Row\Entry\ListEntry; -use Flow\ETL\Row\Entry\MapEntry; -use Flow\ETL\Row\Entry\StringEntry; -use Flow\ETL\Row\Entry\StructureEntry; -use Flow\ETL\Row\Entry\TimeEntry; -use Flow\ETL\Row\Entry\UuidEntry; -use Flow\ETL\Row\Entry\XMLElementEntry; -use Flow\ETL\Row\Entry\XMLEntry; use Flow\PostgreSql\Client\TypedValue; use Flow\PostgreSql\Client\Types\ValueType; use Flow\PostgreSql\QueryBuilder\Schema\ColumnType; @@ -64,32 +46,32 @@ final readonly class EntryTypesMap { /** - * Default mapping of Entry classes to PostgreSQL types. + * Default mapping of Flow type classes to PostgreSQL value types. * - * @var array>, ValueType> + * @var array>, ValueType> */ public const array DEFAULT_TYPES = [ - StringEntry::class => ValueType::TEXT, - IntegerEntry::class => ValueType::INT8, - FloatEntry::class => ValueType::FLOAT8, - BooleanEntry::class => ValueType::BOOL, - DateEntry::class => ValueType::DATE, - DateTimeEntry::class => ValueType::TIMESTAMP, - TimeEntry::class => ValueType::TIME, - UuidEntry::class => ValueType::UUID, - JsonEntry::class => ValueType::JSONB, - XMLEntry::class => ValueType::XML, - XMLElementEntry::class => ValueType::XML, - HTMLEntry::class => ValueType::TEXT, - HTMLElementEntry::class => ValueType::TEXT, - EnumEntry::class => ValueType::TEXT, - ListEntry::class => ValueType::JSONB, - MapEntry::class => ValueType::JSONB, - StructureEntry::class => ValueType::JSONB, + StringType::class => ValueType::TEXT, + IntegerType::class => ValueType::INT8, + FloatType::class => ValueType::FLOAT8, + BooleanType::class => ValueType::BOOL, + DateType::class => ValueType::DATE, + DateTimeType::class => ValueType::TIMESTAMP, + TimeType::class => ValueType::TIME, + UuidType::class => ValueType::UUID, + JsonType::class => ValueType::JSONB, + XMLType::class => ValueType::XML, + LogicalXMLElementType::class => ValueType::XML, + HTMLType::class => ValueType::TEXT, + HTMLElementType::class => ValueType::TEXT, + EnumType::class => ValueType::TEXT, + ListType::class => ValueType::JSONB, + MapType::class => ValueType::JSONB, + StructureType::class => ValueType::JSONB, ]; /** - * @var array>, ValueType> + * @var array>, ValueType> */ private array $typeMap; @@ -99,7 +81,7 @@ private array $columnTypeMap; /** - * @param array>, ValueType> $overrides Entry class to ValueType mappings that override defaults + * @param array>, ValueType> $overrides Flow type class to ValueType mappings that override defaults * @param array>, ColumnType> $columnTypeOverrides Flow Type class to ColumnType mappings that override defaults */ public function __construct(array $overrides = [], array $columnTypeOverrides = []) @@ -109,25 +91,23 @@ public function __construct(array $overrides = [], array $columnTypeOverrides = } /** - * Maps an Entry to a TypedValue suitable for PostgreSQL queries. + * Maps a column value + Flow type to a TypedValue suitable for PostgreSQL queries. * - * @param Entry $entry + * @param Type $type * - * @throws TypeMappingException when entry type is not in the map + * @throws TypeMappingException when the Flow type is not in the map */ - public function mapEntry(Entry $entry): ?TypedValue + public function map(string $column, Type $type, mixed $value): ?TypedValue { - if ($entry->value() === null) { + if ($value === null) { return null; } - $entryClass = $entry::class; - - if (!array_key_exists($entryClass, $this->typeMap)) { - throw TypeMappingException::ambiguousEntryType($entryClass); + if (!array_key_exists($type::class, $this->typeMap)) { + throw TypeMappingException::unmappedColumn($column, $type::class); } - return new TypedValue($entry->value(), $this->typeMap[$entryClass]); + return new TypedValue($value, $this->typeMap[$type::class]); } /** diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/Exception/TypeMappingException.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/Exception/TypeMappingException.php index d4e2d97310..c7d08b68ba 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/Exception/TypeMappingException.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/Exception/TypeMappingException.php @@ -32,6 +32,15 @@ public static function unsupportedEntryType(string $entryClass): self )); } + public static function unmappedColumn(string $column, string $flowTypeClass): self + { + return new self(sprintf( + 'Column "%s" of Flow type "%s" cannot be automatically mapped to a PostgreSQL type. Provide a type override to map it explicitly.', + $column, + $flowTypeClass, + )); + } + public static function unsupportedFlowType(string $flowTypeClass): self { return new self(sprintf( diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlCursorExtractor.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlCursorExtractor.php index b0c453011f..ebde047a60 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlCursorExtractor.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlCursorExtractor.php @@ -15,7 +15,6 @@ use Generator; use function bin2hex; -use function Flow\ETL\DSL\array_to_rows; use function Flow\PostgreSql\DSL\close_cursor; use function Flow\PostgreSql\DSL\declare_cursor; use function Flow\PostgreSql\DSL\fetch; @@ -54,6 +53,7 @@ public function __construct( */ public function extract(FlowContext $context): Generator { + $encoder = new PostgreSqlEncoder(); $cursorName = $this->cursorName ?? 'flow_cursor_' . bin2hex(random_bytes(8)); $ownTransaction = $this->client->getTransactionNestingLevel() === 0; @@ -77,26 +77,28 @@ public function extract(FlowContext $context): Generator break; } + $rawBatch = []; + foreach ($cursor->iterate() as $row) { - $signal = yield array_to_rows($row, $context->entryFactory(), [], $this->schema); + $rawBatch[] = $row; + } + + $cursor->free(); + + foreach ($context->hydrator()->cast($encoder->decode($rawBatch), $this->schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); $totalFetched++; if ($signal === Signal::STOP) { - $cursor->free(); - return; } if ($this->maximum !== null && $totalFetched >= $this->maximum) { - $cursor->free(); - return; } } - $cursor->free(); - if ($rowCount < $this->fetchSize) { break; } diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlEncoder.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlEncoder.php new file mode 100644 index 0000000000..fa6b5df279 --- /dev/null +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlEncoder.php @@ -0,0 +1,36 @@ +> + */ +final class PostgreSqlEncoder implements Encoder +{ + public function decode(array $batch): array + { + $decoded = []; + + foreach ($batch as $values) { + $decoded[] = new RawRowValues($values); + } + + return $decoded; + } + + public function encode(array $batch): array + { + $encoded = []; + + foreach ($batch as $rowValues) { + $encoded[] = $rowValues->values; + } + + return $encoded; + } +} diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlKeySetExtractor.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlKeySetExtractor.php index fdab16baeb..c7aa8021d8 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlKeySetExtractor.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlKeySetExtractor.php @@ -21,7 +21,6 @@ use function array_merge; use function end; use function explode; -use function Flow\ETL\DSL\array_to_rows; use function Flow\PostgreSql\DSL\sql_to_keyset_query; use function get_debug_type; use function is_bool; @@ -55,6 +54,7 @@ public function extract(FlowContext $context): Generator { $sql = $this->query instanceof Sql ? $this->query->toSql() : $this->query; + $encoder = new PostgreSqlEncoder(); $totalFetched = 0; $cursorValues = null; @@ -65,30 +65,30 @@ public function extract(FlowContext $context): Generator $hasRows = false; $lastRow = null; + $rawBatch = []; foreach ($cursor->iterate() as $row) { $hasRows = true; $lastRow = $row; + $rawBatch[] = $row; + } + + $cursor->free(); - $signal = yield array_to_rows($row, $context->entryFactory(), [], $this->schema); + foreach ($context->hydrator()->cast($encoder->decode($rawBatch), $this->schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); $totalFetched++; if ($signal === Signal::STOP) { - $cursor->free(); - return; } if ($this->maximum !== null && $totalFetched >= $this->maximum) { - $cursor->free(); - return; } } - $cursor->free(); - if (!$hasRows || $lastRow === null) { break; } diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLimitOffsetExtractor.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLimitOffsetExtractor.php index 6ec29341da..2446ab98e1 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLimitOffsetExtractor.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLimitOffsetExtractor.php @@ -15,7 +15,6 @@ use Generator; use function ceil; -use function Flow\ETL\DSL\array_to_rows; use function Flow\PostgreSql\DSL\sql_parse; use function Flow\PostgreSql\DSL\sql_query_order_by; use function Flow\PostgreSql\DSL\sql_to_count_query; @@ -57,6 +56,7 @@ public function extract(FlowContext $context): Generator return; } + $encoder = new PostgreSqlEncoder(); $totalFetched = 0; $pages = (int) ceil($total / $this->pageSize); @@ -67,25 +67,27 @@ public function extract(FlowContext $context): Generator $cursor = $this->client->cursor($paginatedSql, $this->parameters); + $rawBatch = []; + foreach ($cursor->iterate() as $row) { - $signal = yield array_to_rows($row, $context->entryFactory(), [], $this->schema); + $rawBatch[] = $row; + } + + $cursor->free(); + + foreach ($context->hydrator()->cast($encoder->decode($rawBatch), $this->schema) as $hydratedRow) { + $signal = yield new Rows($hydratedRow); $totalFetched++; if ($signal === Signal::STOP) { - $cursor->free(); - return; } if ($this->maximum !== null && $totalFetched >= $this->maximum) { - $cursor->free(); - return; } } - - $cursor->free(); } } diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLoader.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLoader.php index 2d05fb52e8..7cd34ba160 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLoader.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/PostgreSqlLoader.php @@ -29,6 +29,8 @@ final class PostgreSqlLoader implements Loader { private ?DeleteOptions $deleteOptions = null; + private ?PostgreSqlEncoder $encoder = null; + private ?InsertOptions $insertOptions = null; private Operation $operation = Operation::INSERT; @@ -54,9 +56,9 @@ public function load(Rows $rows, FlowContext $context): void try { match ($this->operation) { - Operation::INSERT => $this->insertRows($rows), - Operation::UPDATE => $this->updateRows($rows), - Operation::DELETE => $this->deleteRows($rows), + Operation::INSERT => $this->insertRows($rows, $context), + Operation::UPDATE => $this->updateRows($rows, $context), + Operation::DELETE => $this->deleteRows($rows, $context), }; $context->telemetry()->loadingCompleted($this, [TelemetryAttributes::ATTR_LOADING_ROWS => $rows->count()]); @@ -102,37 +104,51 @@ public function withUpdateOptions(UpdateOptions $options): self return $this; } - private function deleteRows(Rows $rows): void + private function encoder(): PostgreSqlEncoder + { + return $this->encoder ??= new PostgreSqlEncoder(); + } + + private function deleteRows(Rows $rows, FlowContext $context): void { - if ($this->deleteOptions === null) { + $deleteOptions = $this->deleteOptions; + + if ($deleteOptions === null) { throw new RuntimeException('DeleteOptions must be set for DELETE operation'); } $builder = new DeleteQueryBuilder($this->table, $this->typesMap); + $schema = $rows->schema(); - foreach ($rows as $row) { - [$query, $params] = $builder->build($row, $this->deleteOptions); + foreach ($this->encoder()->encode($context->hydrator()->dehydrate($rows)) as $values) { + [$query, $params] = $builder->build($values, $schema, $deleteOptions); $this->client->execute($query, $params); } } - private function insertRows(Rows $rows): void + private function insertRows(Rows $rows, FlowContext $context): void { + $sorted = $rows->sortEntries(); $builder = new InsertQueryBuilder($this->table, $this->typesMap); - [$query, $params] = $builder->build($rows, $this->insertOptions); + $values = $this->encoder()->encode($context->hydrator()->dehydrate($sorted)); + + [$query, $params] = $builder->build($values, $sorted->schema(), $this->insertOptions); $this->client->execute($query, $params); } - private function updateRows(Rows $rows): void + private function updateRows(Rows $rows, FlowContext $context): void { - if ($this->updateOptions === null) { + $updateOptions = $this->updateOptions; + + if ($updateOptions === null) { throw new RuntimeException('UpdateOptions must be set for UPDATE operation'); } $builder = new UpdateQueryBuilder($this->table, $this->typesMap); + $schema = $rows->schema(); - foreach ($rows as $row) { - [$query, $params] = $builder->build($row, $this->updateOptions); + foreach ($this->encoder()->encode($context->hydrator()->dehydrate($rows)) as $values) { + [$query, $params] = $builder->build($values, $schema, $updateOptions); if ($query !== null) { $this->client->execute($query, $params); diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/DeleteQueryBuilder.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/DeleteQueryBuilder.php index 72de601b22..f8ee1a6064 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/DeleteQueryBuilder.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/DeleteQueryBuilder.php @@ -7,11 +7,12 @@ use Flow\ETL\Adapter\PostgreSql\EntryTypesMap; use Flow\ETL\Adapter\PostgreSql\Exception\RuntimeException; use Flow\ETL\Adapter\PostgreSql\LoaderOptions\DeleteOptions; -use Flow\ETL\Row; -use Flow\ETL\Row\Entry; +use Flow\ETL\Schema; use Flow\PostgreSql\Client\TypedValue; use Flow\PostgreSql\QueryBuilder\Sql; +use function array_key_exists; +use function Flow\ETL\DSL\ref; use function Flow\PostgreSql\DSL\and_; use function Flow\PostgreSql\DSL\col; use function Flow\PostgreSql\DSL\delete; @@ -27,9 +28,11 @@ public function __construct( ) {} /** + * @param array $value dehydrated value map for a single row + * * @return array{Sql, list} */ - public function build(Row $row, DeleteOptions $options): array + public function build(array $value, Schema $schema, DeleteOptions $options): array { $primaryKeys = $options->primaryKeys; @@ -42,26 +45,16 @@ public function build(Row $row, DeleteOptions $options): array $conditions = []; foreach ($primaryKeys as $key) { - if (!$row->has($key)) { + if (!array_key_exists($key, $value)) { throw new RuntimeException(sprintf('Primary key "%s" not found in row', $key)); } - $entry = $row->get($key); - $conditions[] = eq(col($key), param($paramIndex++)); - $params[] = $this->mapEntryToParameter($entry); + $params[] = $this->typesMap->map($key, $schema->get(ref($key))->type(), $value[$key]); } $query = delete()->from($this->table)->where(and_(...$conditions)); return [$query, $params]; } - - /** - * @param Entry $entry - */ - private function mapEntryToParameter(Entry $entry): ?TypedValue - { - return $this->typesMap->mapEntry($entry); - } } diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/InsertQueryBuilder.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/InsertQueryBuilder.php index 736fe25b6d..dd28b6c7fd 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/InsertQueryBuilder.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/InsertQueryBuilder.php @@ -6,12 +6,14 @@ use Flow\ETL\Adapter\PostgreSql\EntryTypesMap; use Flow\ETL\Adapter\PostgreSql\LoaderOptions\InsertOptions; -use Flow\ETL\Row\Entry; -use Flow\ETL\Rows; +use Flow\ETL\Schema; use Flow\PostgreSql\Client\TypedValue; use Flow\PostgreSql\QueryBuilder\Insert\BulkInsert; use Flow\PostgreSql\QueryBuilder\Sql; +use function array_keys; +use function count; +use function Flow\ETL\DSL\ref; use function Flow\PostgreSql\DSL\bulk_insert; use function Flow\PostgreSql\DSL\conflict_columns; use function Flow\PostgreSql\DSL\conflict_constraint; @@ -24,27 +26,24 @@ public function __construct( ) {} /** + * @param list> $values pre-sorted dehydrated value maps + * * @return array{Sql, list} */ - public function build(Rows $rows, ?InsertOptions $options = null): array + public function build(array $values, Schema $schema, ?InsertOptions $options = null): array { - $sortedRows = $rows->sortEntries(); - $firstRow = $sortedRows->first(); - $columns = []; - - foreach ($firstRow->entries() as $entry) { - $columns[] = $entry->name(); - } + $columns = $values === [] ? [] : array_keys($values[0]); $params = []; - foreach ($sortedRows as $row) { - foreach ($row->entries() as $entry) { - $params[] = $this->mapEntryToParameter($entry); + foreach ($values as $row) { + /** @var mixed $value */ + foreach ($row as $column => $value) { + $params[] = $this->typesMap->map($column, $schema->get(ref($column))->type(), $value); } } - $query = bulk_insert($this->table, $columns, $sortedRows->count()); + $query = bulk_insert($this->table, $columns, count($values)); if ($options !== null && $options->hasConflictHandling()) { $query = $this->applyConflictHandling($query, $options); @@ -75,12 +74,4 @@ private function applyConflictHandling(BulkInsert $query, InsertOptions $options return $query->onConflictDoUpdate($conflictTarget, $updateColumns); } - - /** - * @param Entry $entry - */ - private function mapEntryToParameter(Entry $entry): ?TypedValue - { - return $this->typesMap->mapEntry($entry); - } } diff --git a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/UpdateQueryBuilder.php b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/UpdateQueryBuilder.php index 6adeacf6ee..93f5c241db 100644 --- a/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/UpdateQueryBuilder.php +++ b/src/adapter/etl-adapter-postgresql/src/Flow/ETL/Adapter/PostgreSql/QueryBuilder/UpdateQueryBuilder.php @@ -7,11 +7,12 @@ use Flow\ETL\Adapter\PostgreSql\EntryTypesMap; use Flow\ETL\Adapter\PostgreSql\Exception\RuntimeException; use Flow\ETL\Adapter\PostgreSql\LoaderOptions\UpdateOptions; -use Flow\ETL\Row; -use Flow\ETL\Row\Entry; +use Flow\ETL\Schema; use Flow\PostgreSql\Client\TypedValue; use Flow\PostgreSql\QueryBuilder\Sql; +use function array_key_exists; +use function Flow\ETL\DSL\ref; use function Flow\PostgreSql\DSL\and_; use function Flow\PostgreSql\DSL\col; use function Flow\PostgreSql\DSL\eq; @@ -28,9 +29,11 @@ public function __construct( ) {} /** + * @param array $value dehydrated value map for a single row + * * @return array{null|Sql, list} */ - public function build(Row $row, UpdateOptions $options): array + public function build(array $value, Schema $schema, UpdateOptions $options): array { $primaryKeys = $options->primaryKeys; @@ -42,13 +45,14 @@ public function build(Row $row, UpdateOptions $options): array $params = []; $assignments = []; - foreach ($row->entries() as $entry) { - if (in_array($entry->name(), $primaryKeys, true)) { + /** @var mixed $columnValue */ + foreach ($value as $column => $columnValue) { + if (in_array($column, $primaryKeys, true)) { continue; } - $assignments[$entry->name()] = param($paramIndex++); - $params[] = $this->mapEntryToParameter($entry); + $assignments[$column] = param($paramIndex++); + $params[] = $this->typesMap->map($column, $schema->get(ref($column))->type(), $columnValue); } if ($assignments === []) { @@ -58,26 +62,16 @@ public function build(Row $row, UpdateOptions $options): array $conditions = []; foreach ($primaryKeys as $key) { - if (!$row->has($key)) { + if (!array_key_exists($key, $value)) { throw new RuntimeException(sprintf('Primary key "%s" not found in row', $key)); } - $entry = $row->get($key); - $conditions[] = eq(col($key), param($paramIndex++)); - $params[] = $this->mapEntryToParameter($entry); + $params[] = $this->typesMap->map($key, $schema->get(ref($key))->type(), $value[$key]); } $query = update()->update($this->table)->setAll($assignments)->where(and_(...$conditions)); return [$query, $params]; } - - /** - * @param Entry $entry - */ - private function mapEntryToParameter(Entry $entry): ?TypedValue - { - return $this->typesMap->mapEntry($entry); - } } diff --git a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/EntryTypesMapTest.php b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/EntryTypesMapTest.php index ee4f5020d3..934fb7915d 100644 --- a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/EntryTypesMapTest.php +++ b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/EntryTypesMapTest.php @@ -7,7 +7,6 @@ use DateTimeImmutable; use Flow\ETL\Adapter\PostgreSql\EntryTypesMap; use Flow\ETL\Adapter\PostgreSql\Exception\TypeMappingException; -use Flow\ETL\Row\Entry\IntegerEntry; use Flow\PostgreSql\Client\TypedValue; use Flow\PostgreSql\Client\Types\ValueType; use Flow\PostgreSql\QueryBuilder\Schema\ColumnType; @@ -16,103 +15,90 @@ use Flow\Types\Type\Native\StringType; use PHPUnit\Framework\TestCase; -use function Flow\ETL\DSL\bool_entry; -use function Flow\ETL\DSL\datetime_entry; -use function Flow\ETL\DSL\float_entry; -use function Flow\ETL\DSL\int_entry; -use function Flow\ETL\DSL\json_entry; -use function Flow\ETL\DSL\list_entry; -use function Flow\ETL\DSL\map_entry; -use function Flow\ETL\DSL\str_entry; -use function Flow\ETL\DSL\structure_entry; -use function Flow\ETL\DSL\uuid_entry; +use function Flow\Types\DSL\type_boolean; +use function Flow\Types\DSL\type_datetime; +use function Flow\Types\DSL\type_float; use function Flow\Types\DSL\type_integer; use function Flow\Types\DSL\type_json; use function Flow\Types\DSL\type_list; use function Flow\Types\DSL\type_map; use function Flow\Types\DSL\type_string; use function Flow\Types\DSL\type_structure; +use function Flow\Types\DSL\type_uuid; use function Flow\Types\DSL\type_xml; final class EntryTypesMapTest extends TestCase { - public function test_allows_override_for_integer_entry_to_int2(): void + public function test_allows_override_for_integer_type_to_int2(): void { $map = new EntryTypesMap([ - IntegerEntry::class => ValueType::INT2, + IntegerType::class => ValueType::INT2, ]); - $result = $map->mapEntry(int_entry('small_count', 42)); + $result = $map->map('small_count', type_integer(), 42); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::INT2, $result->targetType); static::assertSame(42, $result->value); } - public function test_maps_boolean_entry_to_bool_type(): void + public function test_maps_boolean_type_to_bool(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(bool_entry('active', true)); + $result = (new EntryTypesMap())->map('active', type_boolean(), true); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::BOOL, $result->targetType); static::assertTrue($result->value); } - public function test_maps_datetime_entry_to_timestamp_type(): void + public function test_maps_datetime_type_to_timestamp(): void { - $map = new EntryTypesMap(); $date = new DateTimeImmutable('2024-01-15 10:30:00'); - $result = $map->mapEntry(datetime_entry('created_at', $date)); + $result = (new EntryTypesMap())->map('created_at', type_datetime(), $date); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::TIMESTAMP, $result->targetType); static::assertEquals($date, $result->value); } - public function test_maps_float_entry_to_float8_type(): void + public function test_maps_float_type_to_float8(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(float_entry('price', 99.99)); + $result = (new EntryTypesMap())->map('price', type_float(), 99.99); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::FLOAT8, $result->targetType); static::assertSame(99.99, $result->value); } - public function test_maps_integer_entry_to_int8_type(): void + public function test_maps_integer_type_to_int8(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(int_entry('count', 42)); + $result = (new EntryTypesMap())->map('count', type_integer(), 42); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::INT8, $result->targetType); static::assertSame(42, $result->value); } - public function test_maps_json_entry_to_jsonb_type(): void + public function test_maps_json_type_to_jsonb(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(json_entry('data', ['key' => 'value'])); + $result = (new EntryTypesMap())->map('data', type_json(), ['key' => 'value']); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::JSONB, $result->targetType); } - public function test_maps_list_entry_to_jsonb_type(): void + public function test_maps_list_type_to_jsonb(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(list_entry('tags', [1, 2, 3], type_list(type_integer()))); + $result = (new EntryTypesMap())->map('tags', type_list(type_integer()), [1, 2, 3]); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::JSONB, $result->targetType); static::assertSame([1, 2, 3], $result->value); } - public function test_maps_map_entry_to_jsonb_type(): void + public function test_maps_map_type_to_jsonb(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(map_entry('metadata', ['key' => 'value'], type_map(type_string(), type_string()))); + $result = (new EntryTypesMap())->map('metadata', type_map(type_string(), type_string()), ['key' => 'value']); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::JSONB, $result->targetType); @@ -121,38 +107,33 @@ public function test_maps_map_entry_to_jsonb_type(): void public function test_maps_null_value_to_null(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(str_entry('name', null)); - - static::assertNull($result); + static::assertNull((new EntryTypesMap())->map('name', type_string(), null)); } - public function test_maps_string_entry_to_text_type(): void + public function test_maps_string_type_to_text(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(str_entry('name', 'Alice')); + $result = (new EntryTypesMap())->map('name', type_string(), 'Alice'); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::TEXT, $result->targetType); static::assertSame('Alice', $result->value); } - public function test_maps_structure_entry_to_jsonb_type(): void + public function test_maps_structure_type_to_jsonb(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(structure_entry('user', ['name' => 'Alice', 'age' => 30], type_structure([ - 'name' => type_string(), - 'age' => type_integer(), - ]))); + $result = (new EntryTypesMap())->map( + 'user', + type_structure(['name' => type_string(), 'age' => type_integer()]), + ['name' => 'Alice', 'age' => 30], + ); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::JSONB, $result->targetType); } - public function test_maps_uuid_entry_to_uuid_type(): void + public function test_maps_uuid_type_to_uuid(): void { - $map = new EntryTypesMap(); - $result = $map->mapEntry(uuid_entry('id', '550e8400-e29b-41d4-a716-446655440000')); + $result = (new EntryTypesMap())->map('id', type_uuid(), '550e8400-e29b-41d4-a716-446655440000'); static::assertInstanceOf(TypedValue::class, $result); static::assertSame(ValueType::UUID, $result->targetType); diff --git a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/PostgreSqlEncoderTest.php b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/PostgreSqlEncoderTest.php new file mode 100644 index 0000000000..850314c656 --- /dev/null +++ b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/PostgreSqlEncoderTest.php @@ -0,0 +1,63 @@ +decode([ + ['id' => 1, 'name' => 'Norbert'], + ['id' => 2, 'name' => null], + ]); + + static::assertEquals( + [new RawRowValues(['id' => 1, 'name' => 'Norbert']), new RawRowValues(['id' => 2, 'name' => null])], + $decoded, + ); + } + + public function test_encode_unwraps_each_typed_row_values_to_its_value_map(): void + { + $types = ['id' => type_integer(), 'name' => type_string()]; + + $encoded = (new PostgreSqlEncoder())->encode([ + new TypedRowValues(['id' => 1, 'name' => 'Norbert'], $types), + new TypedRowValues(['id' => 2, 'name' => null], $types), + ]); + + static::assertSame([['id' => 1, 'name' => 'Norbert'], ['id' => 2, 'name' => null]], $encoded); + } + + public function test_encode_returns_the_original_value_maps(): void + { + $types = ['id' => type_integer(), 'active' => type_boolean()]; + + static::assertSame( + [['id' => 1, 'active' => true], ['id' => 2, 'active' => false]], + (new PostgreSqlEncoder())->encode([ + new TypedRowValues(['id' => 1, 'active' => true], $types), + new TypedRowValues(['id' => 2, 'active' => false], $types), + ]), + ); + } + + public function test_encode_and_decode_of_an_empty_batch_return_empty(): void + { + $encoder = new PostgreSqlEncoder(); + + static::assertSame([], $encoder->decode([])); + static::assertSame([], $encoder->encode([])); + } +} diff --git a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/DeleteQueryBuilderTest.php b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/DeleteQueryBuilderTest.php index adbb2e31a3..41c257c8de 100644 --- a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/DeleteQueryBuilderTest.php +++ b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/DeleteQueryBuilderTest.php @@ -12,9 +12,9 @@ use Flow\PostgreSql\Client\Types\ValueType; use PHPUnit\Framework\TestCase; -use function Flow\ETL\DSL\int_entry; -use function Flow\ETL\DSL\row; -use function Flow\ETL\DSL\str_entry; +use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\str_schema; final class DeleteQueryBuilderTest extends TestCase { @@ -22,7 +22,7 @@ public function test_build_returns_typed_values(): void { $builder = new DeleteQueryBuilder('users', new EntryTypesMap()); - [$_query, $params] = $builder->build(row(int_entry('id', 1)), new DeleteOptions(['id'])); + [$_query, $params] = $builder->build(['id' => 1], schema(int_schema('id')), new DeleteOptions(['id'])); static::assertCount(1, $params); static::assertInstanceOf(TypedValue::class, $params[0]); @@ -34,7 +34,7 @@ public function test_build_simple_delete(): void { $builder = new DeleteQueryBuilder('users', new EntryTypesMap()); - [$query, $params] = $builder->build(row(int_entry('id', 1)), new DeleteOptions(['id'])); + [$query, $params] = $builder->build(['id' => 1], schema(int_schema('id')), new DeleteOptions(['id'])); $sql = $query->toSql(); static::assertStringContainsString('DELETE FROM users', $sql); @@ -49,7 +49,7 @@ public function test_build_throws_when_no_primary_keys(): void $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Primary keys must be specified for DELETE operation'); - $builder->build(row(int_entry('id', 1)), new DeleteOptions([])); + $builder->build(['id' => 1], schema(int_schema('id')), new DeleteOptions([])); } public function test_build_throws_when_primary_key_not_in_row(): void @@ -59,7 +59,7 @@ public function test_build_throws_when_primary_key_not_in_row(): void $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Primary key "id" not found in row'); - $builder->build(row(str_entry('name', 'Alice')), new DeleteOptions(['id'])); + $builder->build(['name' => 'Alice'], schema(str_schema('name')), new DeleteOptions(['id'])); } public function test_build_with_multiple_primary_keys(): void @@ -67,7 +67,8 @@ public function test_build_with_multiple_primary_keys(): void $builder = new DeleteQueryBuilder('order_items', new EntryTypesMap()); [$query, $params] = $builder->build( - row(int_entry('order_id', 1), int_entry('product_id', 2)), + ['order_id' => 1, 'product_id' => 2], + schema(int_schema('order_id'), int_schema('product_id')), new DeleteOptions(['order_id', 'product_id']), ); diff --git a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/InsertQueryBuilderTest.php b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/InsertQueryBuilderTest.php index 36871e2e5a..ce02e37de3 100644 --- a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/InsertQueryBuilderTest.php +++ b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/InsertQueryBuilderTest.php @@ -11,10 +11,9 @@ use Flow\PostgreSql\Client\Types\ValueType; use PHPUnit\Framework\TestCase; -use function Flow\ETL\DSL\int_entry; -use function Flow\ETL\DSL\row; -use function Flow\ETL\DSL\rows; -use function Flow\ETL\DSL\str_entry; +use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\str_schema; final class InsertQueryBuilderTest extends TestCase { @@ -22,7 +21,10 @@ public function test_build_returns_typed_values(): void { $builder = new InsertQueryBuilder('users', new EntryTypesMap()); - [$_query, $params] = $builder->build(rows(row(int_entry('id', 1), str_entry('name', 'Alice')))); + [$_query, $params] = $builder->build( + [['id' => 1, 'name' => 'Alice']], + schema(int_schema('id'), str_schema('name')), + ); static::assertCount(2, $params); @@ -40,10 +42,10 @@ public function test_build_simple_insert(): void { $builder = new InsertQueryBuilder('users', new EntryTypesMap()); - [$query, $params] = $builder->build(rows( - row(int_entry('id', 1), str_entry('name', 'Alice')), - row(int_entry('id', 2), str_entry('name', 'Bob')), - )); + [$query, $params] = $builder->build( + [['id' => 1, 'name' => 'Alice'], ['id' => 2, 'name' => 'Bob']], + schema(int_schema('id'), str_schema('name')), + ); static::assertStringContainsString('INSERT INTO "users"', $query->toSql()); static::assertStringContainsString('("id", "name")', $query->toSql()); @@ -55,7 +57,10 @@ public function test_build_with_null_values(): void { $builder = new InsertQueryBuilder('users', new EntryTypesMap()); - [$_query, $params] = $builder->build(rows(row(int_entry('id', 1), str_entry('name', null)))); + [$_query, $params] = $builder->build( + [['id' => 1, 'name' => null]], + schema(int_schema('id'), str_schema('name', nullable: true)), + ); static::assertCount(2, $params); static::assertNull($params[1]); @@ -66,7 +71,8 @@ public function test_build_with_skip_conflicts(): void $builder = new InsertQueryBuilder('users', new EntryTypesMap()); [$query, $_params] = $builder->build( - rows(row(int_entry('id', 1), str_entry('name', 'Alice'))), + [['id' => 1, 'name' => 'Alice']], + schema(int_schema('id'), str_schema('name')), InsertOptions::skipConflicts(), ); @@ -78,7 +84,8 @@ public function test_build_with_upsert_on_columns(): void $builder = new InsertQueryBuilder('users', new EntryTypesMap()); [$query, $_params] = $builder->build( - rows(row(int_entry('id', 1), str_entry('name', 'Alice'))), + [['id' => 1, 'name' => 'Alice']], + schema(int_schema('id'), str_schema('name')), InsertOptions::upsertOnColumns(['id']), ); @@ -92,7 +99,8 @@ public function test_build_with_upsert_on_constraint(): void $builder = new InsertQueryBuilder('users', new EntryTypesMap()); [$query, $_params] = $builder->build( - rows(row(int_entry('id', 1), str_entry('name', 'Alice'))), + [['id' => 1, 'name' => 'Alice']], + schema(int_schema('id'), str_schema('name')), InsertOptions::upsertOnConstraint('users_pkey'), ); diff --git a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/UpdateQueryBuilderTest.php b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/UpdateQueryBuilderTest.php index ae77173936..fa01badd37 100644 --- a/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/UpdateQueryBuilderTest.php +++ b/src/adapter/etl-adapter-postgresql/tests/Flow/ETL/Adapter/PostgreSql/Tests/Unit/QueryBuilder/UpdateQueryBuilderTest.php @@ -12,9 +12,9 @@ use Flow\PostgreSql\Client\Types\ValueType; use PHPUnit\Framework\TestCase; -use function Flow\ETL\DSL\int_entry; -use function Flow\ETL\DSL\row; -use function Flow\ETL\DSL\str_entry; +use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\str_schema; final class UpdateQueryBuilderTest extends TestCase { @@ -22,7 +22,7 @@ public function test_build_returns_null_when_no_columns_to_update(): void { $builder = new UpdateQueryBuilder('users', new EntryTypesMap()); - [$query, $params] = $builder->build(row(int_entry('id', 1)), new UpdateOptions(['id'])); + [$query, $params] = $builder->build(['id' => 1], schema(int_schema('id')), new UpdateOptions(['id'])); static::assertNull($query); static::assertEmpty($params); @@ -33,7 +33,8 @@ public function test_build_returns_typed_values(): void $builder = new UpdateQueryBuilder('users', new EntryTypesMap()); [$_query, $params] = $builder->build( - row(int_entry('id', 1), str_entry('name', 'Alice')), + ['id' => 1, 'name' => 'Alice'], + schema(int_schema('id'), str_schema('name')), new UpdateOptions(['id']), ); @@ -51,7 +52,8 @@ public function test_build_simple_update(): void $builder = new UpdateQueryBuilder('users', new EntryTypesMap()); [$query, $params] = $builder->build( - row(int_entry('id', 1), str_entry('name', 'Alice')), + ['id' => 1, 'name' => 'Alice'], + schema(int_schema('id'), str_schema('name')), new UpdateOptions(['id']), ); @@ -70,7 +72,11 @@ public function test_build_throws_when_no_primary_keys(): void $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Primary keys must be specified for UPDATE operation'); - $builder->build(row(int_entry('id', 1), str_entry('name', 'Alice')), new UpdateOptions([])); + $builder->build( + ['id' => 1, 'name' => 'Alice'], + schema(int_schema('id'), str_schema('name')), + new UpdateOptions([]), + ); } public function test_build_throws_when_primary_key_not_in_row(): void @@ -80,7 +86,7 @@ public function test_build_throws_when_primary_key_not_in_row(): void $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Primary key "id" not found in row'); - $builder->build(row(str_entry('name', 'Alice')), new UpdateOptions(['id'])); + $builder->build(['name' => 'Alice'], schema(str_schema('name')), new UpdateOptions(['id'])); } public function test_build_with_multiple_primary_keys(): void @@ -88,7 +94,8 @@ public function test_build_with_multiple_primary_keys(): void $builder = new UpdateQueryBuilder('order_items', new EntryTypesMap()); [$query, $params] = $builder->build( - row(int_entry('order_id', 1), int_entry('product_id', 2), int_entry('quantity', 5)), + ['order_id' => 1, 'product_id' => 2, 'quantity' => 5], + schema(int_schema('order_id'), int_schema('product_id'), int_schema('quantity')), new UpdateOptions(['order_id', 'product_id']), ); diff --git a/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/RowsNormalizer.php b/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/RowsNormalizer.php deleted file mode 100644 index 385b39d213..0000000000 --- a/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/RowsNormalizer.php +++ /dev/null @@ -1,32 +0,0 @@ -> - */ - public function normalize(Rows $rows): Generator - { - foreach ($rows as $row) { - $document = []; - - foreach ($row->entries() as $entry) { - $document[$entry->name()] = $this->normalizer->normalize($entry); - } - - yield $document; - } - } -} diff --git a/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/RowsNormalizer/EntryNormalizer.php b/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/RowsNormalizer/EntryNormalizer.php deleted file mode 100644 index 0a7e538acc..0000000000 --- a/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/RowsNormalizer/EntryNormalizer.php +++ /dev/null @@ -1,90 +0,0 @@ - $entry - * - * @return null|array|bool|float|int|string - */ - public function normalize(Entry $entry): string|float|int|bool|array|null - { - return match ($entry::class) { - UuidEntry::class => $entry->toString(), - DateTimeEntry::class => $entry->value()?->format($this->dateTimeFormat), - DateEntry::class => $entry->value()?->format($this->dateFormat), - EnumEntry::class => $entry->value()?->name, - XMLElementEntry::class, XMLEntry::class => $entry->toString(), - JsonEntry::class => $this->normalizeArray($entry->value()?->toArray()), - ListEntry::class, MapEntry::class, StructureEntry::class => $this->normalizeArray($entry->value()), - default => $this->normalizeValue($entry->value()), - }; - } - - /** - * @return null|array - */ - private function normalizeArray(mixed $value): ?array - { - if (!is_array($value)) { - return null; - } - - $normalized = []; - - foreach (array_keys($value) as $key) { - $normalized[$key] = $this->normalizeValue($value[$key]); - } - - return $normalized; - } - - /** - * @return null|array|bool|float|int|string - */ - private function normalizeValue(mixed $value): string|float|int|bool|array|null - { - if ($value instanceof DateTimeInterface) { - return $value->format($this->dateTimeFormat); - } - - if (is_array($value)) { - return $this->normalizeArray($value); - } - - if (is_string($value) || is_int($value) || is_float($value) || is_bool($value)) { - return $value; - } - - return null; - } -} diff --git a/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/SealEncoder.php b/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/SealEncoder.php new file mode 100644 index 0000000000..f071810eb0 --- /dev/null +++ b/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/SealEncoder.php @@ -0,0 +1,179 @@ +> + */ +final class SealEncoder implements Encoder +{ + public function __construct( + private readonly string $dateTimeFormat = DateTimeInterface::ATOM, + private readonly string $dateFormat = 'Y-m-d', + ) {} + + public function decode(array $batch): array + { + $decoded = []; + + foreach ($batch as $values) { + $decoded[] = new RawRowValues($values); + } + + return $decoded; + } + + public function encode(array $batch): array + { + $documents = []; + + foreach ($batch as $rowValues) { + $document = []; + + /** @var mixed $value */ + foreach ($rowValues->values as $name => $value) { + $document[$name] = $this->renderValue($rowValues->types[$name], $value); + } + + $documents[] = $document; + } + + return $documents; + } + + private function renderValue(Type $type, mixed $value): string|float|int|bool|array|null + { + if ($value === null) { + return null; + } + + return match ($type::class) { + DateType::class => $value instanceof DateTimeInterface ? $value->format($this->dateFormat) : null, + DateTimeType::class => $value instanceof DateTimeInterface ? $value->format($this->dateTimeFormat) : null, + TimeType::class => $value instanceof DateInterval ? date_interval_to_microseconds($value) : null, + UuidType::class => $value instanceof Uuid ? $value->toString() : null, + EnumType::class => $value instanceof UnitEnum ? $value->name : null, + XMLType::class, XMLElementType::class => $this->xmlToString($value), + JsonType::class => $value instanceof Json ? $this->normalizeArray($value->toArray()) : null, + ListType::class, MapType::class, StructureType::class, ArrayType::class => $this->normalizeArray($value), + default => $this->normalizeValue($value), + }; + } + + /** + * @return null|array + */ + private function normalizeArray(mixed $value): ?array + { + if (!is_array($value)) { + return null; + } + + $normalized = []; + + foreach (array_keys($value) as $key) { + $normalized[$key] = $this->normalizeValue($value[$key]); + } + + return $normalized; + } + + private function normalizeValue(mixed $value): string|float|int|bool|array|null + { + if ($value instanceof DateTimeInterface) { + return $value->format($this->dateTimeFormat); + } + + if (is_array($value)) { + return $this->normalizeArray($value); + } + + if (is_string($value) || is_int($value) || is_float($value) || is_bool($value)) { + return $value; + } + + return null; + } + + private function xmlToString(mixed $value): ?string + { + if ($value instanceof XMLDocument) { + return $this->domString($value->saveXml($value->documentElement)); + } + + if ($value instanceof DOMDocument) { + return $this->domString($value->saveXML($value->documentElement)); + } + + if ($value instanceof Element || $value instanceof DOMElement) { + return $this->elementToString($value); + } + + return null; + } + + private function elementToString(Element|DOMElement $value): string + { + $ownerDocument = $value->ownerDocument; + + if ($ownerDocument === null) { + return ''; + } + + if ($ownerDocument instanceof XMLDocument) { + // @mago-ignore analysis:possibly-invalid-argument + return $this->domString($ownerDocument->saveXml($value)); + } + + /** @var false|string $serialized */ + // @mago-ignore analysis:possibly-invalid-argument,non-existent-method + $serialized = $ownerDocument->saveXML($value); + + return $this->domString($serialized); + } + + private function domString(string|false $serialized): string + { + if ($serialized === false) { + throw new RuntimeException('Failed to serialize XML document.'); + } + + return $serialized; + } +} diff --git a/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/SealLoader.php b/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/SealLoader.php index 7fd1cf75cf..6498324d39 100644 --- a/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/SealLoader.php +++ b/src/adapter/etl-adapter-seal/src/Flow/ETL/Adapter/Seal/SealLoader.php @@ -5,7 +5,7 @@ namespace Flow\ETL\Adapter\Seal; use CmsIg\Seal\EngineInterface; -use Flow\ETL\Adapter\Seal\RowsNormalizer\EntryNormalizer; +use DateTimeInterface; use Flow\ETL\Config\Telemetry\TelemetryAttributes; use Flow\ETL\Exception\RuntimeException; use Flow\ETL\FlowContext; @@ -14,6 +14,7 @@ use Generator; use Throwable; +use function array_key_exists; use function is_int; use function is_string; @@ -21,6 +22,12 @@ final class SealLoader implements Loader { private int $bulkSize = 100; + private string $dateFormat = 'Y-m-d'; + + private string $dateTimeFormat = DateTimeInterface::ATOM; + + private ?SealEncoder $encoder = null; + private string $identifierEntry = 'id'; public function __construct( @@ -41,9 +48,9 @@ public function load(Rows $rows, FlowContext $context): void $this->engine->bulk( $this->index, $this->operation === Operation::UPSERT - ? (new RowsNormalizer(new EntryNormalizer()))->normalize($rows) + ? $this->encoder()->encode($context->hydrator()->dehydrate($rows)) : [], - $this->operation === Operation::DELETE ? $this->deleteIdentifiers($rows) : [], + $this->operation === Operation::DELETE ? $this->deleteIdentifiers($rows, $context) : [], $this->bulkSize, ); @@ -62,6 +69,20 @@ public function withBulkSize(int $bulkSize): self return $this; } + public function withDateFormat(string $dateFormat): self + { + $this->dateFormat = $dateFormat; + + return $this; + } + + public function withDateTimeFormat(string $dateTimeFormat): self + { + $this->dateTimeFormat = $dateTimeFormat; + + return $this; + } + public function withIdentifierEntry(string $entry): self { $this->identifierEntry = $entry; @@ -69,15 +90,21 @@ public function withIdentifierEntry(string $entry): self return $this; } + private function encoder(): SealEncoder + { + return $this->encoder ??= new SealEncoder($this->dateTimeFormat, $this->dateFormat); + } + /** * @return Generator */ - private function deleteIdentifiers(Rows $rows): Generator + private function deleteIdentifiers(Rows $rows, FlowContext $context): Generator { - $normalizer = new EntryNormalizer(); - - foreach ($rows as $row) { - $identifier = $normalizer->normalize($row->get($this->identifierEntry)); + foreach ($this->encoder()->encode($context->hydrator()->dehydrate($rows)) as $document) { + // @mago-ignore analysis:mixed-assignment + $identifier = array_key_exists($this->identifierEntry, $document) + ? $document[$this->identifierEntry] + : null; if (!is_string($identifier) && !is_int($identifier)) { throw new RuntimeException( diff --git a/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php b/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php deleted file mode 100644 index 242bf5dd6f..0000000000 --- a/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php +++ /dev/null @@ -1,122 +0,0 @@ - [str_entry('string', 'value'), 'value']; - yield 'string_nullable' => [str_entry('string', null), null]; - yield 'int' => [int_entry('integer', 1), 1]; - yield 'int_nullable' => [int_entry('integer', null), null]; - yield 'float' => [float_entry('float', 1.1), 1.1]; - yield 'float_nullable' => [float_entry('float', null), null]; - yield 'bool' => [bool_entry('bool', true), true]; - yield 'bool_nullable' => [bool_entry('bool', null), null]; - yield 'uuid' => [ - uuid_entry('uuid', 'f47ac10b-58cc-4372-a567-0e02b2c3d479'), - 'f47ac10b-58cc-4372-a567-0e02b2c3d479', - ]; - yield 'datetime' => [ - datetime_entry('datetime', new DateTimeImmutable('2023-10-01 12:02:01')), - '2023-10-01T12:02:01+00:00', - ]; - yield 'datetime_nullable' => [datetime_entry('datetime', null), null]; - yield 'date' => [date_entry('date', new DateTimeImmutable('2023-10-01 12:02:01')), '2023-10-01']; - yield 'date_nullable' => [date_entry('date', null), null]; - yield 'enum' => [enum_entry('enum', BackedStringEnum::one), 'one']; - yield 'enum_nullable' => [enum_entry('enum', null), null]; - yield 'xml' => [xml_entry('xml', '1'), '1']; - yield 'json' => [json_entry('json', ['a' => 1, 'b' => 'two']), ['a' => 1, 'b' => 'two']]; - yield 'json_nullable' => [json_entry('json', null), null]; - yield 'list' => [list_entry('list', ['a', 'b'], type_list(type_string())), ['a', 'b']]; - yield 'list_nullable' => [list_entry('list', null, type_list(type_string())), null]; - yield 'list_of_datetimes' => [ - list_entry('list', [new DateTimeImmutable('2023-10-01 12:02:01')], type_list(type_datetime())), - ['2023-10-01T12:02:01+00:00'], - ]; - yield 'map' => [ - map_entry('map', ['a' => 1, 'b' => 2], type_map(type_string(), type_integer())), - ['a' => 1, 'b' => 2], - ]; - yield 'structure' => [ - struct_entry('structure', ['name' => 'John', 'age' => 30], type_structure([ - 'name' => type_string(), - 'age' => type_integer(), - ])), - ['name' => 'John', 'age' => 30], - ]; - yield 'structure_with_nested_datetime' => [ - struct_entry( - 'structure', - ['name' => 'John', 'created_at' => new DateTimeImmutable('2023-10-01 12:02:01')], - type_structure(['name' => type_string(), 'created_at' => type_datetime()]), - ), - ['name' => 'John', 'created_at' => '2023-10-01T12:02:01+00:00'], - ]; - yield 'structure_nullable' => [ - struct_entry('structure', null, type_structure(['name' => type_string()])), - null, - ]; - } - - /** - * @param Entry $entry - */ - #[DataProvider('entries_provider')] - public function test_normalizing_entries(Entry $entry, mixed $expected): void - { - static::assertSame($expected, (new EntryNormalizer())->normalize($entry)); - } - - public function test_normalizing_a_date_with_a_custom_format(): void - { - $normalizer = new EntryNormalizer(dateFormat: 'd/m/Y'); - - static::assertSame( - '01/10/2023', - $normalizer->normalize(date_entry('date', new DateTimeImmutable('2023-10-01'))), - ); - } - - public function test_normalizing_a_datetime_with_a_custom_format(): void - { - $normalizer = new EntryNormalizer(dateTimeFormat: 'Y-m-d H:i:s'); - - static::assertSame( - '2023-10-01 12:02:01', - $normalizer->normalize(datetime_entry('datetime', new DateTimeImmutable('2023-10-01 12:02:01'))), - ); - } -} diff --git a/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/RowsNormalizerTest.php b/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/RowsNormalizerTest.php deleted file mode 100644 index d1fde59d69..0000000000 --- a/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/RowsNormalizerTest.php +++ /dev/null @@ -1,42 +0,0 @@ -normalize(rows()))); - } - - public function test_normalizing_rows_into_documents_keyed_by_entry_names(): void - { - $normalizer = new RowsNormalizer(new EntryNormalizer()); - - static::assertSame( - [ - ['id' => '1', 'age' => 30, 'active' => true], - ['id' => '2', 'age' => 25, 'active' => false], - ], - iterator_to_array($normalizer->normalize(rows( - row(string_entry('id', '1'), integer_entry('age', 30), bool_entry('active', true)), - row(string_entry('id', '2'), integer_entry('age', 25), bool_entry('active', false)), - ))), - ); - } -} diff --git a/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/SealEncoderTest.php b/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/SealEncoderTest.php new file mode 100644 index 0000000000..71e3b29cc6 --- /dev/null +++ b/src/adapter/etl-adapter-seal/tests/Flow/ETL/Adapter/Seal/Tests/Unit/SealEncoderTest.php @@ -0,0 +1,119 @@ + ['value', 'value', type_string()]; + yield 'string_nullable' => [null, null, type_string()]; + yield 'int' => [1, 1, type_integer()]; + yield 'float' => [1.1, 1.1, type_float()]; + yield 'bool' => [true, true, type_boolean()]; + yield 'uuid' => [ + new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'), + 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + type_uuid(), + ]; + yield 'datetime' => [ + new DateTimeImmutable('2023-10-01 12:02:01'), + '2023-10-01T12:02:01+00:00', + type_datetime(), + ]; + yield 'time' => [new DateInterval('PT1H'), 3600000000, type_time()]; + yield 'enum' => [BackedStringEnum::one, 'one', type_enum(BackedStringEnum::class)]; + yield 'json' => [new Json('{"a":1,"b":"two"}'), ['a' => 1, 'b' => 'two'], type_json()]; + yield 'list' => [['a', 'b'], ['a', 'b'], type_list(type_string())]; + yield 'list_of_datetimes' => [ + [new DateTimeImmutable('2023-10-01 12:02:01')], + ['2023-10-01T12:02:01+00:00'], + type_list(type_datetime()), + ]; + yield 'map' => [['a' => 1, 'b' => 2], ['a' => 1, 'b' => 2], type_map(type_string(), type_integer())]; + yield 'structure' => [ + ['name' => 'John', 'age' => 30], + ['name' => 'John', 'age' => 30], + type_structure(['name' => type_string(), 'age' => type_integer()]), + ]; + yield 'structure_with_nested_datetime' => [ + ['name' => 'John', 'created_at' => new DateTimeImmutable('2023-10-01 12:02:01')], + ['name' => 'John', 'created_at' => '2023-10-01T12:02:01+00:00'], + type_structure(['name' => type_string(), 'created_at' => type_datetime()]), + ]; + } + + /** + * @param Type $type + */ + #[DataProvider('values_provider')] + public function test_encodes_values_into_documents(mixed $value, mixed $expected, Type $type): void + { + static::assertSame( + $expected, + (new SealEncoder())->encode([new TypedRowValues(['field' => $value], ['field' => $type])])[0]['field'], + ); + } + + public function test_encodes_xml_document_to_string(): void + { + $doc = new DOMDocument(); + $doc->loadXML('1'); + + static::assertSame( + '1', + (new SealEncoder())->encode([new TypedRowValues(['xml' => $doc], ['xml' => type_xml()])])[0]['xml'], + ); + } + + public function test_renders_date_with_the_date_format(): void + { + static::assertSame( + '2023-10-01', + (new SealEncoder())->encode([ + new TypedRowValues(['date' => new DateTimeImmutable('2023-10-01 00:00:00')], ['date' => type_date()]), + ])[0]['date'], + ); + } + + public function test_produces_documents_keyed_by_column_name(): void + { + static::assertSame( + [['id' => 1, 'name' => 'Alice'], ['id' => 2, 'name' => 'Bob']], + (new SealEncoder())->encode([ + new TypedRowValues(['id' => 1, 'name' => 'Alice'], ['id' => type_integer(), 'name' => type_string()]), + new TypedRowValues(['id' => 2, 'name' => 'Bob'], ['id' => type_integer(), 'name' => type_string()]), + ]), + ); + } +} diff --git a/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextEncoder.php b/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextEncoder.php new file mode 100644 index 0000000000..a5ab22f982 --- /dev/null +++ b/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextEncoder.php @@ -0,0 +1,74 @@ + + */ +final class TextEncoder implements Encoder +{ + public function __construct( + private readonly string $newLineSeparator = PHP_EOL, + ) {} + + public function decode(array $batch): array + { + $maps = []; + + foreach ($batch as $line) { + $maps[] = new RawRowValues(['text' => rtrim($line)]); + } + + return $maps; + } + + public function encode(array $batch): array + { + $lines = []; + + foreach ($batch as $rowValues) { + $values = $rowValues->values; + + if (count($values) > 1) { + throw new RuntimeException(sprintf( + 'Text data loader supports only a single entry rows, and you have %d rows.', + count($values), + )); + } + + /** @var mixed $value */ + $value = array_values($values)[0] ?? null; + + $lines[] = $this->renderValue($value) . $this->newLineSeparator; + } + + return $lines; + } + + private function renderValue(mixed $value): string + { + return match (true) { + $value === null => '', + is_bool($value) => $value ? 'true' : 'false', + is_scalar($value), $value instanceof Stringable => (string) $value, + default => throw new RuntimeException( + 'Text data loader supports only scalar values, got ' . get_debug_type($value), + ), + }; + } +} diff --git a/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextExtractor.php b/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextExtractor.php index 88aa2822be..2f0b6685ec 100644 --- a/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextExtractor.php +++ b/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextExtractor.php @@ -11,12 +11,15 @@ use Flow\ETL\Extractor\PathFiltering; use Flow\ETL\Extractor\Signal; use Flow\ETL\FlowContext; +use Flow\ETL\Row\RawRowValues; use Flow\ETL\Rows; +use Flow\ETL\Schema; use Flow\Filesystem\Path; use Generator; -use function Flow\ETL\DSL\array_to_rows; -use function rtrim; +use function count; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\str_schema; final class TextExtractor implements Extractor, FileExtractor, LimitableExtractor { @@ -35,19 +38,80 @@ public function __construct( public function extract(FlowContext $context): Generator { $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); + $encoder = new TextEncoder(); + + $baseSchema = $this->schema($shouldPutInputIntoRows); foreach ($context->streams()->list($this->path, $this->filter()) as $stream) { - $uri = $stream->path()->uri(); + $streamUri = $shouldPutInputIntoRows ? $stream->path()->uri() : null; $partitions = $stream->path()->partitions(); - foreach ($stream->readLines() as $rowData) { - if ($shouldPutInputIntoRows) { - $row = [['text' => rtrim($rowData), '_input_file_uri' => $uri]]; - } else { - $row = [['text' => rtrim($rowData)]]; + $schema = $baseSchema; + + foreach ($partitions as $partition) { + if ($schema->findDefinition($partition->name) === null) { + $schema = $schema->add(str_schema($partition->name)); + } + } + + $rawLines = []; + + foreach ($stream->readLines() as $line) { + $rawLines[] = $line; + + if (count($rawLines) >= $batchSize) { + $batch = []; + + foreach ($encoder->decode($rawLines) as $rowValues) { + $row = $rowValues->values; + + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($row); + } + + $rawLines = []; + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + + return; + } + } + } + } + + $batch = []; + + foreach ($encoder->decode($rawLines) as $rowValues) { + $row = $rowValues->values; + + if ($streamUri !== null) { + $row['_input_file_uri'] = $streamUri; } - $signal = yield array_to_rows($row, $context->entryFactory(), $partitions); + foreach ($partitions as $partition) { + $row[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($row); + } + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); $this->incrementReturnedRows(); @@ -66,4 +130,13 @@ public function source(): Path { return $this->path; } + + private function schema(bool $shouldPutInputIntoRows): Schema + { + if ($shouldPutInputIntoRows) { + return schema(str_schema('text'), str_schema('_input_file_uri')); + } + + return schema(str_schema('text')); + } } diff --git a/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextLoader.php b/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextLoader.php index a3f7cf4913..027bfc6acf 100644 --- a/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextLoader.php +++ b/src/adapter/etl-adapter-text/src/Flow/ETL/Adapter/Text/TextLoader.php @@ -5,7 +5,6 @@ namespace Flow\ETL\Adapter\Text; use Flow\ETL\Config\Telemetry\TelemetryAttributes; -use Flow\ETL\Exception\RuntimeException; use Flow\ETL\FlowContext; use Flow\ETL\Loader; use Flow\ETL\Loader\Closure; @@ -16,10 +15,12 @@ use Flow\Filesystem\Path\Option\ContentType; use Throwable; -use function sprintf; +use function implode; final class TextLoader implements Closure, FileLoader, Loader { + private ?TextEncoder $encoder = null; + private string $newLineSeparator = PHP_EOL; private readonly Path $path; @@ -50,34 +51,12 @@ public function load(Rows $rows, FlowContext $context): void ]); try { + $lines = implode('', $this->encoder()->encode($context->hydrator()->dehydrate($rows))); + if ($rows->partitions()->count()) { - foreach ($rows as $row) { - if ($row->entries()->count() > 1) { - throw new RuntimeException(sprintf( - 'Text data loader supports only a single entry rows, and you have %d rows.', - $row->entries()->count(), - )); - } - - $context - ->streams() - ->writeTo($this->path, $rows->partitions()->toArray()) - ->append($row->entries()->all()[0]->toString() . $this->newLineSeparator); - } + $context->streams()->writeTo($this->path, $rows->partitions()->toArray())->append($lines); } else { - foreach ($rows as $row) { - if ($row->entries()->count() > 1) { - throw new RuntimeException(sprintf( - 'Text data loader supports only a single entry rows, and you have %d rows.', - $row->entries()->count(), - )); - } - - $context - ->streams() - ->writeTo($this->path) - ->append($row->entries()->all()[0]->toString() . $this->newLineSeparator); - } + $context->streams()->writeTo($this->path)->append($lines); } $context->telemetry()->loadingCompleted($this, [TelemetryAttributes::ATTR_LOADING_ROWS => $rows->count()]); @@ -94,4 +73,9 @@ public function withNewLineSeparator(string $newLineSeparator): self return $this; } + + private function encoder(): TextEncoder + { + return $this->encoder ??= new TextEncoder($this->newLineSeparator); + } } diff --git a/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Fixtures/parity_lines.txt b/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Fixtures/parity_lines.txt new file mode 100644 index 0000000000..85c30401ce --- /dev/null +++ b/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Fixtures/parity_lines.txt @@ -0,0 +1,3 @@ +alpha +beta +gamma diff --git a/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Integration/TextHydratorParityTest.php b/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Integration/TextHydratorParityTest.php new file mode 100644 index 0000000000..198c93bc3e --- /dev/null +++ b/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Integration/TextHydratorParityTest.php @@ -0,0 +1,72 @@ +extract(flow_context(Config::builder()->build())) as $rows) { + foreach ($rows as $row) { + static::assertInstanceOf(StringEntry::class, $row->get('text')); + $actual[] = $row->toArray(); + } + } + + static::assertSame([['text' => 'alpha'], ['text' => 'beta'], ['text' => 'gamma']], $actual); + } + + public function test_appends_input_file_uri_when_put_input_into_rows_is_enabled(): void + { + $extractor = from_text($path = path_real(__DIR__ . '/../Fixtures/parity_lines.txt')); + + $actual = []; + + foreach ($extractor->extract(flow_context(Config::builder()->putInputIntoRows()->build())) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + static::assertSame( + [ + ['text' => 'alpha', '_input_file_uri' => $path->uri()], + ['text' => 'beta', '_input_file_uri' => $path->uri()], + ['text' => 'gamma', '_input_file_uri' => $path->uri()], + ], + $actual, + ); + } + + public function test_honours_a_hydrator_configured_on_the_context(): void + { + $extractor = from_text(path_real(__DIR__ . '/../Fixtures/parity_lines.txt')); + + $actual = []; + + foreach ($extractor->extract( + flow_context(Config::builder()->hydrator(new AdaptiveRowHydrator())->build()), + ) as $rows) { + foreach ($rows as $row) { + $actual[] = $row->toArray(); + } + } + + static::assertSame([['text' => 'alpha'], ['text' => 'beta'], ['text' => 'gamma']], $actual); + } +} diff --git a/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Unit/TextEncoderTest.php b/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Unit/TextEncoderTest.php new file mode 100644 index 0000000000..d68cae6cf5 --- /dev/null +++ b/src/adapter/etl-adapter-text/tests/Flow/ETL/Adapter/Text/Tests/Unit/TextEncoderTest.php @@ -0,0 +1,58 @@ + 'first'], ['text' => 'second']], + array_map( + static fn(RawRowValues $rowValues): array => $rowValues->values, + (new TextEncoder())->decode(["first\n", "second\r\n"]), + ), + ); + } + + public function test_encode_appends_the_new_line_separator_to_the_single_value(): void + { + static::assertSame( + ["first\n", "second\n"], + (new TextEncoder("\n"))->encode([ + new TypedRowValues(['text' => 'first'], ['text' => type_string()]), + new TypedRowValues(['text' => 'second'], ['text' => type_string()]), + ]), + ); + } + + public function test_encode_renders_null_as_an_empty_line(): void + { + static::assertSame( + ["\n"], + (new TextEncoder("\n"))->encode([new TypedRowValues(['text' => null], ['text' => type_string()])]), + ); + } + + public function test_encode_throws_when_a_row_has_more_than_one_column(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Text data loader supports only a single entry rows, and you have 2 rows.'); + + (new TextEncoder())->encode([ + new TypedRowValues(['a' => 1, 'b' => 2], ['a' => type_integer(), 'b' => type_integer()]), + ]); + } +} diff --git a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/Loader/XMLLoader.php b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/Loader/XMLLoader.php index 74d441432b..f0d546001f 100644 --- a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/Loader/XMLLoader.php +++ b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/Loader/XMLLoader.php @@ -4,9 +4,7 @@ namespace Flow\ETL\Adapter\XML\Loader; -use Flow\ETL\Adapter\XML\RowsNormalizer; -use Flow\ETL\Adapter\XML\RowsNormalizer\EntryNormalizer; -use Flow\ETL\Adapter\XML\RowsNormalizer\EntryNormalizer\PHPValueNormalizer; +use Flow\ETL\Adapter\XML\XMLEncoder; use Flow\ETL\Adapter\XML\XMLWriter; use Flow\ETL\Config\Telemetry\TelemetryAttributes; use Flow\ETL\FlowContext; @@ -28,8 +26,12 @@ final class XMLLoader implements Closure, FileLoader, Loader { private string $attributePrefix = '_'; + private string $dateFormat = 'Y-m-d'; + private string $dateTimeFormat = 'Y-m-d\TH:i:s.uP'; + private ?XMLEncoder $encoder = null; + private string $listElementName = 'element'; private string $mapElementKeyName = 'key'; @@ -86,21 +88,7 @@ public function load(Rows $rows, FlowContext $context): void ]); try { - $normalizer = new RowsNormalizer( - new EntryNormalizer( - new PHPValueNormalizer( - $this->attributePrefix, - $this->dateTimeFormat, - $this->listElementName, - $this->mapElementName, - $this->mapElementKeyName, - $this->mapElementValueName, - ), - ), - $this->rowElementName, - ); - - $this->write($rows, $rows->partitions()->toArray(), $context, $normalizer); + $this->write($rows, $rows->partitions()->toArray(), $context); $context->telemetry()->loadingCompleted($this, [TelemetryAttributes::ATTR_LOADING_ROWS => $rows->count()]); } catch (Throwable $e) { @@ -117,6 +105,13 @@ public function withAttributePrefix(string $attributePrefix): self return $this; } + public function withDateFormat(string $dateFormat): self + { + $this->dateFormat = $dateFormat; + + return $this; + } + public function withDateTimeFormat(string $dateTimeFormat): self { $this->dateTimeFormat = $dateTimeFormat; @@ -179,7 +174,7 @@ public function withXMLAttributes(array $xmlAttributes): self /** * @param array $partitions */ - public function write(Rows $nextRows, array $partitions, FlowContext $context, RowsNormalizer $normalizer): void + public function write(Rows $nextRows, array $partitions, FlowContext $context): void { $streams = $context->streams(); @@ -200,23 +195,34 @@ public function write(Rows $nextRows, array $partitions, FlowContext $context, R $stream = $streams->writeTo($this->path, $partitions); } - $this->writeXML($nextRows, $stream, $normalizer); + $this->writeXML($nextRows, $stream, $context); } - /** - * @param Rows $rows - * @param DestinationStream $stream - */ - public function writeXML(Rows $rows, DestinationStream $stream, RowsNormalizer $normalizer): void + public function writeXML(Rows $rows, DestinationStream $stream, FlowContext $context): void { if (!count($rows)) { return; } - foreach ($normalizer->normalize($rows) as $node) { - $stream->append($this->xmlWriter->write($node) . "\n"); + foreach ($this->encoder()->encode($context->hydrator()->dehydrate($rows)) as $node) { + $stream->append($node . "\n"); } $this->writes[$stream->path()->path()]++; } + + private function encoder(): XMLEncoder + { + return $this->encoder ??= new XMLEncoder( + $this->xmlWriter, + $this->attributePrefix, + $this->dateTimeFormat, + $this->dateFormat, + $this->listElementName, + $this->mapElementName, + $this->mapElementKeyName, + $this->mapElementValueName, + $this->rowElementName, + ); + } } diff --git a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer.php b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer.php deleted file mode 100644 index 53e3770538..0000000000 --- a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ - public function normalize(Rows $rows): Generator - { - foreach ($rows as $row) { - $node = XMLNode::nestedNode($this->rowNodeName); - - foreach ($row->entries() as $entry) { - $node = $node->append($this->entryNormalizer->normalize($entry)); - } - - yield $node; - } - } -} diff --git a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer/EntryNormalizer.php b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer/EntryNormalizer.php deleted file mode 100644 index 11ce131112..0000000000 --- a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer/EntryNormalizer.php +++ /dev/null @@ -1,212 +0,0 @@ - $entry - */ - public function normalize(Entry $entry): XMLNode|XMLAttribute - { - if (str_starts_with($entry->name(), $this->valueNormalizer->attributePrefix)) { - return new XMLAttribute( - substr($entry->name(), strlen($this->valueNormalizer->attributePrefix)), - $entry->toString(), - ); - } - - if ($entry instanceof ListEntry) { - return $this->listToNode($entry); - } - - if ($entry instanceof MapEntry) { - return $this->mapToNode($entry); - } - - if ($entry instanceof StructureEntry) { - return $this->structureToNode($entry); - } - - return match ($entry::class) { - StringEntry::class => XMLNode::flatNode($entry->name(), $entry->value()), - IntegerEntry::class => XMLNode::flatNode($entry->name(), (string) $entry->value()), - FloatEntry::class => XMLNode::flatNode($entry->name(), (string) $entry->value()), - BooleanEntry::class => XMLNode::flatNode($entry->name(), $entry->value() ? 'true' : 'false'), - DateTimeEntry::class => XMLNode::flatNode( - $entry->name(), - $entry->value()?->format($this->valueNormalizer->dateTimeFormat), - ), - EnumEntry::class => XMLNode::flatNode($entry->name(), $entry->toString()), - JsonEntry::class => XMLNode::flatNode($entry->name(), $entry->toString()), - UuidEntry::class => XMLNode::flatNode($entry->name(), $entry->toString()), - XMLEntry::class => XMLNode::flatNode($entry->name(), $entry->toString()), - default => throw new InvalidArgumentException("Given entry type can't be converted to node, given entry type: " - . $entry::class), - }; - } - - /** - * Since we don't have yet a good way of defining a custom metadata for a specific entries, we need to hardcode name of list node elements to "element". - * It might be possible to use a schema here, if provided we might be able to take a metadata from entry definition and use it to define a node name. - * However this might be a bit problematic in case of deeply nested lists. - * - * @param ListEntry|null> $entry - */ - private function listToNode(ListEntry $entry): XMLNode - { - $node = XMLNode::nestedNode($entry->name()); - - $type = $entry->type(); - - $listValue = $entry->value(); - - if (!is_array($listValue) || !count($listValue)) { - return $node; - } - - // @mago-ignore analysis:mixed-assignment - foreach ($listValue as $value) { - $node = $node->append($this->valueNormalizer->normalize( - $this->valueNormalizer->listElementName, - $type, - $value, - )); - } - - return $node; - } - - /** - * There are at least 3 different ways of representing Maps in XML: - * - * Example 1: - * - * - * - * - * - * - * - * Example 2: - * - * - * - * - * Example 3: - * - * <{key}>{value} - * - * - * But we need to remember about node naming rules: - * - * XML elements must follow these naming rules: - * - Names can contain letters, numbers, and other characters - * - Names cannot start with a number or punctuation character - * - Names cannot start with the letters xml (or XML, or Xml, etc) - * - Names cannot contain spaces - * - Any name can be used, no words are reserved. - * - * Because of that and because Map Values can be other nested structures, the only valid solution is solution from Example 1. - * - * @param MapEntry|null> $entry - */ - private function mapToNode(MapEntry $entry): XMLNode - { - $node = XMLNode::nestedNode($entry->name()); - $mapValue = $entry->value(); - - if (!is_array($mapValue) || !count($mapValue)) { - return $node; - } - - $type = $entry->type(); - - // @mago-ignore analysis:mixed-assignment - foreach ($mapValue as $key => $value) { - $node = $node->append($this->valueNormalizer->normalize( - $this->valueNormalizer->mapElementKeyName, - $type->key(), - $key, - )); - $node = $node->append($this->valueNormalizer->normalize( - $this->valueNormalizer->mapElementValueName, - $type->value(), - $value, - )); - } - - return $node; - } - - /** - * @param StructureEntry|null> $entry - */ - private function structureToNode(StructureEntry $entry): XMLNode - { - $node = XMLNode::nestedNode($entry->name()); - - $value = $entry->value(); - - if (!is_array($value) || !count($value)) { - return $node; - } - - /** @var StructureType> $type */ - $type = $entry->type(); - - $structureIterator = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC); - $structureIterator->attachIterator(new ArrayIterator($type->elements()), 'structure_element'); - $structureIterator->attachIterator(new ArrayIterator($value), 'value_element'); - - foreach ($structureIterator as $keys => $element) { - /** @var Type $structureElementType */ - $structureElementType = $element['structure_element']; - // @mago-ignore analysis:mixed-assignment - $structureValue = $element['value_element']; - - $node = $node->append($this->valueNormalizer->normalize( - type_string()->assert($keys['structure_element']), - $structureElementType, - $structureValue, - )); - } - - return $node; - } -} diff --git a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer/EntryNormalizer/PHPValueNormalizer.php b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLEncoder.php similarity index 62% rename from src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer/EntryNormalizer/PHPValueNormalizer.php rename to src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLEncoder.php index d2feabdced..80b14f080f 100644 --- a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/RowsNormalizer/EntryNormalizer/PHPValueNormalizer.php +++ b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLEncoder.php @@ -2,23 +2,33 @@ declare(strict_types=1); -namespace Flow\ETL\Adapter\XML\RowsNormalizer\EntryNormalizer; +namespace Flow\ETL\Adapter\XML; use ArrayIterator; use BackedEnum; use Countable; +use DateInterval; use DateTimeInterface; +use Dom\XMLDocument; +use DOMDocument; use Flow\ETL\Adapter\XML\Abstraction\XMLAttribute; use Flow\ETL\Adapter\XML\Abstraction\XMLNode; use Flow\ETL\Exception\InvalidArgumentException; +use Flow\ETL\Exception\RuntimeException; +use Flow\ETL\Row\Encoder; +use Flow\ETL\Row\RawRowValues; use Flow\Types\Type; use Flow\Types\Type\Logical\DateTimeType; +use Flow\Types\Type\Logical\DateType; use Flow\Types\Type\Logical\InstanceOfType; use Flow\Types\Type\Logical\JsonType; use Flow\Types\Type\Logical\ListType; use Flow\Types\Type\Logical\MapType; use Flow\Types\Type\Logical\StructureType; +use Flow\Types\Type\Logical\TimeType; use Flow\Types\Type\Logical\UuidType; +use Flow\Types\Type\Logical\XMLElementType; +use Flow\Types\Type\Logical\XMLType; use Flow\Types\Type\Native\ArrayType; use Flow\Types\Type\Native\BooleanType; use Flow\Types\Type\Native\EnumType; @@ -29,6 +39,7 @@ use Stringable; use function count; +use function Flow\ETL\DSL\date_interval_to_microseconds; use function Flow\Types\DSL\type_string; use function is_array; use function is_iterable; @@ -40,23 +51,59 @@ use const JSON_THROW_ON_ERROR; -final readonly class PHPValueNormalizer +/** + * @implements Encoder + */ +final class XMLEncoder implements Encoder { public function __construct( - public string $attributePrefix = '_', - public string $dateTimeFormat = 'Y-m-d\TH:i:s.uP', - public string $listElementName = 'element', - public string $mapElementName = 'element', - public string $mapElementKeyName = 'key', - public string $mapElementValueName = 'value', + private readonly ?XMLWriter $xmlWriter = null, + private readonly string $attributePrefix = '_', + private readonly string $dateTimeFormat = 'Y-m-d\TH:i:s.uP', + private readonly string $dateFormat = 'Y-m-d', + private readonly string $listElementName = 'element', + private readonly string $mapElementName = 'element', + private readonly string $mapElementKeyName = 'key', + private readonly string $mapElementValueName = 'value', + private readonly string $rowElementName = 'row', ) {} + public function decode(array $batch): array + { + $maps = []; + + foreach ($batch as $xml) { + $maps[] = new RawRowValues(['node' => $xml]); + } + + return $maps; + } + + public function encode(array $batch): array + { + $xmlWriter = $this->xmlWriter ?? throw new RuntimeException('XMLEncoder requires an XMLWriter to encode rows'); + + $lines = []; + + foreach ($batch as $rowValues) { + $node = XMLNode::nestedNode($this->rowElementName); + + foreach ($rowValues->types as $name => $type) { + $node = $node->append($this->normalize($name, $type, $rowValues->values[$name])); + } + + $lines[] = $xmlWriter->write($node); + } + + return $lines; + } + /** * @param Type $type * * @throws InvalidArgumentException */ - public function normalize(string $name, Type $type, mixed $value): XMLNode|XMLAttribute + private function normalize(string $name, Type $type, mixed $value): XMLNode|XMLAttribute { if (str_starts_with($name, $this->attributePrefix)) { return new XMLAttribute(substr($name, strlen($this->attributePrefix)), type_string()->cast($value)); @@ -69,15 +116,7 @@ public function normalize(string $name, Type $type, mixed $value): XMLNode|XMLAt if ($type instanceof ListType) { $listNode = XMLNode::nestedNode($name); - if (!is_array($value) && !$value instanceof Countable) { - return $listNode; - } - - if (!count($value)) { - return $listNode; - } - - if (!is_iterable($value)) { + if (!is_array($value) && !$value instanceof Countable || !count($value) || !is_iterable($value)) { return $listNode; } @@ -96,15 +135,7 @@ public function normalize(string $name, Type $type, mixed $value): XMLNode|XMLAt if ($type instanceof MapType) { $mapNode = XMLNode::nestedNode($name); - if (!is_array($value) && !$value instanceof Countable) { - return $mapNode; - } - - if (!count($value)) { - return $mapNode; - } - - if (!is_iterable($value)) { + if (!is_array($value) && !$value instanceof Countable || !count($value) || !is_iterable($value)) { return $mapNode; } @@ -162,14 +193,42 @@ public function normalize(string $name, Type $type, mixed $value): XMLNode|XMLAt $name, type_string()->cast($value instanceof DateTimeInterface ? $value->format($this->dateTimeFormat) : ''), ), + DateType::class => XMLNode::flatNode( + $name, + type_string()->cast($value instanceof DateTimeInterface ? $value->format($this->dateFormat) : ''), + ), + TimeType::class => XMLNode::flatNode( + $name, + $value instanceof DateInterval ? (string) date_interval_to_microseconds($value) : '', + ), JsonType::class => XMLNode::flatNode($name, $value instanceof Stringable ? $value->__toString() : ''), UuidType::class => XMLNode::flatNode( $name, is_scalar($value) || $value instanceof Stringable ? (string) $value : '', ), + XMLType::class, XMLElementType::class => XMLNode::flatNode($name, $this->xmlToString($value)), default => throw new InvalidArgumentException( "Given type can't be converted to node, given type: {$type->toString()}", ), }; } + + private function xmlToString(mixed $value): string + { + if ($value instanceof XMLDocument) { + $serialized = $value->saveXml($value->documentElement); + } elseif ($value instanceof DOMDocument) { + $serialized = $value->saveXML($value->documentElement); + } elseif ($value instanceof Stringable || is_scalar($value)) { + return (string) $value; + } else { + return ''; + } + + if ($serialized === false) { + throw new RuntimeException('Failed to serialize XML document.'); + } + + return $serialized; + } } diff --git a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLParserExtractor.php b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLParserExtractor.php index 653d09bad4..4e73b94d0c 100644 --- a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLParserExtractor.php +++ b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLParserExtractor.php @@ -4,8 +4,6 @@ namespace Flow\ETL\Adapter\XML; -use DOMDocument; -use DOMNode; use Flow\ETL\Exception\RuntimeException; use Flow\ETL\Extractor; use Flow\ETL\Extractor\FileExtractor; @@ -14,6 +12,7 @@ use Flow\ETL\Extractor\PathFiltering; use Flow\ETL\Extractor\Signal; use Flow\ETL\FlowContext; +use Flow\ETL\Row\RawRowValues; use Flow\ETL\Rows; use Flow\ETL\Schema; use Flow\Filesystem\Path; @@ -22,7 +21,9 @@ use XMLWriter; use function count; -use function Flow\ETL\DSL\array_to_rows; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\str_schema; +use function Flow\ETL\DSL\xml_schema; final class XMLParserExtractor implements Extractor, FileExtractor, LimitableExtractor { @@ -111,11 +112,30 @@ public function endElementHandler(XMLParser $parser, string $name): void public function extract(FlowContext $context): Generator { $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); + $encoder = new XMLEncoder(); + + $baseSchema = $this->schema ?? schema(xml_schema('node')); + + if ($shouldPutInputIntoRows && $baseSchema->findDefinition('_input_file_uri') === null) { + $baseSchema = $baseSchema->add(str_schema('_input_file_uri')); + } foreach ($context->streams()->list($this->path, $this->filter()) as $stream) { - $uri = $stream->path()->uri(); + $streamUri = $shouldPutInputIntoRows ? $stream->path()->uri() : null; $partitions = $stream->path()->partitions(); + $schema = $baseSchema; + + foreach ($partitions as $partition) { + if ($schema->findDefinition($partition->name) === null) { + $schema = $schema->add(str_schema($partition->name)); + } + } + + $rawNodes = []; + foreach ($stream->iterate($this->bufferSize) as $chunk) { if (!xml_parse($this->parser(), $chunk)) { throw new RuntimeException(sprintf( @@ -126,26 +146,74 @@ public function extract(FlowContext $context): Generator } foreach ($this->elements as $element) { - $rowData = ['node' => $this->createDOMNode($element)]; - if ($shouldPutInputIntoRows) { - $rowData['_input_file_uri'] = $uri; - } + $rawNodes[] = $element; - $signal = yield array_to_rows($rowData, $context->entryFactory(), $partitions, $this->schema); + if (count($rawNodes) >= $batchSize) { + $batch = []; - $this->incrementReturnedRows(); + foreach ($encoder->decode($rawNodes) as $rowValues) { + $rowData = $rowValues->values; - if ($signal === Signal::STOP || $this->reachedLimit()) { - $context->streams()->closeStreams($this->path); - $this->freeParser(); + if ($streamUri !== null) { + $rowData['_input_file_uri'] = $streamUri; + } - return; + foreach ($partitions as $partition) { + $rowData[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($rowData); + } + + $rawNodes = []; + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + $this->freeParser(); + + return; + } + } } } $this->elements = []; } + $batch = []; + + foreach ($encoder->decode($rawNodes) as $rowValues) { + $rowData = $rowValues->values; + + if ($streamUri !== null) { + $rowData['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $rowData[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($rowData); + } + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $context->streams()->closeStreams($this->path); + $this->freeParser(); + + return; + } + } + xml_parse($this->parser(), '', true); $this->freeParser(); @@ -225,14 +293,6 @@ public function withXMLNodePath(string $xmlNodePath): self return $this; } - private function createDOMNode(string $xmlString): DOMNode - { - $doc = new DOMDocument(); - $doc->loadXML($xmlString); - - return $doc; - } - private function freeParser(): void { $this->parser = null; diff --git a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLReaderExtractor.php b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLReaderExtractor.php index 62a10da005..edb9cc4edf 100644 --- a/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLReaderExtractor.php +++ b/src/adapter/etl-adapter-xml/src/Flow/ETL/Adapter/XML/XMLReaderExtractor.php @@ -13,13 +13,17 @@ use Flow\ETL\Extractor\PathFiltering; use Flow\ETL\Extractor\Signal; use Flow\ETL\FlowContext; +use Flow\ETL\Row\RawRowValues; use Flow\ETL\Rows; use Flow\Filesystem\Path; use Generator; use XMLReader; use function array_pop; -use function Flow\ETL\DSL\array_to_rows; +use function count; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\str_schema; +use function Flow\ETL\DSL\xml_schema; use function implode; /** @@ -63,14 +67,36 @@ public function __construct( public function extract(FlowContext $context): Generator { $shouldPutInputIntoRows = $context->config->shouldPutInputIntoRows(); + $hydrator = $context->hydrator(); + $batchSize = $context->config->extractorBatchSize(); + $encoder = new XMLEncoder(); + + $baseSchema = schema(xml_schema('node')); + + if ($shouldPutInputIntoRows && $baseSchema->findDefinition('_input_file_uri') === null) { + $baseSchema = $baseSchema->add(str_schema('_input_file_uri')); + } foreach ($context->streams()->list($this->path, $this->filter()) as $stream) { + $streamUri = $shouldPutInputIntoRows ? $stream->path()->uri() : null; + $partitions = $stream->path()->partitions(); + + $schema = $baseSchema; + + foreach ($partitions as $partition) { + if ($schema->findDefinition($partition->name) === null) { + $schema = $schema->add(str_schema($partition->name)); + } + } + $xmlReader = new XMLReader(); $xmlReader->open($stream->path()->path()); $previousDepth = 0; $currentPathBreadCrumbs = []; + $rawNodes = []; + while ($xmlReader->read()) { if ($xmlReader->nodeType === XMLReader::ELEMENT) { if ($previousDepth === $xmlReader->depth) { @@ -92,29 +118,39 @@ public function extract(FlowContext $context): Generator if ($currentPath === $this->xmlNodePath || $this->xmlNodePath === '' && $xmlReader->depth === 0) { $dom = new DOMDocument('1.0', ''); $node = $xmlReader->expand($dom); + $rawNodes[] = $node === false ? '' : (string) $dom->saveXML($node); - if ($shouldPutInputIntoRows) { - $rowData = [ - 'node' => $node, - '_input_file_uri' => $stream->path()->uri(), - ]; - } else { - $rowData = ['node' => $node]; - } + if (count($rawNodes) >= $batchSize) { + $batch = []; + + foreach ($encoder->decode($rawNodes) as $rowValues) { + $rowData = $rowValues->values; + + if ($streamUri !== null) { + $rowData['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $rowData[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($rowData); + } + + $rawNodes = []; - $signal = yield array_to_rows( - $rowData, - $context->entryFactory(), - $stream->path()->partitions(), - ); + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); - $this->incrementReturnedRows(); + $this->incrementReturnedRows(); - if ($signal === Signal::STOP || $this->reachedLimit()) { - $xmlReader->close(); - $context->streams()->closeStreams($this->path); + if ($signal === Signal::STOP || $this->reachedLimit()) { + $xmlReader->close(); + $context->streams()->closeStreams($this->path); - return; + return; + } + } } } @@ -122,6 +158,35 @@ public function extract(FlowContext $context): Generator } } + $batch = []; + + foreach ($encoder->decode($rawNodes) as $rowValues) { + $rowData = $rowValues->values; + + if ($streamUri !== null) { + $rowData['_input_file_uri'] = $streamUri; + } + + foreach ($partitions as $partition) { + $rowData[$partition->name] = $partition->value; + } + + $batch[] = new RawRowValues($rowData); + } + + foreach ($hydrator->cast($batch, $schema) as $hydratedRow) { + $signal = yield Rows::partitioned([$hydratedRow], $partitions); + + $this->incrementReturnedRows(); + + if ($signal === Signal::STOP || $this->reachedLimit()) { + $xmlReader->close(); + $context->streams()->closeStreams($this->path); + + return; + } + } + $xmlReader->close(); } } diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Integration/XMLHydratorParityTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Integration/XMLHydratorParityTest.php new file mode 100644 index 0000000000..c1a8f57cd3 --- /dev/null +++ b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Integration/XMLHydratorParityTest.php @@ -0,0 +1,64 @@ +withXMLNodePath('root/items/item'); + + $rows = []; + + foreach ($extractor->extract(flow_context(Config::builder()->build())) as $batch) { + foreach ($batch as $row) { + static::assertInstanceOf(XMLEntry::class, $row->get('node')); + $rows[] = $row; + } + } + + static::assertCount(5, $rows); + } + + public function test_appends_input_file_uri_when_put_input_into_rows_is_enabled(): void + { + $extractor = from_xml($path = path_real(__DIR__ . '/../Fixtures/simple_items.xml')) + ->withXMLNodePath('root/items/item'); + + foreach ($extractor->extract(flow_context(Config::builder()->putInputIntoRows()->build())) as $batch) { + foreach ($batch as $row) { + static::assertTrue($row->has('_input_file_uri')); + static::assertSame($path->uri(), $row->valueOf('_input_file_uri')); + } + } + } + + public function test_honours_a_hydrator_configured_on_the_context(): void + { + $extractor = from_xml(path_real(__DIR__ . '/../Fixtures/simple_items.xml'))->withXMLNodePath('root/items/item'); + + $count = 0; + + foreach ($extractor->extract( + flow_context(Config::builder()->hydrator(new AdaptiveRowHydrator())->build()), + ) as $batch) { + foreach ($batch as $row) { + static::assertInstanceOf(XMLEntry::class, $row->get('node')); + $count++; + } + } + + static::assertSame(5, $count); + } +} diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/ListNormalizationTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/ListNormalizationTest.php deleted file mode 100644 index 3b1af120d7..0000000000 --- a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/ListNormalizationTest.php +++ /dev/null @@ -1,129 +0,0 @@ -append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('name', 'John')) - ->append(XMLNode::flatNode('age', '30')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('name', 'Jane')) - ->append(XMLNode::flatNode('age', '25')), - ), - $normalizer->normalize( - 'list', - type_list(type_structure([ - 'name' => type_string(), - 'age' => type_integer(), - ])), - [['name' => 'John', 'age' => 30], ['name' => 'Jane', 'age' => 25]], - ), - ); - } - - public function test_normalizing_empty_list(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::nestedNode('list'), - $normalizer->normalize('list', type_list(type_integer()), []), - ); - } - - public function test_normalizing_list_of_integers(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::nestedNode('list') - ->append(XMLNode::flatNode('element', '1')) - ->append(XMLNode::flatNode('element', '2')) - ->append(XMLNode::flatNode('element', '3')), - $normalizer->normalize('list', type_list(type_integer()), [1, 2, 3]), - ); - } - - public function test_normalizing_list_of_list_of_integers(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::nestedNode('list') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('element', '1')) - ->append(XMLNode::flatNode('element', '2')) - ->append(XMLNode::flatNode('element', '3')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('element', '4')) - ->append(XMLNode::flatNode('element', '5')) - ->append(XMLNode::flatNode('element', '6')), - ), - $normalizer->normalize('list', type_list(type_list(type_integer())), [[1, 2, 3], [4, 5, 6]]), - ); - } - - public function test_normalizing_list_of_map_of_str_to_int(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::nestedNode('list') - ->append( - XMLNode::nestedNode('element') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'one')) - ->append(XMLNode::flatNode('value', '1')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'two')) - ->append(XMLNode::flatNode('value', '2')), - ), - ) - ->append( - XMLNode::nestedNode('element') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'three')) - ->append(XMLNode::flatNode('value', '3')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'four')) - ->append(XMLNode::flatNode('value', '4')), - ), - ), - $normalizer->normalize('list', type_list(type_map(type_integer(), type_string())), [ - ['one' => 1, 'two' => 2], - ['three' => 3, 'four' => 4], - ]), - ); - } -} diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/MapNormalizationTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/MapNormalizationTest.php deleted file mode 100644 index a00a4ea267..0000000000 --- a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/MapNormalizationTest.php +++ /dev/null @@ -1,89 +0,0 @@ -normalize('map', type_map(type_integer(), type_string()), []), - ); - } - - public function test_normalizing_map_of_int_to_str(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::nestedNode('map') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', '1')) - ->append(XMLNode::flatNode('value', 'one')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', '2')) - ->append(XMLNode::flatNode('value', 'two')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', '3')) - ->append(XMLNode::flatNode('value', 'three')), - ), - $normalizer->normalize('map', type_map(type_integer(), type_string()), [ - 1 => 'one', - 2 => 'two', - 3 => 'three', - ]), - ); - } - - public function test_normalizing_map_of_str_to_list_of_ints(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::nestedNode('map') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'one')) - ->append( - XMLNode::nestedNode('value') - ->append(XMLNode::flatNode('element', '1')) - ->append(XMLNode::flatNode('element', '2')) - ->append(XMLNode::flatNode('element', '3')), - ), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'two')) - ->append( - XMLNode::nestedNode('value') - ->append(XMLNode::flatNode('element', '4')) - ->append(XMLNode::flatNode('element', '5')) - ->append(XMLNode::flatNode('element', '6')), - ), - ), - $normalizer->normalize('map', type_map(type_string(), type_list(type_integer())), [ - 'one' => [1, 2, 3], - 'two' => [4, 5, 6], - ]), - ); - } -} diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/StructureNormalizationTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/StructureNormalizationTest.php deleted file mode 100644 index cdc8772d0e..0000000000 --- a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizer/StructureNormalizationTest.php +++ /dev/null @@ -1,112 +0,0 @@ -normalize( - 'structure', - type_structure([ - '_id' => type_string(), - 'name' => type_string(), - 'age' => type_string(), - ]), - ['_id' => 1, 'name' => 'John', 'age' => 30], - ); - - static::assertEquals( - XMLNode::nestedNode('structure') - ->append(new XMLAttribute('id', '1')) - ->append(XMLNode::flatNode('name', 'John')) - ->append(XMLNode::flatNode('age', '30')), - $normalized, - ); - } - - public function test_normalization_of_structure_with_list_of_int(): void - { - $normalizer = new PHPValueNormalizer(); - - $normalized = $normalizer->normalize( - 'structure', - type_structure([ - 'name' => type_string(), - 'age' => type_string(), - 'numbers' => type_list(type_integer()), - ]), - ['name' => 'John', 'age' => 30, 'numbers' => [1, 2, 3, 4, 5]], - ); - - static::assertEquals( - XMLNode::nestedNode('structure') - ->append(XMLNode::flatNode('name', 'John')) - ->append(XMLNode::flatNode('age', '30')) - ->append( - XMLNode::nestedNode('numbers') - ->append(XMLNode::flatNode('element', '1')) - ->append(XMLNode::flatNode('element', '2')) - ->append(XMLNode::flatNode('element', '3')) - ->append(XMLNode::flatNode('element', '4')) - ->append(XMLNode::flatNode('element', '5')), - ), - $normalized, - ); - } - - public function test_normalization_of_structure_with_nested_structure(): void - { - $normalizer = new PHPValueNormalizer(); - - $normalized = $normalizer->normalize( - 'structure', - type_structure([ - '_created-at' => type_datetime(), - 'name' => type_string(), - 'age' => type_string(), - 'address' => type_structure([ - 'street' => type_string(), - 'city' => type_string(), - 'zip' => type_string(), - ]), - ]), - [ - '_created-at' => new DateTimeImmutable('2024-08-22 00:00:00'), - 'name' => 'John', - 'age' => 30, - 'address' => ['street' => 'Main St.', 'city' => 'New York', 'zip' => '10001'], - ], - ); - - static::assertEquals( - XMLNode::nestedNode('structure') - ->append(new XMLAttribute('created-at', '2024-08-22T00:00:00+00:00')) - ->append(XMLNode::flatNode('name', 'John')) - ->append(XMLNode::flatNode('age', '30')) - ->append( - XMLNode::nestedNode('address') - ->append(XMLNode::flatNode('street', 'Main St.')) - ->append(XMLNode::flatNode('city', 'New York')) - ->append(XMLNode::flatNode('zip', '10001')), - ), - $normalized, - ); - } -} diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizerTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizerTest.php deleted file mode 100644 index b7d2a30aba..0000000000 --- a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizer/PHPValueNormalizerTest.php +++ /dev/null @@ -1,103 +0,0 @@ -normalize('array', type_array(), ['a' => '1', 'b' => 22]), - ); - } - - public function test_normalizing_attribute(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - new XMLAttribute('attribute', 'a'), - $normalizer->normalize('_attribute', type_string(), 'a'), - ); - } - - public function test_normalizing_boolean_type(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals(XMLNode::flatNode('bool', 'false'), $normalizer->normalize('bool', type_boolean(), false)); - static::assertEquals(XMLNode::flatNode('bool', 'true'), $normalizer->normalize('bool', type_boolean(), true)); - } - - public function test_normalizing_datetime_type(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::flatNode('array', '2024-08-22T02:00:00.000000+00:00'), - $normalizer->normalize('array', type_datetime(), new DateTimeImmutable('2024-08-22 02:00:00 UTC')), - ); - } - - public function test_normalizing_float_type(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals(XMLNode::flatNode('float', '1.1'), $normalizer->normalize('float', type_float(), 1.1)); - } - - public function test_normalizing_integer_type(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals(XMLNode::flatNode('int', '1'), $normalizer->normalize('int', type_integer(), 1)); - - static::assertEquals( - XMLNode::flatNode('int', ''), - $normalizer->normalize('int', type_optional(type_integer()), null), - ); - } - - public function test_normalizing_json_type(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals( - XMLNode::flatNode('json', '{"a":"1","b":22}'), - $normalizer->normalize('json', type_json(), Json::fromArray(['a' => '1', 'b' => 22])), - ); - } - - public function test_normalizing_object_type(): void - { - static::markTestSkipped('We need to figure out what to do with object types'); - } - - public function test_normalizing_string_type(): void - { - $normalizer = new PHPValueNormalizer(); - - static::assertEquals(XMLNode::flatNode('str', 'a'), $normalizer->normalize('str', type_string(), 'a')); - } -} diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php deleted file mode 100644 index eb10039023..0000000000 --- a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizer/EntryNormalizerTest.php +++ /dev/null @@ -1,127 +0,0 @@ -normalize(str_entry('_id', '1'))); - } - - public function test_normalizing_structure_entry(): void - { - $entryNormalizer = new EntryNormalizer(new PHPValueNormalizer()); - - $structure = structure_entry( - 'structure', - [ - 'id' => 1, - 'name' => 'name', - 'active' => true, - 'date' => new DateTimeImmutable('2024-04-04 00:00:00 UTC'), - 'list' => [1, 2, 3], - 'map' => ['a' => 1, 'b' => 2], - 'nested_structure' => [ - 'id' => 2, - 'name' => 'nested-name', - 'active' => false, - 'date' => new DateTimeImmutable('2024-04-04 00:00:00 UTC'), - 'list' => [4, 5, 6], - 'map' => ['c' => 3, 'd' => 4], - ], - ], - type_structure([ - 'id' => type_integer(), - 'name' => type_string(), - 'active' => type_boolean(), - 'date' => type_datetime(), - 'list' => type_list(type_integer()), - 'map' => type_map(type_string(), type_integer()), - 'nested_structure' => type_structure([ - 'id' => type_integer(), - 'name' => type_string(), - 'active' => type_boolean(), - 'date' => type_datetime(), - 'list' => type_list(type_integer()), - 'map' => type_map(type_string(), type_integer()), - ]), - ]), - ); - - static::assertEquals( - XMLNode::nestedNode('structure') - ->append(XMLNode::flatNode('id', '1')) - ->append(XMLNode::flatNode('name', 'name')) - ->append(XMLNode::flatNode('active', 'true')) - ->append(XMLNode::flatNode('date', '2024-04-04T00:00:00.000000+00:00')) - ->append( - XMLNode::nestedNode('list') - ->append(XMLNode::flatNode('element', '1')) - ->append(XMLNode::flatNode('element', '2')) - ->append(XMLNode::flatNode('element', '3')), - ) - ->append( - XMLNode::nestedNode('map') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'a')) - ->append(XMLNode::flatNode('value', '1')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'b')) - ->append(XMLNode::flatNode('value', '2')), - ), - ) - ->append( - XMLNode::nestedNode('nested_structure') - ->append(XMLNode::flatNode('id', '2')) - ->append(XMLNode::flatNode('name', 'nested-name')) - ->append(XMLNode::flatNode('active', 'false')) - ->append(XMLNode::flatNode('date', '2024-04-04T00:00:00.000000+00:00')) - ->append( - XMLNode::nestedNode('list') - ->append(XMLNode::flatNode('element', '4')) - ->append(XMLNode::flatNode('element', '5')) - ->append(XMLNode::flatNode('element', '6')), - ) - ->append( - XMLNode::nestedNode('map') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'c')) - ->append(XMLNode::flatNode('value', '3')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'd')) - ->append(XMLNode::flatNode('value', '4')), - ), - ), - ), - $entryNormalizer->normalize($structure), - ); - } -} diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizerTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizerTest.php deleted file mode 100644 index e60ab5e8e1..0000000000 --- a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/RowsNormalizerTest.php +++ /dev/null @@ -1,141 +0,0 @@ - 1, - 'name' => 'name', - 'active' => true, - 'date' => new DateTimeImmutable('2024-04-04 00:00:00 UTC'), - 'list' => [1, 2, 3], - 'map' => ['a' => 1, 'b' => 2], - 'nested_structure' => [ - 'id' => 2, - 'name' => 'nested-name', - 'active' => false, - 'date' => new DateTimeImmutable('2024-04-04 00:00:00 UTC'), - 'list' => [4, 5, 6], - 'map' => ['c' => 3, 'd' => 4], - ], - ], - type_structure([ - 'id' => type_integer(), - 'name' => type_string(), - 'active' => type_boolean(), - 'date' => type_datetime(), - 'list' => type_list(type_integer()), - 'map' => type_map(type_string(), type_integer()), - 'nested_structure' => type_structure([ - 'id' => type_integer(), - 'name' => type_string(), - 'active' => type_boolean(), - 'date' => type_datetime(), - 'list' => type_list(type_integer()), - 'map' => type_map(type_string(), type_integer()), - ]), - ]), - ))); - - static::assertEquals( - XMLNode::nestedNode('row')->append( - XMLNode::nestedNode('structure') - ->append(XMLNode::flatNode('id', '1')) - ->append(XMLNode::flatNode('name', 'name')) - ->append(XMLNode::flatNode('active', 'true')) - ->append(XMLNode::flatNode('date', '2024-04-04T00:00:00.000000+00:00')) - ->append( - XMLNode::nestedNode('list') - ->append(XMLNode::flatNode('element', '1')) - ->append(XMLNode::flatNode('element', '2')) - ->append(XMLNode::flatNode('element', '3')), - ) - ->append( - XMLNode::nestedNode('map') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'a')) - ->append(XMLNode::flatNode('value', '1')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'b')) - ->append(XMLNode::flatNode('value', '2')), - ), - ) - ->append( - XMLNode::nestedNode('nested_structure') - ->append(XMLNode::flatNode('id', '2')) - ->append(XMLNode::flatNode('name', 'nested-name')) - ->append(XMLNode::flatNode('active', 'false')) - ->append(XMLNode::flatNode('date', '2024-04-04T00:00:00.000000+00:00')) - ->append( - XMLNode::nestedNode('list') - ->append(XMLNode::flatNode('element', '4')) - ->append(XMLNode::flatNode('element', '5')) - ->append(XMLNode::flatNode('element', '6')), - ) - ->append( - XMLNode::nestedNode('map') - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'c')) - ->append(XMLNode::flatNode('value', '3')), - ) - ->append( - XMLNode::nestedNode('element') - ->append(XMLNode::flatNode('key', 'd')) - ->append(XMLNode::flatNode('value', '4')), - ), - ), - ), - ), - iterator_to_array($normalizer->normalize($rows))[0], - ); - } - - public function test_normalizing_rows_with_attributes(): void - { - $normalizer = new RowsNormalizer(new EntryNormalizer(new PHPValueNormalizer())); - - static::assertEquals( - XMLNode::nestedNode('row') - ->append(new XMLAttribute('id', '1')) - ->append(XMLNode::flatNode('name', 'John Doe')), - iterator_to_array($normalizer->normalize(rows(row( - str_entry('_id', '1'), - str_entry('name', 'John Doe'), - ))))[0], - ); - } -} diff --git a/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/XMLEncoderTest.php b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/XMLEncoderTest.php new file mode 100644 index 0000000000..7fa3a73686 --- /dev/null +++ b/src/adapter/etl-adapter-xml/tests/Flow/ETL/Adapter/XML/Tests/Unit/XMLEncoderTest.php @@ -0,0 +1,178 @@ + '1'], + $encoder->decode(['1'])[0]->values, + ); + } + + public function test_encodes_scalars_into_flat_nodes(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + '1Norbert', + $encoder->encode([new TypedRowValues(['id' => 1, 'name' => 'Norbert'], [ + 'id' => type_integer(), + 'name' => type_string(), + ])])[0], + ); + } + + public function test_encodes_prefixed_columns_as_attributes(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + 'Norbert', + $encoder->encode([new TypedRowValues(['_id' => 1, 'name' => 'Norbert'], [ + '_id' => type_integer(), + 'name' => type_string(), + ])])[0], + ); + } + + public function test_encodes_date_with_the_date_format(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + '2024-08-01', + $encoder->encode([new TypedRowValues(['at' => new DateTimeImmutable('2024-08-01 10:00:00')], [ + 'at' => type_date(), + ])])[0], + ); + } + + public function test_encodes_datetime_with_the_configured_format(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter(), dateTimeFormat: 'Y-m-d'); + + static::assertXmlStringEqualsXmlString( + '2024-08-01', + $encoder->encode([new TypedRowValues(['at' => new DateTimeImmutable('2024-08-01 10:00:00')], [ + 'at' => type_datetime(), + ])])[0], + ); + } + + public function test_encodes_time_as_microseconds(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + '3600000000', + $encoder->encode([new TypedRowValues(['d' => new DateInterval('PT1H')], ['d' => type_time()])])[0], + ); + } + + public function test_encodes_enum_as_its_name(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + 'one', + $encoder->encode([new TypedRowValues(['e' => BackedIntEnum::one], [ + 'e' => type_enum(BackedIntEnum::class), + ])])[0], + ); + } + + public function test_encodes_uuid_as_string(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + $encoder->encode([new TypedRowValues(['id' => new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479')], [ + 'id' => type_uuid(), + ])])[0], + ); + } + + public function test_encodes_list_into_element_nodes(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + 'ab', + $encoder->encode([new TypedRowValues(['tags' => ['a', 'b']], ['tags' => type_list(type_string())])])[0], + ); + } + + public function test_encodes_map_into_key_value_element_nodes(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + 'x1', + $encoder->encode([new TypedRowValues(['m' => ['x' => 1]], ['m' => type_map( + type_string(), + type_integer(), + )])])[0], + ); + } + + public function test_encodes_structure_into_nested_nodes(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + '
Krakow31-021
', + $encoder->encode([new TypedRowValues(['address' => [ + 'city' => 'Krakow', + 'zip' => '31-021', + ]], ['address' => type_structure(['city' => type_string(), 'zip' => type_string()])])])[0], + ); + } + + public function test_encodes_null_scalar_as_an_empty_node(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter()); + + static::assertXmlStringEqualsXmlString( + '', + $encoder->encode([new TypedRowValues(['name' => null], ['name' => type_string()])])[0], + ); + } + + public function test_uses_the_configured_row_element_name(): void + { + $encoder = new XMLEncoder(new DOMDocumentWriter(), rowElementName: 'record'); + + static::assertXmlStringEqualsXmlString( + '1', + $encoder->encode([new TypedRowValues(['id' => 1], ['id' => type_integer()])])[0], + ); + } +} diff --git a/src/cli/tests/Flow/CLI/Tests/Integration/FileSchemaCommandTest.php b/src/cli/tests/Flow/CLI/Tests/Integration/FileSchemaCommandTest.php index 035867b02b..b5f2104b46 100644 --- a/src/cli/tests/Flow/CLI/Tests/Integration/FileSchemaCommandTest.php +++ b/src/cli/tests/Flow/CLI/Tests/Integration/FileSchemaCommandTest.php @@ -337,19 +337,19 @@ public function test_run_schema_with_table_output_on_json(): void $tester->assertCommandIsSuccessful(); self::assertCommandOutputIdentical(<<<'OUTPUT' - +--------------+-----------+----------+--------------------+ - | name | type | nullable | metadata | - +--------------+-----------+----------+--------------------+ - | order_id | uuid | false | [] | - | created_at | datetime | false | [] | - | updated_at | datetime | false | [] | - | cancelled_at | string | true | {"from_null":true} | - | total_price | float | false | [] | - | discount | float | false | [] | - | customer | structure | false | [] | - | address | structure | false | [] | - | notes | list | false | [] | - +--------------+-----------+----------+--------------------+ + +--------------+-----------+----------+----------+ + | name | type | nullable | metadata | + +--------------+-----------+----------+----------+ + | order_id | uuid | false | [] | + | created_at | datetime | false | [] | + | updated_at | datetime | false | [] | + | cancelled_at | null | true | [] | + | total_price | float | false | [] | + | discount | float | false | [] | + | customer | structure | false | [] | + | address | structure | false | [] | + | notes | list | false | [] | + +--------------+-----------+----------+----------+ 9 rows OUTPUT, $tester->getDisplay()); diff --git a/src/core/etl/composer.json b/src/core/etl/composer.json index 5f871f3008..15c83a2446 100644 --- a/src/core/etl/composer.json +++ b/src/core/etl/composer.json @@ -39,7 +39,8 @@ "autoload": { "files": [ "src/Flow/ETL/DSL/functions.php", - "src/Flow/Floe/DSL/functions.php" + "src/Flow/Floe/DSL/functions.php", + "src/Flow/Serializer/DSL/functions.php" ], "psr-4": { "Flow\\": [ diff --git a/src/core/etl/src/Flow/ETL/Cache.php b/src/core/etl/src/Flow/ETL/Cache.php index acdc8c8ee1..ce9a51c36b 100644 --- a/src/core/etl/src/Flow/ETL/Cache.php +++ b/src/core/etl/src/Flow/ETL/Cache.php @@ -5,7 +5,6 @@ namespace Flow\ETL; use Flow\ETL\Exception\KeyNotInCacheException; -use Generator; interface Cache { @@ -18,13 +17,6 @@ public function delete(string $key): void; */ public function get(string $key): Rows; - /** - * @throws KeyNotInCacheException during iteration when the key is absent - * - * @return Generator - */ - public function read(string $key): Generator; - public function has(string $key): bool; public function set(string $key, Rows $value): void; diff --git a/src/core/etl/src/Flow/ETL/Cache/Implementation/ApcuCache.php b/src/core/etl/src/Flow/ETL/Cache/Implementation/ApcuCache.php index cc206e0e3c..275b4f286e 100644 --- a/src/core/etl/src/Flow/ETL/Cache/Implementation/ApcuCache.php +++ b/src/core/etl/src/Flow/ETL/Cache/Implementation/ApcuCache.php @@ -9,7 +9,6 @@ use Flow\ETL\Exception\KeyNotInCacheException; use Flow\ETL\Exception\RuntimeException; use Flow\ETL\Rows; -use Generator; use function apcu_delete; use function apcu_enabled; @@ -71,16 +70,6 @@ public function has(string $key): bool return (bool) apcu_exists($this->namespacedKey($key)); } - /** - * @throws KeyNotInCacheException - * - * @return Generator - */ - public function read(string $key): Generator - { - yield $this->get($key); - } - public function set(string $key, Rows $value): void { $result = apcu_store($this->namespacedKey($key), $value); diff --git a/src/core/etl/src/Flow/ETL/Cache/Implementation/FilesystemCache.php b/src/core/etl/src/Flow/ETL/Cache/Implementation/FilesystemCache.php index 03407ff990..80425c8862 100644 --- a/src/core/etl/src/Flow/ETL/Cache/Implementation/FilesystemCache.php +++ b/src/core/etl/src/Flow/ETL/Cache/Implementation/FilesystemCache.php @@ -5,19 +5,15 @@ namespace Flow\ETL\Cache\Implementation; use Flow\ETL\Cache; -use Flow\ETL\Exception\InvalidArgumentException; use Flow\ETL\Exception\KeyNotInCacheException; use Flow\ETL\Hash\NativePHPHash; use Flow\ETL\Rows; use Flow\Filesystem\Filesystem; use Flow\Filesystem\Path; -use Flow\Floe\Exception\FloeException; -use Flow\Floe\FloeReader; -use Flow\Floe\FloeWriter; -use Flow\Floe\RowsValueMapper; -use Generator; +use Flow\Floe\FloeSerializer; +use Flow\Serializer\Exception\SerializationException; +use Flow\Serializer\Serializer; -use function count; use function str_split; use function substr; @@ -25,23 +21,12 @@ { private Path $cacheDir; - private FloeReader $reader; - - /** - * @param int<1, max> $serializerBatchSize - */ public function __construct( private Filesystem $filesystem, ?Path $cacheDir = null, - private int $serializerBatchSize = 1000, + private Serializer $serializer = new FloeSerializer(), ) { - // @mago-ignore analysis:impossible-condition,redundant-comparison - if ($this->serializerBatchSize < 1) { - throw new InvalidArgumentException('Serializer batch size must be at least 1'); - } - $this->cacheDir = $cacheDir ?? $this->filesystem->getSystemTmpDir(); - $this->reader = new FloeReader($this->filesystem); } public function clear(): void @@ -62,24 +47,9 @@ public function get(string $key): Rows throw new KeyNotInCacheException($key); } - $file = $this->reader->read($path); - try { - $footer = $file->footer(); - $rows = []; - - foreach ($file->recover($this->serializerBatchSize) as $batch) { - foreach ($batch->all() as $row) { - $rows[] = $row; - } - } - - if (count($rows) !== $footer->totalRows) { - throw new KeyNotInCacheException($key); - } - - return RowsValueMapper::wrap(RowsValueMapper::reconstructFrom($rows, $footer)); - } catch (FloeException $e) { + return $this->serializer->unserialize($this->filesystem->readFrom($path)); + } catch (SerializationException $e) { throw new KeyNotInCacheException($key, $e); } } @@ -89,46 +59,15 @@ public function has(string $key): bool return $this->filesystem->status($this->cachePath($key)) !== null; } - public function read(string $key): Generator - { - $path = $this->cachePath($key); - - if (!$this->filesystem->status($path)) { - throw new KeyNotInCacheException($key); - } - - $file = $this->reader->read($path); - - try { - $partitions = RowsValueMapper::partitionsFrom($file->footer()); - } catch (FloeException $e) { - throw new KeyNotInCacheException($key, $e); - } - - foreach ($file->recover($this->serializerBatchSize) as $batch) { - // recover() attaches partitions in on-wire order; the caller-visible order is footer metadata - yield $partitions === [] ? $batch : Rows::partitioned($batch->all(), $partitions); - } - } - public function set(string $key, Rows $value): void { - $writer = new FloeWriter($this->filesystem); - $writer->create($this->cachePath($key), RowsValueMapper::metadataFor($value)); - - // an empty Rows still crosses once - chunks() would yield nothing and an - // empty-but-partitioned value would lose its PARTITIONS frame (byte parity) - foreach ($value->count() === 0 ? [$value] : $value->chunks($this->serializerBatchSize) as $chunk) { - $writer->write($chunk); - } - - $writer->close(); + $this->serializer->serialize($value, $this->filesystem->writeTo($this->cachePath($key))); } private function cachePath(string $key): Path { return $this->cacheDir->suffix( - implode('/', str_split(substr(NativePHPHash::xxh128($key), 0, 8), 2)) . '/' . $key . '.floe', + implode('/', str_split(substr(NativePHPHash::xxh128($key), 0, 8), 2)) . '/' . $key, ); } } diff --git a/src/core/etl/src/Flow/ETL/Cache/Implementation/InMemoryCache.php b/src/core/etl/src/Flow/ETL/Cache/Implementation/InMemoryCache.php index 4f7749948e..5bd0f1b660 100644 --- a/src/core/etl/src/Flow/ETL/Cache/Implementation/InMemoryCache.php +++ b/src/core/etl/src/Flow/ETL/Cache/Implementation/InMemoryCache.php @@ -7,7 +7,6 @@ use Flow\ETL\Cache; use Flow\ETL\Exception\KeyNotInCacheException; use Flow\ETL\Rows; -use Generator; use function array_key_exists; @@ -51,16 +50,6 @@ public function has(string $key): bool return array_key_exists($key, $this->cache); } - /** - * @throws KeyNotInCacheException - * - * @return Generator - */ - public function read(string $key): Generator - { - yield $this->get($key); - } - public function set(string $key, Rows $value): void { $this->cache[$key] = $value; diff --git a/src/core/etl/src/Flow/ETL/Cache/Implementation/PSRSimpleCache.php b/src/core/etl/src/Flow/ETL/Cache/Implementation/PSRSimpleCache.php index 06d34bb69e..9b357bcb20 100644 --- a/src/core/etl/src/Flow/ETL/Cache/Implementation/PSRSimpleCache.php +++ b/src/core/etl/src/Flow/ETL/Cache/Implementation/PSRSimpleCache.php @@ -11,10 +11,11 @@ use Flow\Floe\FloeSerializer; use Flow\Serializer\Exception\SerializationException; use Flow\Serializer\Serializer; -use Generator; use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\InvalidArgumentException; +use function Flow\Serializer\DSL\serialize_to_string; +use function Flow\Serializer\DSL\unserialize_from_string; use function is_string; final readonly class PSRSimpleCache implements Cache @@ -45,7 +46,7 @@ public function get(string $key): Rows } try { - return $this->serializer->unserialize(is_string($serializedValue) ? $serializedValue : '', [Rows::class]); + return unserialize_from_string($this->serializer, is_string($serializedValue) ? $serializedValue : ''); } catch (SerializationException $e) { throw new KeyNotInCacheException($key, $e); } @@ -60,18 +61,8 @@ public function has(string $key): bool } } - /** - * @throws KeyNotInCacheException - * - * @return Generator - */ - public function read(string $key): Generator - { - yield $this->get($key); - } - public function set(string $key, Rows $value): void { - $this->cache->set($key, $this->serializer->serialize($value), $this->ttl); + $this->cache->set($key, serialize_to_string($this->serializer, $value), $this->ttl); } } diff --git a/src/core/etl/src/Flow/ETL/Cache/Implementation/TraceableCache.php b/src/core/etl/src/Flow/ETL/Cache/Implementation/TraceableCache.php index 40df264236..67225ade44 100644 --- a/src/core/etl/src/Flow/ETL/Cache/Implementation/TraceableCache.php +++ b/src/core/etl/src/Flow/ETL/Cache/Implementation/TraceableCache.php @@ -17,7 +17,6 @@ use Flow\Telemetry\Tracer\SpanKind; use Flow\Telemetry\Tracer\SpanStatus; use Flow\Telemetry\Tracer\Tracer; -use Generator; use Throwable; final readonly class TraceableCache implements Cache @@ -94,29 +93,6 @@ public function get(string $key): Rows } } - /** - * @throws KeyNotInCacheException - * - * @return Generator - */ - public function read(string $key): Generator - { - $attributes = [TelemetryAttributes::ATTR_DATAFRAME_NAME => $this->dataframeName]; - $batches = $this->cache->read($key); - - try { - $batches->rewind(); - } catch (KeyNotInCacheException $exception) { - $this->missCounter->add(1, $attributes); - - throw $exception; - } - - $this->hitCounter->add(1, $attributes); - - yield from $batches; - } - public function has(string $key): bool { $attributes = [TelemetryAttributes::ATTR_DATAFRAME_NAME => $this->dataframeName]; diff --git a/src/core/etl/src/Flow/ETL/Config.php b/src/core/etl/src/Flow/ETL/Config.php index cfe0dc1e99..81291b5972 100644 --- a/src/core/etl/src/Flow/ETL/Config.php +++ b/src/core/etl/src/Flow/ETL/Config.php @@ -8,11 +8,13 @@ use Flow\ETL\Config\Cache\CacheConfig; use Flow\ETL\Config\ConfigBuilder; use Flow\ETL\Config\Grouping\GroupingConfig; +use Flow\ETL\Config\Join\JoinConfig; use Flow\ETL\Config\Sort\SortConfig; use Flow\ETL\Config\Telemetry\TelemetryConfig; use Flow\ETL\Filesystem\FilesystemStreams; use Flow\ETL\Pipeline\Optimizer; use Flow\ETL\Row\EntryFactory; +use Flow\ETL\Row\Hydrator; use Flow\Filesystem\FilesystemTable; use Flow\Serializer\Serializer; use Psr\Clock\ClockInterface; @@ -23,6 +25,10 @@ */ final readonly class Config { + /** + * @param Hydrator $hydrator + * @param int<1, max> $extractorBatchSize + */ public function __construct( private string $id, private string $name, @@ -33,12 +39,15 @@ public function __construct( private FilesystemStreams $filesystemStreams, private Optimizer $optimizer, private bool $putInputIntoRows, - private EntryFactory $entryFactory, + private Hydrator $hydrator, public CacheConfig $cache, public SortConfig $sort, private ?Analyze $analyze, public TelemetryConfig $telemetry, public GroupingConfig $grouping, + public JoinConfig $join, + private int $extractorBatchSize = 1000, + private EntryFactory $entryFactory = new EntryFactory(), private Calculator $calculator = new Calculator(), ) {} @@ -67,19 +76,35 @@ public function clock(): ClockInterface return $this->clock; } + public function filesystemStreams(): FilesystemStreams + { + return $this->filesystemStreams; + } + + public function fstab(): FilesystemTable + { + return $this->filesystemTable; + } + public function entryFactory(): EntryFactory { return $this->entryFactory; } - public function filesystemStreams(): FilesystemStreams + /** + * @return int<1, max> + */ + public function extractorBatchSize(): int { - return $this->filesystemStreams; + return $this->extractorBatchSize; } - public function fstab(): FilesystemTable + /** + * @return Hydrator + */ + public function hydrator(): Hydrator { - return $this->filesystemTable; + return $this->hydrator; } public function id(): string diff --git a/src/core/etl/src/Flow/ETL/Config/Cache/CacheConfigBuilder.php b/src/core/etl/src/Flow/ETL/Config/Cache/CacheConfigBuilder.php index c084bc9fd8..db1e238095 100644 --- a/src/core/etl/src/Flow/ETL/Config/Cache/CacheConfigBuilder.php +++ b/src/core/etl/src/Flow/ETL/Config/Cache/CacheConfigBuilder.php @@ -10,6 +10,7 @@ use Flow\ETL\Config\Telemetry\TelemetryConfig; use Flow\ETL\Exception\InvalidArgumentException; use Flow\Filesystem\FilesystemTable; +use Flow\Serializer\Serializer; use function Flow\Filesystem\DSL\path_real; use function getenv; @@ -36,13 +37,9 @@ final class CacheConfigBuilder private string $filesystemMount = 'file'; - /** - * @var int<1, max> - */ - private int $serializerBatchSize = 1000; - public function build( FilesystemTable $fstab, + Serializer $serializer, ?TelemetryConfig $telemetryConfig = null, string $dataframeName = 'flow_dataframe', ): CacheConfig { @@ -52,7 +49,7 @@ public function build( $cache = $this->cache ?? new FilesystemCache( $fstab->for($this->filesystemMount), cacheDir: $cachePath, - serializerBatchSize: $this->serializerBatchSize, + serializer: $serializer, ); if ($telemetryConfig !== null && $telemetryConfig->options->traceCache) { @@ -131,17 +128,4 @@ public function filesystemMount(string $mount): self return $this; } - - /** - * Serializer batch size for the default FilesystemCache; ignored when a custom Cache was - * injected via cache(). - * - * @param int<1, max> $serializerBatchSize - */ - public function serializerBatchSize(int $serializerBatchSize): self - { - $this->serializerBatchSize = $serializerBatchSize; - - return $this; - } } diff --git a/src/core/etl/src/Flow/ETL/Config/ConfigBuilder.php b/src/core/etl/src/Flow/ETL/Config/ConfigBuilder.php index 7d1b8701dd..5052a05722 100644 --- a/src/core/etl/src/Flow/ETL/Config/ConfigBuilder.php +++ b/src/core/etl/src/Flow/ETL/Config/ConfigBuilder.php @@ -10,6 +10,7 @@ use Flow\ETL\Config; use Flow\ETL\Config\Cache\CacheConfigBuilder; use Flow\ETL\Config\Grouping\GroupingConfigBuilder; +use Flow\ETL\Config\Join\JoinConfigBuilder; use Flow\ETL\Config\Sort\SortConfigBuilder; use Flow\ETL\Config\Telemetry\TelemetryConfig; use Flow\ETL\Config\Telemetry\TelemetryOptions; @@ -19,7 +20,8 @@ use Flow\ETL\Pipeline\Optimizer\BatchSizeOptimization; use Flow\ETL\Pipeline\Optimizer\LimitOptimization; use Flow\ETL\RandomValueGenerator; -use Flow\ETL\Row\EntryFactory; +use Flow\ETL\Row\AdaptiveRowHydrator; +use Flow\ETL\Row\Hydrator; use Flow\ETL\Sort\ExternalSort\BucketsCache; use Flow\Filesystem\Filesystem; use Flow\Filesystem\FilesystemTable; @@ -38,14 +40,26 @@ final class ConfigBuilder public readonly GroupingConfigBuilder $grouping; + public readonly JoinConfigBuilder $join; + public readonly SortConfigBuilder $sort; private ?Analyze $analyze; private ?ClockInterface $clock; + /** + * @var int<1, max> + */ + private int $extractorBatchSize; + private ?FilesystemTable $fstab; + /** + * @var null|Hydrator + */ + private ?Hydrator $hydrator; + private ?string $id; private ?string $name; @@ -68,11 +82,14 @@ public function __construct() $this->name = null; $this->serializer = null; $this->fstab = null; + $this->hydrator = null; $this->putInputIntoRows = false; $this->optimizer = null; $this->clock = null; + $this->extractorBatchSize = 1000; $this->cache = new CacheConfigBuilder(); $this->grouping = new GroupingConfigBuilder(); + $this->join = new JoinConfigBuilder(); $this->sort = new SortConfigBuilder(); $this->randomValueGenerator = new NativePHPRandomValueGenerator(); $this->analyze = null; @@ -89,17 +106,20 @@ public function analyze(Analyze $analyze): self return $this; } - public function build(EntryFactory $entryFactory = new EntryFactory()): Config + public function build(): Config { $id = $this->id ??= 'flow-php-' . $this->randomValueGenerator->string(32); - $this->serializer ??= new FloeSerializer(); $this->optimizer ??= new Optimizer(new LimitOptimization(), new BatchSizeOptimization(batchSize: 1000)); + $this->hydrator ??= new AdaptiveRowHydrator(); + // the default serializer shares the context hydrator - one source of Row objects + $this->serializer ??= new FloeSerializer(hydrator: $this->hydrator); $serializer = $this->serializer; $optimizer = $this->optimizer; + $hydrator = $this->hydrator; $dataframeName = $this->name ?? 'flow_dataframe'; - $cacheConfig = $this->cache->build($this->fstab(), $this->telemetryConfig, $dataframeName); + $cacheConfig = $this->cache->build($this->fstab(), $serializer, $this->telemetryConfig, $dataframeName); return new Config( $id, @@ -111,12 +131,14 @@ public function build(EntryFactory $entryFactory = new EntryFactory()): Config new FilesystemStreams($this->fstab()), $optimizer, $this->putInputIntoRows, - $entryFactory, + $hydrator, $cacheConfig, $this->sort->build(), $this->analyze, $this->telemetryConfig ?? TelemetryConfig::default($this->getClock()), $this->grouping->build($this->fstab(), $cacheConfig->localFilesystemCacheDir), + $this->join->build($this->fstab(), $cacheConfig->localFilesystemCacheDir), + $this->extractorBatchSize, ); } @@ -134,19 +156,21 @@ public function cacheFilesystem(string $protocol): self return $this; } - /** - * @param int<1, max> $serializerBatchSize - */ - public function cacheSerializerBatchSize(int $serializerBatchSize): self + public function clock(ClockInterface $clocks): self { - $this->cache->serializerBatchSize($serializerBatchSize); + $this->clock = $clocks; return $this; } - public function clock(ClockInterface $clocks): self + /** + * Number of rows a streaming extractor buffers before hydrating them in one batch. + * + * @param int<1, max> $extractorBatchSize + */ + public function extractorBatchSize(int $extractorBatchSize): self { - $this->clock = $clocks; + $this->extractorBatchSize = $extractorBatchSize; return $this; } @@ -222,6 +246,16 @@ public function groupingCache(BucketsCache $cache): self return $this; } + /** + * @param Hydrator $hydrator + */ + public function hydrator(Hydrator $hydrator): self + { + $this->hydrator = $hydrator; + + return $this; + } + public function id(string $id): self { $this->id = $id; @@ -229,6 +263,33 @@ public function id(string $id): self return $this; } + /** + * @param int<1, max> $batchSize + */ + public function joinBatchSize(int $batchSize): self + { + $this->join->batchSize($batchSize); + + return $this; + } + + /** + * @param int<1, max> $bucketsCount + */ + public function joinBucketsCount(int $bucketsCount): self + { + $this->join->bucketsCount($bucketsCount); + + return $this; + } + + public function joinCache(BucketsCache $cache): self + { + $this->join->cache($cache); + + return $this; + } + public function mount(Filesystem $filesystem): self { $this->fstab()->mount($filesystem); diff --git a/src/core/etl/src/Flow/ETL/Config/Join/JoinConfig.php b/src/core/etl/src/Flow/ETL/Config/Join/JoinConfig.php new file mode 100644 index 0000000000..b04cdfa3e1 --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Config/Join/JoinConfig.php @@ -0,0 +1,20 @@ + $bucketsCount + * @param int<1, max> $batchSize + */ + public function __construct( + public BucketsCache $cache, + public int $bucketsCount = 64, + public int $batchSize = 1000, + ) {} +} diff --git a/src/core/etl/src/Flow/ETL/Config/Join/JoinConfigBuilder.php b/src/core/etl/src/Flow/ETL/Config/Join/JoinConfigBuilder.php new file mode 100644 index 0000000000..25269bdc61 --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Config/Join/JoinConfigBuilder.php @@ -0,0 +1,76 @@ + + */ + private int $batchSize = 1000; + + /** + * @var int<1, max> + */ + private int $bucketsCount = 64; + + private ?BucketsCache $cache = null; + + private string $filesystemMount = 'file'; + + /** + * @param int<1, max> $batchSize + */ + public function batchSize(int $batchSize): self + { + // @mago-ignore analysis:impossible-condition,redundant-comparison + if ($batchSize < 1) { + throw new InvalidArgumentException('Batch size must be at least 1'); + } + + $this->batchSize = $batchSize; + + return $this; + } + + public function build(FilesystemTable $filesystemTable, Path $localFilesystemCacheDir): JoinConfig + { + $cache = $this->cache ?? new FilesystemBucketsCache( + $filesystemTable->for($this->filesystemMount), + $localFilesystemCacheDir->suffix('/flow-php-join/'), + $this->batchSize, + ); + + return new JoinConfig($cache, $this->bucketsCount, $this->batchSize); + } + + /** + * @param int<1, max> $bucketsCount + */ + public function bucketsCount(int $bucketsCount): self + { + // @mago-ignore analysis:impossible-condition,redundant-comparison + if ($bucketsCount < 1) { + throw new InvalidArgumentException('Buckets count must be greater than 0'); + } + + $this->bucketsCount = $bucketsCount; + + return $this; + } + + public function cache(BucketsCache $cache): self + { + $this->cache = $cache; + + return $this; + } +} diff --git a/src/core/etl/src/Flow/ETL/DSL/functions.php b/src/core/etl/src/Flow/ETL/DSL/functions.php index 986a000903..998cb906f7 100644 --- a/src/core/etl/src/Flow/ETL/DSL/functions.php +++ b/src/core/etl/src/Flow/ETL/DSL/functions.php @@ -37,7 +37,6 @@ use Flow\ETL\ErrorHandler\ThrowError; use Flow\ETL\Exception\InvalidArgumentException; use Flow\ETL\Exception\RuntimeException; -use Flow\ETL\Exception\SchemaDefinitionNotFoundException; use Flow\ETL\Extractor; use Flow\ETL\Extractor\ArrayExtractor; use Flow\ETL\Extractor\BatchByExtractor; @@ -159,6 +158,7 @@ use Flow\ETL\Retry\RetryStrategy\AnyThrowable; use Flow\ETL\Retry\RetryStrategy\OnExceptionTypes; use Flow\ETL\Row; +use Flow\ETL\Row\AdaptiveRowHydrator; use Flow\ETL\Row\Entries; use Flow\ETL\Row\Entry; use Flow\ETL\Row\Entry\BooleanEntry; @@ -172,6 +172,7 @@ use Flow\ETL\Row\Entry\JsonEntry; use Flow\ETL\Row\Entry\ListEntry; use Flow\ETL\Row\Entry\MapEntry; +use Flow\ETL\Row\Entry\NullEntry; use Flow\ETL\Row\Entry\StringEntry; use Flow\ETL\Row\Entry\StructureEntry; use Flow\ETL\Row\Entry\TimeEntry; @@ -181,6 +182,8 @@ use Flow\ETL\Row\EntryFactory; use Flow\ETL\Row\EntryReference; use Flow\ETL\Row\Formatter\ASCIISchemaFormatter; +use Flow\ETL\Row\Hydrator; +use Flow\ETL\Row\RawRowValues; use Flow\ETL\Row\Reference; use Flow\ETL\Row\References; use Flow\ETL\Row\SortOrder; @@ -198,6 +201,7 @@ use Flow\ETL\Schema\Definition\JsonDefinition; use Flow\ETL\Schema\Definition\ListDefinition; use Flow\ETL\Schema\Definition\MapDefinition; +use Flow\ETL\Schema\Definition\NullDefinition; use Flow\ETL\Schema\Definition\StringDefinition; use Flow\ETL\Schema\Definition\StructureDefinition; use Flow\ETL\Schema\Definition\TimeDefinition; @@ -253,6 +257,8 @@ use Flow\Filesystem\Path; use Flow\Filesystem\Stream\Mode; use Flow\Filesystem\Telemetry\FilesystemTelemetryOptions; +use Flow\Floe\FloeSerializer; +use Flow\Serializer\Serializer; use Flow\Types\Type; use Flow\Types\Type\Logical\DateTimeType; use Flow\Types\Type\Logical\DateType; @@ -271,6 +277,7 @@ use Flow\Types\Type\Native\EnumType; use Flow\Types\Type\Native\FloatType; use Flow\Types\Type\Native\IntegerType; +use Flow\Types\Type\Native\NullType; use Flow\Types\Type\Native\StringType; use Flow\Types\Type\Native\UnionType; use Flow\Types\Type\TypeFactory; @@ -284,7 +291,6 @@ use function array_is_list; use function array_key_exists; use function array_map; -use function array_values; use function class_exists; use function enum_exists; use function Flow\Filesystem\DSL\path; @@ -409,20 +415,13 @@ function files(string|Path $directory): FilesExtractor return new FilesExtractor(is_string($directory) ? path($directory) : $directory); } -/** - * @param int<1, max> $serializer_batch_size - */ #[DocumentationDSL(module: Module::CORE, type: DSLType::DATA_FRAME)] function filesystem_cache( Path|string|null $cache_dir = null, Filesystem $filesystem = new NativeLocalFilesystem(), - int $serializer_batch_size = 1000, + Serializer $serializer = new FloeSerializer(), ): FilesystemCache { - return new FilesystemCache( - $filesystem, - is_string($cache_dir) ? path_real($cache_dir) : $cache_dir, - $serializer_batch_size, - ); + return new FilesystemCache($filesystem, is_string($cache_dir) ? path_real($cache_dir) : $cache_dir, $serializer); } /** @@ -837,21 +836,16 @@ function str_entry(string $name, ?string $value, ?Metadata $metadata = null): En } /** - * This functions is an alias for creating string entry from null. - * The main difference between using this function an simply str_entry with second argument null - * is that this function will also keep a note in the metadata that type might not be final. - * For example when we need to guess column type from rows because schema was not provided, - * and given column in the first row is null, it might still change once we get to the second row. - * That metadata is used to determine if string_entry was created from null or not. + * Creates an entry of the null type. Used when a column value is null and its final type is not yet known. + * When guessing a schema from rows, a null column stays a NullDefinition until a later row reveals a real type, + * at which point the schema merge turns it into that type made nullable. * - * By design flow assumes when guessing column type that null would be a string (the most flexible type). - * - * @return Entry + * @return Entry */ #[DocumentationDSL(module: Module::CORE, type: DSLType::ENTRY)] function null_entry(string $name, ?Metadata $metadata = null): Entry { - return StringEntry::fromNull($name, $metadata); + return new NullEntry($name, $metadata); } /** @@ -1641,7 +1635,7 @@ function number_format( * @return Entry */ #[DocumentationDSL(module: Module::CORE, type: DSLType::DATA_FRAME)] -function to_entry(string $name, mixed $data, EntryFactory $entryFactory): Entry +function to_entry(string $name, mixed $data, EntryFactory $entryFactory = new EntryFactory()): Entry { return $entryFactory->create($name, $data); } @@ -1654,46 +1648,25 @@ function to_entry(string $name, mixed $data, EntryFactory $entryFactory): Entry #[DocumentationDSL(module: Module::CORE, type: DSLType::DATA_FRAME)] function array_to_row( array $data, - EntryFactory $entryFactory, + Hydrator $hydrator = new AdaptiveRowHydrator(), array|Partitions $partitions = [], ?Schema $schema = null, ): Row { - $entries = []; + $map = []; // @mago-ignore analysis:mixed-assignment foreach ($data as $key => $value) { $name = is_int($key) ? 'e' . str_pad((string) $key, 2, '0', STR_PAD_LEFT) : $key; - - try { - $entries[$name] = $entryFactory->create($name, $value, $schema); - } catch (SchemaDefinitionNotFoundException $e) { - if ($schema === null) { - throw $e; - } - } + $map[$name] = $value; } foreach ($partitions as $partition) { - if (!array_key_exists($partition->name, $entries)) { - try { - $entries[$partition->name] = $entryFactory->create($partition->name, $partition->value, $schema); - } catch (SchemaDefinitionNotFoundException $e) { - if ($schema === null) { - throw $e; - } - } - } - } - - if ($schema !== null) { - foreach ($schema->definitions() as $definition) { - if (!array_key_exists($definition->entry()->name(), $entries)) { - $entries[$definition->entry()->name()] = str_entry($definition->entry()->name(), null); - } + if (!array_key_exists($partition->name, $map)) { + $map[$partition->name] = $partition->value; } } - return Row::create(...array_values($entries)); + return $hydrator->cast([new RawRowValues($map)], $schema)->first(); } /** @@ -1704,7 +1677,7 @@ function array_to_row( #[DocumentationDSL(module: Module::CORE, type: DSLType::DATA_FRAME)] function array_to_rows( array $data, - EntryFactory $entryFactory, + Hydrator $hydrator = new AdaptiveRowHydrator(), array|Partitions $partitions = [], ?Schema $schema = null, ): Rows { @@ -1721,19 +1694,30 @@ function array_to_rows( } } - if (!$isRows) { - return Rows::partitioned([array_to_row($data, $entryFactory, $partitions, $schema)], $partitions); - } - - $rows = []; + $rawRows = $isRows ? $data : [$data]; + $maps = []; // @mago-ignore analysis:mixed-assignment - foreach ($data as $row) { + foreach ($rawRows as $row) { $row = type_array()->assert($row); - $rows[] = array_to_row($row, $entryFactory, $partitions, $schema); + $map = []; + + // @mago-ignore analysis:mixed-assignment + foreach ($row as $key => $value) { + $name = is_int($key) ? 'e' . str_pad((string) $key, 2, '0', STR_PAD_LEFT) : $key; + $map[$name] = $value; + } + + foreach ($partitions as $partition) { + if (!array_key_exists($partition->name, $map)) { + $map[$partition->name] = $partition->value; + } + } + + $maps[] = new RawRowValues($map); } - return Rows::partitioned($rows, $partitions); + return Rows::partitioned($hydrator->cast($maps, $schema)->all(), $partitions); } #[DocumentationDSL(module: Module::CORE, type: DSLType::WINDOW_FUNCTION)] @@ -2015,13 +1999,9 @@ function enum_schema(string $name, string $type, bool $nullable = false, ?Metada } #[DocumentationDSL(module: Module::CORE, type: DSLType::SCHEMA)] -function null_schema(string $name, ?Metadata $metadata = null): StringDefinition +function null_schema(string $name, ?Metadata $metadata = null): NullDefinition { - return new StringDefinition( - $name, - true, - Metadata::fromArray([Metadata::FROM_NULL => true])->merge($metadata ?? Metadata::empty()), - ); + return new NullDefinition($name, $metadata); } #[DocumentationDSL(module: Module::CORE, type: DSLType::SCHEMA)] @@ -2177,6 +2157,7 @@ function definition_from_type( $type instanceof HTMLElementType => new HTMLElementDefinition($ref, $nullable, $metadata), $type instanceof XMLType => new XMLDefinition($ref, $nullable, $metadata), $type instanceof XMLElementType => new XMLElementDefinition($ref, $nullable, $metadata), + $type instanceof NullType => new NullDefinition($ref, $metadata), // @mago-expect linter:no-fully-qualified-global-function default => throw new RuntimeException(\sprintf('Cannot create Definition from type: %s', $type::class)), }; diff --git a/src/core/etl/src/Flow/ETL/Extractor/ArrayExtractor.php b/src/core/etl/src/Flow/ETL/Extractor/ArrayExtractor.php index 888b89f1d4..0049eae94f 100644 --- a/src/core/etl/src/Flow/ETL/Extractor/ArrayExtractor.php +++ b/src/core/etl/src/Flow/ETL/Extractor/ArrayExtractor.php @@ -28,7 +28,7 @@ public function __construct( public function extract(FlowContext $context): Generator { foreach ($this->dataset as $row) { - $signal = yield array_to_rows([$row], $context->entryFactory(), [], $this->schema); + $signal = yield array_to_rows([$row], $context->hydrator(), [], $this->schema); if ($signal === Signal::STOP) { return; diff --git a/src/core/etl/src/Flow/ETL/Extractor/CacheExtractor.php b/src/core/etl/src/Flow/ETL/Extractor/CacheExtractor.php index b67cc9bf66..d111a6563a 100644 --- a/src/core/etl/src/Flow/ETL/Extractor/CacheExtractor.php +++ b/src/core/etl/src/Flow/ETL/Extractor/CacheExtractor.php @@ -39,12 +39,10 @@ public function extract(FlowContext $context): Generator $index = CacheIndex::fromRows($this->id, $context->cache()->get($this->id)); foreach ($index->values() as $cacheKey) { - foreach ($context->cache()->read($cacheKey) as $rows) { - $signal = yield $rows; + $signal = yield $context->cache()->get($cacheKey); - if ($signal === Signal::STOP) { - return; - } + if ($signal === Signal::STOP) { + return; } if ($this->clear) { diff --git a/src/core/etl/src/Flow/ETL/Extractor/FilesExtractor.php b/src/core/etl/src/Flow/ETL/Extractor/FilesExtractor.php index 9f4b43e13e..c32b4e626a 100644 --- a/src/core/etl/src/Flow/ETL/Extractor/FilesExtractor.php +++ b/src/core/etl/src/Flow/ETL/Extractor/FilesExtractor.php @@ -34,7 +34,7 @@ public function extract(FlowContext $context): Generator 'is_file' => $fileStatus->isFile(), 'is_dir' => $fileStatus->isDirectory(), 'extension' => $fileStatus->path->extension(), - ], $context->entryFactory()); + ], $context->hydrator()); $this->incrementReturnedRows(); diff --git a/src/core/etl/src/Flow/ETL/Extractor/MemoryExtractor.php b/src/core/etl/src/Flow/ETL/Extractor/MemoryExtractor.php index 461a43a1cb..a841db1b2a 100644 --- a/src/core/etl/src/Flow/ETL/Extractor/MemoryExtractor.php +++ b/src/core/etl/src/Flow/ETL/Extractor/MemoryExtractor.php @@ -26,7 +26,7 @@ public function __construct( public function extract(FlowContext $context): Generator { foreach ($this->memory->dump() as $row) { - $signal = yield array_to_rows([$row], $context->entryFactory()); + $signal = yield array_to_rows([$row], $context->hydrator()); if ($signal === Signal::STOP) { return; diff --git a/src/core/etl/src/Flow/ETL/FlowContext.php b/src/core/etl/src/Flow/ETL/FlowContext.php index deb60f4d7e..e695a2c724 100644 --- a/src/core/etl/src/Flow/ETL/FlowContext.php +++ b/src/core/etl/src/Flow/ETL/FlowContext.php @@ -11,6 +11,7 @@ use Flow\ETL\Function\ExecutionMode; use Flow\ETL\Function\Functions; use Flow\ETL\Row\EntryFactory; +use Flow\ETL\Row\Hydrator; use Flow\Filesystem\Filesystem; use Flow\Filesystem\Path; @@ -63,6 +64,14 @@ public function functions(): Functions return $this->functions; } + /** + * @return Hydrator + */ + public function hydrator(): Hydrator + { + return $this->config->hydrator(); + } + public function setErrorHandler(ErrorHandler $handler): self { $this->errorHandler = $handler; diff --git a/src/core/etl/src/Flow/ETL/Function/CallUserFunc.php b/src/core/etl/src/Flow/ETL/Function/CallUserFunc.php index c3e8c43de2..ac7e2b7dd7 100644 --- a/src/core/etl/src/Flow/ETL/Function/CallUserFunc.php +++ b/src/core/etl/src/Flow/ETL/Function/CallUserFunc.php @@ -51,7 +51,11 @@ public function eval(Row $row, FlowContext $context): mixed } if ($this->returnType) { - return new ScalarResult(call_user_func($callable, ...$parameters), $this->returnType); + // The callable's output may not match the declared type - coerce it before trusting the ScalarResult. + // @mago-ignore analysis:mixed-assignment + $result = call_user_func($callable, ...$parameters); + + return new ScalarResult($result === null ? null : $this->returnType->cast($result), $this->returnType); } return call_user_func($callable, ...$parameters); diff --git a/src/core/etl/src/Flow/ETL/Function/Collect.php b/src/core/etl/src/Flow/ETL/Function/Collect.php index 12209f5710..c5f69e2518 100644 --- a/src/core/etl/src/Flow/ETL/Function/Collect.php +++ b/src/core/etl/src/Flow/ETL/Function/Collect.php @@ -12,7 +12,6 @@ use Flow\ETL\Row\Reference; use function current; -use function Flow\ETL\DSL\to_entry; final class Collect implements AggregatingFunction { @@ -50,6 +49,6 @@ public function result(EntryFactory $entryFactory): Entry $this->ref->as($this->ref->name() . '_collection'); } - return to_entry($this->ref->name(), $this->collection, $entryFactory); + return $entryFactory->create($this->ref->name(), $this->collection); } } diff --git a/src/core/etl/src/Flow/ETL/Function/CollectUnique.php b/src/core/etl/src/Flow/ETL/Function/CollectUnique.php index 3f87b0ff09..6bb887570b 100644 --- a/src/core/etl/src/Flow/ETL/Function/CollectUnique.php +++ b/src/core/etl/src/Flow/ETL/Function/CollectUnique.php @@ -12,7 +12,6 @@ use Flow\ETL\Row\Reference; use function current; -use function Flow\ETL\DSL\to_entry; use function in_array; final class CollectUnique implements AggregatingFunction @@ -58,6 +57,6 @@ public function result(EntryFactory $entryFactory): Entry $this->ref->as($this->ref->name() . '_collection_unique'); } - return to_entry($this->ref->name(), $this->collection, $entryFactory); + return $entryFactory->create($this->ref->name(), $this->collection); } } diff --git a/src/core/etl/src/Flow/ETL/Function/OnEach.php b/src/core/etl/src/Flow/ETL/Function/OnEach.php index b4c0f92e4a..23d6b16801 100644 --- a/src/core/etl/src/Flow/ETL/Function/OnEach.php +++ b/src/core/etl/src/Flow/ETL/Function/OnEach.php @@ -34,7 +34,7 @@ public function eval(Row $row, FlowContext $context): mixed $output = []; - $entryFactory = $context->entryFactory(); + $hydrator = $context->hydrator(); // @mago-ignore analysis:mixed-assignment foreach ($value as $key => $item) { @@ -42,7 +42,7 @@ public function eval(Row $row, FlowContext $context): mixed try { $output[$key] = (new Parameter($this->function))->eval(array_to_row([ 'element' => $item, - ], $entryFactory), $context); + ], $hydrator), $context); } catch (InvalidArgumentException) { $output[$key] = null; } @@ -50,7 +50,7 @@ public function eval(Row $row, FlowContext $context): mixed try { $output[] = (new Parameter($this->function))->eval(array_to_row([ 'element' => $item, - ], $entryFactory), $context); + ], $hydrator), $context); } catch (InvalidArgumentException) { $output[] = null; } diff --git a/src/core/etl/src/Flow/ETL/Function/Parameter.php b/src/core/etl/src/Flow/ETL/Function/Parameter.php index d77f6a5e47..592c21e576 100644 --- a/src/core/etl/src/Flow/ETL/Function/Parameter.php +++ b/src/core/etl/src/Flow/ETL/Function/Parameter.php @@ -9,7 +9,6 @@ use Flow\ETL\Row; use Flow\ETL\Row\Entry; use Flow\ETL\Row\Reference; -use Flow\ETL\Schema\Metadata; use Flow\Types\Exception\InvalidTypeException; use Flow\Types\Type; use Flow\Types\Value\Json; @@ -21,7 +20,6 @@ use function Flow\Types\DSL\type_float; use function Flow\Types\DSL\type_instance_of; use function Flow\Types\DSL\type_integer; -use function Flow\Types\DSL\type_null; use function Flow\Types\DSL\type_object; use function Flow\Types\DSL\type_string; @@ -222,10 +220,6 @@ public function asString(Row $row, FlowContext $context, ?string $default = null public function asType(Row $row, FlowContext $context): Type { if ($this->function instanceof Reference) { - if ($row->get($this->function)->definition()->metadata()->has(Metadata::FROM_NULL)) { - return type_null(); - } - return $row->get($this->function)->type(); } diff --git a/src/core/etl/src/Flow/ETL/GroupBy.php b/src/core/etl/src/Flow/ETL/GroupBy.php index 8ae5424a18..950d2bf575 100644 --- a/src/core/etl/src/Flow/ETL/GroupBy.php +++ b/src/core/etl/src/Flow/ETL/GroupBy.php @@ -194,13 +194,13 @@ public function pivotResult(Generator $rows, FlowContext $context): Generator $buffer[] = $row; if (count($buffer) >= self::RESULT_BATCH_SIZE) { - yield array_to_rows($buffer, $context->entryFactory()); + yield array_to_rows($buffer, $context->hydrator()); $buffer = []; } } if ($buffer !== []) { - yield array_to_rows($buffer, $context->entryFactory()); + yield array_to_rows($buffer, $context->hydrator()); } } } diff --git a/src/core/etl/src/Flow/ETL/Join/BucketedHashJoin.php b/src/core/etl/src/Flow/ETL/Join/BucketedHashJoin.php new file mode 100644 index 0000000000..23c3b7cf56 --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/BucketedHashJoin.php @@ -0,0 +1,174 @@ + $bucketsCount + * @param int<1, max> $batchSize + */ + public function __construct( + private DataFrame $right, + private Expression $expression, + private Join $type, + private BucketsCache $cache, + private int $bucketsCount = 64, + private int $batchSize = 1000, + ) { + // @mago-ignore analysis:invalid-operand + // @mago-ignore analysis:impossible-condition,redundant-comparison + if ($this->bucketsCount < 1) { + throw new InvalidArgumentException('Buckets count must be greater than 0, given: ' . $this->bucketsCount); + } + + // @mago-ignore analysis:invalid-operand + // @mago-ignore analysis:impossible-condition,redundant-comparison + if ($this->batchSize < 1) { + throw new InvalidArgumentException('Batch size must be greater than 0, given: ' . $this->batchSize); + } + } + + /** + * @param Generator $left + * + * @return Generator + */ + public function joinGenerator(Generator $left, FlowContext $context): Generator + { + $joiner = new Joiner($this->expression, $this->type, $context->entryFactory(), $this->batchSize); + $resident = $this->cache instanceof ResidentBucketsCache; + $runId = bin2hex(random_bytes(8)); + + $rightSpiller = new BucketSpiller($this->cache, 'join-' . $runId . '-right-bucket-', $this->batchSize); + $leftSpiller = new BucketSpiller($this->cache, 'join-' . $runId . '-left-bucket-', $this->batchSize); + + try { + $nullRightBuilder = $this->type === Join::left ? new NullRowBuilder($context->entryFactory()) : null; + + foreach ($this->right->get() as $batch) { + foreach ($batch as $row) { + $nullRightBuilder?->collect($row); + // a resident cache is consumed as one bucket, hashing rows into buckets would be wasted work + $rightSpiller->add($resident ? 0 : $this->bucket($joiner->keys()->rightHash($row)), $row); + } + } + + $rightSpiller->flush(); + $rightBuckets = $rightSpiller->bucketIds(); + $nullRightRow = $nullRightBuilder?->row(); + + if ($resident) { + yield from $joiner->join($left, $this->bucketRows($rightBuckets[0] ?? null), null, $nullRightRow); + + return; + } + + $nullLeftBuilder = $this->type === Join::right ? new NullRowBuilder($context->entryFactory()) : null; + + foreach ($left as $batch) { + foreach ($batch as $row) { + $nullLeftBuilder?->collect($row); + $leftSpiller->add($this->bucket($joiner->keys()->leftHash($row)), $row); + } + } + + $leftSpiller->flush(); + $leftBuckets = $leftSpiller->bucketIds(); + + $buckets = match ($this->type) { + Join::inner => array_keys(array_intersect_key($leftBuckets, $rightBuckets)), + Join::left, Join::left_anti => array_keys($leftBuckets), + Join::right => array_keys($rightBuckets), + }; + + $nullLeftRow = $nullLeftBuilder?->row(); + + foreach ($buckets as $bucket) { + $joinedBatches = $joiner->join( + $this->bucketRows($leftBuckets[$bucket] ?? null), + $this->bucketRows($rightBuckets[$bucket] ?? null), + $nullLeftRow, + $nullRightRow, + ); + + // re-key batches, yield from would restart keys at 0 for every bucket + foreach ($joinedBatches as $joinedBatch) { + yield $joinedBatch; + } + } + } finally { + foreach ([ + ...array_values($leftSpiller->bucketIds()), + ...array_values($rightSpiller->bucketIds()), + ] as $bucketId) { + try { + $this->cache->remove($bucketId); + } catch (Throwable) { + } + } + } + } + + private function bucket(string $hash): int + { + // JoinKeys hashes are xxh128 hex strings, reuse their first 8 chars instead of hashing again + return (int) hexdec(substr($hash, 0, 8)) % $this->bucketsCount; + } + + /** + * @return Generator + */ + private function bucketRows(?string $bucketId): Generator + { + if ($bucketId === null) { + return; + } + + $buffer = []; + + foreach ($this->cache->get($bucketId) as $row) { + $buffer[] = $row; + + if (count($buffer) >= $this->batchSize) { + yield new Rows(...$buffer); + $buffer = []; + } + } + + if ($buffer !== []) { + yield new Rows(...$buffer); + } + } +} diff --git a/src/core/etl/src/Flow/ETL/Join/Comparison/All.php b/src/core/etl/src/Flow/ETL/Join/Comparison/All.php index 728982b76c..05e7224f60 100644 --- a/src/core/etl/src/Flow/ETL/Join/Comparison/All.php +++ b/src/core/etl/src/Flow/ETL/Join/Comparison/All.php @@ -34,6 +34,14 @@ public function compare(Row $left, Row $right): bool return true; } + /** + * @return array + */ + public function comparisons(): array + { + return $this->comparisons; + } + /** * @return array */ diff --git a/src/core/etl/src/Flow/ETL/Join/Comparison/Any.php b/src/core/etl/src/Flow/ETL/Join/Comparison/Any.php index 9dfa2ed9fa..7584490e84 100644 --- a/src/core/etl/src/Flow/ETL/Join/Comparison/Any.php +++ b/src/core/etl/src/Flow/ETL/Join/Comparison/Any.php @@ -34,6 +34,14 @@ public function compare(Row $left, Row $right): bool return false; } + /** + * @return array + */ + public function comparisons(): array + { + return $this->comparisons; + } + /** * @return array */ diff --git a/src/core/etl/src/Flow/ETL/Join/Comparison/Equal.php b/src/core/etl/src/Flow/ETL/Join/Comparison/Equal.php index 1926c75695..31e0dfc5de 100644 --- a/src/core/etl/src/Flow/ETL/Join/Comparison/Equal.php +++ b/src/core/etl/src/Flow/ETL/Join/Comparison/Equal.php @@ -4,16 +4,16 @@ namespace Flow\ETL\Join\Comparison; -use DateInterval; -use DateTimeInterface; use Flow\ETL\Join\Comparison; use Flow\ETL\Row; use Flow\ETL\Row\EntryReference; use Flow\ETL\Row\Reference; +use Flow\Types\Value\Uuid; use function is_array; use function is_bool; use function is_numeric; +use function is_object; use function is_string; final readonly class Equal implements Comparison @@ -44,16 +44,16 @@ public function compare(Row $left, Row $right): bool return $leftValue === $rightValue; } - if ($leftValue instanceof DateTimeInterface && $rightValue instanceof DateTimeInterface) { - return $leftValue == $rightValue; + if (is_array($leftValue) && is_array($rightValue)) { + return $leftValue === $rightValue; } - if ($leftValue instanceof DateInterval && $rightValue instanceof DateInterval) { - return $leftValue == $rightValue; - } + if (is_object($leftValue) && is_object($rightValue)) { + if ($leftValue instanceof Uuid && $rightValue instanceof Uuid) { + return $leftValue->isEqual($rightValue); + } - if (is_array($leftValue) && is_array($rightValue)) { - return $leftValue === $rightValue; + return $leftValue == $rightValue; } return false; diff --git a/src/core/etl/src/Flow/ETL/Join/Expression.php b/src/core/etl/src/Flow/ETL/Join/Expression.php index 1498315eb8..83f1a3fd58 100644 --- a/src/core/etl/src/Flow/ETL/Join/Expression.php +++ b/src/core/etl/src/Flow/ETL/Join/Expression.php @@ -68,6 +68,11 @@ public static function on(array|Comparison $comparison, string $joinPrefix = '') return new self($comparison, $joinPrefix); } + public function comparison(): Comparison + { + return $this->comparison; + } + public function dropDuplicateLeftEntries(Row $left): Row { if ($this->joinPrefix !== '') { diff --git a/src/core/etl/src/Flow/ETL/Join/HashJoin/BucketSpiller.php b/src/core/etl/src/Flow/ETL/Join/HashJoin/BucketSpiller.php new file mode 100644 index 0000000000..9f30a9898b --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/HashJoin/BucketSpiller.php @@ -0,0 +1,68 @@ + + */ + private array $bucketIds = []; + + /** + * @var array> + */ + private array $pending = []; + + private int $pendingCount = 0; + + /** + * @param int<1, max> $batchSize + */ + public function __construct( + private readonly BucketsCache $cache, + private readonly string $bucketIdPrefix, + private readonly int $batchSize, + ) {} + + public function add(int $bucket, Row $row): void + { + $this->pending[$bucket][] = $row; + $this->pendingCount++; + + if ($this->pendingCount >= $this->batchSize) { + $this->flush(); + } + } + + /** + * @return array + */ + public function bucketIds(): array + { + return $this->bucketIds; + } + + public function flush(): void + { + foreach ($this->pending as $bucket => $rows) { + if ($rows !== []) { + $this->cache->append($this->bucketId($bucket), new Rows(...$rows)); + } + } + + $this->pending = []; + $this->pendingCount = 0; + } + + private function bucketId(int $bucket): string + { + return $this->bucketIds[$bucket] ??= $this->bucketIdPrefix . $bucket; + } +} diff --git a/src/core/etl/src/Flow/ETL/Join/HashJoin/EqualityJoinKeys.php b/src/core/etl/src/Flow/ETL/Join/HashJoin/EqualityJoinKeys.php new file mode 100644 index 0000000000..0978b3f5a0 --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/HashJoin/EqualityJoinKeys.php @@ -0,0 +1,144 @@ + $leftRefs + * @param array $rightRefs + */ + private function __construct( + private array $leftRefs, + private array $rightRefs, + ) {} + + public static function fromComparison(Comparison $comparison): ?self + { + $pairs = self::pairs($comparison); + + if ($pairs === null) { + return null; + } + + $uniquePairs = []; + + foreach ($pairs as $pair) { + $uniquePairs[$pair[0]->name() . "\x00" . $pair[1]->name()] = $pair; + } + + $leftRefs = []; + $rightRefs = []; + + foreach ($uniquePairs as [$leftRef, $rightRef]) { + $leftRefs[] = $leftRef; + $rightRefs[] = $rightRef; + } + + return new self($leftRefs, $rightRefs); + } + + public static function normalize(mixed $value): string + { + if ($value === null) { + return 'null'; + } + + if (is_bool($value)) { + return 'b:' . ($value ? '1' : '0'); + } + + if (is_numeric($value)) { + $float = (float) $value; + + // -0.0 == 0.0 but casts to the string "-0" + return 'n:' . ($float === 0.0 ? '0' : (string) $float); + } + + if (is_string($value)) { + return 's:' . $value; + } + + if ($value instanceof DateTimeInterface) { + return 'd:' . $value->format('U.u'); + } + + if (is_object($value)) { + return $value instanceof Stringable + ? 'o:' . $value::class . ':' . $value->__toString() + : 'o:' . serialize($value); + } + + return 'a:' . serialize($value); + } + + public function leftHash(Row $row): string + { + return $this->hash($row, $this->leftRefs); + } + + public function rightHash(Row $row): string + { + return $this->hash($row, $this->rightRefs); + } + + /** + * @param array $refs + */ + private function hash(Row $row, array $refs): string + { + $parts = []; + + foreach ($refs as $ref) { + $parts[] = self::normalize($row->valueOf($ref)); + } + + return NativePHPHash::xxh128(serialize($parts)); + } + + /** + * @return null|list + */ + private static function pairs(Comparison $comparison): ?array + { + if ($comparison instanceof Equal || $comparison instanceof Identical) { + return [[$comparison->left()[0], $comparison->right()[0]]]; + } + + if ($comparison instanceof All) { + $pairs = []; + + foreach ($comparison->comparisons() as $child) { + $childPairs = self::pairs($child); + + if ($childPairs === null) { + return null; + } + + $pairs = [...$pairs, ...$childPairs]; + } + + return $pairs; + } + + return null; + } +} diff --git a/src/core/etl/src/Flow/ETL/Join/HashJoin/HashTable.php b/src/core/etl/src/Flow/ETL/Join/HashJoin/HashTable.php new file mode 100644 index 0000000000..27047bef1d --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/HashJoin/HashTable.php @@ -0,0 +1,86 @@ +> + */ + private array $buckets = []; + + /** + * @var list + */ + private array $rows = []; + + /** + * @var array + */ + private array $unmatched = []; + + public function __construct( + private readonly JoinKeys $keys, + private readonly bool $trackUnmatched = false, + ) {} + + public function add(Row $row): void + { + $index = count($this->rows); + $this->rows[] = $row; + $this->buckets[$this->keys->rightHash($row)][] = $index; + + if ($this->trackUnmatched) { + $this->unmatched[$index] = true; + } + } + + /** + * @return array + */ + public function candidatesFor(Row $leftRow): array + { + $hash = $this->keys->leftHash($leftRow); + + if (!array_key_exists($hash, $this->buckets)) { + return []; + } + + $candidates = []; + + foreach ($this->buckets[$hash] as $index) { + $candidates[$index] = $this->rows[$index]; + } + + return $candidates; + } + + public function count(): int + { + return count($this->rows); + } + + public function matched(int $index): void + { + unset($this->unmatched[$index]); + } + + /** + * @return Generator + */ + public function unmatchedRows(): Generator + { + foreach (array_keys($this->unmatched) as $index) { + yield $this->rows[$index]; + } + } +} diff --git a/src/core/etl/src/Flow/ETL/Join/HashJoin/JoinKeys.php b/src/core/etl/src/Flow/ETL/Join/HashJoin/JoinKeys.php new file mode 100644 index 0000000000..5241555ade --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/HashJoin/JoinKeys.php @@ -0,0 +1,14 @@ + $batchSize - size of output batches emitted for unmatched right side rows + */ + public function __construct( + private readonly Expression $expression, + private readonly Join $type, + private readonly EntryFactory $entryFactory = new EntryFactory(), + private readonly int $batchSize = 1000, + ) { + // @mago-ignore analysis:invalid-operand + // @mago-ignore analysis:impossible-condition,redundant-comparison + if ($this->batchSize < 1) { + throw new InvalidArgumentException('Batch size must be greater than 0, given: ' . $this->batchSize); + } + + $this->keys = EqualityJoinKeys::fromComparison($expression->comparison()) ?? new SingleBucketJoinKeys(); + + $duplicates = []; + + if ($expression->prefix() === '') { + foreach ($expression->left() as $leftRef) { + foreach ($expression->right() as $rightRef) { + if ($leftRef->name() === $rightRef->name()) { + $duplicates[] = $leftRef->name(); + + continue 2; + } + } + } + } + + $this->merger = new RowMerger( + $expression->prefix(), + $this->type === Join::right ? $duplicates : [], + $this->type === Join::right ? [] : $duplicates, + ); + } + + /** + * @param Generator $left + * @param Generator $right + * @param null|Row $nullLeftRow - pre-computed row used to null-pad unmatched right rows, collected from left rows when null + * @param null|Row $nullRightRow - pre-computed row used to null-pad unmatched left rows, collected from right rows when null + * + * @throws DuplicatedEntriesException + * + * @return Generator + */ + public function join( + Generator $left, + Generator $right, + ?Row $nullLeftRow = null, + ?Row $nullRightRow = null, + ): Generator { + $hashTable = new HashTable($this->keys, trackUnmatched: $this->type === Join::right); + + $nullRightBuilder = + $this->type === Join::left && $nullRightRow === null ? new NullRowBuilder($this->entryFactory) : null; + + foreach ($right as $batch) { + foreach ($batch as $row) { + $hashTable->add($row); + $nullRightBuilder?->collect($row); + } + } + + $nullRightRow ??= $nullRightBuilder?->row(); + + $nullLeftBuilder = + $this->type === Join::right && $nullLeftRow === null ? new NullRowBuilder($this->entryFactory) : null; + + foreach ($left as $batch) { + $joined = []; + + foreach ($batch as $leftRow) { + $nullLeftBuilder?->collect($leftRow); + + $matched = false; + + foreach ($hashTable->candidatesFor($leftRow) as $index => $rightRow) { + if (!$this->expression->meet($leftRow, $rightRow)) { + continue; + } + + $matched = true; + + if ($this->type === Join::left_anti) { + break; + } + + if ($this->type === Join::right) { + $hashTable->matched($index); + } + + $joined[] = $this->merge($leftRow, $rightRow); + } + + if (!$matched && $this->type === Join::left) { + /** @var Row $nullRightRow */ + $joined[] = $this->merge($leftRow, $nullRightRow); + } + + if (!$matched && $this->type === Join::left_anti) { + $joined[] = $leftRow; + } + } + + if ($joined !== []) { + yield new Rows(...$joined); + } + } + + if ($this->type === Join::right) { + $nullLeftRow ??= $nullLeftBuilder?->row() ?? new Row(Entries::recreate([])); + $joined = []; + + foreach ($hashTable->unmatchedRows() as $rightRow) { + $joined[] = $this->merge($nullLeftRow, $rightRow); + + if (count($joined) >= $this->batchSize) { + yield new Rows(...$joined); + $joined = []; + } + } + + if ($joined !== []) { + yield new Rows(...$joined); + } + } + } + + public function keys(): JoinKeys + { + return $this->keys; + } + + private function merge(Row $left, Row $right): Row + { + try { + return $this->merger->merge($left, $right); + } catch (DuplicatedEntriesException $e) { + throw new DuplicatedEntriesException( + $e->getMessage() . ' try to use a different join prefix than: "' . $this->expression->prefix() . '"', + (int) $e->getCode(), + $e, + ); + } + } +} diff --git a/src/core/etl/src/Flow/ETL/Join/HashJoin/NullRowBuilder.php b/src/core/etl/src/Flow/ETL/Join/HashJoin/NullRowBuilder.php new file mode 100644 index 0000000000..7874b1847e --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/HashJoin/NullRowBuilder.php @@ -0,0 +1,46 @@ +> + */ + private array $entries = []; + + public function __construct( + private readonly EntryFactory $entryFactory, + ) {} + + public function collect(Row $row): void + { + foreach ($row->entries()->all() as $entry) { + $name = $entry->name(); + + if (!array_key_exists($name, $this->entries)) { + $nullable = $entry->definition()->makeNullable(); + $this->entries[$name] = $this->entryFactory->create( + $name, + null, + $nullable->type(), + $nullable->metadata(), + ); + } + } + } + + public function row(): Row + { + return new Row(Entries::recreate($this->entries)); + } +} diff --git a/src/core/etl/src/Flow/ETL/Join/HashJoin/RowMerger.php b/src/core/etl/src/Flow/ETL/Join/HashJoin/RowMerger.php new file mode 100644 index 0000000000..93e804cc5e --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/HashJoin/RowMerger.php @@ -0,0 +1,188 @@ + + */ + private readonly array $dropLeft; + + /** + * @var array + */ + private readonly array $dropRight; + + private readonly Instantiators $instantiators; + + /** + * @var array, array, array}> + */ + private array $plans = []; + + /** + * @var array, Definition}> + */ + private array $renamedDefinitions = []; + + /** + * @param array $dropLeft - left side entries skipped in the output (duplicated join columns) + * @param array $dropRight - right side entries skipped in the output (duplicated join columns) + */ + public function __construct( + private readonly string $prefix = '', + array $dropLeft = [], + array $dropRight = [], + ) { + $dropLeftSet = []; + + foreach ($dropLeft as $name) { + $dropLeftSet[$name] = true; + } + + $dropRightSet = []; + + foreach ($dropRight as $name) { + $dropRightSet[$name] = true; + } + + $this->dropLeft = $dropLeftSet; + $this->dropRight = $dropRightSet; + $this->instantiators = new Instantiators(); + } + + /** + * @throws DuplicatedEntriesException + */ + public function merge(Row $left, Row $right): Row + { + $leftEntries = $left->entries(); + $rightEntries = $right->entries(); + + $planKey = implode("\x00", $leftEntries->names()) . "\x01" . implode("\x00", $rightEntries->names()); + + [$keepLeft, $keepRight, $renames] = + $this->plans[$planKey] ??= $this->plan($leftEntries->names(), $rightEntries->names()); + + $entries = []; + + foreach ($leftEntries->all() as $entry) { + $name = $entry->name(); + + if (array_key_exists($name, $keepLeft)) { + $entries[$name] = $entry; + } + } + + foreach ($rightEntries->all() as $entry) { + $name = $entry->name(); + + if (!array_key_exists($name, $keepRight)) { + continue; + } + + if (array_key_exists($name, $renames)) { + $entries[$renames[$name]] = $this->rename($entry, $renames[$name]); + } else { + $entries[$name] = $entry; + } + } + + return new Row(Entries::recreate($entries)); + } + + /** + * Entry::rename() runs the full entry constructor and rebuilds the definition for every call, + * this path instantiates the renamed entry without the constructor and reuses the renamed + * definition as long as the source rows share the same definition instance per column. + * + * @param Entry $entry + * + * @return Entry + */ + private function rename(Entry $entry, string $newName): Entry + { + $definition = $entry->definition(); + $cached = $this->renamedDefinitions[$newName] ?? null; + + if ($cached === null || $cached[0] !== $definition) { + $cached = [$definition, $definition->rename($newName)]; + $this->renamedDefinitions[$newName] = $cached; + } + + return $this->instantiators->for($entry::class)->instantiate($newName, $entry->value(), $cached[1]); + } + + /** + * @param array $leftNames + * @param array $rightNames + * + * @throws DuplicatedEntriesException + * + * @return array{array, array, array} + */ + private function plan(array $leftNames, array $rightNames): array + { + $keepLeft = []; + $outputNames = []; + + foreach ($leftNames as $name) { + if (array_key_exists($name, $this->dropLeft)) { + continue; + } + + $keepLeft[$name] = true; + $outputNames[$name] = true; + } + + $keepRight = []; + $renames = []; + $rightOutputNames = []; + $collision = false; + + foreach ($rightNames as $name) { + if (array_key_exists($name, $this->dropRight)) { + continue; + } + + $keepRight[$name] = true; + $outputName = $this->prefix === '' ? $name : $this->prefix . $name; + + if ($this->prefix !== '') { + $renames[$name] = $outputName; + } + + if (array_key_exists($outputName, $outputNames)) { + $collision = true; + } + + $outputNames[$outputName] = true; + $rightOutputNames[] = $outputName; + } + + if ($collision) { + throw new DuplicatedEntriesException(sprintf( + 'Merged entries names must be unique, given: [%s] + [%s]', + implode(', ', array_keys($keepLeft)), + implode(', ', $rightOutputNames), + )); + } + + return [$keepLeft, $keepRight, $renames]; + } +} diff --git a/src/core/etl/src/Flow/ETL/Join/HashJoin/SingleBucketJoinKeys.php b/src/core/etl/src/Flow/ETL/Join/HashJoin/SingleBucketJoinKeys.php new file mode 100644 index 0000000000..81f657cf1d --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Join/HashJoin/SingleBucketJoinKeys.php @@ -0,0 +1,20 @@ + - */ - private array $rowsArray; - - /** - * @var array - */ - private array $rowsMatches = []; - - /** - * @param string $hash - hash of the bucket calculated from join expression columns and row - */ - public function __construct( - public readonly string $hash, - ) { - $this->rowsArray = []; - $this->rows = null; - } - - public function add(Row $row): void - { - $this->rowsArray[$rowHash = $row->hash()] = $row; - $this->rowsMatches[$rowHash] = 0; - $this->rows = null; - } - - public function count(): int - { - return count($this->rowsArray); - } - - public function findMatch(Row $row, Expression $expression): ?Row - { - foreach ($this->rowsArray as $hash => $bucketRow) { - if ($expression->meet($row, $bucketRow)) { - $this->rowsMatches[$hash]++; - - return $bucketRow; - } - } - - return null; - } - - public function rows(): Rows - { - if ($this->rows === null) { - $this->rows = rows(...$this->rowsArray); - } - - return $this->rows; - } - - /** - * @return array - */ - public function unmatchedRows(): array - { - $unmatchedRows = []; - - foreach ($this->rowsArray as $hash => $bucketRow) { - if ($this->rowsMatches[$hash] === 0) { - $unmatchedRows[$hash] = $bucketRow; - } - } - - return $unmatchedRows; - } -} diff --git a/src/core/etl/src/Flow/ETL/Processor/HashJoin/HashTable.php b/src/core/etl/src/Flow/ETL/Processor/HashJoin/HashTable.php deleted file mode 100644 index 7534c90411..0000000000 --- a/src/core/etl/src/Flow/ETL/Processor/HashJoin/HashTable.php +++ /dev/null @@ -1,82 +0,0 @@ - - */ - private array $buckets; - - /** - * @var array - */ - private array $bucketsMatches; - - public function __construct( - private readonly Algorithm $hashAlgorithm, - ) { - $this->buckets = []; - $this->bucketsMatches = []; - } - - public function add(Row $row, References $hashBy): void - { - $hash = $this->hash($hashBy, $row); - - if (!array_key_exists($hash, $this->buckets)) { - $this->buckets[$hash] = new Bucket($hash); - $this->bucketsMatches[$hash] = 0; - } - - $this->buckets[$hash]->add($row); - } - - public function bucketFor(Row $row, References $hashBy): ?Bucket - { - $hash = $this->hash($hashBy, $row); - - if (!array_key_exists($hash, $this->buckets)) { - return null; - } - - $this->bucketsMatches[$hash]++; - - return $this->buckets[$hash]; - } - - public function unmatchedRows(): Rows - { - $rows = []; - - foreach ($this->buckets as $hash => $bucket) { - if ($this->bucketsMatches[$hash] === 0) { - $rows = array_merge($rows, $bucket->unmatchedRows()); - } - } - - return new Rows(...$rows); - } - - private function hash(References $hashBy, Row $row): string - { - $value = ''; - - foreach ($hashBy->all() as $reference) { - $value .= $row->get($reference)->toString(); - } - - return $this->hashAlgorithm->hash($value); - } -} diff --git a/src/core/etl/src/Flow/ETL/Processor/HashJoinProcessor.php b/src/core/etl/src/Flow/ETL/Processor/HashJoinProcessor.php index 458f44caed..5b787d1c5e 100644 --- a/src/core/etl/src/Flow/ETL/Processor/HashJoinProcessor.php +++ b/src/core/etl/src/Flow/ETL/Processor/HashJoinProcessor.php @@ -8,23 +8,15 @@ use Flow\ETL\Exception\DuplicatedEntriesException; use Flow\ETL\Exception\JoinException; use Flow\ETL\FlowContext; -use Flow\ETL\Hash\NativePHPHash; +use Flow\ETL\Join\BucketedHashJoin; use Flow\ETL\Join\Expression; use Flow\ETL\Join\Join; use Flow\ETL\Processor; -use Flow\ETL\Processor\HashJoin\HashTable; -use Flow\ETL\Row; -use Flow\ETL\Row\Entry; -use Flow\ETL\Rows; use Generator; -use function Flow\ETL\DSL\refs; -use function Flow\ETL\DSL\row; -use function Flow\ETL\DSL\rows; -use function Flow\ETL\DSL\schema; - /** - * Performs hash join between upstream data and a DataFrame. + * Performs hash join between upstream data and a DataFrame, spilling through the buckets + * cache configured in the join config - in-memory (default) or on-disk. * * @internal */ @@ -37,106 +29,18 @@ public function __construct( ) {} public function process(Generator $rows, FlowContext $context): Generator - { - $leftReferences = refs(...$this->expression->left()); - $rightReferences = refs(...$this->expression->right()); - - $hashTable = new HashTable(new NativePHPHash()); - - $rightSchema = schema(); - - foreach ($this->right->getEach() as $rightRow) { - $hashTable->add($rightRow, $rightReferences); - $rightSchema = $rightSchema->merge($rightRow->schema()); - } - - /** @var array> $leftEntries */ - $leftEntries = []; - /** @var array> $rightEntries */ - $rightEntries = []; - - if ($this->join === Join::left) { - foreach ($rightSchema->definitions() as $rightEntryDefinition) { - $rightEntries[] = $context->entryFactory()->create( - $rightEntryDefinition->entry()->name(), - null, - $rightEntryDefinition->makeNullable(), - ); - } - } - - $leftSchema = schema(); - - foreach ($rows as $leftRows) { - /** @var Rows $leftRows */ - foreach ($leftRows as $leftRow) { - $bucket = $hashTable->bucketFor($leftRow, $leftReferences); - - if ($bucket === null) { - if ($this->join === Join::left) { - $rightEmptyRow = row(...$rightEntries); - - yield $this->createRows($leftRow, $rightEmptyRow, $context); - } - - if ($this->join === Join::left_anti) { - yield rows($leftRow); - } - - continue; - } - - $rightRow = $bucket->findMatch($leftRow, $this->expression); - - if ($this->join === Join::left_anti) { - continue; - } - - if ($rightRow !== null) { - yield $this->createRows($leftRow, $rightRow, $context); - } - } - - $leftSchema = $leftSchema->merge($leftRows->schema()); - } - - if ($this->join === Join::right) { - foreach ($leftSchema->definitions() as $leftEntryDefinition) { - $leftEntries[] = $context->entryFactory()->create( - $leftEntryDefinition->entry()->name(), - null, - $leftEntryDefinition->makeNullable(), - ); - } - - foreach ($hashTable->unmatchedRows() as $unmatchedRow) { - $leftEmptyRow = row(...$leftEntries); - yield $this->createRows($leftEmptyRow, $unmatchedRow, $context); - } - } - } - - private function createRows(Row $leftRow, Row $rightRow, FlowContext $context): Rows { try { - return match ($this->join) { - Join::inner => rows($leftRow->merge($rightRow, $this->expression->prefix())), - Join::left => rows($leftRow->merge( - $this->expression->dropDuplicateRightEntries($rightRow), - $this->expression->prefix(), - )), - Join::right => rows($this->expression->dropDuplicateLeftEntries($leftRow)->merge( - $rightRow, - $this->expression->prefix(), - )), - Join::left_anti => rows(), - }; + yield from (new BucketedHashJoin( + $this->right, + $this->expression, + $this->join, + $context->config->join->cache, + $context->config->join->bucketsCount, + $context->config->join->batchSize, + ))->joinGenerator($rows, $context); } catch (DuplicatedEntriesException $e) { - throw new JoinException( - $e->getMessage() . ' try to use a different join prefix than: "' . $this->expression->prefix() . '"', - (int) $e->getCode(), - $e, - ); + throw new JoinException($e->getMessage(), (int) $e->getCode(), $e); } } } diff --git a/src/core/etl/src/Flow/ETL/Processor/WindowProcessor.php b/src/core/etl/src/Flow/ETL/Processor/WindowProcessor.php index 57c0564c75..109289e56b 100644 --- a/src/core/etl/src/Flow/ETL/Processor/WindowProcessor.php +++ b/src/core/etl/src/Flow/ETL/Processor/WindowProcessor.php @@ -111,11 +111,16 @@ private function processPartition(array $rows, FlowContext $context): Rows $entryName = $this->entry instanceof Definition ? $this->entry->entry()->name() : $this->entry; - $newRow = $row->add($context->entryFactory()->create( - $entryName, - $value, - $this->entry instanceof Definition ? $this->entry : null, - )); + $newRow = $row->add( + $this->entry instanceof Definition + ? $context->entryFactory()->create( + $entryName, + $value, + $this->entry->type(), + $this->entry->metadata(), + ) + : $context->entryFactory()->create($entryName, $value), + ); $processedRows[] = $newRow; } diff --git a/src/core/etl/src/Flow/ETL/Row/AdaptiveRowHydrator.php b/src/core/etl/src/Flow/ETL/Row/AdaptiveRowHydrator.php new file mode 100644 index 0000000000..df5135534f --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/AdaptiveRowHydrator.php @@ -0,0 +1,33 @@ +delegate = NativeRowHydrator::isSupported() ? new NativeRowHydrator() : new PhpRowHydrator(); + } + + public function cast(array $batch, ?Schema $schema = null): Rows + { + return $this->delegate->cast($batch, $schema); + } + + public function dehydrate(Rows $rows): array + { + return $this->delegate->dehydrate($rows); + } + + public function hydrate(array $batch, ?Schema $schema = null): Rows + { + return $this->delegate->hydrate($batch, $schema); + } +} diff --git a/src/core/etl/src/Flow/ETL/Row/Encoder.php b/src/core/etl/src/Flow/ETL/Row/Encoder.php new file mode 100644 index 0000000000..0cab32540f --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/Encoder.php @@ -0,0 +1,25 @@ + $batch + * + * @return list + */ + public function encode(array $batch): array; + + /** + * @param list $batch + * + * @return list + */ + public function decode(array $batch): array; +} diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/NullEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/NullEntry.php new file mode 100644 index 0000000000..6bc76d3f14 --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/Entry/NullEntry.php @@ -0,0 +1,94 @@ + + */ +final class NullEntry implements Entry +{ + use EntryRef; + + private readonly null $value; + + private NullDefinition $definition; + + /** + * @throws InvalidArgumentException + */ + public function __construct( + private readonly string $name, + ?Metadata $metadata = null, + ) { + if ('' === $name) { + throw InvalidArgumentException::because('Entry name cannot be empty'); + } + + $this->value = null; + $this->definition = new NullDefinition($this->name, $metadata ?: Metadata::empty()); + } + + public function __toString(): string + { + return $this->toString(); + } + + public function definition(): NullDefinition + { + return $this->definition; + } + + public function is(string|Reference $name): bool + { + if ($name instanceof Reference) { + return $this->name === $name->name(); + } + + return $this->name === $name; + } + + public function isEqual(Entry $entry): bool + { + return $this->is($entry->name()) && $entry instanceof self; + } + + public function name(): string + { + return $this->name; + } + + /** + * @throws InvalidArgumentException + */ + public function rename(string $name): static + { + return new self($name, $this->definition->metadata()); + } + + public function toString(): string + { + return ''; + } + + /** + * @return Type + */ + public function type(): Type + { + return $this->definition->type(); + } + + public function value(): null + { + return $this->value; + } +} diff --git a/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php b/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php index ea665b76ad..1cd1469da6 100644 --- a/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php +++ b/src/core/etl/src/Flow/ETL/Row/Entry/StringEntry.php @@ -35,26 +35,12 @@ public function __construct( private readonly string $name, private readonly ?string $value, ?Metadata $metadata = null, - bool $fromNull = false, ) { if ('' === $name) { throw InvalidArgumentException::because('Entry name cannot be empty'); } - $metadata = $metadata ?: Metadata::empty(); - $this->definition = new StringDefinition( - $this->name, - $this->value === null, - $fromNull ? $metadata->merge(Metadata::fromArray([Metadata::FROM_NULL => true])) : $metadata, - ); - } - - /** - * @return self - */ - public static function fromNull(string $name, ?Metadata $metadata = null): self - { - return new self($name, null, $metadata, fromNull: true); + $this->definition = new StringDefinition($this->name, $this->value === null, $metadata ?: Metadata::empty()); } /** diff --git a/src/core/etl/src/Flow/ETL/Row/EntryFactory.php b/src/core/etl/src/Flow/ETL/Row/EntryFactory.php index d530618f0c..271ea6e654 100644 --- a/src/core/etl/src/Flow/ETL/Row/EntryFactory.php +++ b/src/core/etl/src/Flow/ETL/Row/EntryFactory.php @@ -5,114 +5,82 @@ namespace Flow\ETL\Row; use Flow\ETL\Exception\InvalidArgumentException; -use Flow\ETL\Exception\SchemaDefinitionNotFoundException; use Flow\ETL\Row\Entry\Instantiators; -use Flow\ETL\Row\Entry\StringEntry; -use Flow\ETL\Schema; +use Flow\ETL\Row\Entry\NullEntry; use Flow\ETL\Schema\Definition; use Flow\ETL\Schema\Metadata; use Flow\Types\Exception\CastingException; use Flow\Types\Type; -use Flow\Types\Type\Logical\DateTimeType; -use Flow\Types\Type\Logical\DateType; -use Flow\Types\Type\Logical\HTMLElementType; -use Flow\Types\Type\Logical\HTMLType; use Flow\Types\Type\Logical\InstanceOfType; -use Flow\Types\Type\Logical\JsonType; use Flow\Types\Type\Logical\ListType; -use Flow\Types\Type\Logical\MapType; use Flow\Types\Type\Logical\OptionalType; -use Flow\Types\Type\Logical\StructureType; -use Flow\Types\Type\Logical\TimeType; use Flow\Types\Type\Logical\TimeZoneType; -use Flow\Types\Type\Logical\UuidType; -use Flow\Types\Type\Logical\XMLElementType; -use Flow\Types\Type\Logical\XMLType; -use Flow\Types\Type\Native\ArrayType; -use Flow\Types\Type\Native\BooleanType; -use Flow\Types\Type\Native\EnumType; -use Flow\Types\Type\Native\FloatType; -use Flow\Types\Type\Native\IntegerType; use Flow\Types\Type\Native\NullType; -use Flow\Types\Type\Native\StringType; use Flow\Types\Type\Native\UnionType; use Flow\Types\Type\TypeDetector; use TypeError; use function array_values; -use function Flow\ETL\DSL\bool_entry; -use function Flow\ETL\DSL\date_entry; -use function Flow\ETL\DSL\datetime_entry; -use function Flow\ETL\DSL\enum_entry; -use function Flow\ETL\DSL\float_entry; -use function Flow\ETL\DSL\html_element_entry; -use function Flow\ETL\DSL\html_entry; -use function Flow\ETL\DSL\int_entry; -use function Flow\ETL\DSL\json_entry; -use function Flow\ETL\DSL\json_object_entry; -use function Flow\ETL\DSL\list_entry; -use function Flow\ETL\DSL\map_entry; -use function Flow\ETL\DSL\null_entry; -use function Flow\ETL\DSL\ref; -use function Flow\ETL\DSL\string_entry; -use function Flow\ETL\DSL\struct_entry; -use function Flow\ETL\DSL\structure_entry; -use function Flow\ETL\DSL\time_entry; -use function Flow\ETL\DSL\uuid_entry; -use function Flow\ETL\DSL\xml_element_entry; -use function Flow\ETL\DSL\xml_entry; -use function Flow\Types\DSL\type_instance_of; -use function Flow\Types\DSL\type_optional; +use function Flow\ETL\DSL\definition_from_type; use function Flow\Types\DSL\type_string; -final readonly class EntryFactory +final class EntryFactory { - private EntryTypeResolver $typeResolver; - private Instantiators $instantiators; + private readonly Instantiators $instantiators; + + private readonly EntryTypeResolver $typeResolver; + + private readonly TypeDetector $typeDetector; public function __construct() { - $this->typeResolver = new EntryTypeResolver(); $this->instantiators = new Instantiators(); + $this->typeResolver = new EntryTypeResolver(); + $this->typeDetector = new TypeDetector(); } /** - * @param null|Definition|Schema $schema - * - * @throws InvalidArgumentException - * @throws SchemaDefinitionNotFoundException + * @param null|Type $type * * @return Entry */ - public function create(string $entryName, mixed $value, Schema|Definition|null $schema = null): Entry + public function create(string $name, mixed $value, ?Type $type = null, ?Metadata $metadata = null): Entry { - if ($schema instanceof Definition) { - return $this->createAs( - $schema->entry()->name(), - $value, - $this->typeResolver->fromDefinition($schema), - $schema->metadata(), - ); - } - - if ($schema instanceof Schema) { - $definition = $schema->get($entryName); + if ($type === null) { + if ($value === null) { + return new NullEntry($name, $metadata); + } - return $this->createAs( - $definition->entry()->name(), - $value, - $this->typeResolver->fromDefinition($definition), - $definition->metadata(), - ); + return $this->build($name, $value, $this->typeDetector->detectType($value), $metadata, cast: true); } - if (null === $value) { - return StringEntry::fromNull($entryName); - } + return $this->build($name, $value, $type, $metadata, cast: false); + } + + /** + * @param Type $type + * + * @return Entry + */ + public function cast(string $name, mixed $value, Type $type, ?Metadata $metadata = null): Entry + { + return $this->build($name, $value, $type, $metadata, cast: true); + } - $valueType = (new TypeDetector())->detectType($value); + /** + * @param Definition $definition + * + * @return Entry + */ + public function fromDefinition(Definition $definition, mixed $value): Entry + { + $variant = $value === null && !$definition->isNullable() ? $definition->makeNullable() : $definition; - return $this->createAs($entryName, $value, $valueType); + return $this->instantiators->for($variant->entryClass())->instantiate( + $variant->entry()->name(), + $value, + $variant, + ); } /** @@ -120,37 +88,8 @@ public function create(string $entryName, mixed $value, Schema|Definition|null $ * * @return Entry */ - public function createAs(string $entryName, mixed $value, Type $type, ?Metadata $metadata = null): Entry + private function build(string $name, mixed $value, Type $type, ?Metadata $metadata, bool $cast): Entry { - if (null === $value && $type instanceof OptionalType) { - return match ($type->base()::class) { - StringType::class => string_entry($entryName, null, $metadata), - IntegerType::class => int_entry($entryName, null, $metadata), - FloatType::class => float_entry($entryName, null, $metadata), - BooleanType::class => bool_entry($entryName, null, $metadata), - MapType::class => map_entry($entryName, null, $type->base(), $metadata), - StructureType::class => struct_entry( - $entryName, - null, - type_instance_of(StructureType::class)->assert($type->base()), - $metadata, - ), - ListType::class => list_entry($entryName, null, $type->base(), $metadata), - UuidType::class => uuid_entry($entryName, null, $metadata), - DateTimeType::class => datetime_entry($entryName, null, $metadata), - TimeType::class => time_entry($entryName, null, $metadata), - DateType::class => date_entry($entryName, null, $metadata), - EnumType::class => enum_entry($entryName, null, $metadata), - ArrayType::class, JsonType::class => json_entry($entryName, null, $metadata), - NullType::class => null_entry($entryName, $metadata), - XMLType::class => xml_entry($entryName, null, $metadata), - XMLElementType::class => xml_element_entry($entryName, null, $metadata), - HTMLType::class => html_entry($entryName, null, $metadata), - HTMLElementType::class => html_element_entry($entryName, null, $metadata), - default => throw new InvalidArgumentException("Can't convert value into type \"{$type->toString()}\""), - }; - } - try { if ($type instanceof OptionalType) { $type = $type->base(); @@ -161,7 +100,7 @@ public function createAs(string $entryName, mixed $value, Type $type, ?Metadata if ($reduced === null) { throw new InvalidArgumentException( - "Entry \"{$entryName}\": cannot reduce optional union type \"{$type->toString()}\".", + "Entry \"{$name}\": cannot reduce optional union type \"{$type->toString()}\".", ); } @@ -169,72 +108,49 @@ public function createAs(string $entryName, mixed $value, Type $type, ?Metadata } if ($type instanceof UnionType) { - $type = $this->typeResolver->fromUnion($type, $value, $entryName); + $type = $this->typeResolver->fromUnion($type, $value, $name); } - if ($type instanceof JsonType) { - try { - return json_object_entry($entryName, type_optional($type)->cast($value), $metadata); - } catch (InvalidArgumentException) { - return json_entry($entryName, type_optional($type)->cast($value), $metadata); - } + if ($type instanceof NullType) { + return new NullEntry($name, $metadata); } - return match ($type::class) { - StringType::class => string_entry($entryName, type_optional($type)->cast($value), $metadata), - IntegerType::class => int_entry($entryName, type_optional($type)->cast($value), $metadata), - BooleanType::class => bool_entry($entryName, type_optional($type)->cast($value), $metadata), - FloatType::class => float_entry($entryName, type_optional($type)->cast($value), $metadata), - UuidType::class => uuid_entry($entryName, type_optional($type)->cast($value), $metadata), - DateType::class => date_entry($entryName, type_optional($type)->cast($value), $metadata), - TimeType::class => time_entry($entryName, type_optional($type)->cast($value), $metadata), - DateTimeType::class => datetime_entry($entryName, type_optional($type)->cast($value), $metadata), - TimeZoneType::class => string_entry($entryName, type_optional(type_string())->cast($value), $metadata), - NullType::class => null_entry($entryName, $metadata), - EnumType::class => enum_entry($entryName, type_optional($type)->cast($value), $metadata), - HTMLType::class => html_entry($entryName, type_optional($type)->cast($value), $metadata), - HTMLElementType::class => html_element_entry($entryName, type_optional($type)->cast($value), $metadata), - XMLType::class => xml_entry($entryName, type_optional($type)->cast($value), $metadata), - XMLElementType::class => xml_element_entry($entryName, type_optional($type)->cast($value), $metadata), - ArrayType::class => json_entry($entryName, type_optional($type)->cast($value), $metadata), - MapType::class => map_entry($entryName, $value === null ? null : $type->cast($value), $type, $metadata), - StructureType::class => structure_entry( - $entryName, - $value === null ? null : $type->cast($value), - $type, - $metadata, - ), - ListType::class => list_entry( - $entryName, - $value === null ? null : array_values($type->cast($value)), - $type, - $metadata, - ), - InstanceOfType::class => throw new InvalidArgumentException( - "{$entryName}: {$type->toString()} can't be converted to any known Entry, please normalize that object first.", - ), - default => throw new InvalidArgumentException( - "Can't convert " . get_debug_type($value) . " value into type \"{$type->toString()}\"", - ), - }; + if ($type instanceof InstanceOfType) { + throw new InvalidArgumentException( + "{$name}: {$type->toString()} can't be converted to any known Entry, please normalize that object first.", + ); + } + + if ($type instanceof TimeZoneType) { + $type = type_string(); + } + + $definition = definition_from_type($name, $type, $value === null, $metadata); + + return $this->fromDefinition($definition, $this->prepareValue($value, $definition->type(), $cast)); // @mago-ignore analysis:avoid-catching-error } catch (InvalidArgumentException|CastingException|TypeError $e) { throw new InvalidArgumentException( - "Entry \"{$entryName}\" conversion exception. {$e->getMessage()}", + "Entry \"{$name}\" conversion exception. {$e->getMessage()}", previous: $e, ); } } - public function instantiate(string $entryName, mixed $value, Schema|Definition $schema): Entry + /** + * @param Type $type + */ + private function prepareValue(mixed $value, Type $type, bool $cast): mixed { - if ($schema instanceof Schema) { - $definition = $schema->get(ref($entryName)); - } else { - $definition = $schema; + if ($value === null || !$cast) { + return $value; + } + + if ($type instanceof ListType) { + return array_values($type->cast($value)); } - return $this->instantiators->for($definition->entryClass())->instantiate($entryName, $value, $definition); + return $type->cast($value); } } diff --git a/src/core/etl/src/Flow/ETL/Row/Hydrator.php b/src/core/etl/src/Flow/ETL/Row/Hydrator.php new file mode 100644 index 0000000000..a6945a8a6e --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/Hydrator.php @@ -0,0 +1,26 @@ + $batch + */ + public function cast(array $batch, ?Schema $schema = null): Rows; + + /** + * @return list + */ + public function dehydrate(Rows $rows): array; + + /** + * @param list $batch + */ + public function hydrate(array $batch, ?Schema $schema = null): Rows; +} diff --git a/src/core/etl/src/Flow/ETL/Row/NativeRowHydrator.php b/src/core/etl/src/Flow/ETL/Row/NativeRowHydrator.php new file mode 100644 index 0000000000..4a43223cef --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/NativeRowHydrator.php @@ -0,0 +1,60 @@ +native = new RustRowHydratorNative(); + $this->php = new PhpRowHydrator(); + } + + public static function isSupported(): bool + { + return extension_loaded('flow_php') && class_exists(RustRowHydratorNative::class, false); + } + + public function cast(array $batch, ?Schema $schema = null): Rows + { + if ($schema === null) { + return $this->php->cast($batch, null); + } + + return $this->native->cast($batch, $schema); + } + + public function dehydrate(Rows $rows): array + { + return $this->native->dehydrate($rows); + } + + public function hydrate(array $batch, ?Schema $schema = null): Rows + { + if ($schema === null) { + throw new InvalidArgumentException( + 'NativeRowHydrator::hydrate() requires a schema, use cast() to infer from values', + ); + } + + return $this->native->hydrate($batch, $schema); + } +} diff --git a/src/core/etl/src/Flow/ETL/Row/PhpRowHydrator.php b/src/core/etl/src/Flow/ETL/Row/PhpRowHydrator.php new file mode 100644 index 0000000000..d476f4ca6c --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/PhpRowHydrator.php @@ -0,0 +1,146 @@ +entryFactory = new EntryFactory(); + } + + public function cast(array $batch, ?Schema $schema = null): Rows + { + if ($schema === null) { + return $this->infer($batch); + } + + return $this->instantiate( + $batch, + $schema, + static fn(mixed $value, Definition $definition): mixed => $value === null + ? null + : $definition->type()->cast($value), + fillMissing: true, + ); + } + + public function dehydrate(Rows $rows): array + { + $batch = []; + + foreach ($rows as $row) { + $values = []; + $types = []; + $metadata = []; + + foreach ($row->entries()->all() as $entry) { + $definition = $entry->definition(); + + $values[$entry->name()] = $entry->value(); + $types[$entry->name()] = $definition->type(); + + if (!$definition->metadata()->isEmpty()) { + $metadata[$entry->name()] = $definition->metadata(); + } + } + + $batch[] = new TypedRowValues($values, $types, $metadata); + } + + return $batch; + } + + public function hydrate(array $batch, ?Schema $schema = null): Rows + { + if ($schema === null) { + throw new InvalidArgumentException( + 'PhpRowHydrator::hydrate() requires a schema, use cast() to infer from values', + ); + } + + return $this->instantiate( + $batch, + $schema, + static fn(mixed $value, Definition $definition): mixed => $value, + fillMissing: false, + ); + } + + /** + * @param list $batch + * @param callable(mixed, Definition): mixed $prepare + */ + private function instantiate(array $batch, Schema $schema, callable $prepare, bool $fillMissing): Rows + { + $definitions = $schema->definitions(); + $rows = []; + + foreach ($batch as $rowValues) { + $entries = []; + + foreach ($definitions as $definition) { + $name = $definition->entry()->name(); + + if (!array_key_exists($name, $rowValues->values)) { + if ($fillMissing) { + $entries[$name] = $this->entryFactory->fromDefinition($definition, null); + } + + continue; + } + + if (array_key_exists($name, $rowValues->metadata)) { + $definition = (clone $definition)->setMetadata($rowValues->metadata[$name]); + } + + // @mago-ignore analysis:mixed-assignment + $value = $rowValues->values[$name]; + + $entries[$name] = $this->entryFactory->fromDefinition($definition, $prepare($value, $definition)); + } + + $rows[] = new Row(Entries::recreate($entries)); + } + + return new Rows(...$rows); + } + + /** + * @param list $batch + */ + private function infer(array $batch): Rows + { + $rows = []; + + foreach ($batch as $rowValues) { + $entries = []; + + /** @var mixed $value */ + foreach ($rowValues->values as $name => $value) { + $entries[$name] = $this->entryFactory->create( + $name, + $value, + null, + array_key_exists($name, $rowValues->metadata) ? $rowValues->metadata[$name] : null, + ); + } + + $rows[] = new Row(Entries::recreate($entries)); + } + + return new Rows(...$rows); + } +} diff --git a/src/core/etl/src/Flow/ETL/Row/RawRowValues.php b/src/core/etl/src/Flow/ETL/Row/RawRowValues.php new file mode 100644 index 0000000000..d6bb23a0d5 --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/RawRowValues.php @@ -0,0 +1,19 @@ + $values + * @param array $metadata + */ + public function __construct( + public array $values, + public array $metadata = [], + ) {} +} diff --git a/src/core/etl/src/Flow/ETL/Row/TypedRowValues.php b/src/core/etl/src/Flow/ETL/Row/TypedRowValues.php new file mode 100644 index 0000000000..88cd6db06b --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Row/TypedRowValues.php @@ -0,0 +1,22 @@ + $values + * @param array> $types + * @param array $metadata + */ + public function __construct( + public array $values, + public array $types, + public array $metadata = [], + ) {} +} diff --git a/src/core/etl/src/Flow/ETL/Rows.php b/src/core/etl/src/Flow/ETL/Rows.php index 5c2b9c9cde..e0ab14518e 100644 --- a/src/core/etl/src/Flow/ETL/Rows.php +++ b/src/core/etl/src/Flow/ETL/Rows.php @@ -9,12 +9,14 @@ use Countable; use DateInterval; use DateTimeInterface; -use Flow\ETL\Exception\DuplicatedEntriesException; use Flow\ETL\Exception\InvalidArgumentException; use Flow\ETL\Exception\RuntimeException; use Flow\ETL\Hash\Algorithm; use Flow\ETL\Hash\NativePHPHash; use Flow\ETL\Join\Expression; +use Flow\ETL\Join\HashJoin\Joiner; +use Flow\ETL\Join\HashJoin\RowMerger; +use Flow\ETL\Join\Join; use Flow\ETL\Row\CartesianProduct; use Flow\ETL\Row\Comparator; use Flow\ETL\Row\Comparator\NativeComparator; @@ -39,7 +41,6 @@ use function array_unique; use function array_values; use function count; -use function Flow\ETL\DSL\row; use function Flow\Types\DSL\type_integer; use function is_array; use function is_int; @@ -371,10 +372,12 @@ public function joinCross(self $right, string $joinPrefix = 'joined_'): self return $right; } + $merger = new RowMerger($joinPrefix); + foreach ($this->rows as $leftRow) { foreach ($right->rows as $rightRow) { try { - $joined[] = $leftRow->merge($rightRow, $joinPrefix); + $joined[] = $merger->merge($leftRow, $rightRow); } catch (InvalidArgumentException $e) { throw new InvalidArgumentException($e->getMessage() . '. Please consider using join prefix option'); } @@ -389,41 +392,7 @@ public function joinCross(self $right, string $joinPrefix = 'joined_'): self */ public function joinInner(self $right, Expression $expression): self { - /** - * @var array $joined - */ - $joined = []; - - foreach ($this->rows as $leftRow) { - /** @var ?Row $joinedRow */ - $joinedRow = null; - - foreach ($right as $rightRow) { - if ($expression->meet($leftRow, $rightRow)) { - try { - $joinedRow = $leftRow->merge( - $expression->dropDuplicateRightEntries($rightRow), - $expression->prefix(), - ); - } catch (DuplicatedEntriesException $e) { - throw new DuplicatedEntriesException( - $e->getMessage() - . ' try to use a different join prefix than: "' - . $expression->prefix() - . '"', - ); - } - - break; - } - } - - if ($joinedRow) { - $joined[] = $joinedRow; - } - } - - return new self(...$joined); + return $this->joinUsing($right, $expression, Join::inner, new EntryFactory()); } /** @@ -431,54 +400,7 @@ public function joinInner(self $right, Expression $expression): self */ public function joinLeft(self $right, Expression $expression, EntryFactory $entryFactory): self { - /** - * @var array $joined - */ - $joined = []; - - $rightSchema = $right->schema(); - - foreach ($this->rows as $leftRow) { - /** @var ?Row $joinedRow */ - $joinedRow = null; - - foreach ($right as $rightRow) { - if ($expression->meet($leftRow, $rightRow)) { - try { - $joinedRow = $leftRow->merge( - $expression->dropDuplicateRightEntries($rightRow), - $expression->prefix(), - ); - } catch (DuplicatedEntriesException $e) { - throw new DuplicatedEntriesException( - $e->getMessage() - . ' try to use a different join prefix than: "' - . $expression->prefix() - . '"', - ); - } - - break; - } - } - - if ($joinedRow === null) { - $entries = []; - - foreach ($rightSchema->definitions() as $definition) { - $entries[] = $entryFactory->create($definition->entry()->name(), null, $definition->makeNullable()); - } - - $joinedRow = $leftRow->merge( - $expression->dropDuplicateRightEntries(row(...$entries)), - $expression->prefix(), - ); - } - - $joined[] = $joinedRow; - } - - return new self(...$joined); + return $this->joinUsing($right, $expression, Join::left, $entryFactory); } /** @@ -486,27 +408,7 @@ public function joinLeft(self $right, Expression $expression, EntryFactory $entr */ public function joinLeftAnti(self $right, Expression $expression): self { - /** - * @var array $joined - */ - $joined = []; - - foreach ($this->rows as $leftRow) { - $foundRight = false; - - foreach ($right as $rightRow) { - if (!$expression->meet($leftRow, $rightRow)) { - continue; - } - $foundRight = true; - } - - if (!$foundRight) { - $joined[] = $leftRow; - } - } - - return new self(...$joined); + return $this->joinUsing($right, $expression, Join::left_anti, new EntryFactory()); } /** @@ -514,48 +416,26 @@ public function joinLeftAnti(self $right, Expression $expression): self */ public function joinRight(self $right, Expression $expression, EntryFactory $entryFactory): self { + return $this->joinUsing($right, $expression, Join::right, $entryFactory); + } + + /** + * @throws InvalidArgumentException + */ + private function joinUsing(self $right, Expression $expression, Join $type, EntryFactory $entryFactory): self + { + $single = static function (self $rows): Generator { + yield $rows; + }; + /** * @var array $joined */ $joined = []; - $leftSchema = $this->schema(); - - foreach ($right->rows as $rightRow) { - /** @var ?Row $joinedRow */ - $joinedRow = null; - - foreach ($this->rows as $leftRow) { - if ($expression->meet($leftRow, $rightRow)) { - try { - $joinedRow = $expression->dropDuplicateLeftEntries($leftRow)->merge( - $rightRow, - $expression->prefix(), - ); - } catch (DuplicatedEntriesException $e) { - throw new DuplicatedEntriesException( - $e->getMessage() - . ' try to use a different join prefix than: "' - . $expression->prefix() - . '"', - ); - } - - $joined[] = $joinedRow; - } - } - - if ($joinedRow === null) { - $entries = []; - - foreach ($leftSchema->definitions() as $definition) { - $entries[] = $entryFactory->create($definition->entry()->name(), null, $definition->makeNullable()); - } - - $joined[] = $expression->dropDuplicateLeftEntries(row(...$entries))->merge( - $rightRow, - $expression->prefix(), - ); + foreach ((new Joiner($expression, $type, $entryFactory))->join($single($this), $single($right)) as $batch) { + foreach ($batch as $row) { + $joined[] = $row; } } diff --git a/src/core/etl/src/Flow/ETL/Schema.php b/src/core/etl/src/Flow/ETL/Schema.php index 0b5d57cf55..8780ec9705 100644 --- a/src/core/etl/src/Flow/ETL/Schema.php +++ b/src/core/etl/src/Flow/ETL/Schema.php @@ -12,6 +12,7 @@ use Flow\ETL\Row\Reference; use Flow\ETL\Row\References; use Flow\ETL\Schema\Definition; +use Flow\ETL\Schema\Definition\NullDefinition; use Flow\ETL\Schema\Metadata; use Flow\ETL\Schema\SortingStrategy; use Flow\ETL\Schema\SortingStrategy\AlphabeticalStrategy; @@ -99,7 +100,7 @@ public static function fromPipeline(Pipeline $pipeline, FlowContext $context, in $allDetected = true; foreach ($schema->definitions() as $definition) { - if ($definition->metadata()->has(Metadata::FROM_NULL)) { + if ($definition instanceof NullDefinition) { $allDetected = false; break; diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/BooleanDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/BooleanDefinition.php index d7b50447f0..d4354a15b1 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/BooleanDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/BooleanDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/DateDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/DateDefinition.php index 06394e162d..9784f46ab2 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/DateDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/DateDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/DateTimeDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/DateTimeDefinition.php index 676d3cb02c..7e77eb1bcc 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/DateTimeDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/DateTimeDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ( $definition instanceof self || $definition instanceof DateDefinition diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/EnumDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/EnumDefinition.php index d2120ce201..2c2058cbf0 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/EnumDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/EnumDefinition.php @@ -137,32 +137,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self && $definition->enumClass === $this->enumClass) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/FloatDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/FloatDefinition.php index e5920f9bfd..6a7f18cfd4 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/FloatDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/FloatDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLDefinition.php index 3271823887..776778931c 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLDefinition.php @@ -116,32 +116,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLElementDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLElementDefinition.php index 9b74788f67..f1d69f2697 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLElementDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/HTMLElementDefinition.php @@ -116,32 +116,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/IntegerDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/IntegerDefinition.php index 1525d7b0b0..a1ee2be2a0 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/IntegerDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/IntegerDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/JsonDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/JsonDefinition.php index 9b20a235b1..98bb919681 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/JsonDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/JsonDefinition.php @@ -116,32 +116,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/ListDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/ListDefinition.php index f6773ec617..6dad210b12 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/ListDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/ListDefinition.php @@ -147,32 +147,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { if (type_equals($this->type, $definition->type)) { return new self( diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/MapDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/MapDefinition.php index a2bfe4e643..3faaf9bb0d 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/MapDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/MapDefinition.php @@ -148,32 +148,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { if (type_equals($this->type, $definition->type)) { return new self( diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/NullDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/NullDefinition.php new file mode 100644 index 0000000000..32b01f6dab --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/NullDefinition.php @@ -0,0 +1,151 @@ + + */ +final class NullDefinition implements Definition +{ + private Metadata $metadata; + + private readonly Reference $ref; + + /** + * @var Type + */ + private readonly Type $type; + + public function __construct(string|Reference $ref, ?Metadata $metadata = null) + { + $this->ref = EntryReference::init($ref); + $this->metadata = $metadata ?? Metadata::empty(); + $this->type = type_null(); + } + + /** + * @param array|bool|float|int|string $value + */ + public function addMetadata(string $key, int|string|bool|float|array $value): static + { + $this->metadata = $this->metadata->add($key, $value); + + return $this; + } + + public function entry(): Reference + { + return $this->ref; + } + + public function isCompatible(Definition $definition): bool + { + if (!$this->ref->is($definition->entry())) { + return false; + } + + return type_equals($this->type, $definition->type()); + } + + public function isNullable(): bool + { + return true; + } + + public function isSame(Definition $definition): bool + { + if (!$definition->isNullable()) { + return false; + } + + if (!type_equals($this->type, $definition->type())) { + return false; + } + + return $this->metadata->isEqual($definition->metadata()); + } + + public function makeNullable(bool $nullable = true): static + { + return new self($this->ref, $this->metadata); + } + + public function matches(Entry $entry): bool + { + return $entry->is($this->ref); + } + + public function merge(Definition $definition): Definition + { + if (!$this->ref->is($definition->entry())) { + throw new RuntimeException(sprintf( + 'Cannot merge different definitions, %s and %s', + $this->ref->name(), + $definition->entry()->name(), + )); + } + + if ($definition instanceof self) { + return new self($this->ref, $definition->metadata()->merge($this->metadata)); + } + + return $definition->makeNullable()->setMetadata($definition->metadata()->merge($this->metadata)); + } + + public function metadata(): Metadata + { + return $this->metadata; + } + + /** + * @return array + */ + public function normalize(): array + { + return [ + 'ref' => $this->ref->name(), + 'type' => $this->type->normalize(), + 'nullable' => true, + 'metadata' => $this->metadata->normalize(), + ]; + } + + public function rename(string $newName): static + { + return new self($newName, $this->metadata); + } + + public function setMetadata(Metadata $metadata): static + { + $this->metadata = $metadata; + + return $this; + } + + public function type(): Type + { + return $this->type; + } + + /** + * @return class-string + */ + public function entryClass(): string + { + return Entry\NullEntry::class; + } +} diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/StringDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/StringDefinition.php index 4924d96ae5..613dd57b65 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/StringDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/StringDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - return new self( $this->ref, $this->nullable || $definition->isNullable(), diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/StructureDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/StructureDefinition.php index 111a5d00fa..9d8cb21b65 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/StructureDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/StructureDefinition.php @@ -164,32 +164,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { if (type_equals($this->type, $definition->type)) { return new self( diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/TimeDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/TimeDefinition.php index c5d5f166b6..b1beb9b15a 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/TimeDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/TimeDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/UnionDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/UnionDefinition.php index 6dc3854ecb..02e8d5791a 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/UnionDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/UnionDefinition.php @@ -113,32 +113,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { if (type_equals($this->type, $definition->type)) { return new self( diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/UuidDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/UuidDefinition.php index dbb454cd47..c450c291ad 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/UuidDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/UuidDefinition.php @@ -116,32 +116,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/XMLDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/XMLDefinition.php index 1e96af066f..50d0518898 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/XMLDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/XMLDefinition.php @@ -116,32 +116,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Definition/XMLElementDefinition.php b/src/core/etl/src/Flow/ETL/Schema/Definition/XMLElementDefinition.php index 423dc35d65..73c22c55c6 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Definition/XMLElementDefinition.php +++ b/src/core/etl/src/Flow/ETL/Schema/Definition/XMLElementDefinition.php @@ -115,32 +115,10 @@ public function merge(Definition $definition): Definition )); } - $thisFromNull = $this->metadata->has(Metadata::FROM_NULL); - $defFromNull = $definition->metadata()->has(Metadata::FROM_NULL); - - if ($thisFromNull && $defFromNull) { + if ($definition instanceof NullDefinition) { return $this->makeNullable()->setMetadata($this->metadata->merge($definition->metadata())); } - if ($thisFromNull) { - return $definition - ->makeNullable() - ->setMetadata( - $definition - ->metadata() - ->remove(Metadata::FROM_NULL) - ->merge($this->metadata->remove(Metadata::FROM_NULL)), - ); - } - - if ($defFromNull) { - return $this->makeNullable()->setMetadata( - $this->metadata - ->remove(Metadata::FROM_NULL) - ->merge($definition->metadata()->remove(Metadata::FROM_NULL)), - ); - } - if ($definition instanceof self) { return new self( $this->ref, diff --git a/src/core/etl/src/Flow/ETL/Schema/Metadata.php b/src/core/etl/src/Flow/ETL/Schema/Metadata.php index 9076c7b6b1..abd032e0e6 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Metadata.php +++ b/src/core/etl/src/Flow/ETL/Schema/Metadata.php @@ -16,8 +16,6 @@ final readonly class Metadata { - public const string FROM_NULL = 'from_null'; - /** * @param array|bool|float|int|string> $map */ diff --git a/src/core/etl/src/Flow/ETL/Schema/Validator/EvolvingValidator.php b/src/core/etl/src/Flow/ETL/Schema/Validator/EvolvingValidator.php index 00bdd980aa..96fc5c0857 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Validator/EvolvingValidator.php +++ b/src/core/etl/src/Flow/ETL/Schema/Validator/EvolvingValidator.php @@ -7,16 +7,20 @@ use Flow\ETL\Schema; use Flow\ETL\SchemaValidator; -use function Flow\Types\DSL\type_equals; - /** - * Rules of evolving schema matching: - * - if schemas are the same, return true - * - if given schema has less fields than expected schema, return false - * - if given schema is making a nullable field non-nullable, return false - * - if given schema is making a non-nullable field nullable, return true - * - if given schema is changing the type of a field, return false - * - if given schema is adding a field, return true + * Compatibility for combining or evolving datasets - the same invariant a merge, + * an append and a per-batch validation all need: combining `expected` and `given` + * must never leave a row holding null in a column that is non-nullable somewhere. + * + * - a shared column must keep a compatible type and must not widen to nullable + * where the expected side is non-nullable (its rows would then read as null), + * - a column in `expected` but absent from `given` is allowed only when nullable + * (given's rows read it as null), + * - a column in `given` but absent from `expected` is allowed only when nullable + * (expected's rows read it as null). + * + * A required (non-nullable) column that is dropped, added, or type-changed is + * therefore incompatible. */ final class EvolvingValidator implements SchemaValidator { @@ -24,27 +28,30 @@ public function validate(Schema $expected, Schema $given): ValidationContext { $missingDefinitions = []; $mismatchedDefinitions = []; + $unexpectedDefinitions = []; foreach ($expected->definitions() as $expectedDefinition) { $givenDefinition = $given->findDefinition($expectedDefinition->entry()); if ($givenDefinition === null) { - $missingDefinitions[] = $expectedDefinition; + if (!$expectedDefinition->isNullable()) { + $missingDefinitions[] = $expectedDefinition; + } continue; } - if (!$givenDefinition->isNullable() && $expectedDefinition->isNullable()) { + if (!$expectedDefinition->isCompatible($givenDefinition)) { $mismatchedDefinitions[] = new MismatchedDefinition($expectedDefinition, $givenDefinition); - - continue; } + } - if (!type_equals($givenDefinition->type(), $expectedDefinition->type())) { - $mismatchedDefinitions[] = new MismatchedDefinition($expectedDefinition, $givenDefinition); + foreach ($given->definitions() as $givenDefinition) { + if ($expected->findDefinition($givenDefinition->entry()) === null && !$givenDefinition->isNullable()) { + $unexpectedDefinitions[] = $givenDefinition; } } - return new ValidationContext($missingDefinitions, $mismatchedDefinitions); + return new ValidationContext($missingDefinitions, $mismatchedDefinitions, $unexpectedDefinitions); } } diff --git a/src/core/etl/src/Flow/ETL/Schema/Validator/SelectiveValidator.php b/src/core/etl/src/Flow/ETL/Schema/Validator/SelectiveValidator.php index a0e431e0d0..8eccf3a499 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Validator/SelectiveValidator.php +++ b/src/core/etl/src/Flow/ETL/Schema/Validator/SelectiveValidator.php @@ -5,12 +5,9 @@ namespace Flow\ETL\Schema\Validator; use Flow\ETL\Schema; -use Flow\ETL\Schema\Metadata; +use Flow\ETL\Schema\Definition\NullDefinition; use Flow\ETL\SchemaValidator; -use function Flow\Types\DSL\type_equals; -use function Flow\Types\DSL\type_string; - /** * Matches only entries defined in the expected schema allowing for extra entries in given schema. */ @@ -30,11 +27,7 @@ public function validate(Schema $expected, Schema $given): ValidationContext continue; } - if ( - $expectedDefinition->isNullable() - && $givenDefinition->metadata()->has(Metadata::FROM_NULL) - && type_equals($givenDefinition->type(), type_string()) - ) { + if ($givenDefinition instanceof NullDefinition && $expectedDefinition->isNullable()) { continue; } diff --git a/src/core/etl/src/Flow/ETL/Schema/Validator/StrictValidator.php b/src/core/etl/src/Flow/ETL/Schema/Validator/StrictValidator.php index 61632d5e36..f1da1f55f0 100644 --- a/src/core/etl/src/Flow/ETL/Schema/Validator/StrictValidator.php +++ b/src/core/etl/src/Flow/ETL/Schema/Validator/StrictValidator.php @@ -5,12 +5,9 @@ namespace Flow\ETL\Schema\Validator; use Flow\ETL\Schema; -use Flow\ETL\Schema\Metadata; +use Flow\ETL\Schema\Definition\NullDefinition; use Flow\ETL\SchemaValidator; -use function Flow\Types\DSL\type_equals; -use function Flow\Types\DSL\type_string; - /** * Matches all entries in the schema, if row comes with any extra entry it will fail validation. */ @@ -31,11 +28,7 @@ public function validate(Schema $expected, Schema $given): ValidationContext continue; } - if ( - $expectedDefinition->isNullable() - && $givenDefinition->metadata()->has(Metadata::FROM_NULL) - && type_equals($givenDefinition->type(), type_string()) - ) { + if ($givenDefinition instanceof NullDefinition && $expectedDefinition->isNullable()) { continue; } diff --git a/src/core/etl/src/Flow/ETL/Sort/ExternalSort/BucketsCache/FilesystemBucketsCache.php b/src/core/etl/src/Flow/ETL/Sort/ExternalSort/BucketsCache/FilesystemBucketsCache.php index f9960ecdfe..1c0373e822 100644 --- a/src/core/etl/src/Flow/ETL/Sort/ExternalSort/BucketsCache/FilesystemBucketsCache.php +++ b/src/core/etl/src/Flow/ETL/Sort/ExternalSort/BucketsCache/FilesystemBucketsCache.php @@ -72,7 +72,7 @@ public function get(string $bucketId): Generator return; } - foreach ($this->reader->read($path)->recover($this->batchSize) as $batch) { + foreach ($this->reader->read($path)->rows($this->batchSize, conform: false) as $batch) { yield from $batch->all(); } } diff --git a/src/core/etl/src/Flow/ETL/Sort/ExternalSort/BucketsCache/InMemoryBucketsCache.php b/src/core/etl/src/Flow/ETL/Sort/ExternalSort/BucketsCache/InMemoryBucketsCache.php new file mode 100644 index 0000000000..439cc290bb --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Sort/ExternalSort/BucketsCache/InMemoryBucketsCache.php @@ -0,0 +1,43 @@ +> + */ + private array $buckets = []; + + public function append(string $bucketId, iterable|Rows $rows): void + { + foreach ($rows as $row) { + $this->buckets[$bucketId][] = $row; + } + } + + public function get(string $bucketId): Generator + { + foreach ($this->buckets[$bucketId] ?? [] as $row) { + yield $row; + } + } + + public function remove(string $bucketId): void + { + unset($this->buckets[$bucketId]); + } + + public function set(string $bucketId, iterable|Rows $rows): void + { + $this->buckets[$bucketId] = []; + $this->append($bucketId, $rows); + } +} diff --git a/src/core/etl/src/Flow/ETL/Sort/ExternalSort/ResidentBucketsCache.php b/src/core/etl/src/Flow/ETL/Sort/ExternalSort/ResidentBucketsCache.php new file mode 100644 index 0000000000..c63e2bfb76 --- /dev/null +++ b/src/core/etl/src/Flow/ETL/Sort/ExternalSort/ResidentBucketsCache.php @@ -0,0 +1,7 @@ +function instanceof ExpandResults) { return $rows->flatMap(fn(Row $r): array => array_map( - fn($val): Row => new Row($r->entries()->set($context->entryFactory()->create( - $this->entryName(), - $val, - $this->entry instanceof Definition ? $this->entry : null, - ))), + fn($val): Row => new Row($r->entries()->set( + $this->entry instanceof Definition + ? $context->entryFactory()->cast($this->entryName(), $val, $this->entry->type()) + : $context->entryFactory()->create($this->entryName(), $val), + )), // @mago-ignore analysis:mixed-argument $this->function->eval($r, $context), )); @@ -79,22 +79,16 @@ private function doTransform(Rows $rows, FlowContext $context): Rows return $rows->map(function (Row $r) use ($context): Row { // @mago-ignore analysis:mixed-assignment $value = $this->function->eval($r, $context); - $type = $this->entry instanceof Definition ? $this->entry->type() : null; + // ScalarResult already carries a native, typed value - trust it, no re-cast. if ($value instanceof ScalarResult) { - $type = $value->type; - // @mago-ignore analysis:mixed-assignment - $value = $value->value; + return $r->set($context->entryFactory()->create($this->entryName(), $value->value, $value->type)); } return $r->set( - $type - ? $context->entryFactory()->createAs($this->entryName(), $value, $type) - : $context->entryFactory()->create( - $this->entryName(), - $value, - $this->entry instanceof Definition ? $this->entry : null, - ), + $this->entry instanceof Definition + ? $context->entryFactory()->cast($this->entryName(), $value, $this->entry->type()) + : $context->entryFactory()->create($this->entryName(), $value), ); }); } diff --git a/src/core/etl/src/Flow/ETL/Transformer/SerializeTransformer.php b/src/core/etl/src/Flow/ETL/Transformer/SerializeTransformer.php index 1b7bc8a8ea..fdae24481b 100644 --- a/src/core/etl/src/Flow/ETL/Transformer/SerializeTransformer.php +++ b/src/core/etl/src/Flow/ETL/Transformer/SerializeTransformer.php @@ -15,7 +15,9 @@ use function Flow\ETL\DSL\ref; use function Flow\ETL\DSL\row; +use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; +use function Flow\Serializer\DSL\serialize_to_string; final readonly class SerializeTransformer implements Transformer { @@ -34,8 +36,8 @@ public function transform(Rows $rows, FlowContext $context): Rows $serializer = new Base64Serializer($context->config->serializer()); $result = $rows->map(fn(Row $row) => $this->standalone - ? row(str_entry($target->name(), $serializer->serialize($row))) - : $row->add(str_entry($target->name(), $serializer->serialize($row)))); + ? row(str_entry($target->name(), serialize_to_string($serializer, rows($row)))) + : $row->add(str_entry($target->name(), serialize_to_string($serializer, rows($row))))); $context->telemetry()->transformationCompleted($this, [ TelemetryAttributes::ATTR_TRANSFORMATION_INPUT_ROWS => $rows->count(), diff --git a/src/core/etl/src/Flow/ETL/Transformer/UnserializeTransformer.php b/src/core/etl/src/Flow/ETL/Transformer/UnserializeTransformer.php index 485a1a4b27..80fdc277d2 100644 --- a/src/core/etl/src/Flow/ETL/Transformer/UnserializeTransformer.php +++ b/src/core/etl/src/Flow/ETL/Transformer/UnserializeTransformer.php @@ -15,6 +15,7 @@ use Throwable; use function Flow\ETL\DSL\ref; +use function Flow\Serializer\DSL\unserialize_from_string; use function is_string; final readonly class UnserializeTransformer implements Transformer @@ -51,14 +52,17 @@ public function transform(Rows $rows, FlowContext $context): Rows } try { - return ( - $this->merge - ? $row->merge($serializer->unserialize($serialized, [Row::class]), $this->mergePrefix) - : $serializer->unserialize($serialized, [Row::class]) - ); + $decoded = unserialize_from_string($serializer, $serialized); } catch (SerializationException) { return $row; } + + // a payload that did not round-trip to a single Row is treated as a soft failure + if ($decoded->count() !== 1) { + return $row; + } + + return $this->merge ? $row->merge($decoded->first(), $this->mergePrefix) : $decoded->first(); }); $context->telemetry()->transformationCompleted($this, [ diff --git a/src/core/etl/src/Flow/Floe/AdaptiveFloeEncoder.php b/src/core/etl/src/Flow/Floe/AdaptiveFloeEncoder.php new file mode 100644 index 0000000000..e24069b766 --- /dev/null +++ b/src/core/etl/src/Flow/Floe/AdaptiveFloeEncoder.php @@ -0,0 +1,36 @@ + + */ +final class AdaptiveFloeEncoder implements Encoder +{ + /** + * @var Encoder + */ + private readonly Encoder $delegate; + + public function __construct(Schema $schema) + { + $this->delegate = NativeFloeEncoder::isSupported() + ? new NativeFloeEncoder($schema) + : new PhpFloeEncoder($schema); + } + + public function decode(array $batch): array + { + return $this->delegate->decode($batch); + } + + public function encode(array $batch): array + { + return $this->delegate->encode($batch); + } +} diff --git a/src/core/etl/src/Flow/Floe/ColumnBlueprint.php b/src/core/etl/src/Flow/Floe/ColumnBlueprint.php index 092eba7b1e..20b63b980c 100644 --- a/src/core/etl/src/Flow/Floe/ColumnBlueprint.php +++ b/src/core/etl/src/Flow/Floe/ColumnBlueprint.php @@ -7,20 +7,9 @@ use Flow\ETL\Row\Entry; use Flow\ETL\Row\Entry\EntryInstantiator; use Flow\ETL\Schema\Definition; -use Flow\ETL\Schema\Metadata; final readonly class ColumnBlueprint { - /** - * @var Definition - */ - public Definition $nullableDefinition; - - /** - * @var Definition - */ - public Definition $fromNullDefinition; - /** * @param Definition $definition * @param EntryInstantiator> $instantiator @@ -30,10 +19,5 @@ public function __construct( public Definition $definition, public Decoding\ValueDecoder $decoder, public EntryInstantiator $instantiator, - ) { - $this->fromNullDefinition = $definition - ->makeNullable() - ->setMetadata($definition->metadata()->merge(Metadata::fromArray([Metadata::FROM_NULL => true]))); - $this->nullableDefinition = $definition->makeNullable(); - } + ) {} } diff --git a/src/core/etl/src/Flow/Floe/EncoderColumn.php b/src/core/etl/src/Flow/Floe/EncoderColumn.php deleted file mode 100644 index a8b620a57f..0000000000 --- a/src/core/etl/src/Flow/Floe/EncoderColumn.php +++ /dev/null @@ -1,17 +0,0 @@ - $columns section columns keyed by name - * @param string $schemaBody SCHEMA frame body describing this plan's columns - */ - public function __construct( - public array $columns, - public string $schemaBody, - ) {} -} diff --git a/src/core/etl/src/Flow/Floe/ExtRowFrameEncoder.php b/src/core/etl/src/Flow/Floe/ExtRowFrameEncoder.php deleted file mode 100644 index 814083249f..0000000000 --- a/src/core/etl/src/Flow/Floe/ExtRowFrameEncoder.php +++ /dev/null @@ -1,28 +0,0 @@ -encoder = new RowsEncoder(); - } - - public function encode(Rows $rows): array - { - try { - return $this->encoder->rows($rows); - } catch (ExtensionException $e) { - throw new FloeException($e->getMessage(), 0, $e); - } - } -} diff --git a/src/core/etl/src/Flow/Floe/FloeExtractor.php b/src/core/etl/src/Flow/Floe/FloeExtractor.php index 59a182f62c..378183e6ee 100644 --- a/src/core/etl/src/Flow/Floe/FloeExtractor.php +++ b/src/core/etl/src/Flow/Floe/FloeExtractor.php @@ -106,7 +106,7 @@ public function withOffset(int $offset): self } /** - * @return \Generator + * @return \Generator */ private function readers(FlowContext $context): Generator { @@ -115,7 +115,12 @@ private function readers(FlowContext $context): Generator $listed->close(); yield [ - (new FloeReader($context->filesystem($this->path), $this->codec, $this->chunkSize))->read($filePath), + (new FloeReader( + $context->filesystem($this->path), + $this->codec, + $this->chunkSize, + hydrator: $context->hydrator(), + ))->read($filePath), $filePath->uri(), ]; } diff --git a/src/core/etl/src/Flow/Floe/FloeFile.php b/src/core/etl/src/Flow/Floe/FloeFile.php deleted file mode 100644 index 9c1088681c..0000000000 --- a/src/core/etl/src/Flow/Floe/FloeFile.php +++ /dev/null @@ -1,1023 +0,0 @@ -schemaDecoder = new SchemaDecoder(new ValueDecoder(), new Instantiators()); - $this->rowHydrator = new RowHydrator(); - $this->useExtension = $useExtension ?? extension_loaded('flow_php'); - } - - /** - * @throws FloeException - */ - public function footer(): Footer - { - if ($this->footer !== null) { - return $this->footer; - } - - $source = ($this->openSource)(); - $size = $source->size(); - - if ($size === null) { - throw new FloeException(sprintf( - 'Floe footer requires a sized stream, "%s" does not report its size', - $this->uri, - )); - } - - if ($size < (Format::HEADER_LENGTH + Format::TRAILER_LENGTH)) { - throw new FloeException(sprintf( - 'Floe file "%s" is torn, too small to hold a header and a trailer', - $this->uri, - )); - } - - $flags = Format::validateHeader($source->read(Format::HEADER_LENGTH, 0)); - - if ($flags !== $this->codec->id()) { - throw new FloeException(sprintf( - 'Floe file "%s" was written with codec 0x%02X, expected 0x%02X', - $this->uri, - $flags, - $this->codec->id(), - )); - } - - $footerLength = Format::parseTrailer($source->read(Format::TRAILER_LENGTH, $size - Format::TRAILER_LENGTH)); - - if (($size - Format::TRAILER_LENGTH - $footerLength) < Format::HEADER_LENGTH) { - throw new FloeException(sprintf('Floe file "%s" is torn, footer does not fit inside the file', $this->uri)); - } - - /** @var int<1, max> $footerLength */ - $footer = Footer::fromJson($source->read($footerLength, $size - Format::TRAILER_LENGTH - $footerLength)); - $source->close(); - - return $this->footer = $footer; - } - - /** - * @throws FloeException - */ - public function metadata(): Metadata - { - return $this->footer()->metadata; - } - - /** - * Salvages complete frames from the beginning of the file sequentially - no - * footer, no ranged reads. Rows are yielded as they were written (no - * padding); reading ends silently at the first truncated or invalid frame. - * - * @param int<1, max> $batchSize - * - * @throws FloeException - * - * @return \Generator - */ - public function recover(int $batchSize = 1000): Generator - { - $frames = (new FrameReader(($this->openSource)(), $this->codec->id(), $this->chunkSize))->frames(lenient: true); - - $extDecoder = $this->useExtension ? new RowsDecoder() : null; - $plan = null; - $partitions = []; - $batch = []; - $pending = []; - - foreach ($frames as [$frameType, $frameBody]) { - if ($frameType === Format::FRAME_ROW) { - if ($extDecoder !== null) { - try { - $pending[] = $this->codec->decode($frameBody); - } catch (Throwable) { - break; - } - - if (count($pending) === $batchSize) { - [$ready, $stop] = $this->flushRecoverPending( - $extDecoder, - $pending, - $batch, - $batchSize, - $partitions, - ); - $pending = []; - - foreach ($ready as $rows) { - yield $rows; - } - - if ($stop) { - break; - } - } - - continue; - } - - try { - $row = $this->hydrate(null, $plan, $this->codec->decode($frameBody)); - } catch (Throwable) { - break; - } - - $batch[] = $row; - - if (count($batch) === $batchSize) { - yield $this->batch($batch, $partitions); - $batch = []; - } - } elseif ($frameType === Format::FRAME_SCHEMA) { - if ($extDecoder !== null && $pending !== []) { - [$ready, $stop] = $this->flushRecoverPending( - $extDecoder, - $pending, - $batch, - $batchSize, - $partitions, - ); - $pending = []; - - foreach ($ready as $rows) { - yield $rows; - } - - if ($stop) { - break; - } - } - - try { - if ($extDecoder !== null) { - $extDecoder->schema($frameBody); - } else { - $plan = $this->schemaDecoder->decode($frameBody); - } - } catch (Throwable) { - break; - } - } elseif ($frameType === Format::FRAME_PARTITIONS) { - if ($extDecoder !== null && $pending !== []) { - [$ready, $stop] = $this->flushRecoverPending( - $extDecoder, - $pending, - $batch, - $batchSize, - $partitions, - ); - $pending = []; - - foreach ($ready as $rows) { - yield $rows; - } - - if ($stop) { - break; - } - } - - $partitions = self::decodePartitions($frameBody); - } elseif ($frameType !== Format::FRAME_FOOTER) { - break; - } - } - - if ($extDecoder !== null && $pending !== []) { - [$ready] = $this->flushRecoverPending($extDecoder, $pending, $batch, $batchSize, $partitions); - - foreach ($ready as $rows) { - yield $rows; - } - } - - if ($batch !== []) { - yield $this->batch($batch, $partitions); - } - } - - /** - * A failed batch is replayed row by row so the prefix before the first - * corrupt body still surfaces; the true stop flag ends the recover read. - * - * @param array $pending - * @param array $batch - * @param int<1, max> $batchSize - * @param array $partitions - * - * @return array{0: array, 1: bool} ready batches + stop flag - */ - private function flushRecoverPending( - RowsDecoder $extDecoder, - array $pending, - array &$batch, - int $batchSize, - array $partitions, - ): array { - $stop = false; - - try { - $rows = $extDecoder->rows($pending)->all(); - } catch (Throwable) { - $rows = []; - - foreach ($pending as $body) { - try { - $rows[] = $extDecoder->row($body); - } catch (Throwable) { - break; - } - } - - $stop = true; - } - - $ready = []; - - foreach ($rows as $row) { - $batch[] = $row; - - if (count($batch) === $batchSize) { - $ready[] = $this->batch($batch, $partitions); - $batch = []; - } - } - - return [$ready, $stop]; - } - - /** - * Hot path: frames are walked in-buffer, unlike recover() which keeps the - * reusable FrameReader. offset skips whole leading sections using the footer, - * then the remaining rows inside the start section; limit stops the read - * after that many rows. - * - * @param int<1, max> $batchSize - * - * @throws FloeException - * - * @return \Generator every batch conforms to the merged file schema - */ - public function rows(int $batchSize = 1000, int $offset = 0, ?int $limit = null): Generator - { - if ($offset < 0) { - throw new FloeException('Floe offset must be greater or equal to 0'); - } - - if ($limit !== null && $limit < 1) { - throw new FloeException('Floe limit must be greater than 0'); - } - - if ($offset > 0) { - yield from $this->rowsFromOffset($batchSize, $offset, $limit); - - return; - } - - $footer = $this->footer(); - $fileSchema = $footer->fileSchema(); - - $partitions = []; - - foreach ($footer->partitions as $name => $value) { - $partitions[] = new Partition($name, $value); - } - - /** @var int<1, max> $chunkSize */ - $chunkSize = $this->chunkSize; - $chunks = ($this->openSource)()->iterate($chunkSize); - $buffer = ''; - $position = 0; - - $fill = static function (int $bytes) use (&$buffer, &$position, $chunks): bool { - while ((strlen($buffer) - $position) < $bytes) { - if (!$chunks->valid()) { - return false; - } - - $buffer .= $chunks->current(); - $chunks->next(); - } - - return true; - }; - - if (!$fill(Format::HEADER_LENGTH)) { - throw new FloeException('Floe stream is truncated, header is incomplete'); - } - - $flags = Format::validateHeader(substr($buffer, 0, Format::HEADER_LENGTH)); - - if ($flags !== $this->codec->id()) { - throw new FloeException(sprintf( - 'Floe stream was written with codec 0x%02X, expected 0x%02X', - $flags, - $this->codec->id(), - )); - } - - $position = Format::HEADER_LENGTH; - $extDecoder = $this->useExtension ? new RowsDecoder() : null; - $noopCodec = $this->codec instanceof NoopCodec; - $plan = null; - $conform = RowPadding::forFileSchema($fileSchema, $this->schemaDecoder); - $fileSchemaNames = self::schemaColumnNames($fileSchema); - $fileSchemaCount = count($fileSchemaNames); - $sectionConforms = false; - $batch = []; - $yielded = 0; - $skip = 0; - $pending = []; - $stop = false; - $flushThreshold = $limit !== null && $limit < $batchSize ? $limit : $batchSize; - - try { - while (true) { - if (!$fill(Format::FRAME_HEADER_LENGTH)) { - if ((strlen($buffer) - $position) === 0) { - break; - } - - throw new FloeException('Floe stream is truncated, frame header is incomplete'); - } - - $frameType = ord($buffer[$position]); - $frameLength = unpack('V', $buffer, $position + 1)[1]; - $position += Format::FRAME_HEADER_LENGTH; - - if (!$fill($frameLength)) { - throw new FloeException('Floe stream is truncated, frame body is incomplete'); - } - - $frameEnd = $position + $frameLength; - - if ($frameType === Format::FRAME_ROW) { - if ($extDecoder !== null) { - $pending[] = $noopCodec - ? substr($buffer, $position, $frameLength) - : $this->codec->decode(substr($buffer, $position, $frameLength)); - $position = $frameEnd; - - if (count($pending) === $flushThreshold) { - foreach ($this->emitExtBatch( - $extDecoder, - $pending, - $conform, - $sectionConforms, - $fileSchemaCount, - $batch, - $batchSize, - $partitions, - $limit, - $yielded, - $stop, - $skip, - ) as $ready) { - yield $ready; - } - $pending = []; - - if ($stop) { - return; - } - } - } else { - if ($plan === null) { - throw new FloeException('Floe found a row frame before any schema frame'); - } - - if ($noopCodec) { - $row = $this->rowHydrator->hydrate($plan, $buffer, $position); - - if ($position !== $frameEnd) { - throw new FloeException('Floe row frame length does not match its content'); - } - } else { - $rowBody = $this->codec->decode(substr($buffer, $position, $frameLength)); - $bodyPosition = 0; - $row = $this->rowHydrator->hydrate($plan, $rowBody, $bodyPosition); - - if ($bodyPosition !== strlen($rowBody)) { - throw new FloeException('Floe row frame length does not match its content'); - } - - $position = $frameEnd; - } - - $batch[] = $sectionConforms && $row->entries()->count() === $fileSchemaCount - ? $row - : $conform->apply($row); - - if ($limit !== null && ++$yielded >= $limit) { - yield $this->batch($batch, $partitions); - - return; - } - - if (count($batch) === $batchSize) { - yield $this->batch($batch, $partitions); - $batch = []; - } - } - } elseif ($frameType === Format::FRAME_SCHEMA) { - $frameBody = substr($buffer, $position, $frameLength); - - if ($extDecoder !== null) { - if ($pending !== []) { - foreach ($this->emitExtBatch( - $extDecoder, - $pending, - $conform, - $sectionConforms, - $fileSchemaCount, - $batch, - $batchSize, - $partitions, - $limit, - $yielded, - $stop, - $skip, - ) as $ready) { - yield $ready; - } - $pending = []; - - if ($stop) { - return; - } - } - - $extDecoder->schema($frameBody); - } else { - $plan = $this->schemaDecoder->decode($frameBody); - } - - $sectionConforms = self::sectionNames($frameBody) === $fileSchemaNames; - $position = $frameEnd; - } elseif ($frameType === Format::FRAME_PARTITIONS || $frameType === Format::FRAME_FOOTER) { - $position = $frameEnd; - } else { - throw new FloeException(sprintf('Floe found unknown frame type 0x%02X', $frameType)); - } - - if ($position >= FrameReader::COMPACT_THRESHOLD) { - $buffer = substr($buffer, $position); - $position = 0; - } - } - - if ($extDecoder !== null && $pending !== []) { - foreach ($this->emitExtBatch( - $extDecoder, - $pending, - $conform, - $sectionConforms, - $fileSchemaCount, - $batch, - $batchSize, - $partitions, - $limit, - $yielded, - $stop, - $skip, - ) as $ready) { - yield $ready; - } - - if ($stop) { - return; - } - } - } catch (SerializationException|ExtensionException $e) { - throw new FloeException($e->getMessage(), 0, $e); - } - - if ($batch !== []) { - yield $this->batch($batch, $partitions); - } - } - - /** - * The first $count rows, without scanning the rest of the file. - * - * @param int<1, max> $batchSize - * - * @throws FloeException - * - * @return \Generator - */ - public function head(int $count, int $batchSize = 1000): Generator - { - if ($count < 1) { - throw new FloeException('Floe head count must be greater than 0'); - } - - return $this->rows($batchSize, 0, $count); - } - - /** - * The last $count rows, decoding only from the boundary section onward - * (footer offsets, no scan). A file with fewer rows yields them all. - * - * @param int<1, max> $batchSize - * - * @throws FloeException - * - * @return \Generator - */ - public function tail(int $count, int $batchSize = 1000): Generator - { - if ($count < 1) { - throw new FloeException('Floe tail count must be greater than 0'); - } - - return $this->rows($batchSize, max(0, $this->totalRows() - $count), null); - } - - /** - * Applies the same per-row skip / padding / batch-yield / limit logic as the - * pure-PHP path; $batch, $yielded, $stop and $skip are updated by reference. - * - * @param array $pending - * @param array $batch - * @param array $partitions - * @param int<1, max> $batchSize - * - * @throws ExtensionException - * - * @return array completed batches ready to yield - */ - private function emitExtBatch( - RowsDecoder $extDecoder, - array $pending, - RowPadding $conform, - bool $sectionConforms, - int $fileSchemaCount, - array &$batch, - int $batchSize, - array $partitions, - ?int $limit, - int &$yielded, - bool &$stop, - int &$skip, - ): array { - $ready = []; - - foreach ($extDecoder->rows($pending)->all() as $row) { - if ($skip > 0) { - $skip--; - - continue; - } - - $batch[] = $sectionConforms && $row->entries()->count() === $fileSchemaCount ? $row : $conform->apply($row); - - if ($limit !== null && ++$yielded >= $limit) { - $ready[] = $this->batch($batch, $partitions); - $batch = []; - $stop = true; - - return $ready; - } - - if (count($batch) === $batchSize) { - $ready[] = $this->batch($batch, $partitions); - $batch = []; - } - } - - return $ready; - } - - /** - * @throws FloeException - */ - public function schema(): Schema - { - return $this->footer()->fileSchema(); - } - - /** - * @throws FloeException - */ - public function totalRows(): int - { - return $this->footer()->totalRows; - } - - /** - * @param array $rows - * @param array $partitions - */ - private function batch(array $rows, array $partitions): Rows - { - return $partitions === [] ? new Rows(...$rows) : Rows::partitioned($rows, $partitions); - } - - /** - * @return \Generator - */ - private function chunksFrom(SourceStream $source, int $startByte, int $size): Generator - { - $chunkSize = $this->chunkSize; - $readAt = $startByte; - - while ($readAt < $size) { - /** @var int<1, max> $length */ - $length = $chunkSize < ($size - $readAt) ? $chunkSize : $size - $readAt; - - yield $source->read($length, $readAt); - - $readAt += $length; - } - } - - /** - * Offset pushdown: seeks to the start section's byte offset, preloads its - * schema (its ROWs may have no inline SCHEMA frame when the schema was - * reused) and skips the remaining rows inside it. - * - * @param int<1, max> $batchSize - * @param int<1, max> $offset - * @param null|int<1, max> $limit - * - * @throws FloeException - * - * @return \Generator - */ - private function rowsFromOffset(int $batchSize, int $offset, ?int $limit): Generator - { - $footer = $this->footer(); - $fileSchema = $footer->fileSchema(); - - $partitions = []; - - foreach ($footer->partitions as $name => $value) { - $partitions[] = new Partition($name, $value); - } - - $cumulative = 0; - $startSection = null; - - foreach ($footer->sections as $section) { - if (($cumulative + $section->rowCount) > $offset) { - $startSection = $section; - - break; - } - - $cumulative += $section->rowCount; - } - - if ($startSection === null) { - return; - } - - $skip = $offset - $cumulative; - $schemaBody = $footer->schemaBody($startSection->schemaId); - - $source = ($this->openSource)(); - $size = $source->size(); - - if ($size === null) { - throw new FloeException(sprintf( - 'Floe offset read requires a sized stream, "%s" does not report its size', - $this->uri, - )); - } - - $chunks = $this->chunksFrom($source, $startSection->offset, $size); - - $buffer = ''; - $position = 0; - - $fill = static function (int $bytes) use (&$buffer, &$position, $chunks): bool { - while ((strlen($buffer) - $position) < $bytes) { - if (!$chunks->valid()) { - return false; - } - - $buffer .= $chunks->current(); - $chunks->next(); - } - - return true; - }; - - $extDecoder = $this->useExtension ? new RowsDecoder() : null; - $noopCodec = $this->codec instanceof NoopCodec; - - if ($extDecoder !== null) { - $extDecoder->schema($schemaBody); - $plan = null; - } else { - $plan = $this->schemaDecoder->decode($schemaBody); - } - - $conform = RowPadding::forFileSchema($fileSchema, $this->schemaDecoder); - $fileSchemaNames = self::schemaColumnNames($fileSchema); - $fileSchemaCount = count($fileSchemaNames); - $sectionConforms = self::sectionNames($schemaBody) === $fileSchemaNames; - $batch = []; - $yielded = 0; - // skipped rows are still decoded - a corrupt skipped row must throw in strict mode - $pending = []; - $stop = false; - $flushThreshold = $limit !== null && $limit < $batchSize ? $limit : $batchSize; - - try { - while (true) { - if (!$fill(Format::FRAME_HEADER_LENGTH)) { - if ((strlen($buffer) - $position) === 0) { - break; - } - - throw new FloeException('Floe stream is truncated, frame header is incomplete'); - } - - $frameType = ord($buffer[$position]); - $frameLength = unpack('V', $buffer, $position + 1)[1]; - $position += Format::FRAME_HEADER_LENGTH; - - if (!$fill($frameLength)) { - throw new FloeException('Floe stream is truncated, frame body is incomplete'); - } - - $frameEnd = $position + $frameLength; - - if ($frameType === Format::FRAME_ROW) { - if ($extDecoder !== null) { - $pending[] = $noopCodec - ? substr($buffer, $position, $frameLength) - : $this->codec->decode(substr($buffer, $position, $frameLength)); - $position = $frameEnd; - - if (count($pending) === $flushThreshold) { - foreach ($this->emitExtBatch( - $extDecoder, - $pending, - $conform, - $sectionConforms, - $fileSchemaCount, - $batch, - $batchSize, - $partitions, - $limit, - $yielded, - $stop, - $skip, - ) as $ready) { - yield $ready; - } - $pending = []; - - if ($stop) { - return; - } - } - } elseif ($plan === null) { - throw new FloeException('Floe found a row frame before any schema frame'); - } else { - if ($noopCodec) { - $row = $this->rowHydrator->hydrate($plan, $buffer, $position); - - if ($position !== $frameEnd) { - throw new FloeException('Floe row frame length does not match its content'); - } - } else { - $rowBody = $this->codec->decode(substr($buffer, $position, $frameLength)); - $bodyPosition = 0; - $row = $this->rowHydrator->hydrate($plan, $rowBody, $bodyPosition); - - if ($bodyPosition !== strlen($rowBody)) { - throw new FloeException('Floe row frame length does not match its content'); - } - - $position = $frameEnd; - } - - if ($skip > 0) { - $skip--; - } else { - $batch[] = $sectionConforms && $row->entries()->count() === $fileSchemaCount - ? $row - : $conform->apply($row); - - if ($limit !== null && ++$yielded >= $limit) { - yield $this->batch($batch, $partitions); - - return; - } - - if (count($batch) === $batchSize) { - yield $this->batch($batch, $partitions); - $batch = []; - } - } - } - } elseif ($frameType === Format::FRAME_SCHEMA) { - $frameBody = substr($buffer, $position, $frameLength); - - if ($extDecoder !== null) { - if ($pending !== []) { - foreach ($this->emitExtBatch( - $extDecoder, - $pending, - $conform, - $sectionConforms, - $fileSchemaCount, - $batch, - $batchSize, - $partitions, - $limit, - $yielded, - $stop, - $skip, - ) as $ready) { - yield $ready; - } - $pending = []; - - if ($stop) { - return; - } - } - - $extDecoder->schema($frameBody); - } else { - $plan = $this->schemaDecoder->decode($frameBody); - } - - $sectionConforms = self::sectionNames($frameBody) === $fileSchemaNames; - $position = $frameEnd; - } elseif ($frameType === Format::FRAME_PARTITIONS || $frameType === Format::FRAME_FOOTER) { - $position = $frameEnd; - } else { - throw new FloeException(sprintf('Floe found unknown frame type 0x%02X', $frameType)); - } - - if ($position >= FrameReader::COMPACT_THRESHOLD) { - $buffer = substr($buffer, $position); - $position = 0; - } - } - - if ($extDecoder !== null && $pending !== []) { - foreach ($this->emitExtBatch( - $extDecoder, - $pending, - $conform, - $sectionConforms, - $fileSchemaCount, - $batch, - $batchSize, - $partitions, - $limit, - $yielded, - $stop, - $skip, - ) as $ready) { - yield $ready; - } - - if ($stop) { - return; - } - } - } catch (SerializationException|ExtensionException $e) { - throw new FloeException($e->getMessage(), 0, $e); - } - - if ($batch !== []) { - yield $this->batch($batch, $partitions); - } - } - - /** - * @param null|array $plan - * - * @throws FloeException - */ - private function hydrate(?RowsDecoder $extDecoder, ?array $plan, string $rowBody): Row - { - if ($extDecoder !== null) { - return $extDecoder->row($rowBody); - } - - if ($plan === null) { - throw new FloeException('Floe found a row frame before any schema frame'); - } - - $position = 0; - $row = $this->rowHydrator->hydrate($plan, $rowBody, $position); - - if ($position !== strlen($rowBody)) { - throw new FloeException('Floe row frame length does not match its content'); - } - - return $row; - } - - /** - * @return array - */ - private static function decodePartitions(string $body): array - { - $count = unpack('V', $body)[1]; - $position = 4; - $partitions = []; - - for ($i = 0; $i < $count; $i++) { - $nameLength = unpack('V', $body, $position)[1]; - $name = substr($body, $position + 4, $nameLength); - $position += 4 + $nameLength; - $valueLength = unpack('V', $body, $position)[1]; - $partitions[] = new Partition($name, substr($body, $position + 4, $valueLength)); - $position += 4 + $valueLength; - } - - return $partitions; - } - - /** - * @return array ordered entry names of a SCHEMA frame body - */ - private static function sectionNames(string $schemaBody): array - { - /** @var array $definitions */ - $definitions = json_decode($schemaBody, true, 512, JSON_THROW_ON_ERROR); - $names = []; - - foreach ($definitions as $definition) { - $names[] = $definition['ref']; - } - - return $names; - } - - /** - * @return array ordered column names of a Schema - */ - private static function schemaColumnNames(Schema $schema): array - { - $names = []; - - foreach (array_values($schema->definitions()) as $definition) { - $names[] = $definition->entry()->name(); - } - - return $names; - } -} diff --git a/src/core/etl/src/Flow/Floe/FloeLoader.php b/src/core/etl/src/Flow/Floe/FloeLoader.php index 8f0430971b..9b66ba4454 100644 --- a/src/core/etl/src/Flow/Floe/FloeLoader.php +++ b/src/core/etl/src/Flow/Floe/FloeLoader.php @@ -10,6 +10,7 @@ use Flow\ETL\Loader\Closure; use Flow\ETL\Loader\FileLoader; use Flow\ETL\Rows; +use Flow\ETL\Schema; use Flow\ETL\Schema\Metadata; use Flow\Filesystem\Path; use Flow\Floe\Codec\NoopCodec; @@ -24,12 +25,23 @@ final class FloeLoader implements Closure, FileLoader, Loader */ private array $writers = []; + private ?Schema $schema = null; + + private ?Schema $inferredSchema = null; + public function __construct( private readonly Path $path, private readonly ?Metadata $metadata = null, private readonly Codec $codec = new NoopCodec(), ) {} + public function withSchema(Schema $schema): self + { + $this->schema = $schema; + + return $this; + } + public function closure(FlowContext $context): void { foreach ($this->writers as $writer) { @@ -52,6 +64,10 @@ public function load(Rows $rows, FlowContext $context): void ]); try { + if ($this->schema === null && $this->inferredSchema === null) { + $this->inferredSchema = FloeStreamWriter::unionSchema($rows)->makeNullable(); + } + $stream = $rows->partitions()->count() ? $context->streams()->writeTo($this->path, $rows->partitions()->toArray()) : $context->streams()->writeTo($this->path); @@ -59,8 +75,12 @@ public function load(Rows $rows, FlowContext $context): void $uri = $stream->path()->uri(); if (!array_key_exists($uri, $this->writers)) { - $writer = new FloeWriter($context->filesystem($this->path), $this->codec); - $writer->createOnStream($stream, $this->metadata); + $writer = new FloeWriter( + $context->filesystem($this->path), + $this->codec, + hydrator: $context->hydrator(), + ); + $writer->createForStream($stream, $this->metadata, schema: $this->schema ?? $this->inferredSchema); $this->writers[$uri] = $writer; } diff --git a/src/core/etl/src/Flow/Floe/FloeMerger.php b/src/core/etl/src/Flow/Floe/FloeMerger.php index 0baf377035..20cab432c5 100644 --- a/src/core/etl/src/Flow/Floe/FloeMerger.php +++ b/src/core/etl/src/Flow/Floe/FloeMerger.php @@ -4,16 +4,18 @@ namespace Flow\Floe; +use Flow\ETL\Row\Hydrator; use Flow\ETL\Schema; use Flow\ETL\Schema\Metadata; +use Flow\ETL\Schema\Validator\EvolvingValidator; use Flow\Filesystem\Filesystem; use Flow\Filesystem\Path; +use Flow\Floe\Codec\NoopCodec; use Flow\Floe\Exception\FloeException; use Flow\Floe\Exception\IncompatibleSchemaException; use function count; use function sprintf; -use function strlen; final readonly class FloeMerger { @@ -21,8 +23,11 @@ public function __construct( private Filesystem $filesystem, - private ?bool $useExtension = null, - ) {} + private ?Hydrator $hydrator = null, + private Codec $codec = new NoopCodec(), + ) { + Format::validateCodecId($this->codec->id()); + } /** * @param array $sources @@ -41,97 +46,99 @@ public function merge(array $sources, Path $dest, bool $compact = false, ?Metada $metadata ??= Metadata::empty(); - if ($compact) { - $this->mergeCompact($sources, $reconciled['layouts'], $dest, $metadata); + // a merged file carries exactly one schema; raw splicing is only valid when every + // source already shares it - differing (but compatible) schemas are re-encoded to + // the union, exactly as compaction does + if ($compact || !$this->sourcesShareSchema($reconciled['layouts'], $reconciled['merged'])) { + $this->mergeCompact($sources, $reconciled['layouts'], $reconciled['merged'], $dest, $metadata); return; } - $this->mergeSplice( - $sources, - $reconciled['layouts'], - $reconciled['merged'], - $reconciled['partitions'], - $dest, - $metadata, - ); + $this->mergeSplice($sources, $reconciled['layouts'], $reconciled['merged'], $dest, $metadata); } /** - * Reads every source's footer/layout and validates the merge is possible: - * one shared partition combination and a schema that evolves cleanly. + * Splicing copies source frames verbatim, so it is only valid when every + * SCHEMA frame it copies is structurally identical to the merged footer + * schema - column order included, since row bytes are laid out in schema + * order. Sources that merely reconcile (isSame is order-insensitive) are + * re-encoded by the compact path instead. * + * @param array $layouts + */ + private function sourcesShareSchema(array $layouts, ?Schema $merged): bool + { + if ($merged === null) { + return true; + } + + $mergedNormalized = $merged->normalize(); + + foreach ($layouts as $layout) { + $schema = $layout['footer']->schema(); + + if ($schema->count() === 0) { + continue; + } + + if ($schema->normalize() !== $mergedNormalized) { + return false; + } + } + + return true; + } + + /** * @param array $sources * * @throws FloeException * @throws IncompatibleSchemaException * - * @return array{layouts: array, merged: null|Schema, partitions: array} + * @return array{layouts: array, merged: null|Schema} */ private function reconcile(array $sources): array { $layouts = []; $merged = null; - $partitions = null; foreach ($sources as $index => $source) { $layout = $this->readLayout($source); - $footer = $layout['footer']; + $layouts[$index] = $layout; + $schema = $layout['footer']->schema(); - if ($partitions === null) { - $partitions = $footer->partitions; - } elseif ($footer->partitions !== $partitions) { - throw new IncompatibleSchemaException(sprintf( - 'Floe merge requires all sources to share one partition combination, "%s" differs', - $source->uri(), - )); + // an empty (zero-row) source has no rows and no columns to reconcile + if ($schema->count() === 0) { + continue; } - $schema = $footer->fileSchema(); - if ($merged !== null) { - $this->assertCompatible($merged, $schema, $source); + $validation = (new EvolvingValidator())->validate($merged, $schema); + + if (!$validation->isValid()) { + throw new IncompatibleSchemaException(sprintf( + 'Floe merge cannot reconcile the schema of "%s":%s', + $source->uri(), + $validation->toString(), + )); + } } $merged = $merged === null ? $schema : $merged->merge($schema); - $layouts[$index] = $layout; } - return ['layouts' => $layouts, 'merged' => $merged, 'partitions' => $partitions ?? []]; - } - - /** - * Columns shared with the running merged schema must keep a compatible type; - * columns present in only some sources are fine - Schema::merge auto-nullables - * them and the reader pads the sections that lack them. - * - * @throws IncompatibleSchemaException - */ - private function assertCompatible(Schema $merged, Schema $incoming, Path $source): void - { - foreach ($incoming->definitions() as $definition) { - $existing = $merged->findDefinition($definition->entry()->name()); - - if ($existing !== null && !$existing->isCompatible($definition)) { - throw new IncompatibleSchemaException(sprintf( - 'Floe merge cannot reconcile column "%s" of "%s": %s is not compatible with %s', - $definition->entry()->name(), - $source->uri(), - $definition->type()->toString(), - $existing->type()->toString(), - )); - } - } + return ['layouts' => $layouts, 'merged' => $merged]; } /** * @param array $sources - * @param array $layouts + * @param array $layouts * * @throws FloeException * @throws IncompatibleSchemaException */ - private function mergeCompact(array $sources, array $layouts, Path $dest, Metadata $metadata): void + private function mergeCompact(array $sources, array $layouts, ?Schema $merged, Path $dest, Metadata $metadata): void { $mergedMetadata = Metadata::empty(); @@ -139,10 +146,10 @@ private function mergeCompact(array $sources, array $layouts, Path $dest, Metada $mergedMetadata = $mergedMetadata->merge($layout['footer']->metadata); } - $writer = new FloeWriter($this->filesystem, useExtension: $this->useExtension); - $writer->create($dest, $mergedMetadata->merge($metadata)); + $writer = new FloeWriter($this->filesystem, $this->codec, hydrator: $this->hydrator); + $writer->create($dest, $mergedMetadata->merge($metadata), schema: $merged); - $reader = new FloeReader($this->filesystem, useExtension: $this->useExtension); + $reader = new FloeReader($this->filesystem, $this->codec, hydrator: $this->hydrator); foreach ($sources as $source) { foreach ($reader->read($source)->rows() as $batch) { @@ -155,39 +162,37 @@ private function mergeCompact(array $sources, array $layouts, Path $dest, Metada /** * @param array $sources - * @param array $layouts - * @param array $partitions + * @param array $layouts * * @throws FloeException */ - private function mergeSplice( - array $sources, - array $layouts, - ?Schema $merged, - array $partitions, - Path $dest, - Metadata $metadata, - ): void { - /** @var array>> $schemas */ - $schemas = []; + private function mergeSplice(array $sources, array $layouts, ?Schema $merged, Path $dest, Metadata $metadata): void + { + /** @var array> $partitions */ + $partitions = []; $sections = []; $totalRows = 0; $mergedMetadata = Metadata::empty(); + $runningCombo = []; - $stream = $this->filesystem->writeTo($dest); - $stream->append(Format::header(0x00)); - $destPosition = Format::HEADER_LENGTH; + $frameWriter = new FrameWriter($this->filesystem->writeTo($dest), $this->codec->id(), self::COPY_CHUNK_SIZE); + $frameWriter->header(); foreach ($sources as $index => $source) { $layout = $layouts[$index]; $footer = $layout['footer']; - $copyStart = $index === 0 - ? Format::HEADER_LENGTH - : Format::HEADER_LENGTH + $layout['partitionsFrameLength']; + $copyStart = Format::HEADER_LENGTH; $regionLength = $layout['footerFrameStart'] - $copyStart; - $outputStart = $destPosition; - $schemaIdMap = $this->mergeSchemas($footer->schemas, $schemas); + $partitionsIdMap = $this->mergePartitions($footer->partitions, $partitions); + + $firstCombo = $footer->sections === [] ? [] : $footer->partitionsFor($footer->sections[0]->partitionsId); + + if ($firstCombo !== $runningCombo && $firstCombo === []) { + $frameWriter->partitions($firstCombo); + } + + $outputStart = $frameWriter->position(); if ($regionLength > 0) { $sourceStream = $this->filesystem->readFrom($source); @@ -197,10 +202,9 @@ private function mergeSplice( while ($remaining > 0) { /** @var int<1, max> $length */ $length = $remaining < self::COPY_CHUNK_SIZE ? $remaining : self::COPY_CHUNK_SIZE; - $stream->append($sourceStream->read($length, $at)); + $frameWriter->raw($sourceStream->read($length, $at)); $at += $length; $remaining -= $length; - $destPosition += $length; } $sourceStream->close(); @@ -209,51 +213,54 @@ private function mergeSplice( foreach ($footer->sections as $section) { $sections[] = new Section( $section->offset - $copyStart + $outputStart, - $schemaIdMap[$section->schemaId], + $partitionsIdMap[$section->partitionsId], $section->rowCount, ); } + if ($footer->sections !== []) { + $runningCombo = $footer->partitionsFor($footer->sections[count($footer->sections) - 1]->partitionsId); + } + $totalRows += $footer->totalRows; $mergedMetadata = $mergedMetadata->merge($footer->metadata); } - /** @var array> $fileSchema */ - $fileSchema = $merged?->normalize() ?? []; + /** @var array> $schema */ + $schema = $merged?->normalize() ?? []; $footerJson = (new Footer( Format::VERSION, - FloeWriter::writerVersion(), - $schemas, - $fileSchema, + FloeStreamWriter::writerVersion(), + $schema, $sections, $partitions, $totalRows, $mergedMetadata->merge($metadata), ))->toJson(); - $stream->append(Format::frame(Format::FRAME_FOOTER, $footerJson . Format::trailer(strlen($footerJson)))); - $stream->close(); + $frameWriter->footer($footerJson); + $frameWriter->close(); } /** - * Adds a source's schemas to the combined table (dedup by equality) and - * returns its old->new schema id mapping. + * Adds a source's partition combinations to the merged table (order-sensitive + * dedup) and returns its old->new partitionsId mapping. * - * @param array>> $sourceSchemas - * @param array>> $schemas combined table, updated in place + * @param array> $sourceTable + * @param array> $table combined table, updated in place * * @return array */ - private function mergeSchemas(array $sourceSchemas, array &$schemas): array + private function mergePartitions(array $sourceTable, array &$table): array { $map = []; - foreach ($sourceSchemas as $oldId => $decoded) { + foreach ($sourceTable as $oldId => $combo) { $newId = null; - foreach ($schemas as $id => $known) { - if ($known == $decoded) { + foreach ($table as $id => $known) { + if ($known === $combo) { $newId = $id; break; @@ -261,8 +268,8 @@ private function mergeSchemas(array $sourceSchemas, array &$schemas): array } if ($newId === null) { - $newId = count($schemas); - $schemas[] = $decoded; + $newId = count($table); + $table[] = $combo; } $map[$oldId] = $newId; @@ -274,7 +281,7 @@ private function mergeSchemas(array $sourceSchemas, array &$schemas): array /** * @throws FloeException * - * @return array{footer: Footer, footerFrameStart: int, partitionsFrameLength: int} + * @return array{footer: Footer, footerFrameStart: int} */ private function readLayout(Path $source): array { @@ -283,80 +290,12 @@ private function readLayout(Path $source): array } $stream = $this->filesystem->readFrom($source); - $size = $stream->size(); - - if ($size === null) { - $stream->close(); - - throw new FloeException(sprintf( - 'Floe merge requires sized sources, "%s" does not report its size', - $source->uri(), - )); - } - - if ($size < (Format::HEADER_LENGTH + Format::TRAILER_LENGTH)) { - $stream->close(); - - throw new FloeException(sprintf( - 'Floe merge source "%s" is torn, too small to hold a header and a trailer', - $source->uri(), - )); - } - - $flags = Format::validateHeader($stream->read(Format::HEADER_LENGTH, 0)); - - if ($flags !== 0x00) { - $stream->close(); - - throw new FloeException(sprintf( - 'Floe merge supports only the no-op codec, source "%s" uses codec 0x%02X', - $source->uri(), - $flags, - )); - } - - $footerLength = Format::parseTrailer($stream->read(Format::TRAILER_LENGTH, $size - Format::TRAILER_LENGTH)); - $footerFrameStart = $size - Format::TRAILER_LENGTH - $footerLength - Format::FRAME_HEADER_LENGTH; - - if ($footerFrameStart < Format::HEADER_LENGTH) { - $stream->close(); - - throw new FloeException(sprintf( - 'Floe merge source "%s" is torn, footer does not fit inside the file', - $source->uri(), - )); - } - - /** @var int<1, max> $footerLength */ - $footer = Footer::fromJson($stream->read($footerLength, $size - Format::TRAILER_LENGTH - $footerLength)); + $location = (new FooterReader())->read($stream, $this->codec); $stream->close(); return [ - 'footer' => $footer, - 'footerFrameStart' => $footerFrameStart, - 'partitionsFrameLength' => $this->partitionsFrameLength($footer->partitions), + 'footer' => $location->footer, + 'footerFrameStart' => $location->footerFrameStart, ]; } - - /** - * Byte length of the leading PARTITIONS frame (0 when not partitioned), - * computed from the footer so no frame walk is needed. Order-independent: - * only the summed name/value lengths matter. - * - * @param array $partitions - */ - private function partitionsFrameLength(array $partitions): int - { - if ($partitions === []) { - return 0; - } - - $bodyLength = 4; - - foreach ($partitions as $name => $value) { - $bodyLength += 4 + strlen($name) + 4 + strlen($value); - } - - return Format::FRAME_HEADER_LENGTH + $bodyLength; - } } diff --git a/src/core/etl/src/Flow/Floe/FloeReader.php b/src/core/etl/src/Flow/Floe/FloeReader.php index 7e3961b8d7..47553c6b96 100644 --- a/src/core/etl/src/Flow/Floe/FloeReader.php +++ b/src/core/etl/src/Flow/Floe/FloeReader.php @@ -4,36 +4,34 @@ namespace Flow\Floe; +use Flow\ETL\Row\Hydrator; use Flow\Filesystem\Filesystem; use Flow\Filesystem\Path; -use Flow\Filesystem\SourceStream; use Flow\Floe\Codec\NoopCodec; use Flow\Floe\Exception\FloeException; final readonly class FloeReader { /** - * @param null|bool $useExtension null auto-detects the flow_php extension; the explicit flag exists for parity tests - * - * @throws FloeException + * @param null|Hydrator $hydrator null uses the adaptive hydrator */ public function __construct( private Filesystem $filesystem, private Codec $codec = new NoopCodec(), private int $chunkSize = 65536, - private ?bool $useExtension = null, - ) { - Format::validateCodecId($this->codec->id()); - } + private ?Hydrator $hydrator = null, + ) {} - public function read(Path $path): FloeFile + /** + * @throws FloeException + */ + public function read(Path $path): FloeStreamReader { - return new FloeFile( - fn(): SourceStream => $this->filesystem->readFrom($path), - $path->uri(), + return new FloeStreamReader( + $this->filesystem->readFrom($path), $this->codec, $this->chunkSize, - $this->useExtension, + $this->hydrator, ); } } diff --git a/src/core/etl/src/Flow/Floe/FloeSerializer.php b/src/core/etl/src/Flow/Floe/FloeSerializer.php index 144f3ac09e..3cedc14948 100644 --- a/src/core/etl/src/Flow/Floe/FloeSerializer.php +++ b/src/core/etl/src/Flow/Floe/FloeSerializer.php @@ -4,59 +4,87 @@ namespace Flow\Floe; -use Flow\ETL\Row; +use Flow\ETL\Row\Hydrator; use Flow\ETL\Rows; +use Flow\Filesystem\DestinationStream; +use Flow\Filesystem\SourceStream; +use Flow\Floe\Codec\NoopCodec; +use Flow\Floe\Exception\ExtensionException; use Flow\Floe\Exception\FloeException; use Flow\Serializer\Exception\SerializationException; use Flow\Serializer\Serializer; -use function get_debug_type; -use function implode; -use function is_a; +use function count; use function sprintf; final class FloeSerializer implements Serializer { - private readonly FloeValueSerializer $serializer; + private const int CHUNK_SIZE = 65_536; /** * @param int<1, max> $batchSize + * @param null|Hydrator $hydrator null uses the adaptive hydrator */ - public function __construct(int $batchSize = 1000, ?bool $useExtension = null) - { - $this->serializer = new FloeValueSerializer($batchSize, $useExtension); + public function __construct( + private readonly int $batchSize = 1000, + private readonly ?Hydrator $hydrator = null, + ) { + // @mago-ignore analysis:impossible-condition,redundant-comparison + if ($this->batchSize < 1) { + throw new FloeException('Serializer batch size must be at least 1'); + } } - public function serialize(object $serializable): string + public function serialize(Rows $rows, DestinationStream $destination): void { - if (!$serializable instanceof Rows && !$serializable instanceof Row) { - throw new SerializationException(sprintf( - 'FloeSerializer supports only Rows and Row, got: %s', - get_debug_type($serializable), - )); - } + try { + $writer = new FloeStreamWriter(hydrator: $this->hydrator); + // multi-chunk payloads need the whole-value union upfront so later chunks with columns + // absent from the first still fit the session; a single chunk derives the identical + // union inside write() - skip the second O(rows) schema pass + $writer->create( + $destination, + schema: $rows->count() > $this->batchSize ? FloeStreamWriter::unionSchema($rows) : null, + ); - return $this->serializer->encode($serializable); + foreach ($rows->count() === 0 ? [$rows] : $rows->chunks($this->batchSize) as $chunk) { + $writer->write($chunk); + } + + $writer->close(); + } catch (FloeException|ExtensionException $e) { + throw new SerializationException($e->getMessage(), 0, $e); + } } - public function unserialize(string $serialized, array $classes): object + public function unserialize(SourceStream $source): Rows { try { - $value = $this->serializer->decode($serialized); - } catch (FloeException $e) { - throw new SerializationException($e->getMessage(), 0, $e); - } + $reader = new FloeStreamReader($source, new NoopCodec(), self::CHUNK_SIZE, $this->hydrator); + + $footer = $reader->footer(); - foreach ($classes as $class) { - if (is_a($value, $class)) { - return $value; + $rows = []; + + foreach ($reader->rows($this->batchSize, conform: false) as $batch) { + foreach ($batch->all() as $row) { + $rows[] = $row; + } } - } - throw new SerializationException(sprintf( - 'FloeSerializer::unserialize must return instance of {%s}, got: %s', - implode(', ', $classes), - get_debug_type($value), - )); + if (count($rows) !== $footer->totalRows) { + throw new FloeException(sprintf( + 'Floe payload is corrupted, decoded %d of %d rows', + count($rows), + $footer->totalRows, + )); + } + + return $footer->reconstructRows($rows); + } catch (FloeException|ExtensionException $e) { + throw new SerializationException($e->getMessage(), 0, $e); + } finally { + $source->close(); + } } } diff --git a/src/core/etl/src/Flow/Floe/FloeStreamReader.php b/src/core/etl/src/Flow/Floe/FloeStreamReader.php new file mode 100644 index 0000000000..49cec5d5d2 --- /dev/null +++ b/src/core/etl/src/Flow/Floe/FloeStreamReader.php @@ -0,0 +1,739 @@ + + */ + private ?Encoder $encoder = null; + + private ?Footer $footer = null; + + private readonly Hydrator $hydrator; + + private readonly SchemaDecoder $schemaDecoder; + + /** + * @param null|Hydrator $hydrator null uses the adaptive hydrator + * + * @throws FloeException + */ + public function __construct( + private readonly SourceStream $source, + private readonly Codec $codec, + private readonly int $chunkSize, + ?Hydrator $hydrator = null, + ) { + Format::validateCodecId($this->codec->id()); + $this->schemaDecoder = new SchemaDecoder(new ValueDecoder(), new Instantiators()); + $this->hydrator = $hydrator ?? new AdaptiveRowHydrator(); + } + + /** + * @return Encoder + */ + private function encoder(Schema $schema): Encoder + { + return $this->encoder ??= new AdaptiveFloeEncoder($schema); + } + + /** + * @throws FloeException + */ + public function footer(): Footer + { + return $this->footer ??= (new FooterReader())->read($this->source, $this->codec)->footer; + } + + /** + * @throws FloeException + */ + public function metadata(): Metadata + { + return $this->footer()->metadata; + } + + /** + * Salvages complete frames from the beginning of the file sequentially - no + * footer, no ranged reads. Rows are yielded as they were written (no + * padding); reading ends silently at the first truncated or invalid frame. + * + * @param int<1, max> $batchSize + * + * @throws FloeException + * + * @return \Generator + */ + public function recover(int $batchSize = 1000): Generator + { + $frames = (new FrameReader($this->source, $this->codec->id(), $this->chunkSize))->frames(lenient: true); + + $schema = null; + $partitions = []; + $batch = []; + /** @var list $pending */ + $pending = []; + + foreach ($frames as [$frameType, $frameBody]) { + if ($frameType === Format::FRAME_ROW) { + if ($schema === null) { + break; + } + + try { + $pending[] = $this->codec->decode($frameBody); + } catch (Throwable) { + break; + } + + if (count($pending) === $batchSize) { + [$ready, $stop] = $this->flushRecoverPending($schema, $pending, $batch, $batchSize, $partitions); + $pending = []; + + foreach ($ready as $rows) { + yield $rows; + } + + if ($stop) { + break; + } + } + } elseif ($frameType === Format::FRAME_SCHEMA) { + if ($schema !== null && $pending !== []) { + [$ready, $stop] = $this->flushRecoverPending($schema, $pending, $batch, $batchSize, $partitions); + $pending = []; + + foreach ($ready as $rows) { + yield $rows; + } + + if ($stop) { + break; + } + } + + try { + $schema = $this->decodeSchema($frameBody); + } catch (Throwable) { + break; + } + } elseif ($frameType === Format::FRAME_PARTITIONS) { + if ($schema !== null && $pending !== []) { + [$ready, $stop] = $this->flushRecoverPending($schema, $pending, $batch, $batchSize, $partitions); + $pending = []; + + foreach ($ready as $rows) { + yield $rows; + } + + if ($stop) { + break; + } + } + + if ($batch !== []) { + yield $this->batch($batch, $partitions); + $batch = []; + } + + $partitions = self::decodePartitions($frameBody); + } elseif ($frameType !== Format::FRAME_FOOTER) { + break; + } + } + + if ($schema !== null && $pending !== []) { + [$ready] = $this->flushRecoverPending($schema, $pending, $batch, $batchSize, $partitions); + + foreach ($ready as $rows) { + yield $rows; + } + } + + if ($batch !== []) { + yield $this->batch($batch, $partitions); + } + } + + /** + * A failed batch is replayed row by row so the prefix before the first + * corrupt body still surfaces; the true stop flag ends the recover read. + * + * @param list $pending + * @param array $batch + * @param int<1, max> $batchSize + * @param array $partitions + * + * @return array{0: array, 1: bool} ready batches + stop flag + */ + private function flushRecoverPending( + Schema $schema, + array $pending, + array &$batch, + int $batchSize, + array $partitions, + ): array { + $stop = false; + + try { + $rows = $this->hydrator->hydrate($this->encoder($schema)->decode($pending), $schema)->all(); + } catch (Throwable) { + $rows = []; + + foreach ($pending as $body) { + try { + $rows[] = $this->hydrator->hydrate($this->encoder($schema)->decode([$body]), $schema)->first(); + } catch (Throwable) { + break; + } + } + + $stop = true; + } + + $ready = []; + + foreach ($rows as $row) { + $batch[] = $row; + + if (count($batch) === $batchSize) { + $ready[] = $this->batch($batch, $partitions); + $batch = []; + } + } + + return [$ready, $stop]; + } + + /** + * Hot path: frames are walked in-buffer, unlike recover() which keeps the + * reusable FrameReader. offset skips whole leading sections using the footer, + * then the remaining rows inside the start section; limit stops the read + * after that many rows. + * + * @param int<1, max> $batchSize + * @param bool $conform pad/reorder every batch to the merged file schema (default); false yields rows verbatim per section (the raw read used by spill buckets) + * + * @throws FloeException + * + * @return \Generator every batch conforms to the merged file schema unless $conform is false + */ + public function rows(int $batchSize = 1000, int $offset = 0, ?int $limit = null, bool $conform = true): Generator + { + if ($offset < 0) { + throw new FloeException('Floe offset must be greater or equal to 0'); + } + + if ($limit !== null && $limit < 1) { + throw new FloeException('Floe limit must be greater than 0'); + } + + if ($offset > 0) { + yield from $this->rowsFromOffset($batchSize, $offset, $limit, $conform); + + return; + } + + $footer = $this->footer(); + $fileSchema = $footer->schema(); + + /** @var int<1, max> $chunkSize */ + $chunkSize = $this->chunkSize; + $chunks = $this->source->iterate($chunkSize); + $buffer = ''; + $position = 0; + + $fill = FrameReader::chunkFiller($buffer, $position, $chunks); + + if (!$fill(Format::HEADER_LENGTH)) { + throw new FloeException('Floe stream is truncated, header is incomplete'); + } + + $flags = Format::validateHeader(substr($buffer, 0, Format::HEADER_LENGTH)); + + if ($flags !== $this->codec->id()) { + throw new FloeException(sprintf( + 'Floe stream was written with codec 0x%02X, expected 0x%02X', + $flags, + $this->codec->id(), + )); + } + + yield from $this->walk( + $chunks, + $buffer, + Format::HEADER_LENGTH, + $fileSchema, + $footer->schemaBody(), + 0, + [], + $conform ? RowPadding::forFileSchema($fileSchema, $this->schemaDecoder) : null, + $fileSchema->count(), + $batchSize, + $limit, + ); + } + + /** + * The first $count rows, without scanning the rest of the file. + * + * @param int<1, max> $batchSize + * + * @throws FloeException + * + * @return \Generator + */ + public function head(int $count, int $batchSize = 1000): Generator + { + if ($count < 1) { + throw new FloeException('Floe head count must be greater than 0'); + } + + return $this->rows($batchSize, 0, $count); + } + + /** + * The last $count rows, decoding only from the boundary section onward + * (footer offsets, no scan). A file with fewer rows yields them all. + * + * @param int<1, max> $batchSize + * + * @throws FloeException + * + * @return \Generator + */ + public function tail(int $count, int $batchSize = 1000): Generator + { + if ($count < 1) { + throw new FloeException('Floe tail count must be greater than 0'); + } + + return $this->rows($batchSize, max(0, $this->totalRows() - $count), null); + } + + /** + * The single strict frame-walk shared by rows() and rowsFromOffset(); they + * differ only in how it is seeded - start position, skip and partitions. The + * file carries exactly one schema, so decode state comes from the footer and + * inline SCHEMA frames are only validated against it. recover() keeps its + * own lenient FrameReader walk. + * + * @param \Generator $chunks + * @param array $partitions + * @param int<1, max> $batchSize + * + * @throws FloeException + * + * @return \Generator + */ + private function walk( + Generator $chunks, + string $buffer, + int $position, + Schema $schema, + string $schemaBody, + int $skip, + array $partitions, + ?RowPadding $padding, + int $fileSchemaCount, + int $batchSize, + ?int $limit, + ): Generator { + $fill = FrameReader::chunkFiller($buffer, $position, $chunks); + + $batch = []; + $yielded = 0; + /** @var list $pending */ + $pending = []; + $stop = false; + $flushThreshold = $limit !== null && $limit < $batchSize ? $limit : $batchSize; + + try { + while (true) { + if (!$fill(Format::FRAME_HEADER_LENGTH)) { + if ((strlen($buffer) - $position) === 0) { + break; + } + + throw new FloeException('Floe stream is truncated, frame header is incomplete'); + } + + $frameType = ord($buffer[$position]); + $frameLength = unpack('V', $buffer, $position + 1)[1]; + $position += Format::FRAME_HEADER_LENGTH; + + if (!$fill($frameLength)) { + throw new FloeException('Floe stream is truncated, frame body is incomplete'); + } + + $frameEnd = $position + $frameLength; + + if ($frameType === Format::FRAME_ROW) { + $pending[] = $this->codec->decode(substr($buffer, $position, $frameLength)); + $position = $frameEnd; + + if (count($pending) === $flushThreshold) { + foreach ($this->emitBatch( + $schema, + $pending, + $padding, + $fileSchemaCount, + $batch, + $batchSize, + $partitions, + $limit, + $yielded, + $stop, + $skip, + ) as $ready) { + yield $ready; + } + $pending = []; + + if ($stop) { + return; + } + } + } elseif ($frameType === Format::FRAME_SCHEMA) { + if (substr($buffer, $position, $frameLength) !== $schemaBody) { + throw new FloeException('Floe found a schema frame that does not match the file schema'); + } + + $position = $frameEnd; + } elseif ($frameType === Format::FRAME_PARTITIONS) { + $frameBody = substr($buffer, $position, $frameLength); + + if ($pending !== []) { + foreach ($this->emitBatch( + $schema, + $pending, + $padding, + $fileSchemaCount, + $batch, + $batchSize, + $partitions, + $limit, + $yielded, + $stop, + $skip, + ) as $ready) { + yield $ready; + } + $pending = []; + + if ($stop) { + return; + } + } + + if ($batch !== []) { + yield $this->batch($batch, $partitions); + $batch = []; + } + + $partitions = self::decodePartitions($frameBody); + $position = $frameEnd; + } elseif ($frameType === Format::FRAME_FOOTER) { + $position = $frameEnd; + } else { + throw new FloeException(sprintf('Floe found unknown frame type 0x%02X', $frameType)); + } + + if ($position >= FrameReader::COMPACT_THRESHOLD) { + $buffer = substr($buffer, $position); + $position = 0; + } + } + + if ($pending !== []) { + foreach ($this->emitBatch( + $schema, + $pending, + $padding, + $fileSchemaCount, + $batch, + $batchSize, + $partitions, + $limit, + $yielded, + $stop, + $skip, + ) as $ready) { + yield $ready; + } + + if ($stop) { + return; + } + } + } catch (SerializationException|ExtensionException $e) { + throw new FloeException($e->getMessage(), 0, $e); + } + + if ($batch !== []) { + yield $this->batch($batch, $partitions); + } + } + + /** + * Applies the per-row skip / padding / batch-yield / limit logic to a hydrated + * batch of row frame bodies; $batch, $yielded, $stop and $skip are updated by reference. + * + * @param list $pending + * @param array $batch + * @param array $partitions + * @param int<1, max> $batchSize + * + * @return array completed batches ready to yield + */ + private function emitBatch( + Schema $schema, + array $pending, + ?RowPadding $padding, + int $fileSchemaCount, + array &$batch, + int $batchSize, + array $partitions, + ?int $limit, + int &$yielded, + bool &$stop, + int &$skip, + ): array { + return $this->emitRows( + $this->hydrator->hydrate($this->encoder($schema)->decode($pending), $schema)->all(), + $padding, + $fileSchemaCount, + $batch, + $batchSize, + $partitions, + $limit, + $yielded, + $stop, + $skip, + ); + } + + /** + * Per-row skip / padding / batch-yield / limit logic over already-hydrated + * rows; $batch, $yielded, $stop and $skip are updated by reference. A null + * $padding yields rows verbatim (per-section, unpadded) - the raw read used + * by external-sort/join/group-by buckets. + * + * @param array $rows + * @param array $batch + * @param array $partitions + * @param int<1, max> $batchSize + * + * @return array completed batches ready to yield + */ + private function emitRows( + array $rows, + ?RowPadding $padding, + int $fileSchemaCount, + array &$batch, + int $batchSize, + array $partitions, + ?int $limit, + int &$yielded, + bool &$stop, + int &$skip, + ): array { + $ready = []; + + foreach ($rows as $row) { + if ($skip > 0) { + $skip--; + + continue; + } + + $batch[] = + $padding === null || $row->entries()->count() === $fileSchemaCount ? $row : $padding->apply($row); + + if ($limit !== null && ++$yielded >= $limit) { + $ready[] = $this->batch($batch, $partitions); + $batch = []; + $stop = true; + + return $ready; + } + + if (count($batch) === $batchSize) { + $ready[] = $this->batch($batch, $partitions); + $batch = []; + } + } + + return $ready; + } + + /** + * @throws FloeException + */ + public function schema(): Schema + { + return $this->footer()->schema(); + } + + /** + * @throws FloeException + */ + public function totalRows(): int + { + return $this->footer()->totalRows; + } + + /** + * @param array $rows + * @param array $partitions + */ + private function batch(array $rows, array $partitions): Rows + { + return $partitions === [] ? new Rows(...$rows) : Rows::partitioned($rows, $partitions); + } + + /** + * @return \Generator + */ + private function chunksFrom(SourceStream $source, int $startByte, int $size): Generator + { + $chunkSize = $this->chunkSize; + $readAt = $startByte; + + while ($readAt < $size) { + /** @var int<1, max> $length */ + $length = $chunkSize < ($size - $readAt) ? $chunkSize : $size - $readAt; + + yield $source->read($length, $readAt); + + $readAt += $length; + } + } + + /** + * Offset pushdown: seeks to the start section's byte offset, takes the + * schema from the footer (the file's single SCHEMA frame sits before the + * seek point) and skips the remaining rows inside the start section. + * + * @param int<1, max> $batchSize + * @param int<1, max> $offset + * @param null|int<1, max> $limit + * + * @throws FloeException + * + * @return \Generator + */ + private function rowsFromOffset(int $batchSize, int $offset, ?int $limit, bool $conform = true): Generator + { + $footer = $this->footer(); + $fileSchema = $footer->schema(); + + $cumulative = 0; + $startSection = null; + + foreach ($footer->sections as $section) { + if (($cumulative + $section->rowCount) > $offset) { + $startSection = $section; + + break; + } + + $cumulative += $section->rowCount; + } + + if ($startSection === null) { + return; + } + + $partitions = []; + + foreach ($footer->partitionsFor($startSection->partitionsId) as $name => $value) { + $partitions[] = new Partition($name, $value); + } + + $size = $this->source->size(); + + if ($size === null) { + throw new FloeException(sprintf( + 'Floe offset read requires a sized stream, "%s" does not report its size', + $this->source->path()->uri(), + )); + } + + yield from $this->walk( + $this->chunksFrom($this->source, $startSection->offset, $size), + '', + 0, + $fileSchema, + $footer->schemaBody(), + $offset - $cumulative, + $partitions, + $conform ? RowPadding::forFileSchema($fileSchema, $this->schemaDecoder) : null, + $fileSchema->count(), + $batchSize, + $limit, + ); + } + + /** + * @return array + */ + private static function decodePartitions(string $body): array + { + $count = unpack('V', $body)[1]; + $position = 4; + $partitions = []; + + for ($i = 0; $i < $count; $i++) { + $nameLength = unpack('V', $body, $position)[1]; + $name = substr($body, $position + 4, $nameLength); + $position += 4 + $nameLength; + $valueLength = unpack('V', $body, $position)[1]; + $partitions[] = new Partition($name, substr($body, $position + 4, $valueLength)); + $position += 4 + $valueLength; + } + + return $partitions; + } + + /** + * @throws FloeException + */ + private function decodeSchema(string $schemaBody): Schema + { + try { + return schema_from_json($schemaBody); + } catch (Throwable $e) { + throw new FloeException('Floe failed to decode schema JSON: ' . $e->getMessage(), 0, $e); + } + } +} diff --git a/src/core/etl/src/Flow/Floe/FloeStreamWriter.php b/src/core/etl/src/Flow/Floe/FloeStreamWriter.php new file mode 100644 index 0000000000..b61693e7db --- /dev/null +++ b/src/core/etl/src/Flow/Floe/FloeStreamWriter.php @@ -0,0 +1,473 @@ +> deduped PARTITIONS combinations, index = partitionsId + */ + private array $partitions = []; + + private ?int $lastSectionPartitionsId = null; + + private ?int $sectionPartitionsId = null; + + private ?int $pendingPartitionsId = null; + + private bool $forcePartitionBreak = false; + + /** + * @var array + */ + private array $sections = []; + + private int $sectionOffset = 0; + + private int $sectionRowCount = 0; + + private bool $sectionOpen = false; + + private bool $schemaFrameWritten = false; + + /** + * The one schema fixed for the whole session: explicit at create, the file + * schema on resume, else the first batch's union. + */ + private ?Schema $sessionSchema = null; + + private ?string $sessionSchemaBody = null; + + /** + * @var null|Encoder built once from the session schema + */ + private ?Encoder $sessionEncoder = null; + + private ?FrameWriter $frameWriter = null; + + private int $totalRows = 0; + + private readonly Hydrator $hydrator; + + /** + * @param null|Hydrator $hydrator null uses the adaptive hydrator + * + * @throws FloeException + */ + public function __construct( + private readonly Codec $codec = new NoopCodec(), + ?Hydrator $hydrator = null, + private readonly int $bufferSize = 65_536, + ) { + Format::validateCodecId($this->codec->id()); + $this->hydrator = $hydrator ?? new AdaptiveRowHydrator(); + } + + /** + * Opens a create session over a fresh destination stream, writing the header. + * + * @param ?Metadata $metadata stored in the footer + * @param ?Schema $schema fixes the session schema; null derives it from the first batch + * + * @throws FloeException + */ + public function create(DestinationStream $stream, ?Metadata $metadata = null, ?Schema $schema = null): void + { + $this->guardNotOpen(); + + $this->frameWriter = new FrameWriter($stream, $this->codec->id(), $this->bufferSize); + $this->metadata = $metadata ?? Metadata::empty(); + $this->sessionSchema = $schema; + $this->frameWriter->header(); + $this->open = true; + } + + /** + * Seeds writer state from an existing file's footer and opens an append + * session over its stream. The caller (facade) owns the filesystem-level + * validation (header/trailer/torn/codec checks) before handing over. The + * session schema is forced to the file union - appended batches must fit it. + * + * @param ?Metadata $metadata merged over the existing footer metadata, new keys win + * + * @throws FloeException + */ + public function resume(DestinationStream $stream, Footer $footer, int $fileLength, ?Metadata $metadata = null): void + { + $this->guardNotOpen(); + + $lastSection = $footer->sections === [] ? null : $footer->sections[count($footer->sections) - 1]; + + $this->frameWriter = new FrameWriter( + $stream, + $this->codec->id(), + $this->bufferSize, + startPosition: $fileLength, + ); + $this->metadata = $footer->metadata->merge($metadata ?? Metadata::empty()); + $this->sections = $footer->sections; + + // a zero-row file records no schema - its session is still schemaless and the + // first appended batch fixes the schema, exactly as on create + if ($footer->schema !== []) { + $this->sessionSchema = $footer->schema(); + $this->sessionSchemaBody = $footer->schemaBody(); + } + + $this->schemaFrameWritten = $footer->sections !== []; + $this->lastSectionPartitionsId = $lastSection?->partitionsId; + $this->partitions = $footer->partitions; + $this->totalRows = $footer->totalRows; + $this->open = true; + } + + /** + * @throws FloeException + */ + public function close(): void + { + $this->guardOpen(); + + $this->closeSection(); + + /** @var array> $schema */ + $schema = $this->sessionSchema?->normalize() ?? []; + + $footerJson = (new Footer( + Format::VERSION, + self::writerVersion(), + $schema, + $this->sections, + $this->partitions, + $this->totalRows, + $this->metadata, + ))->toJson(); + + $this->frameWriter()->footer($footerJson); + $this->frameWriter()->close(); + $this->open = false; + } + + /** + * @throws FloeException + * @throws IncompatibleSchemaException + */ + public function write(Rows $rows): void + { + $this->guardOpen(); + $this->trackPartitions($rows); + + if ($rows->count() === 0) { + return; + } + + $batchSchema = self::unionSchema($rows); + + if ($this->sessionEncoder === null) { + $this->openSession($batchSchema); + } + + $this->assertFitsSession($batchSchema); + + if (!$this->sectionOpen || $this->forcePartitionBreak) { + $this->startSection(); + } + + $this->emitBatch($this->hydrator->dehydrate($rows)); + } + + public static function writerVersion(): string + { + return InstalledVersions::isInstalled('flow-php/etl') + ? InstalledVersions::getPrettyVersion('flow-php/etl') ?? 'unknown' + : 'unknown'; + } + + /** + * The union schema of a batch, built without touching the rows' lazily-cached + * schema() - the writer must not mutate caller rows. + */ + public static function unionSchema(Rows $rows): Schema + { + $schema = null; + + foreach ($rows->all() as $row) { + $rowSchema = self::rowSchema($row); + $schema = $schema === null ? $rowSchema : $schema->merge($rowSchema); + } + + return $schema ?? new Schema(); + } + + /** + * The row's schema built from its entry definitions, without touching the + * row's lazily-cached schema(). + */ + private static function rowSchema(Row $row): Schema + { + $definitions = []; + + foreach ($row->entries()->all() as $entry) { + $definitions[] = $entry->definition(); + } + + return new Schema(...$definitions); + } + + /** + * @throws FloeException + */ + private function openSession(Schema $batchSchema): void + { + $this->sessionSchema ??= $batchSchema; + $this->sessionSchemaBody ??= self::encodeSchemaBody($this->sessionSchema); + $this->sessionEncoder = new AdaptiveFloeEncoder($this->sessionSchema); + } + + /** + * @throws FloeException + */ + private static function encodeSchemaBody(Schema $schema): string + { + try { + return json_encode($schema->normalize(), JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new FloeException('Floe failed to encode schema as JSON: ' . $e->getMessage(), 0, $e); + } + } + + /** + * A batch fits the session when every one of its columns exists in the + * session schema with a type the session column accepts (nullable-narrower + * is fine); a wholly-null column fits any column. A new column or an + * incompatible type throws, naming the offending column(s). + * + * @throws FloeException + * @throws IncompatibleSchemaException + */ + private function assertFitsSession(Schema $batchSchema): void + { + $session = $this->sessionSchema ?? throw new FloeException('Floe writer has no active session schema'); + + $violations = []; + + foreach ($batchSchema->definitions() as $batchDefinition) { + $name = $batchDefinition->entry()->name(); + $sessionDefinition = $session->findDefinition($batchDefinition->entry()); + + if ($sessionDefinition === null) { + $violations[] = sprintf('new column "%s"', $name); + + continue; + } + + if ($batchDefinition->type() instanceof NullType) { + continue; + } + + // nullable-narrower is fine (a batch value fits a wider session column); nulls into a + // non-null column or a changed concrete type are drift. Compared structurally via + // type_equals - Definition::isCompatible reconstructs container element definitions, + // which throws for element types without a Definition class (mixed, timezone, ...). + if ( + !$sessionDefinition->isNullable() && $batchDefinition->isNullable() + || !type_equals($sessionDefinition->type(), $batchDefinition->type()) + ) { + $violations[] = sprintf( + 'column "%s" (%s) is not compatible with the session type (%s)', + $name, + $batchDefinition->type()->toString(), + $sessionDefinition->type()->toString(), + ); + } + } + + if ($violations !== []) { + throw new IncompatibleSchemaException(sprintf('Floe write session schema is fixed and this batch does not fit it: %s. ' + . 'Align the pipeline with DataFrame::match($schema) before writing.', implode('; ', $violations))); + } + } + + /** + * Body-encodes the whole batch in one call, then applies the codec and frames + * each row body. + * + * @param list<\Flow\ETL\Row\TypedRowValues> $typed + * + * @throws FloeException + */ + private function emitBatch(array $typed): void + { + foreach ($this->sessionEncoder()->encode($typed) as $encoded) { + $this->frameWriter()->row($this->codec->encode($encoded)); + $this->sectionRowCount++; + $this->totalRows++; + } + } + + private function closeSection(): void + { + if ($this->sectionOpen) { + $this->sections[] = new Section( + $this->sectionOffset, + $this->sectionPartitionsId ?? throw new FloeException( + 'Floe writer has no active section partitions id', + ), + $this->sectionRowCount, + ); + $this->lastSectionPartitionsId = $this->sectionPartitionsId; + $this->sectionOpen = false; + $this->sectionRowCount = 0; + } + } + + /** + * Records the batch's partition combination (in the caller's original order, + * no ksort) into the deduped table and flags a forced section break when it + * differs from the currently open section - a partition change starts a new + * section under the same session schema. + */ + private function trackPartitions(Rows $rows): void + { + $combo = []; + + foreach ($rows->partitions() as $partition) { + $combo[$partition->name] = $partition->value; + } + + $partitionsId = null; + + foreach ($this->partitions as $id => $known) { + if ($known === $combo) { + $partitionsId = $id; + + break; + } + } + + if ($partitionsId === null) { + $partitionsId = count($this->partitions); + $this->partitions[] = $combo; + } + + $this->pendingPartitionsId = $partitionsId; + $this->forcePartitionBreak = $partitionsId !== $this->sectionPartitionsId; + } + + /** + * @throws FloeException + */ + private function guardNotOpen(): void + { + if ($this->frameWriter !== null) { + throw new FloeException('Floe writer session is already open'); + } + } + + /** + * @throws FloeException + */ + private function guardOpen(): void + { + if (!$this->open) { + throw new FloeException('Floe writer session is not open'); + } + } + + /** + * Opens a new section over the fixed session schema. The single SCHEMA frame + * is written once, before the first section; a PARTITIONS frame only when the + * combination changes. + * + * @throws FloeException + */ + private function startSection(): void + { + $this->closeSection(); + + $partitionsId = $this->pendingPartitionsId ?? throw new FloeException( + 'Floe writer starting a section before its partitions were tracked', + ); + + $this->sectionOffset = $this->frameWriter()->position(); + + if ($this->partitionsFrameChanged($partitionsId)) { + $this->frameWriter()->partitions($this->partitions[$partitionsId]); + } + + if (!$this->schemaFrameWritten) { + $this->frameWriter()->schema( + $this->sessionSchemaBody ?? throw new FloeException('Floe writer has no session schema body'), + ); + $this->schemaFrameWritten = true; + } + + $this->sectionOpen = true; + $this->sectionPartitionsId = $partitionsId; + $this->sectionRowCount = 0; + $this->forcePartitionBreak = false; + } + + /** + * A PARTITIONS frame is written only when the section's combination differs + * from what the reader currently holds - mirror of the SCHEMA-frame dedup. + * The reader starts at the empty combination, so the first section emits a + * frame only when it is partitioned; a later change back to unpartitioned + * emits an empty-body (count=0) frame. + */ + private function partitionsFrameChanged(int $partitionsId): bool + { + if ($this->lastSectionPartitionsId === null) { + return $this->partitions[$partitionsId] !== []; + } + + return $partitionsId !== $this->lastSectionPartitionsId; + } + + /** + * @throws FloeException + * + * @return Encoder + */ + private function sessionEncoder(): Encoder + { + return $this->sessionEncoder ?? throw new FloeException('Floe writer has no active session encoder'); + } + + /** + * @throws FloeException + */ + private function frameWriter(): FrameWriter + { + return $this->frameWriter ?? throw new FloeException('Floe writer session is not open'); + } +} diff --git a/src/core/etl/src/Flow/Floe/FloeValueSerializer.php b/src/core/etl/src/Flow/Floe/FloeValueSerializer.php deleted file mode 100644 index 4553ca5378..0000000000 --- a/src/core/etl/src/Flow/Floe/FloeValueSerializer.php +++ /dev/null @@ -1,114 +0,0 @@ - $batchSize - */ - public function __construct( - private readonly int $batchSize = 1000, - private readonly ?bool $useExtension = null, - ) { - // @mago-ignore analysis:impossible-condition,redundant-comparison - if ($this->batchSize < 1) { - throw new FloeException('Serializer batch size must be at least 1'); - } - } - - public function decode(string $bytes): Row|Rows - { - try { - $footer = $this->readFooter($bytes); - - $filesystem = memory_filesystem(); - $path = path('memory://floe-value.floe'); - $filesystem->writeTo($path)->append($bytes)->close(); - - $rows = []; - - foreach ((new FloeReader($filesystem, useExtension: $this->useExtension)) - ->read($path) - ->recover($this->batchSize) as $batch) { - foreach ($batch->all() as $row) { - $rows[] = $row; - } - } - - // recover() salvages a readable prefix; a whole-value decode must not - // silently return partial data - if (count($rows) !== $footer->totalRows) { - throw new FloeException(sprintf( - 'Floe payload is corrupted, recovered %d of %d rows', - count($rows), - $footer->totalRows, - )); - } - - return RowsValueMapper::reconstructFrom($rows, $footer); - } catch (ExtensionException $e) { - throw new FloeException($e->getMessage(), 0, $e); - } - } - - public function encode(Row|Rows $value): string - { - $rows = RowsValueMapper::wrap($value); - - $filesystem = memory_filesystem(); - $path = path('memory://floe-value.floe'); - - try { - $writer = new FloeWriter($filesystem, useExtension: $this->useExtension); - $writer->create($path, RowsValueMapper::metadataFor($value)); - - // an empty Rows still crosses once - chunks() would yield nothing and an - // empty-but-partitioned value would lose its PARTITIONS frame (byte parity) - foreach ($rows->count() === 0 ? [$rows] : $rows->chunks($this->batchSize) as $chunk) { - $writer->write($chunk); - } - - $writer->close(); - } catch (ExtensionException $e) { - throw new FloeException($e->getMessage(), 0, $e); - } - - return $filesystem->readFrom($path)->content(); - } - - /** - * @throws FloeException - */ - private function readFooter(string $bytes): Footer - { - $length = strlen($bytes); - - if ($length < (Format::HEADER_LENGTH + Format::TRAILER_LENGTH)) { - throw new FloeException('Floe payload is torn, too small to hold a header and a trailer'); - } - - $footerLength = Format::parseTrailer(substr($bytes, $length - Format::TRAILER_LENGTH)); - $footerStart = $length - Format::TRAILER_LENGTH - $footerLength; - - if ($footerStart < Format::HEADER_LENGTH) { - throw new FloeException('Floe payload is torn, footer does not fit inside the payload'); - } - - return Footer::fromJson(substr($bytes, $footerStart, $footerLength)); - } -} diff --git a/src/core/etl/src/Flow/Floe/FloeWriter.php b/src/core/etl/src/Flow/Floe/FloeWriter.php index c5990479f7..5aa684589b 100644 --- a/src/core/etl/src/Flow/Floe/FloeWriter.php +++ b/src/core/etl/src/Flow/Floe/FloeWriter.php @@ -4,8 +4,7 @@ namespace Flow\Floe; -use Composer\InstalledVersions; -use Flow\ETL\Row; +use Flow\ETL\Row\Hydrator; use Flow\ETL\Rows; use Flow\ETL\Schema; use Flow\ETL\Schema\Metadata; @@ -14,98 +13,34 @@ use Flow\Filesystem\Path; use Flow\Floe\Codec\NoopCodec; use Flow\Floe\Exception\FloeException; -use Flow\Floe\Exception\IncompatibleSchemaException; -use function array_key_exists; -use function array_values; -use function count; -use function extension_loaded; -use function json_decode; -use function json_encode; -use function ksort; -use function pack; use function sprintf; -use function strlen; - -use const JSON_THROW_ON_ERROR; final class FloeWriter { - private const int IO_BUFFER_SIZE = 65_536; - - private string $buffer = ''; - - private readonly RowFrameEncoder $encoder; - - /** - * Logical write position: flushed bytes + buffered bytes. - */ - private int $length = 0; - - private Metadata $metadata; - - private ?Schema $mergedSchema = null; - - private bool $open = false; - - /** - * @var null|array null until the first write fixes the file's partitions - */ - private ?array $partitions = null; - - private ?Schema $appendBaseSchema = null; - - private ?int $lastSectionSchemaId = null; - - /** - * @var array>> - */ - private array $schemas = []; - - /** - * @var array - */ - private array $sections = []; - - private int $sectionOffset = 0; - - private int $sectionRowCount = 0; - - private ?int $sectionSchemaId = null; - - private ?DestinationStream $stream = null; - - private int $totalRows = 0; + private readonly FloeStreamWriter $inner; /** - * @param null|bool $useExtension null auto-detects flow_php; even when true, a non-Noop codec gets the PHP engine + * @param null|Hydrator $hydrator null uses the adaptive hydrator * * @throws FloeException */ public function __construct( private readonly Filesystem $filesystem, private readonly Codec $codec = new NoopCodec(), - private readonly ?bool $useExtension = null, + ?Hydrator $hydrator = null, + int $bufferSize = 65_536, ) { - Format::validateCodecId($this->codec->id()); - $this->encoder = - ($this->useExtension ?? extension_loaded('flow_php')) && $this->codec instanceof NoopCodec - ? new ExtRowFrameEncoder() - : new PhpRowFrameEncoder($this->codec); + $this->inner = new FloeStreamWriter($this->codec, $hydrator, $bufferSize); } /** - * Opens an append session on an existing file; a missing or empty file is - * created instead. Torn files (invalid trailer) throw. - * * @param ?Metadata $metadata merged over the existing footer metadata, new keys win * * @throws FloeException */ public function append(Path $path, ?Metadata $metadata = null): void { - $this->guardNotOpen(); - if ($this->filesystem->status($path) === null) { $this->create($path, $metadata); @@ -131,56 +66,10 @@ public function append(Path $path, ?Metadata $metadata = null): void return; } - if ($size < (Format::HEADER_LENGTH + Format::TRAILER_LENGTH)) { - $source->close(); - - throw new FloeException(sprintf( - 'Floe file "%s" is torn, too small to hold a header and a trailer', - $path->uri(), - )); - } - - $flags = Format::validateHeader($source->read(Format::HEADER_LENGTH, 0)); - - if ($flags !== $this->codec->id()) { - $source->close(); - - throw new FloeException(sprintf( - 'Floe file "%s" was written with codec 0x%02X, expected 0x%02X', - $path->uri(), - $flags, - $this->codec->id(), - )); - } - - $footerLength = Format::parseTrailer($source->read(Format::TRAILER_LENGTH, $size - Format::TRAILER_LENGTH)); - - if (($size - Format::TRAILER_LENGTH - $footerLength) < Format::HEADER_LENGTH) { - $source->close(); - - throw new FloeException(sprintf( - 'Floe file "%s" is torn, footer does not fit inside the file', - $path->uri(), - )); - } - - /** @var int<1, max> $footerLength */ - $footer = Footer::fromJson($source->read($footerLength, $size - Format::TRAILER_LENGTH - $footerLength)); + $location = (new FooterReader())->read($source, $this->codec); $source->close(); - $lastSection = $footer->sections === [] ? null : $footer->sections[count($footer->sections) - 1]; - - $this->stream = $this->filesystem->appendTo($path); - $this->metadata = $footer->metadata->merge($metadata ?? Metadata::empty()); - $this->schemas = $footer->schemas; - $this->sections = $footer->sections; - $this->appendBaseSchema = $footer->fileSchema(); - $this->lastSectionSchemaId = $lastSection?->schemaId; - $this->length = $size; - $this->mergedSchema = $footer->fileSchema(); - $this->partitions = $footer->partitions; - $this->totalRows = $footer->totalRows; - $this->open = true; + $this->inner->resume($this->filesystem->appendTo($path), $location->footer, $size, $metadata); } /** @@ -188,287 +77,37 @@ public function append(Path $path, ?Metadata $metadata = null): void */ public function close(): void { - $this->guardOpen(); - - $this->closeSection(); - - /** @var array> $fileSchema */ - $fileSchema = $this->mergedSchema?->normalize() ?? []; - - $footerJson = (new Footer( - Format::VERSION, - self::writerVersion(), - $this->schemas, - $fileSchema, - $this->sections, - $this->partitions ?? [], - $this->totalRows, - $this->metadata, - ))->toJson(); - - $this->buffer .= Format::frame(Format::FRAME_FOOTER, $footerJson . Format::trailer(strlen($footerJson))); - - $this->flush(); - $this->stream()->close(); - $this->open = false; + $this->inner->close(); } /** - * Opens a create session, overwriting an existing file. - * * @param ?Metadata $metadata stored in the footer + * @param ?Schema $schema fixes the session schema; null derives it from the first batch * * @throws FloeException */ - public function create(Path $path, ?Metadata $metadata = null): void + public function create(Path $path, ?Metadata $metadata = null, ?Schema $schema = null): void { - $this->beginCreate($this->filesystem->writeTo($path), $metadata ?? Metadata::empty()); + $this->inner->create($this->filesystem->writeTo($path), $metadata, $schema); } /** - * Opens a create session over an already-open destination stream (e.g. one - * provided by the ETL FilesystemStreams machinery). Produces byte-identical - * output to create(); the only difference is who owns the stream. - * * @param ?Metadata $metadata stored in the footer + * @param ?Schema $schema fixes the session schema; null derives it from the first batch * * @throws FloeException */ - public function createOnStream(DestinationStream $stream, ?Metadata $metadata = null): void + public function createForStream(DestinationStream $stream, ?Metadata $metadata = null, ?Schema $schema = null): void { - $this->beginCreate($stream, $metadata ?? Metadata::empty()); + $this->inner->create($stream, $metadata, $schema); } /** * @throws FloeException - * @throws IncompatibleSchemaException + * @throws Exception\IncompatibleSchemaException */ public function write(Rows $rows): void { - $this->guardOpen(); - - $this->fixPartitions($rows); - - foreach ($this->encoder->encode($rows) as $segment) { - if ($segment->schemaBody !== null) { - $this->startSectionFromBody($segment->schemaBody); - } - - $this->buffer .= $segment->frames; - $this->length += strlen($segment->frames); - $this->sectionRowCount += $segment->rowCount; - $this->totalRows += $segment->rowCount; - - if (strlen($this->buffer) >= self::IO_BUFFER_SIZE) { - $this->flush(); - } - } - } - - public static function writerVersion(): string - { - return InstalledVersions::isInstalled('flow-php/etl') - ? InstalledVersions::getPrettyVersion('flow-php/etl') ?? 'unknown' - : 'unknown'; - } - - public static function growSectionPlan(?string $currentSchemaBody, Row $row): EncoderPlan - { - $rowSchema = self::rowSchema($row); - - if ($currentSchemaBody === null) { - $schema = $rowSchema; - } else { - /** @var array> $decoded */ - $decoded = json_decode($currentSchemaBody, true, 512, JSON_THROW_ON_ERROR); - $schema = self::growUnion(Schema::fromArray($decoded), $rowSchema); - } - - return (new SchemaEncoder(new ValueEncoder()))->encodeSchema($schema); - } - - /** - * @throws FloeException - */ - private function beginCreate(DestinationStream $stream, Metadata $metadata): void - { - $this->guardNotOpen(); - - $this->stream = $stream; - $this->metadata = $metadata; - $this->length = Format::HEADER_LENGTH; - $this->buffer = Format::header($this->codec->id()); - $this->open = true; - } - - private function closeSection(): void - { - if ($this->sectionSchemaId !== null) { - $this->sections[] = new Section($this->sectionOffset, $this->sectionSchemaId, $this->sectionRowCount); - $this->lastSectionSchemaId = $this->sectionSchemaId; - $this->sectionSchemaId = null; - $this->sectionRowCount = 0; - } - } - - /** - * @throws FloeException - */ - private function fixPartitions(Rows $rows): void - { - $incoming = []; - - foreach ($rows->partitions() as $partition) { - $incoming[$partition->name] = $partition->value; - } - - ksort($incoming); - - if ($this->partitions === null) { - $this->partitions = $incoming; - - if ($incoming !== []) { - $body = pack('V', count($incoming)); - - foreach ($rows->partitions() as $partition) { - $body .= - pack('V', strlen($partition->name)) - . $partition->name - . pack('V', strlen($partition->value)) - . $partition->value; - } - - $this->buffer .= Format::frame(Format::FRAME_PARTITIONS, $body); - $this->length += Format::FRAME_HEADER_LENGTH + strlen($body); - } - - return; - } - - if ($incoming !== $this->partitions) { - throw new FloeException(sprintf( - 'Floe file holds one partition combination, got rows partitioned by "%s" into a file partitioned by "%s"', - json_encode($incoming, JSON_THROW_ON_ERROR), - json_encode($this->partitions, JSON_THROW_ON_ERROR), - )); - } - } - - private function flush(): void - { - if ($this->buffer !== '') { - $this->stream()->append($this->buffer); - $this->buffer = ''; - } - } - - /** - * @throws FloeException - */ - private function guardNotOpen(): void - { - if ($this->stream !== null) { - throw new FloeException('Floe writer session is already open'); - } - } - - /** - * @throws FloeException - */ - private function guardOpen(): void - { - if (!$this->open) { - throw new FloeException('Floe writer session is not open'); - } - } - - /** - * Bookkeeping half of a section change - the engine already grew the union into $schemaBody. - * - * @throws FloeException - * @throws IncompatibleSchemaException - */ - private function startSectionFromBody(string $schemaBody): void - { - /** @var array> $decoded */ - $decoded = json_decode($schemaBody, true, 512, JSON_THROW_ON_ERROR); - $schema = Schema::fromArray($decoded); - - if ($this->appendBaseSchema !== null) { - (new SchemaEvolution())->validate($this->appendBaseSchema, $schema); - } - - $this->closeSection(); - - $schemaId = null; - - foreach ($this->schemas as $id => $known) { - if ($known == $decoded) { - $schemaId = $id; - - break; - } - } - - if ($schemaId === null) { - $schemaId = count($this->schemas); - $this->schemas[] = $decoded; - } - - $this->sectionOffset = $this->length; - - if ($schemaId !== $this->lastSectionSchemaId) { - $this->buffer .= Format::frame(Format::FRAME_SCHEMA, $schemaBody); - $this->length += Format::FRAME_HEADER_LENGTH + strlen($schemaBody); - } - - $this->mergedSchema = $this->mergedSchema === null ? $schema : $this->mergedSchema->merge($schema); - $this->sectionSchemaId = $schemaId; - $this->sectionRowCount = 0; - } - - /** - * The row's schema built from its entry definitions, without touching the - * row's lazily-cached schema() (the writer must not mutate caller rows). - */ - private static function rowSchema(Row $row): Schema - { - $definitions = []; - - foreach ($row->entries()->all() as $entry) { - $definitions[] = $entry->definition(); - } - - return new Schema(...$definitions); - } - - /** - * Unlike Schema::merge, never nullables a column absent from one side - in - * Floe absence is carried by the row's absent marker, not by a null. - */ - private static function growUnion(Schema $current, Schema $incoming): Schema - { - $definitions = []; - - foreach (array_values($current->definitions()) as $definition) { - $definitions[$definition->entry()->name()] = $definition; - } - - foreach (array_values($incoming->definitions()) as $definition) { - $name = $definition->entry()->name(); - $definitions[$name] = array_key_exists($name, $definitions) - ? $definitions[$name]->merge($definition) - : $definition; - } - - return new Schema(...array_values($definitions)); - } - - /** - * @throws FloeException - */ - private function stream(): DestinationStream - { - return $this->stream ?? throw new FloeException('Floe writer session is not open'); + $this->inner->write($rows); } } diff --git a/src/core/etl/src/Flow/Floe/Footer.php b/src/core/etl/src/Flow/Floe/Footer.php index e0db4e2a3b..9832b0bd20 100644 --- a/src/core/etl/src/Flow/Floe/Footer.php +++ b/src/core/etl/src/Flow/Floe/Footer.php @@ -5,8 +5,11 @@ namespace Flow\Floe; use Flow\ETL\Exception\InvalidArgumentException; +use Flow\ETL\Row; +use Flow\ETL\Rows; use Flow\ETL\Schema; use Flow\ETL\Schema\Metadata; +use Flow\Filesystem\Partition; use Flow\Floe\Exception\FloeException; use Flow\Types\Exception\InvalidTypeException; use JsonException; @@ -17,6 +20,7 @@ use function Flow\Types\DSL\type_list; use function Flow\Types\DSL\type_string; use function Flow\Types\DSL\type_structure; +use function is_array; use function json_decode; use function json_encode; use function sprintf; @@ -26,16 +30,14 @@ final readonly class Footer { /** - * @param array>> $schemas decoded SCHEMA frame bodies, index = schemaId - * @param array> $fileSchema normalized merged schema + * @param array> $schema normalized file schema (a file carries exactly one) * @param array $sections - * @param array $partitions + * @param array> $partitions deduped PARTITIONS frame combinations, index = partitionsId */ public function __construct( public int $version, public string $writer, - public array $schemas, - public array $fileSchema, + public array $schema, public array $sections, public array $partitions, public int $totalRows, @@ -54,14 +56,27 @@ public static function fromJson(string $json): self throw new FloeException('Floe failed to decode footer JSON: ' . $e->getMessage(), 0, $e); } + if (!is_array($data)) { + throw new FloeException('Floe footer is malformed: footer JSON is not an object'); + } + + return self::fromArray($data); + } + + /** + * @param array $data + * + * @throws FloeException + */ + public static function fromArray(array $data): self + { try { $data = type_structure([ 'version' => type_integer(), 'writer' => type_string(), - 'schemas' => type_array(), - 'fileSchema' => type_array(), + 'schema' => type_array(), 'sections' => type_list(type_array()), - 'partitions' => type_array(), + 'partitions' => type_list(type_array()), 'totalRows' => type_integer(), 'metadata' => type_array(), ])->assert($data); @@ -78,11 +93,9 @@ public static function fromJson(string $json): self $sections[] = Section::fromArray($section); } - /** @var array>> $schemas */ - $schemas = $data['schemas']; - /** @var array> $fileSchema */ - $fileSchema = $data['fileSchema']; - /** @var array $partitions */ + /** @var array> $schema */ + $schema = $data['schema']; + /** @var array> $partitions */ $partitions = $data['partitions']; try { @@ -96,8 +109,7 @@ public static function fromJson(string $json): self return new self( $data['version'], $data['writer'], - $schemas, - $fileSchema, + $schema, $sections, $partitions, $data['totalRows'], @@ -105,24 +117,90 @@ public static function fromJson(string $json): self ); } - public function fileSchema(): Schema + public function schema(): Schema { - return Schema::fromArray($this->fileSchema); + return Schema::fromArray($this->schema); } /** + * The single combination of a single-combination file, in the order it was + * written (the PARTITIONS frame / table entry preserves it). A zero-section + * value keeps only its combination in the table, so it is recovered from the + * last non-empty table entry. + * * @throws FloeException + * + * @return array */ - public function schemaBody(int $schemaId): string + public function filePartitions(): array { - if (!array_key_exists($schemaId, $this->schemas)) { - throw new FloeException(sprintf('Floe footer does not hold schema with id %d', $schemaId)); + if ($this->sections !== []) { + $combo = $this->partitionsFor($this->sections[0]->partitionsId); + } else { + $combo = []; + + foreach ($this->partitions as $entry) { + if ($entry !== []) { + $combo = $entry; + } + } + } + + $partitions = []; + + foreach ($combo as $name => $value) { + $partitions[] = new Partition($name, $value); } - return json_encode($this->schemas[$schemaId], JSON_THROW_ON_ERROR); + return $partitions; } - public function toJson(): string + /** + * Rebuilds Rows from already-decoded (un-partitioned) rows, reattaching the + * file's single partition combination in its original order. + * + * @param array $rows + * + * @throws FloeException + */ + public function reconstructRows(array $rows): Rows + { + $partitions = $this->filePartitions(); + + return $partitions === [] ? new Rows(...$rows) : Rows::partitioned($rows, $partitions); + } + + public function schemaBody(): string + { + return json_encode($this->schema, JSON_THROW_ON_ERROR); + } + + /** + * @throws FloeException + * + * @return array + */ + public function partitionsFor(int $partitionsId): array + { + if (!array_key_exists($partitionsId, $this->partitions)) { + throw new FloeException(sprintf('Floe footer does not hold partitions with id %d', $partitionsId)); + } + + return $this->partitions[$partitionsId]; + } + + /** + * @return array{ + * version: int, + * writer: string, + * schema: array>, + * sections: array, + * partitions: array>, + * totalRows: int, + * metadata: array, + * } + */ + public function normalize(): array { $sections = []; @@ -130,15 +208,26 @@ public function toJson(): string $sections[] = $section->normalize(); } - return json_encode([ + return [ 'version' => $this->version, 'writer' => $this->writer, - 'schemas' => $this->schemas, - 'fileSchema' => $this->fileSchema, + 'schema' => $this->schema, 'sections' => $sections, - 'partitions' => (object) $this->partitions, + 'partitions' => $this->partitions, 'totalRows' => $this->totalRows, - 'metadata' => (object) $this->metadata->normalize(), - ], JSON_THROW_ON_ERROR); + 'metadata' => $this->metadata->normalize(), + ]; + } + + /** + * @throws JsonException + */ + public function toJson(): string + { + $data = $this->normalize(); + // metadata is a map: an empty one must encode as a JSON object ({}), not a list ([]) + $data['metadata'] = (object) $data['metadata']; + + return json_encode($data, JSON_THROW_ON_ERROR); } } diff --git a/src/core/etl/src/Flow/Floe/FooterLocation.php b/src/core/etl/src/Flow/Floe/FooterLocation.php new file mode 100644 index 0000000000..7c8c5bc976 --- /dev/null +++ b/src/core/etl/src/Flow/Floe/FooterLocation.php @@ -0,0 +1,13 @@ +path()->uri(); + $size = $source->size(); + + if ($size === null) { + throw new FloeException(sprintf( + 'Floe footer requires a sized stream, "%s" does not report its size', + $uri, + )); + } + + if ($size < (Format::HEADER_LENGTH + Format::TRAILER_LENGTH)) { + throw new FloeException(sprintf('Floe file "%s" is torn, too small to hold a header and a trailer', $uri)); + } + + $flags = Format::validateHeader($source->read(Format::HEADER_LENGTH, 0)); + + if ($flags !== $codec->id()) { + throw new FloeException(sprintf( + 'Floe file "%s" was written with codec 0x%02X, expected 0x%02X', + $uri, + $flags, + $codec->id(), + )); + } + + $footerLength = Format::parseTrailer($source->read(Format::TRAILER_LENGTH, $size - Format::TRAILER_LENGTH)); + + if (($size - Format::TRAILER_LENGTH - $footerLength - Format::FRAME_HEADER_LENGTH) < Format::HEADER_LENGTH) { + throw new FloeException(sprintf('Floe file "%s" is torn, footer does not fit inside the file', $uri)); + } + + /** @var int<1, max> $footerLength */ + $footerFrameStart = $size - Format::TRAILER_LENGTH - $footerLength - Format::FRAME_HEADER_LENGTH; + + return new FooterLocation( + Footer::fromJson($source->read($footerLength, $size - Format::TRAILER_LENGTH - $footerLength)), + $footerFrameStart, + ); + } +} diff --git a/src/core/etl/src/Flow/Floe/Format.php b/src/core/etl/src/Flow/Floe/Format.php index 8d62f9fac0..a8fe35b69e 100644 --- a/src/core/etl/src/Flow/Floe/Format.php +++ b/src/core/etl/src/Flow/Floe/Format.php @@ -4,9 +4,13 @@ namespace Flow\Floe; +use Flow\ETL\Schema\Metadata; use Flow\Floe\Exception\FloeException; +use JsonException; use function chr; +use function json_decode; +use function json_encode; use function ord; use function pack; use function sprintf; @@ -15,6 +19,8 @@ use function substr; use function unpack; +use const JSON_THROW_ON_ERROR; + final class Format { public const string MAGIC = 'FLOE'; @@ -39,18 +45,22 @@ final class Format public const int VALUE_PRESENT = 0x01; - public const int VALUE_NULL_FROM_NULL = 0x02; + public const int VALUE_NULL_WITH_META = 0x02; public const int VALUE_ABSENT = 0x03; + public const int VALUE_PRESENT_WITH_META = 0x04; + public const string VALUE_NULL_BYTE = "\x00"; public const string VALUE_PRESENT_BYTE = "\x01"; - public const string VALUE_NULL_FROM_NULL_BYTE = "\x02"; + public const string VALUE_NULL_WITH_META_BYTE = "\x02"; public const string VALUE_ABSENT_BYTE = "\x03"; + public const string VALUE_PRESENT_WITH_META_BYTE = "\x04"; + public const int DATETIME_IMMUTABLE = 0x00; public const int DATETIME_MUTABLE = 0x01; @@ -82,6 +92,41 @@ public static function frame(int $type, string $body): string return chr($type) . pack('V', strlen($body)) . $body; } + /** + * @throws FloeException + */ + public static function metadataBytes(Metadata $metadata): string + { + try { + $json = json_encode($metadata->normalize(), JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new FloeException('Floe failed to encode per-value metadata: ' . $e->getMessage(), 0, $e); + } + + return pack('V', strlen($json)) . $json; + } + + /** + * @throws FloeException + */ + public static function readMetadata(string $body, int &$position): Metadata + { + $length = unpack('V', substr($body, $position, 4))[1]; + $position += 4; + + $json = substr($body, $position, $length); + $position += $length; + + try { + /** @var array|bool|float|int|string> $map */ + $map = json_decode($json, true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new FloeException('Floe failed to decode per-value metadata: ' . $e->getMessage(), 0, $e); + } + + return Metadata::fromArray($map); + } + public static function header(int $flags): string { return self::MAGIC . chr(self::VERSION) . chr($flags); diff --git a/src/core/etl/src/Flow/Floe/FrameReader.php b/src/core/etl/src/Flow/Floe/FrameReader.php index 3c6dbc4229..c65f7cb1c8 100644 --- a/src/core/etl/src/Flow/Floe/FrameReader.php +++ b/src/core/etl/src/Flow/Floe/FrameReader.php @@ -4,6 +4,7 @@ namespace Flow\Floe; +use Closure; use Flow\Filesystem\SourceStream; use Flow\Floe\Exception\FloeException; use Generator; @@ -25,19 +26,13 @@ public function __construct( ) {} /** - * @throws FloeException + * @param \Generator $chunks * - * @return \Generator frame type and frame body + * @return Closure(int): bool */ - public function frames(bool $lenient = false): Generator + public static function chunkFiller(string &$buffer, int &$position, Generator $chunks): Closure { - /** @var int<1, max> $chunkSize */ - $chunkSize = $this->chunkSize; - $chunks = $this->stream->iterate($chunkSize); - $buffer = ''; - $position = 0; - - $fill = static function (int $bytes) use (&$buffer, &$position, $chunks): bool { + return static function (int $bytes) use (&$buffer, &$position, $chunks): bool { while ((strlen($buffer) - $position) < $bytes) { if (!$chunks->valid()) { return false; @@ -49,6 +44,22 @@ public function frames(bool $lenient = false): Generator return true; }; + } + + /** + * @throws FloeException + * + * @return \Generator frame type and frame body + */ + public function frames(bool $lenient = false): Generator + { + /** @var int<1, max> $chunkSize */ + $chunkSize = $this->chunkSize; + $chunks = $this->stream->iterate($chunkSize); + $buffer = ''; + $position = 0; + + $fill = self::chunkFiller($buffer, $position, $chunks); if (!$fill(Format::HEADER_LENGTH)) { if (strlen($buffer) === 0 && $lenient) { diff --git a/src/core/etl/src/Flow/Floe/FrameSegment.php b/src/core/etl/src/Flow/Floe/FrameSegment.php deleted file mode 100644 index 870e1cac0f..0000000000 --- a/src/core/etl/src/Flow/Floe/FrameSegment.php +++ /dev/null @@ -1,14 +0,0 @@ -position = $startPosition; + } + + public function header(): void + { + $this->buffer .= Format::header($this->codecId); + $this->position += Format::HEADER_LENGTH; + } + + public function row(string $body): void + { + $this->buffer .= chr(Format::FRAME_ROW) . pack('V', strlen($body)) . $body; + $this->position += Format::FRAME_HEADER_LENGTH + strlen($body); + $this->flushIfFull(); + } + + public function schema(string $schemaBody): void + { + $this->buffer .= Format::frame(Format::FRAME_SCHEMA, $schemaBody); + $this->position += Format::FRAME_HEADER_LENGTH + strlen($schemaBody); + $this->flushIfFull(); + } + + /** + * @param array $combo + */ + public function partitions(array $combo): void + { + $body = self::partitionsBody($combo); + $this->buffer .= Format::frame(Format::FRAME_PARTITIONS, $body); + $this->position += Format::FRAME_HEADER_LENGTH + strlen($body); + $this->flushIfFull(); + } + + public function footer(string $footerJson): void + { + $this->buffer .= Format::frame(Format::FRAME_FOOTER, $footerJson . Format::trailer(strlen($footerJson))); + $this->flush(); + } + + /** + * Verbatim byte passthrough for the mergeSplice fast path (no re-encode). + */ + public function raw(string $bytes): void + { + $this->buffer .= $bytes; + $this->position += strlen($bytes); + $this->flushIfFull(); + } + + public function position(): int + { + return $this->position; + } + + public function flush(): void + { + if ($this->buffer !== '') { + $this->stream->append($this->buffer); + $this->buffer = ''; + } + } + + public function close(): void + { + $this->flush(); + $this->stream->close(); + } + + /** + * @param array $combo + */ + private static function partitionsBody(array $combo): string + { + $body = pack('V', count($combo)); + + foreach ($combo as $name => $value) { + $body .= pack('V', strlen($name)) . $name . pack('V', strlen($value)) . $value; + } + + return $body; + } + + private function flushIfFull(): void + { + if (strlen($this->buffer) >= $this->bufferSize) { + $this->flush(); + } + } +} diff --git a/src/core/etl/src/Flow/Floe/NativeFloeEncoder.php b/src/core/etl/src/Flow/Floe/NativeFloeEncoder.php new file mode 100644 index 0000000000..d5982cea0d --- /dev/null +++ b/src/core/etl/src/Flow/Floe/NativeFloeEncoder.php @@ -0,0 +1,74 @@ + + */ +final class NativeFloeEncoder implements Encoder +{ + private readonly RustFloeEncoderNative $native; + + private ?string $schemaBody = null; + + public function __construct( + private readonly Schema $schema, + ) { + if (!self::isSupported()) { + throw new RuntimeException('flow_php extension with RustFloeEncoderNative is not loaded'); + } + + $this->native = new RustFloeEncoderNative(); + } + + public static function isSupported(): bool + { + return extension_loaded('flow_php') && class_exists(RustFloeEncoderNative::class, false); + } + + public function decode(array $batch): array + { + try { + return $this->native->decode($batch, $this->schemaBody()); + } catch (ExtensionException $e) { + throw new FloeException($e->getMessage(), 0, $e); + } + } + + public function encode(array $batch): array + { + try { + return $this->native->encode($batch, $this->schemaBody()); + } catch (ExtensionException $e) { + throw new FloeException($e->getMessage(), 0, $e); + } + } + + private function schemaBody(): string + { + if ($this->schemaBody !== null) { + return $this->schemaBody; + } + + try { + return $this->schemaBody = json_encode($this->schema->normalize(), JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new FloeException('Floe failed to encode schema as JSON: ' . $e->getMessage(), 0, $e); + } + } +} diff --git a/src/core/etl/src/Flow/Floe/PhpFloeEncoder.php b/src/core/etl/src/Flow/Floe/PhpFloeEncoder.php new file mode 100644 index 0000000000..57cfa33385 --- /dev/null +++ b/src/core/etl/src/Flow/Floe/PhpFloeEncoder.php @@ -0,0 +1,163 @@ + + */ +final class PhpFloeEncoder implements Encoder +{ + /** + * @var null|array + */ + private ?array $decodePlan = null; + + /** + * @var null|array per-column value encoder, keyed by column name + */ + private ?array $encoders = null; + + private ?string $schemaBody = null; + + private readonly SchemaDecoder $schemaDecoder; + + public function __construct( + private readonly Schema $schema, + ) { + $this->schemaDecoder = new SchemaDecoder(new ValueDecoder(), new Instantiators()); + } + + public function decode(array $batch): array + { + $decodePlan = $this->decodePlan ??= $this->schemaDecoder->decode($this->schemaBody()); + + $decoded = []; + + foreach ($batch as $body) { + $position = 0; + $values = []; + $metadata = []; + + foreach ($decodePlan as $column) { + $flag = ord($body[$position++]); + + if ($flag === Format::VALUE_ABSENT) { + continue; + } + + if ($flag === Format::VALUE_PRESENT) { + $values[$column->name] = $column->decoder->decode($body, $position); + } elseif ($flag === Format::VALUE_NULL) { + $values[$column->name] = null; + } elseif ($flag === Format::VALUE_PRESENT_WITH_META) { + $metadata[$column->name] = Format::readMetadata($body, $position); + $values[$column->name] = $column->decoder->decode($body, $position); + } elseif ($flag === Format::VALUE_NULL_WITH_META) { + $metadata[$column->name] = Format::readMetadata($body, $position); + $values[$column->name] = null; + } else { + throw new FloeException(sprintf('Floe found unknown value flag 0x%02X', $flag)); + } + } + + if ($position !== strlen($body)) { + throw new FloeException('Floe row frame length does not match its content'); + } + + $decoded[] = new RawRowValues($values, $metadata); + } + + return $decoded; + } + + public function encode(array $batch): array + { + $encoders = $this->encoders ??= $this->buildEncoders(); + + $bodies = []; + + foreach ($batch as $rowValues) { + $body = ''; + + foreach ($this->schema->definitions() as $name => $definition) { + if (!array_key_exists($name, $rowValues->values)) { + $body .= Format::VALUE_ABSENT_BYTE; + + continue; + } + + // @mago-ignore analysis:mixed-assignment + $value = $rowValues->values[$name]; + $metadata = $rowValues->metadata[$name] ?? Metadata::empty(); + $columnMetadata = $definition->metadata(); + $diverges = $metadata->isEmpty() && $columnMetadata->isEmpty() + ? false + : !$metadata->isEqual($columnMetadata); + + if ($value === null) { + $body .= $diverges + ? Format::VALUE_NULL_WITH_META_BYTE . Format::metadataBytes($metadata) + : Format::VALUE_NULL_BYTE; + + continue; + } + + $body .= $diverges + ? Format::VALUE_PRESENT_WITH_META_BYTE + . Format::metadataBytes($metadata) + . $encoders[$name]->encode($value) + : Format::VALUE_PRESENT_BYTE . $encoders[$name]->encode($value); + } + + $bodies[] = $body; + } + + return $bodies; + } + + /** + * @return array + */ + private function buildEncoders(): array + { + $valueEncoder = new ValueEncoder(); + $encoders = []; + + foreach ($this->schema->definitions() as $name => $definition) { + $encoders[$name] = $valueEncoder->encoderFor($definition->type()); + } + + return $encoders; + } + + private function schemaBody(): string + { + if ($this->schemaBody !== null) { + return $this->schemaBody; + } + + try { + return $this->schemaBody = json_encode($this->schema->normalize(), JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw new FloeException('Floe failed to encode schema as JSON: ' . $e->getMessage(), 0, $e); + } + } +} diff --git a/src/core/etl/src/Flow/Floe/PhpRowFrameEncoder.php b/src/core/etl/src/Flow/Floe/PhpRowFrameEncoder.php deleted file mode 100644 index 8dc86d2416..0000000000 --- a/src/core/etl/src/Flow/Floe/PhpRowFrameEncoder.php +++ /dev/null @@ -1,55 +0,0 @@ -all() as $row) { - if ($this->plan === null || !$this->schemaTracker->fits($this->plan, $row)) { - if ($rowCount > 0 || $schemaBody !== null) { - $segments[] = new FrameSegment($schemaBody, $frames, $rowCount); - } - - $this->plan = FloeWriter::growSectionPlan($this->plan?->schemaBody, $row); - $schemaBody = $this->plan->schemaBody; - $frames = ''; - $rowCount = 0; - } - - $body = $this->codec->encode($this->rowEncoder->encode($this->plan, $row)); - - $frames .= chr(Format::FRAME_ROW) . pack('V', strlen($body)) . $body; - $rowCount++; - } - - if ($rowCount > 0) { - $segments[] = new FrameSegment($schemaBody, $frames, $rowCount); - } - - return $segments; - } -} diff --git a/src/core/etl/src/Flow/Floe/RowEncoder.php b/src/core/etl/src/Flow/Floe/RowEncoder.php deleted file mode 100644 index 54a757a182..0000000000 --- a/src/core/etl/src/Flow/Floe/RowEncoder.php +++ /dev/null @@ -1,79 +0,0 @@ -entries()->all(); - - // fast path: the row's columns align positionally with the plan (every row - // of a homogeneous batch), so no per-row name-keyed map is needed - if (count($entries) === count($plan->columns)) { - $body = ''; - $index = 0; - - foreach ($plan->columns as $column) { - $entry = $entries[$index++]; - - if ($entry->name() !== $column->name) { - return $this->encodeByName($plan, $entries); - } - - $body .= $this->entryBytes($column, $entry); - } - - return $body; - } - - return $this->encodeByName($plan, $entries); - } - - /** - * @param array> $entries - */ - private function encodeByName(EncoderPlan $plan, array $entries): string - { - $keyed = []; - - foreach ($entries as $entry) { - $keyed[$entry->name()] = $entry; - } - - $body = ''; - - foreach ($plan->columns as $column) { - $entry = $keyed[$column->name] ?? null; - - $body .= $entry === null ? Format::VALUE_ABSENT_BYTE : $this->entryBytes($column, $entry); - } - - return $body; - } - - /** - * @param Entry $entry - */ - private function entryBytes(EncoderColumn $column, Entry $entry): string - { - // @mago-ignore analysis:mixed-assignment - $value = $entry->value(); - - if ($value === null) { - return $entry->definition()->metadata()->has(Metadata::FROM_NULL) - ? Format::VALUE_NULL_FROM_NULL_BYTE - : Format::VALUE_NULL_BYTE; - } - - return Format::VALUE_PRESENT_BYTE . $column->encoder->encode($value); - } -} diff --git a/src/core/etl/src/Flow/Floe/RowFrameEncoder.php b/src/core/etl/src/Flow/Floe/RowFrameEncoder.php deleted file mode 100644 index bd946185ac..0000000000 --- a/src/core/etl/src/Flow/Floe/RowFrameEncoder.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ - public function encode(Rows $rows): array; -} diff --git a/src/core/etl/src/Flow/Floe/RowHydrator.php b/src/core/etl/src/Flow/Floe/RowHydrator.php deleted file mode 100644 index 49d440d104..0000000000 --- a/src/core/etl/src/Flow/Floe/RowHydrator.php +++ /dev/null @@ -1,50 +0,0 @@ - $plan - */ - public function hydrate(array $plan, string $data, int &$position): Row - { - $entries = []; - - foreach ($plan as $column) { - $flag = ord($data[$position++]); - - if ($flag === Format::VALUE_ABSENT) { - // The row had no such column; reconstruct it as written (omitted). - continue; - } - - if ($flag === Format::VALUE_PRESENT) { - // @mago-ignore analysis:mixed-assignment - $value = $column->decoder->decode($data, $position); - $definition = clone $column->definition; - } elseif ($flag === Format::VALUE_NULL) { - $value = null; - $definition = clone $column->nullableDefinition; - } elseif ($flag === Format::VALUE_NULL_FROM_NULL) { - $value = null; - $definition = clone $column->fromNullDefinition; - } else { - throw new SerializationException(sprintf('Floe found unknown value flag 0x%02X', $flag)); - } - - $entries[$column->name] = $column->instantiator->instantiate($column->name, $value, $definition); - } - - return new Row(Entries::recreate($entries)); - } -} diff --git a/src/core/etl/src/Flow/Floe/RowPadding.php b/src/core/etl/src/Flow/Floe/RowPadding.php index 739975d4ce..ed45daff05 100644 --- a/src/core/etl/src/Flow/Floe/RowPadding.php +++ b/src/core/etl/src/Flow/Floe/RowPadding.php @@ -9,7 +9,6 @@ use Flow\ETL\Row\Entry; use Flow\ETL\Schema; -use function array_values; use function json_encode; use const JSON_THROW_ON_ERROR; @@ -30,11 +29,13 @@ public static function forFileSchema(Schema $fileSchema, SchemaDecoder $decoder) $order = []; $nulls = []; - foreach (array_values($fileSchema->definitions()) as $definition) { - $name = $definition->entry()->name(); - $order[] = $name; - $column = $decoder->decode(json_encode([$definition->normalize()], JSON_THROW_ON_ERROR))[0]; - $nulls[$name] = $column->instantiator->instantiate($name, null, clone $column->fromNullDefinition); + foreach ($decoder->decode(json_encode($fileSchema->normalize(), JSON_THROW_ON_ERROR)) as $column) { + $order[] = $column->name; + $nulls[$column->name] = $column->instantiator->instantiate( + $column->name, + null, + $column->definition->makeNullable(), + ); } return new self($order, $nulls); diff --git a/src/core/etl/src/Flow/Floe/RowsValueMapper.php b/src/core/etl/src/Flow/Floe/RowsValueMapper.php deleted file mode 100644 index 9898394c83..0000000000 --- a/src/core/etl/src/Flow/Floe/RowsValueMapper.php +++ /dev/null @@ -1,105 +0,0 @@ -partitions()->count() > 0) { - $metadata = $metadata->add(self::PARTITION_ORDER_KEY, array_map( - static fn(Partition $p): string => $p->name, - $value->partitions()->toArray(), - )); - } - - return $metadata; - } - - /** - * The value's partitions in the caller's original order (footer metadata) when recorded, - * in footer order otherwise. - * - * @throws FloeException - * - * @return array - */ - public static function partitionsFrom(Footer $footer): array - { - $partitions = []; - - if ($footer->metadata->has(self::PARTITION_ORDER_KEY)) { - try { - /** @var list $order */ - $order = $footer->metadata->getAs(self::PARTITION_ORDER_KEY, type_list(type_string()), []); - } catch (CastingException $e) { - throw new FloeException('Floe cache partition order metadata is malformed: ' . $e->getMessage(), 0, $e); - } - - foreach ($order as $name) { - $partitions[] = new Partition($name, $footer->partitions[$name]); - } - } else { - foreach ($footer->partitions as $name => $value) { - $partitions[] = new Partition($name, $value); - } - } - - return $partitions; - } - - /** - * Rebuilds the original Row|Rows from already-decoded (un-partitioned) rows and the file footer: - * reattaches partitions in the caller's original order (footer metadata) and unwraps a tagged - * single Row. - * - * @param array $rows - * - * @throws FloeException - */ - public static function reconstructFrom(array $rows, Footer $footer): Row|Rows - { - $partitions = self::partitionsFrom($footer); - - $valueType = $footer->metadata->has(self::VALUE_TYPE_KEY) - ? $footer->metadata->get(self::VALUE_TYPE_KEY) - : self::VALUE_TYPE_ROWS; - - if ($valueType === self::VALUE_TYPE_ROW) { - return $rows[0] ?? throw new FloeException('Floe value tagged as a single Row contained no rows'); - } - - return $partitions === [] ? new Rows(...$rows) : Rows::partitioned($rows, $partitions); - } - - public static function wrap(Row|Rows $value): Rows - { - return $value instanceof Row ? new Rows($value) : $value; - } -} diff --git a/src/core/etl/src/Flow/Floe/SchemaDecoder.php b/src/core/etl/src/Flow/Floe/SchemaDecoder.php index 03443094ca..408bbc98da 100644 --- a/src/core/etl/src/Flow/Floe/SchemaDecoder.php +++ b/src/core/etl/src/Flow/Floe/SchemaDecoder.php @@ -17,6 +17,7 @@ use Flow\ETL\Row\Entry\JsonEntry; use Flow\ETL\Row\Entry\ListEntry; use Flow\ETL\Row\Entry\MapEntry; +use Flow\ETL\Row\Entry\NullEntry; use Flow\ETL\Row\Entry\StringEntry; use Flow\ETL\Row\Entry\StructureEntry; use Flow\ETL\Row\Entry\TimeEntry; @@ -34,13 +35,13 @@ use Flow\ETL\Schema\Definition\JsonDefinition; use Flow\ETL\Schema\Definition\ListDefinition; use Flow\ETL\Schema\Definition\MapDefinition; +use Flow\ETL\Schema\Definition\NullDefinition; use Flow\ETL\Schema\Definition\StringDefinition; use Flow\ETL\Schema\Definition\StructureDefinition; use Flow\ETL\Schema\Definition\TimeDefinition; use Flow\ETL\Schema\Definition\UuidDefinition; use Flow\ETL\Schema\Definition\XMLDefinition; use Flow\ETL\Schema\Definition\XMLElementDefinition; -use Flow\ETL\Schema\Metadata; use Flow\Floe\Exception\FloeException; use Flow\Types\Exception\InvalidTypeException; use JsonException; @@ -73,6 +74,7 @@ final class SchemaDecoder UuidDefinition::class => UuidEntry::class, XMLDefinition::class => XMLEntry::class, XMLElementDefinition::class => XMLElementEntry::class, + NullDefinition::class => NullEntry::class, ]; public function __construct( @@ -106,14 +108,11 @@ public function decode(string $schemaJson): array /** @var array{ref: string, type: array, nullable?: bool, metadata?: array|bool|float|int|string>} $normalized */ foreach ($definitions as $normalized) { - $metadata = $normalized['metadata'] ?? []; - unset($metadata[Metadata::FROM_NULL]); - $definition = definition_from_array([ 'ref' => $normalized['ref'], 'type' => $normalized['type'], - 'nullable' => false, - 'metadata' => $metadata, + 'nullable' => $normalized['nullable'] ?? false, + 'metadata' => $normalized['metadata'] ?? [], ]); $entryClass = self::ENTRY_CLASSES[$definition::class] ?? throw new FloeException(sprintf( @@ -121,11 +120,6 @@ public function decode(string $schemaJson): array $definition::class, )); - $fromNullDefinition = $definition->makeNullable(); - $fromNullDefinition->setMetadata( - $fromNullDefinition->metadata()->merge(Metadata::fromArray([Metadata::FROM_NULL => true])), - ); - /** @var class-string> $entryClass */ $plan[] = new ColumnBlueprint( $normalized['ref'], diff --git a/src/core/etl/src/Flow/Floe/SchemaEncoder.php b/src/core/etl/src/Flow/Floe/SchemaEncoder.php deleted file mode 100644 index 20a890732d..0000000000 --- a/src/core/etl/src/Flow/Floe/SchemaEncoder.php +++ /dev/null @@ -1,57 +0,0 @@ -definitions()) as $definition) { - $name = $definition->entry()->name(); - $columns[$name] = $this->column($name, $definition->type()); - $definitions[] = $definition->normalize(); - } - - return new EncoderPlan($columns, json_encode($definitions, JSON_THROW_ON_ERROR)); - } catch (JsonException $e) { - throw new FloeException('Floe failed to encode schema as JSON: ' . $e->getMessage(), 0, $e); - } - } - - /** - * @param Type $type - * - * @throws JsonException - */ - private function column(string $name, Type $type): EncoderColumn - { - return new EncoderColumn( - $name, - json_encode($type->normalize(), JSON_THROW_ON_ERROR), - $this->valueEncoder->encoderFor($type), - ); - } -} diff --git a/src/core/etl/src/Flow/Floe/SchemaEvolution.php b/src/core/etl/src/Flow/Floe/SchemaEvolution.php deleted file mode 100644 index 9dd1add295..0000000000 --- a/src/core/etl/src/Flow/Floe/SchemaEvolution.php +++ /dev/null @@ -1,60 +0,0 @@ -definitions() as $incomingDefinition) { - $name = $incomingDefinition->entry()->name(); - $existing = $fileSchema->findDefinition($name); - - if ($existing === null) { - if (!$incomingDefinition->isNullable()) { - throw new IncompatibleSchemaException(sprintf( - 'Floe append adds new column "%s" which must be nullable - rows already in the file hold null for it', - $name, - )); - } - - continue; - } - - if (!$existing->isCompatible($incomingDefinition)) { - throw new IncompatibleSchemaException(sprintf( - 'Floe append changes column "%s" from %s to %s which is not compatible', - $name, - $existing->type()->toString(), - $incomingDefinition->type()->toString(), - )); - } - } - - foreach ($fileSchema->definitions() as $existingDefinition) { - $name = $existingDefinition->entry()->name(); - - if ($incoming->findDefinition($name) === null && !$existingDefinition->isNullable()) { - throw new IncompatibleSchemaException(sprintf( - 'Floe append omits column "%s" which is not nullable in the file schema', - $name, - )); - } - } - } -} diff --git a/src/core/etl/src/Flow/Floe/SchemaTracker.php b/src/core/etl/src/Flow/Floe/SchemaTracker.php deleted file mode 100644 index df6b715856..0000000000 --- a/src/core/etl/src/Flow/Floe/SchemaTracker.php +++ /dev/null @@ -1,100 +0,0 @@ - true, - PositiveIntegerType::class => true, - FloatType::class => true, - BooleanType::class => true, - StringType::class => true, - NonEmptyStringType::class => true, - NumericStringType::class => true, - ScalarType::class => true, - DateTimeType::class => true, - DateType::class => true, - TimeType::class => true, - HTMLType::class => true, - HTMLElementType::class => true, - TimeZoneType::class => true, - UuidType::class => true, - JsonType::class => true, - XMLType::class => true, - XMLElementType::class => true, - ]; - - /** - * @var array - */ - private array $fingerprints = []; - - /** - * Container types (structure, list, map) normalize recursively, which is too expensive to - * repeat for every row; their instances are shared across rows, so fingerprints are cached - * per instance. - * - * @var \WeakMap, string> - */ - private WeakMap $structuralFingerprints; - - public function __construct() - { - $this->structuralFingerprints = new WeakMap(); - } - - public function fits(EncoderPlan $plan, Row $row): bool - { - foreach ($row->entries()->all() as $entry) { - $name = $entry->name(); - - if (!array_key_exists($name, $plan->columns)) { - return false; - } - - $type = $entry->definition()->type(); - - $fingerprint = array_key_exists($type::class, self::CONSTANT_NORMALIZE_TYPES) - ? ($this->fingerprints[$type::class] ??= json_encode($type->normalize(), JSON_THROW_ON_ERROR)) - : ($this->structuralFingerprints[$type] ??= json_encode($type->normalize(), JSON_THROW_ON_ERROR)); - - if ($fingerprint !== $plan->columns[$name]->typeFingerprint) { - return false; - } - } - - return true; - } -} diff --git a/src/core/etl/src/Flow/Floe/Section.php b/src/core/etl/src/Flow/Floe/Section.php index 88ef9e60df..a759dcf241 100644 --- a/src/core/etl/src/Flow/Floe/Section.php +++ b/src/core/etl/src/Flow/Floe/Section.php @@ -10,16 +10,11 @@ use function Flow\Types\DSL\type_integer; use function Flow\Types\DSL\type_structure; -/** - * One schema section of a Floe file - the frames written between schema - * changes within a single write session. Appends always start a new section, - * even when they reuse the previous schema. - */ final readonly class Section { public function __construct( public int $offset, - public int $schemaId, + public int $partitionsId, public int $rowCount, ) {} @@ -33,21 +28,25 @@ public static function fromArray(array $data): self try { $data = type_structure([ 'offset' => type_integer(), - 'schemaId' => type_integer(), + 'partitionsId' => type_integer(), 'rowCount' => type_integer(), ])->assert($data); } catch (InvalidTypeException $e) { throw new FloeException('Floe footer section is malformed: ' . $e->getMessage(), 0, $e); } - return new self($data['offset'], $data['schemaId'], $data['rowCount']); + return new self($data['offset'], $data['partitionsId'], $data['rowCount']); } /** - * @return array{offset: int, schemaId: int, rowCount: int} + * @return array{offset: int, partitionsId: int, rowCount: int} */ public function normalize(): array { - return ['offset' => $this->offset, 'schemaId' => $this->schemaId, 'rowCount' => $this->rowCount]; + return [ + 'offset' => $this->offset, + 'partitionsId' => $this->partitionsId, + 'rowCount' => $this->rowCount, + ]; } } diff --git a/src/core/etl/src/Flow/Floe/ValueEncoder.php b/src/core/etl/src/Flow/Floe/ValueEncoder.php index a0a456d599..0f063fbdc3 100644 --- a/src/core/etl/src/Flow/Floe/ValueEncoder.php +++ b/src/core/etl/src/Flow/Floe/ValueEncoder.php @@ -67,6 +67,22 @@ final class ValueEncoder { + private readonly DateTimeEncoder $dateTimeEncoder; + + private readonly JsonEncoder $jsonEncoder; + + private readonly TimeZoneEncoder $timeZoneEncoder; + + private readonly UuidEncoder $uuidEncoder; + + public function __construct() + { + $this->dateTimeEncoder = new DateTimeEncoder(); + $this->timeZoneEncoder = new TimeZoneEncoder(); + $this->uuidEncoder = new UuidEncoder(); + $this->jsonEncoder = new JsonEncoder(); + } + /** * @param Type $type * @@ -83,11 +99,11 @@ public function encoderFor(Type $type): Encoding\ValueEncoder NumericStringType::class, ClassStringType::class, => new StringEncoder(), - TimeZoneType::class => new TimeZoneEncoder(), - DateTimeType::class, DateType::class => new DateTimeEncoder(), + TimeZoneType::class => $this->timeZoneEncoder, + DateTimeType::class, DateType::class => $this->dateTimeEncoder, TimeType::class => new IntervalEncoder(), - UuidType::class => new UuidEncoder(), - JsonType::class => new JsonEncoder(), + UuidType::class => $this->uuidEncoder, + JsonType::class => $this->jsonEncoder, EnumType::class => new EnumEncoder(), XMLType::class => new XmlDocumentEncoder(), XMLElementType::class => new XmlElementEncoder(), @@ -103,7 +119,7 @@ public function encoderFor(Type $type): Encoding\ValueEncoder ScalarType::class, LiteralType::class, ArrayType::class, - => new DynamicEncoder(), + => $this->dynamicEncoder(), default => throw new FloeException(sprintf('Floe does not support values of type "%s"', $type->toString())), }; } @@ -149,6 +165,11 @@ public static function xmlElementToString(DOMElement $value): string return $xml; } + private function dynamicEncoder(): DynamicEncoder + { + return new DynamicEncoder($this->dateTimeEncoder); + } + /** * @param Type $type */ @@ -179,7 +200,7 @@ private function mapEncoder(Type $type): Encoding\ValueEncoder $keyEncoder = match (true) { $key instanceof IntegerType => new Int64Encoder(), $key instanceof StringType => new StringKeyEncoder(), - default => new DynamicEncoder(), + default => $this->dynamicEncoder(), }; return new MapEncoder($keyEncoder, $this->encoderFor($type->value())); @@ -201,6 +222,6 @@ private function structureEncoder(Type $type): Encoding\ValueEncoder $elements[$name] = $this->encoderFor($elementType); } - return new StructureEncoder($elements, $type->allowsExtra(), new DynamicEncoder()); + return new StructureEncoder($elements, $type->allowsExtra(), $this->dynamicEncoder()); } } diff --git a/src/core/etl/src/Flow/Serializer/Base64Serializer.php b/src/core/etl/src/Flow/Serializer/Base64Serializer.php index beb3635e2d..a50d65d07e 100644 --- a/src/core/etl/src/Flow/Serializer/Base64Serializer.php +++ b/src/core/etl/src/Flow/Serializer/Base64Serializer.php @@ -4,10 +4,15 @@ namespace Flow\Serializer; +use Flow\ETL\Rows; +use Flow\Filesystem\DestinationStream; +use Flow\Filesystem\SourceStream; use Flow\Serializer\Exception\SerializationException; use function base64_decode; use function base64_encode; +use function Flow\Serializer\DSL\serialize_to_string; +use function Flow\Serializer\DSL\unserialize_from_string; final readonly class Base64Serializer implements Serializer { @@ -15,19 +20,23 @@ public function __construct( private Serializer $serializer, ) {} - public function serialize(object $serializable): string + public function serialize(Rows $rows, DestinationStream $destination): void { - return base64_encode($this->serializer->serialize($serializable)); + $destination->append(base64_encode(serialize_to_string($this->serializer, $rows))); + $destination->close(); } - public function unserialize(string $serialized, array $classes): object + public function unserialize(SourceStream $source): Rows { - $decodedString = base64_decode($serialized, true); + $payload = $source->content(); + $source->close(); - if ($decodedString === false) { + $decoded = base64_decode($payload, true); + + if ($decoded === false) { throw new SerializationException('Base64Serializer::unserialize failed to decode string'); } - return $this->serializer->unserialize($decodedString, $classes); + return unserialize_from_string($this->serializer, $decoded); } } diff --git a/src/core/etl/src/Flow/Serializer/CompressingSerializer.php b/src/core/etl/src/Flow/Serializer/CompressingSerializer.php index 37b355c7a4..7260a7ba17 100644 --- a/src/core/etl/src/Flow/Serializer/CompressingSerializer.php +++ b/src/core/etl/src/Flow/Serializer/CompressingSerializer.php @@ -4,8 +4,13 @@ namespace Flow\Serializer; -use Flow\ETL\Exception\RuntimeException; +use Flow\ETL\Rows; +use Flow\Filesystem\DestinationStream; +use Flow\Filesystem\SourceStream; +use Flow\Serializer\Exception\SerializationException; +use function Flow\Serializer\DSL\serialize_to_string; +use function Flow\Serializer\DSL\unserialize_from_string; use function function_exists; use function gzcompress; use function gzuncompress; @@ -17,47 +22,53 @@ public function __construct( private int $compressionLevel = 9, ) {} - public function serialize(object $serializable): string + public function serialize(Rows $rows, DestinationStream $destination): void { if (!function_exists('gzcompress')) { // @codeCoverageIgnoreStart - throw new RuntimeException("'ext-zlib' is missing in, compression impossible due to lack of gzcompress."); + throw new SerializationException( + "'ext-zlib' is missing in, compression impossible due to lack of gzcompress.", + ); // @codeCoverageIgnoreEnd } - $content = gzcompress($this->serializer->serialize($serializable), $this->compressionLevel); + $content = gzcompress(serialize_to_string($this->serializer, $rows), $this->compressionLevel); if (false === $content) { // @codeCoverageIgnoreStart - throw new RuntimeException('Unable to compress serialized data.'); + throw new SerializationException('Unable to compress serialized data.'); // @codeCoverageIgnoreEnd } - return $content; + $destination->append($content); + $destination->close(); } - public function unserialize(string $serialized, array $classes): object + public function unserialize(SourceStream $source): Rows { if (!function_exists('gzcompress')) { // @codeCoverageIgnoreStart - throw new RuntimeException( + throw new SerializationException( "'ext-zlib' is missing in, decompression impossible due to lack of gzuncompress.", ); // @codeCoverageIgnoreEnd } - $content = gzuncompress($serialized); + $payload = $source->content(); + $source->close(); + + $content = gzuncompress($payload); if (false === $content) { // @codeCoverageIgnoreStart - throw new RuntimeException('Unable to decompress unserialized data.'); + throw new SerializationException('Unable to decompress unserialized data.'); // @codeCoverageIgnoreEnd } - return $this->serializer->unserialize($content, $classes); + return unserialize_from_string($this->serializer, $content); } } diff --git a/src/core/etl/src/Flow/Serializer/DSL/functions.php b/src/core/etl/src/Flow/Serializer/DSL/functions.php new file mode 100644 index 0000000000..5d2450dd79 --- /dev/null +++ b/src/core/etl/src/Flow/Serializer/DSL/functions.php @@ -0,0 +1,30 @@ +serialize($rows, $destination); + + return $destination->content(); +} + +#[DocumentationDSL(module: Module::CORE, type: DSLType::HELPER)] +function unserialize_from_string(Serializer $serializer, string $payload): Rows +{ + return $serializer->unserialize(new StringSourceStream(path('memory://serialized'), $payload)); +} diff --git a/src/core/etl/src/Flow/Serializer/NativePHPSerializer.php b/src/core/etl/src/Flow/Serializer/NativePHPSerializer.php index f71cc7bbc5..5d1456c6e9 100644 --- a/src/core/etl/src/Flow/Serializer/NativePHPSerializer.php +++ b/src/core/etl/src/Flow/Serializer/NativePHPSerializer.php @@ -4,11 +4,12 @@ namespace Flow\Serializer; -use Flow\ETL\Exception\RuntimeException; +use Flow\ETL\Rows; +use Flow\Filesystem\DestinationStream; +use Flow\Filesystem\SourceStream; +use Flow\Serializer\Exception\SerializationException; -use function implode; -use function is_a; -use function is_object; +use function get_debug_type; use function serialize; use function sprintf; use function unserialize; @@ -17,26 +18,28 @@ final class NativePHPSerializer implements Serializer { public function __construct() {} - public function serialize(object $serializable): string + public function serialize(Rows $rows, DestinationStream $destination): void { - return serialize($serializable); + $destination->append(serialize($rows)); + $destination->close(); } - public function unserialize(string $serialized, array $classes): object + public function unserialize(SourceStream $source): Rows { - // @mago-ignore analysis:mixed-assignment - $value = unserialize($serialized, ['allowed_classes' => true]); + $payload = $source->content(); + $source->close(); - foreach ($classes as $class) { - if (is_object($value) && is_a($value, $class)) { - return $value; - } + // @mago-ignore analysis:mixed-assignment + $value = unserialize($payload, ['allowed_classes' => true]); + + if (!$value instanceof Rows) { + throw new SerializationException(sprintf( + 'NativePHPSerializer::unserialize must return instance of %s, got: %s', + Rows::class, + get_debug_type($value), + )); } - throw new RuntimeException(sprintf( - 'NativePHPSerializer::unserialize must return instance of {%s}, got: %s', - implode(', ', $classes), - get_debug_type($value), - )); + return $value; } } diff --git a/src/core/etl/src/Flow/Serializer/Serializer.php b/src/core/etl/src/Flow/Serializer/Serializer.php index 23b5a7342f..ebf662895c 100644 --- a/src/core/etl/src/Flow/Serializer/Serializer.php +++ b/src/core/etl/src/Flow/Serializer/Serializer.php @@ -4,24 +4,23 @@ namespace Flow\Serializer; +use Flow\ETL\Rows; +use Flow\Filesystem\DestinationStream; +use Flow\Filesystem\SourceStream; +use Flow\Serializer\Exception\SerializationException; + /** * @internal */ interface Serializer { /** - * @throw RuntimeException + * @throws SerializationException */ - public function serialize(object $serializable): string; + public function serialize(Rows $rows, DestinationStream $destination): void; /** - * @template T of object - * - * @param non-empty-array> $classes - * - * @throw RuntimeException - * - * @return T + * @throws SerializationException */ - public function unserialize(string $serialized, array $classes): object; + public function unserialize(SourceStream $source): Rows; } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Double/FakeRandomOrdersExtractor.php b/src/core/etl/tests/Flow/ETL/Tests/Double/FakeRandomOrdersExtractor.php index 2a1cb78056..eed79074a4 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Double/FakeRandomOrdersExtractor.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Double/FakeRandomOrdersExtractor.php @@ -70,7 +70,7 @@ public function extract(FlowContext $context): Generator $schema = self::schema(); foreach ($this->rawData() as $row) { - yield array_to_rows($row, $context->entryFactory(), schema: $schema); + yield array_to_rows($row, $context->hydrator(), schema: $schema); } } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Double/FakeStaticOrdersExtractor.php b/src/core/etl/tests/Flow/ETL/Tests/Double/FakeStaticOrdersExtractor.php index e15bf25d16..1f5b1ab3ed 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Double/FakeStaticOrdersExtractor.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Double/FakeStaticOrdersExtractor.php @@ -8,7 +8,8 @@ use Flow\ETL\Extractor; use Flow\ETL\Extractor\Signal; use Flow\ETL\FlowContext; -use Flow\ETL\Row\EntryFactory; +use Flow\ETL\Row\AdaptiveRowHydrator; +use Flow\ETL\Row\Hydrator; use Flow\ETL\Rows; use Flow\ETL\Schema; use Generator; @@ -69,7 +70,7 @@ public function extract(FlowContext $context): Generator $schema = self::schema(); foreach ($this->rawData() as $row) { - yield array_to_rows($row, $context->entryFactory(), schema: $schema); + yield array_to_rows($row, $context->hydrator(), schema: $schema); } } @@ -127,13 +128,13 @@ public function rawData(): Generator } } - public function toRows(EntryFactory $entryFactory = new EntryFactory()): Rows + public function toRows(Hydrator $hydrator = new AdaptiveRowHydrator()): Rows { $rows = rows(); $schema = self::schema(); foreach ($this->rawData() as $row) { - $rows = $rows->merge(array_to_rows($row, entryFactory: $entryFactory, schema: $schema)); + $rows = $rows->merge(array_to_rows($row, hydrator: $hydrator, schema: $schema)); } return $rows; diff --git a/src/core/etl/tests/Flow/ETL/Tests/Double/MemoryBucketsCache.php b/src/core/etl/tests/Flow/ETL/Tests/Double/MemoryBucketsCache.php new file mode 100644 index 0000000000..a15c09cc4f --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Double/MemoryBucketsCache.php @@ -0,0 +1,50 @@ + + */ + public array $appendCalls = []; + + /** + * @var array> + */ + private array $buckets = []; + + public function append(string $bucketId, iterable|Rows $rows): void + { + $this->appendCalls[$bucketId] = ($this->appendCalls[$bucketId] ?? 0) + 1; + + foreach ($rows as $row) { + $this->buckets[$bucketId][] = $row; + } + } + + public function get(string $bucketId): Generator + { + foreach ($this->buckets[$bucketId] ?? [] as $row) { + yield $row; + } + } + + public function remove(string $bucketId): void + { + unset($this->buckets[$bucketId]); + } + + public function set(string $bucketId, iterable|Rows $rows): void + { + $this->buckets[$bucketId] = []; + $this->append($bucketId, $rows); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Double/SpySerializer.php b/src/core/etl/tests/Flow/ETL/Tests/Double/SpySerializer.php new file mode 100644 index 0000000000..b485dd23db --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Double/SpySerializer.php @@ -0,0 +1,49 @@ + + */ + public array $serialized = []; + + /** + * @var list + */ + public array $unserialized = []; + + public function __construct( + private readonly Serializer $inner = new FloeSerializer(), + ) {} + + public function serialize(Rows $rows, DestinationStream $destination): void + { + $payload = serialize_to_string($this->inner, $rows); + $this->serialized[] = $payload; + + $destination->append($payload); + $destination->close(); + } + + public function unserialize(SourceStream $source): Rows + { + $payload = $source->content(); + $this->unserialized[] = $payload; + $source->close(); + + return unserialize_from_string($this->inner, $payload); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/CacheTestCase.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/CacheTestCase.php index 6e3671f037..190fac3955 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/CacheTestCase.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/CacheTestCase.php @@ -12,13 +12,10 @@ use Flow\Filesystem\Partition; use Override; -use function array_map; -use function array_merge; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; -use function iterator_to_array; abstract class CacheTestCase extends FlowIntegrationTestCase { @@ -118,56 +115,6 @@ public function test_getting_non_existing_cache_key(): void $cache->get('non-existing'); } - public function test_reading_cached_value_in_batches(): void - { - $cache = $this->cache(); - - $cache->set('rows', $rows = rows(row(str_entry('name', 'John')), row(str_entry('name', 'Jane')))); - - $batches = iterator_to_array($cache->read('rows'), preserve_keys: false); - - static::assertNotEmpty($batches); - static::assertEquals( - $rows, - rows(...array_merge(...array_map(static fn(Rows $batch): array => $batch->all(), $batches))), - ); - } - - public function test_reading_non_existing_cache_key(): void - { - $cache = $this->cache(); - - $this->expectException(KeyNotInCacheException::class); - - iterator_to_array($cache->read('non-existing')); - } - - public function test_reading_partitioned_rows_in_batches(): void - { - $cache = $this->cache(); - - $cache->set( - 'partitioned', - $rows = Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( - 'country', - 'PL', - )]), - ); - - $batches = iterator_to_array($cache->read('partitioned'), preserve_keys: false); - - static::assertNotEmpty($batches); - - foreach ($batches as $batch) { - static::assertEquals($rows->partitions()->toArray(), $batch->partitions()->toArray()); - } - - static::assertEquals( - $rows->all(), - array_merge(...array_map(static fn(Rows $batch): array => $batch->all(), $batches)), - ); - } - public function test_removing_from_cache(): void { $cache = $this->cache(); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/FilesystemCacheStreamingTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/FilesystemCacheStreamingTest.php deleted file mode 100644 index 87fefed3a3..0000000000 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/FilesystemCacheStreamingTest.php +++ /dev/null @@ -1,120 +0,0 @@ - row(int_entry('id', $id)), range(1, 10))); - - $bulkCache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/filesystem-cache-bulk')); - - $this->cache()->set('parity', $rows); - $bulkCache->set('parity', $rows); - - $streamingFiles = glob(__DIR__ . '/var/filesystem-cache-streaming/*/*/*/*/parity.floe') ?: []; - $bulkFiles = glob(__DIR__ . '/var/filesystem-cache-bulk/*/*/*/*/parity.floe') ?: []; - - static::assertNotEmpty($streamingFiles); - static::assertNotEmpty($bulkFiles); - static::assertSame(file_get_contents($bulkFiles[0]), file_get_contents($streamingFiles[0])); - - $bulkCache->clear(); - } - - public function test_filesystem_cache_dsl_delegates_mode_and_batch_size(): void - { - $cache = filesystem_cache(path(__DIR__ . '/var/filesystem-cache-dsl'), serializer_batch_size: 2); - - $cache->set('dsl', rows(...array_map(static fn(int $id): Row => row(int_entry('id', $id)), range(1, 5)))); - - static::assertCount(3, iterator_to_array($cache->read('dsl'), preserve_keys: false)); - - $cache->clear(); - } - - public function test_reading_yields_batches_of_batch_size(): void - { - $cache = $this->cache(); - - $cache->set('batched', rows(...array_map(static fn(int $id): Row => row(int_entry('id', $id)), range(1, 10)))); - - $batches = iterator_to_array($cache->read('batched'), preserve_keys: false); - - static::assertCount(4, $batches); - static::assertSame([3, 3, 3, 1], array_map(static fn(Rows $batch): int => $batch->count(), $batches)); - } - - public function test_torn_entry_is_treated_as_a_cache_miss(): void - { - $cache = $this->cache(); - $cache->set('torn', rows(row(int_entry('id', 1)))); - - $files = glob(__DIR__ . '/var/filesystem-cache-streaming/*/*/*/*/torn.floe') ?: []; - static::assertNotEmpty($files); - file_put_contents($files[0], 'not a valid floe file'); - - $this->expectException(KeyNotInCacheException::class); - - $cache->get('torn'); - } - - public function test_corrupted_frame_with_intact_footer_is_treated_as_a_cache_miss(): void - { - $cache = $this->cache(); - $cache->set('corrupt', rows(row(int_entry('id', 1)))); - - $files = glob(__DIR__ . '/var/filesystem-cache-streaming/*/*/*/*/corrupt.floe') ?: []; - static::assertNotEmpty($files); - - // corrupt the first frame type (SCHEMA -> unknown 0x7F); the footer at the end stays - // intact, so the recovered row count no longer matches the footer's totalRows - $bytes = (string) file_get_contents($files[0]); - $bytes[6] = "\x7F"; - file_put_contents($files[0], $bytes); - - $this->expectException(KeyNotInCacheException::class); - - $cache->get('corrupt'); - } - - public function test_torn_entry_read_is_treated_as_a_cache_miss(): void - { - $cache = $this->cache(); - $cache->set('torn-read', rows(row(int_entry('id', 1)))); - - $files = glob(__DIR__ . '/var/filesystem-cache-streaming/*/*/*/*/torn-read.floe') ?: []; - static::assertNotEmpty($files); - file_put_contents($files[0], 'not a valid floe file'); - - $this->expectException(KeyNotInCacheException::class); - - iterator_to_array($cache->read('torn-read')); - } - - protected function cache(): Cache - { - return new FilesystemCache($this->fs(), path(__DIR__ . '/var/filesystem-cache-streaming'), 3); - } -} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/FilesystemCacheTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/FilesystemCacheTest.php index 690c701206..8526be30f5 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/FilesystemCacheTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/Cache/FilesystemCacheTest.php @@ -7,7 +7,9 @@ use Flow\ETL\Cache; use Flow\ETL\Cache\Implementation\FilesystemCache; use Flow\ETL\Exception\KeyNotInCacheException; +use Flow\ETL\Tests\Double\SpySerializer; +use function file_get_contents; use function file_put_contents; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; @@ -22,8 +24,8 @@ public function test_torn_entry_is_treated_as_a_cache_miss(): void $cache = $this->cache(); $cache->set('torn', rows(row(int_entry('id', 1)))); - // simulate a crash mid-write / bit rot: overwrite the closed .floe file with garbage - $files = glob(__DIR__ . '/var/filesystem-cache/*/*/*/*/torn.floe') ?: []; + // simulate a crash mid-write / bit rot: overwrite the closed cache file with garbage + $files = glob(__DIR__ . '/var/filesystem-cache/*/*/*/*/torn') ?: []; static::assertNotEmpty($files); file_put_contents($files[0], 'not a valid floe file'); @@ -32,6 +34,40 @@ public function test_torn_entry_is_treated_as_a_cache_miss(): void $cache->get('torn'); } + public function test_corrupted_frame_with_intact_footer_is_treated_as_a_cache_miss(): void + { + $cache = $this->cache(); + $cache->set('corrupt', rows(row(int_entry('id', 1)))); + + $files = glob(__DIR__ . '/var/filesystem-cache/*/*/*/*/corrupt') ?: []; + static::assertNotEmpty($files); + + // corrupt the first frame type (SCHEMA -> unknown 0x7F); the footer at the end stays + // intact, so the recovered row count no longer matches the footer's totalRows + $bytes = (string) file_get_contents($files[0]); + $bytes[6] = "\x7F"; + file_put_contents($files[0], $bytes); + + $this->expectException(KeyNotInCacheException::class); + + $cache->get('corrupt'); + } + + public function test_custom_serializer_is_used_for_set_and_get(): void + { + $spy = new SpySerializer(); + $cache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/filesystem-cache-spy'), $spy); + $cache->clear(); + + $cache->set('spy', $rows = rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); + + static::assertEquals($rows, $cache->get('spy')); + static::assertCount(1, $spy->serialized); + static::assertCount(1, $spy->unserialized); + + $cache->clear(); + } + protected function cache(): Cache { return new FilesystemCache($this->fs(), path(__DIR__ . '/var/filesystem-cache')); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/CacheTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/CacheTest.php index d661cbf869..c17cc34bf0 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/CacheTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/CacheTest.php @@ -11,6 +11,7 @@ use Flow\ETL\FlowContext; use Flow\ETL\Rows; use Flow\ETL\Tests\Double\FakeExtractor; +use Flow\ETL\Tests\Double\SpySerializer; use Flow\ETL\Tests\FlowIntegrationTestCase; use Flow\Telemetry\Context\MemoryContextStorage; use Flow\Telemetry\Logger\LoggerProvider; @@ -98,24 +99,27 @@ public function test_cache_with_previously_set_batch_size(): void } } - public function test_cache_streaming_serializer_mode_end_to_end(): void + public function test_cache_end_to_end_with_custom_serializer(): void { $input = array_map(static fn(int $i) => ['id' => $i], range(1, 25)); - $bulkCache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-mode-bulk')); - $streamingCache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-mode-streaming'), 4); + $defaultCache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-mode-default')); + $spy = new SpySerializer(); + $customCache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-mode-custom'), $spy); - df(config_builder()->cache($bulkCache))->read(from_array($input))->batchSize(10)->cache('parity')->run(); - df(config_builder()->cache($streamingCache))->read(from_array($input))->batchSize(10)->cache('parity')->run(); + df(config_builder()->cache($defaultCache))->read(from_array($input))->batchSize(10)->cache('parity')->run(); + df(config_builder()->cache($customCache))->read(from_array($input))->batchSize(10)->cache('parity')->run(); - $bulkRows = df(config_builder()->cache($bulkCache))->read(from_cache('parity'))->fetch(); - $streamingRows = df(config_builder()->cache($streamingCache))->read(from_cache('parity'))->fetch(); + $defaultRows = df(config_builder()->cache($defaultCache))->read(from_cache('parity'))->fetch(); + $customRows = df(config_builder()->cache($customCache))->read(from_cache('parity'))->fetch(); - static::assertSame($input, $bulkRows->toArray()); - static::assertSame($input, $streamingRows->toArray()); + static::assertSame($input, $defaultRows->toArray()); + static::assertSame($input, $customRows->toArray()); + static::assertNotEmpty($spy->serialized); + static::assertNotEmpty($spy->unserialized); - $bulkCache->clear(); - $streamingCache->clear(); + $defaultCache->clear(); + $customCache->clear(); } public function test_cache_with_telemetry_collects_spans_and_metrics(): void diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/ConfigBuilderTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/ConfigBuilderTest.php index f99603a22c..2ab293bed2 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/ConfigBuilderTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/ConfigBuilderTest.php @@ -6,7 +6,10 @@ use Flow\ETL\Cache\Implementation\InMemoryCache; use Flow\ETL\Config\Cache\CacheConfig; +use Flow\ETL\Row\AdaptiveRowHydrator; +use Flow\ETL\Row\PhpRowHydrator; use Flow\ETL\Sort\SortAlgorithms; +use Flow\ETL\Tests\Double\SpySerializer; use Flow\ETL\Tests\FlowIntegrationTestCase; use Flow\Filesystem\Filesystem; use Flow\Filesystem\Mount; @@ -33,7 +36,6 @@ use function Flow\Telemetry\DSL\telemetry; use function Flow\Telemetry\DSL\tracer_provider; use function Flow\Telemetry\DSL\void_exporter; -use function iterator_to_array; use function str_replace; final class ConfigBuilderTest extends FlowIntegrationTestCase @@ -56,28 +58,29 @@ public function test_cache_filesystem_protocol_override(): void static::assertSame('custom-cache', $config->cache->filesystemMount); } - public function test_cache_serializer_mode_reaches_the_default_cache(): void + public function test_config_serializer_reaches_the_default_cache(): void { putenv(CacheConfig::CACHE_DIR_ENV . '=' . __DIR__ . '/var/cache-serializer-mode'); - $config = config_builder()->cacheSerializerBatchSize(2)->build(); + $config = config_builder()->serializer($spy = new SpySerializer())->build(); - $config->cache->cache->set('key', rows( - row(int_entry('id', 1)), - row(int_entry('id', 2)), - row(int_entry('id', 3)), - )); + $config->cache->cache->set( + 'key', + $rows = rows(row(int_entry('id', 1)), row(int_entry('id', 2)), row(int_entry('id', 3))), + ); - static::assertCount(2, iterator_to_array($config->cache->cache->read('key'))); + static::assertEquals($rows, $config->cache->cache->get('key')); + static::assertCount(1, $spy->serialized); + static::assertCount(1, $spy->unserialized); $config->cache->cache->clear(); } - public function test_custom_cache_wins_over_serializer_mode(): void + public function test_custom_cache_is_untouched_by_config_serializer(): void { $custom = new InMemoryCache(); - $config = config_builder()->cache($custom)->cacheSerializerBatchSize(500)->build(); + $config = config_builder()->cache($custom)->serializer(new SpySerializer())->build(); static::assertSame($custom, $config->cache->cache); } @@ -141,6 +144,11 @@ public function test_default_external_sort_filesystem_protocol_is_file(): void static::assertSame('file', $config->sort->filesystemProtocol); } + public function test_default_hydrator_is_the_adaptive_hydrator(): void + { + static::assertInstanceOf(AdaptiveRowHydrator::class, config_builder()->build()->hydrator()); + } + public function test_default_sorting_algorithm(): void { $config = config_builder()->build(); @@ -148,6 +156,13 @@ public function test_default_sorting_algorithm(): void static::assertSame(SortAlgorithms::EXTERNAL_SORT, $config->sort->algorithm); } + public function test_hydrator_override_wins_over_the_default(): void + { + $hydrator = new PhpRowHydrator(); + + static::assertSame($hydrator, config_builder()->hydrator($hydrator)->build()->hydrator()); + } + public function test_external_sort_filesystem_protocol_override(): void { $config = config_builder()->externalSortFilesystem('custom-sort')->build(); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/GroupByAggregationTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/GroupByAggregationTest.php index 64abf624d6..caf3655d21 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/GroupByAggregationTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/GroupByAggregationTest.php @@ -16,10 +16,14 @@ use function Flow\ETL\DSL\count; use function Flow\ETL\DSL\data_frame; use function Flow\ETL\DSL\first; +use function Flow\ETL\DSL\float_schema; use function Flow\ETL\DSL\from_array; use function Flow\ETL\DSL\last; use function Flow\ETL\DSL\ref; +use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\sum; +use function Flow\ETL\DSL\uuid_schema; use function iterator_to_array; final class GroupByAggregationTest extends FlowIntegrationTestCase @@ -234,9 +238,14 @@ public function test_partition_count_does_not_affect_a_realistic_dataset(): void 'discount' => $order['discount'], ], $raw); + // one schema per spill file: declare the source schema so a null discount carries a + // float (nullable) definition instead of NullType, otherwise an all-null-first spill + // batch would fix a bucket's schema to null and reject later float values + $schema = schema(uuid_schema('seller_id'), string_schema('email'), float_schema('discount', true)); + $pipeline = static fn(ConfigBuilder $config): array => iterator_to_array( data_frame($config) - ->read(from_array($data)) + ->read(from_array($data, $schema)) ->groupBy(ref('email')) ->aggregate(count(ref('email')), sum(ref('discount'))) ->sortBy(ref('email')->asc()) diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/GroupByScaleTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/GroupByScaleTest.php deleted file mode 100644 index 47dc9f8d46..0000000000 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/GroupByScaleTest.php +++ /dev/null @@ -1,54 +0,0 @@ -rawData() as $order) { - $data[] = [ - 'seller_id' => $order['seller_id'], - 'email' => $order['email'], - 'discount' => $order['discount'], - ]; - } - - $start = microtime(true); - - $result = iterator_to_array( - data_frame(config_builder()) - ->read(from_array($data)) - ->groupBy(ref('email')) - ->aggregate(count(ref('email')), sum(ref('discount'))) - ->sortBy(ref('email')->asc()) - ->getEachAsArray(), - ); - - $elapsed = microtime(true) - $start; - - static::assertNotEmpty($result); - - static::assertLessThan( - 30.0, - $elapsed, - 'filesystem aggregation at 100k regressed toward the old super-linear cliff', - ); - } -} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/JoinTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/JoinTest.php index 1199a91c6b..b64d0aa448 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/JoinTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/JoinTest.php @@ -10,6 +10,7 @@ use Flow\ETL\Loader; use Flow\ETL\Tests\FlowIntegrationTestCase; +use function Flow\ETL\DSL\config_builder; use function Flow\ETL\DSL\data_frame; use function Flow\ETL\DSL\datetime_entry; use function Flow\ETL\DSL\df; @@ -19,6 +20,7 @@ use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; +use function usort; final class JoinTest extends FlowIntegrationTestCase { @@ -59,6 +61,39 @@ public function test_join_inner(): void ); } + public function test_join_inner_with_on_disk_buckets_cache(): void + { + $rows = df(config_builder()->joinBucketsCount(4)) + ->from(from_rows(rows( + row(int_entry('id', 1), str_entry('country', 'PL')), + row(int_entry('id', 2), str_entry('country', 'US')), + row(int_entry('id', 3), str_entry('country', 'FR')), + row(int_entry('id', 4), str_entry('country', 'UK')), + ))) + ->join( + data_frame()->process(rows( + row(str_entry('code', 'PL'), str_entry('name', 'Poland')), + row(str_entry('code', 'US'), str_entry('name', 'United States')), + row(str_entry('code', 'FR'), str_entry('name', 'France')), + )), + join_on(['country' => 'code'], 'joined_'), + Join::inner, + ) + ->fetch(); + + $joined = $rows->toArray(); + usort($joined, static fn(array $left, array $right): int => (int) $left['id'] <=> (int) $right['id']); + + static::assertEquals( + [ + ['id' => 1, 'country' => 'PL', 'joined_code' => 'PL', 'joined_name' => 'Poland'], + ['id' => 2, 'country' => 'US', 'joined_code' => 'US', 'joined_name' => 'United States'], + ['id' => 3, 'country' => 'FR', 'joined_code' => 'FR', 'joined_name' => 'France'], + ], + $joined, + ); + } + public function test_join_left(): void { $loader = $this->createMock(Loader::class); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/SchemaTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/SchemaTest.php index 18e04f5085..f912d236a8 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/SchemaTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/DataFrame/SchemaTest.php @@ -6,7 +6,6 @@ use Flow\ETL\Pipeline; use Flow\ETL\Schema; -use Flow\ETL\Schema\Metadata; use Flow\ETL\Tests\FlowIntegrationTestCase; use function array_map; @@ -23,6 +22,7 @@ use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\int_schema; use function Flow\ETL\DSL\null_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\schema; @@ -76,14 +76,7 @@ public function test_extraction_without_to_schema(): void ], $rows->toArray(), ); - static::assertEquals( - schema( - int_schema('id'), - str_schema('name'), - str_schema('active', nullable: true, metadata: Metadata::fromArray([Metadata::FROM_NULL => true])), - ), - $rows->schema(), - ); + static::assertEquals(schema(int_schema('id'), str_schema('name'), null_schema('active')), $rows->schema()); } public function test_getting_schema(): void @@ -97,7 +90,7 @@ public function test_getting_schema(): void ], range(1, 100), ), - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), ); static::assertEquals( @@ -118,7 +111,7 @@ public function test_getting_schema_from_limited_rows(): void ], range(1, 100), ), - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), ); static::assertEquals( diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/Extractor/CacheExtractorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/Extractor/CacheExtractorTest.php index abcd35e673..7abc6d55c3 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/Extractor/CacheExtractorTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/Extractor/CacheExtractorTest.php @@ -33,9 +33,9 @@ public function test_extracting_rows_from_cache(): void $index->add('rows_02'); $index->add('rows_03'); - $cache->set('rows_01', array_to_rows([['id' => 1], ['id' => 2]], flow_context(config())->entryFactory())); - $cache->set('rows_02', array_to_rows([['id' => 3], ['id' => 4]], flow_context(config())->entryFactory())); - $cache->set('rows_03', array_to_rows([['id' => 5]], flow_context(config())->entryFactory())); + $cache->set('rows_01', array_to_rows([['id' => 1], ['id' => 2]], flow_context(config())->hydrator())); + $cache->set('rows_02', array_to_rows([['id' => 3], ['id' => 4]], flow_context(config())->hydrator())); + $cache->set('rows_03', array_to_rows([['id' => 5]], flow_context(config())->hydrator())); $cache->set('key', $index->toRows()); @@ -59,9 +59,9 @@ public function test_extracting_rows_from_cache_with_clearing_cache_afterwards() $index->add('rows_02'); $index->add('rows_03'); - $cache->set('rows_01', array_to_rows([['id' => 1], ['id' => 2]], flow_context(config())->entryFactory())); - $cache->set('rows_02', array_to_rows([['id' => 3], ['id' => 4]], flow_context(config())->entryFactory())); - $cache->set('rows_03', array_to_rows([['id' => 5]], flow_context(config())->entryFactory())); + $cache->set('rows_01', array_to_rows([['id' => 1], ['id' => 2]], flow_context(config())->hydrator())); + $cache->set('rows_02', array_to_rows([['id' => 3], ['id' => 4]], flow_context(config())->hydrator())); + $cache->set('rows_03', array_to_rows([['id' => 5]], flow_context(config())->hydrator())); $cache->set('key', $index->toRows()); @@ -76,9 +76,9 @@ public function test_extracting_rows_from_cache_with_clearing_cache_afterwards() static::assertFalse($cache->has('key')); } - public function test_extracting_rows_from_streaming_cache_in_batches(): void + public function test_extracting_rows_from_filesystem_cache(): void { - $cache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-extractor-streaming'), 2); + $cache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-extractor-streaming')); $cache->clear(); $index = new CacheIndex($cacheKey = 'key'); @@ -90,14 +90,14 @@ public function test_extracting_rows_from_streaming_cache_in_batches(): void ['id' => 3], ['id' => 4], ['id' => 5], - ], flow_context(config())->entryFactory())); + ], flow_context(config())->hydrator())); $cache->set('key', $index->toRows()); $extractor = from_cache($cacheKey); $rows = iterator_to_array($extractor->extract(flow_context(config_builder()->cache($cache)->build()))); - static::assertCount(3, $rows); + static::assertCount(1, $rows); static::assertEquals( [['id' => 1], ['id' => 2], ['id' => 3], ['id' => 4], ['id' => 5]], array_merge(...array_map(static fn(Rows $batch): array => $batch->toArray(), $rows)), @@ -106,9 +106,9 @@ public function test_extracting_rows_from_streaming_cache_in_batches(): void $cache->clear(); } - public function test_stop_signal_stops_streaming_batches_and_skips_clearing(): void + public function test_stop_signal_stops_extraction_and_skips_clearing(): void { - $cache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-extractor-streaming-stop'), 2); + $cache = new FilesystemCache($this->fs(), path(__DIR__ . '/var/cache-extractor-streaming-stop')); $cache->clear(); $index = new CacheIndex($cacheKey = 'key'); @@ -120,7 +120,7 @@ public function test_stop_signal_stops_streaming_batches_and_skips_clearing(): v ['id' => 3], ['id' => 4], ['id' => 5], - ], flow_context(config())->entryFactory())); + ], flow_context(config())->hydrator())); $cache->set('key', $index->toRows()); $generator = from_cache($cacheKey) diff --git a/src/core/etl/tests/Flow/ETL/Tests/Integration/Sort/ExternalSort/FilesystemBucketsCacheTest.php b/src/core/etl/tests/Flow/ETL/Tests/Integration/Sort/ExternalSort/FilesystemBucketsCacheTest.php index 9da14e55d5..00622f2a65 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Integration/Sort/ExternalSort/FilesystemBucketsCacheTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Integration/Sort/ExternalSort/FilesystemBucketsCacheTest.php @@ -4,9 +4,11 @@ namespace Flow\ETL\Tests\Integration\Sort\ExternalSort; +use Flow\ETL\Row; use Flow\ETL\Sort\ExternalSort\BucketsCache\FilesystemBucketsCache; use Flow\ETL\Tests\FlowIntegrationTestCase; +use function array_map; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\str_entry; @@ -157,7 +159,13 @@ public function test_round_trips_schema_changing_rows(): void $cache->set('bucket', $input); - static::assertEquals($input, iterator_to_array($cache->get('bucket'), false)); + // one write session = one schema: rows keep their own columns (unpadded) but entry + // types widen to the batch union, so compare values rather than exact definitions + $result = iterator_to_array($cache->get('bucket'), false); + static::assertSame( + array_map(static fn(Row $r): array => $r->toArray(), $input), + array_map(static fn(Row $r): array => $r->toArray(), $result), + ); $this->fs()->rm($cacheDir); } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/ApcuCacheTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/ApcuCacheTest.php index 743471524b..e4e6ff4969 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/ApcuCacheTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/ApcuCacheTest.php @@ -16,7 +16,6 @@ use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; -use function iterator_to_array; #[CoversClass(ApcuCache::class)] #[RequiresPhpExtension('apcu')] @@ -90,20 +89,6 @@ public function test_getting_non_existing_cache_key(): void $this->cache->get('non-existing'); } - public function test_reading_rows(): void - { - $this->cache->set('rows', $rows = rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); - - static::assertEquals([$rows], iterator_to_array($this->cache->read('rows'), false)); - } - - public function test_reading_non_existing_cache_key(): void - { - $this->expectException(KeyNotInCacheException::class); - - iterator_to_array($this->cache->read('non-existing'), false); - } - public function test_removing_from_cache(): void { $this->cache->set('first', rows(row(int_entry('id', 1)))); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/TraceableCacheTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/TraceableCacheTest.php index 6cc4e3d636..528c9a4c3d 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/TraceableCacheTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Cache/Implementation/TraceableCacheTest.php @@ -26,7 +26,6 @@ use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; -use function iterator_to_array; #[CoversClass(TraceableCache::class)] final class TraceableCacheTest extends FlowTestCase @@ -135,46 +134,6 @@ public function test_get_increments_miss_counter_and_throws_on_non_existing_key( } } - public function test_read_increments_hit_counter_on_existing_key(): void - { - $innerCache = new InMemoryCache(); - $cache = new TraceableCache($innerCache, $this->telemetry, 'test_dataframe'); - - $innerCache->set('existing-key', $rows = rows(row())); - - static::assertEquals([$rows], iterator_to_array($cache->read('existing-key'), preserve_keys: false)); - - $this->telemetry->flush(); - $hitMetrics = $this->metricProcessor->metricsWithName('flow.cache.hits'); - $missMetrics = $this->metricProcessor->metricsWithName('flow.cache.misses'); - - static::assertCount(1, $hitMetrics); - static::assertCount(0, $missMetrics); - static::assertSame(1, $hitMetrics[0]->value); - static::assertSame('test_dataframe', $hitMetrics[0]->attributes->get('flow.etl.dataframe.name')); - } - - public function test_read_increments_miss_counter_and_throws_on_non_existing_key(): void - { - $innerCache = new InMemoryCache(); - $cache = new TraceableCache($innerCache, $this->telemetry, 'test_dataframe'); - - $this->expectException(KeyNotInCacheException::class); - - try { - iterator_to_array($cache->read('non-existing-key')); - } finally { - $this->telemetry->flush(); - $hitMetrics = $this->metricProcessor->metricsWithName('flow.cache.hits'); - $missMetrics = $this->metricProcessor->metricsWithName('flow.cache.misses'); - - static::assertCount(0, $hitMetrics); - static::assertCount(1, $missMetrics); - static::assertSame(1, $missMetrics[0]->value); - static::assertSame('test_dataframe', $missMetrics[0]->attributes->get('flow.etl.dataframe.name')); - } - } - public function test_has_increments_hit_counter_when_key_exists(): void { $innerCache = new InMemoryCache(); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Config/Join/JoinConfigBuilderTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Config/Join/JoinConfigBuilderTest.php new file mode 100644 index 0000000000..f4823d028e --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Config/Join/JoinConfigBuilderTest.php @@ -0,0 +1,47 @@ +bucketsCount(4) + ->batchSize(250) + ->build(fstab(), Path::realpath(__DIR__)); + + static::assertSame(4, $config->bucketsCount); + static::assertSame(250, $config->batchSize); + } + + public function test_default_builds_a_filesystem_buckets_cache(): void + { + $config = (new JoinConfigBuilder())->build(fstab(), Path::realpath(__DIR__)); + + static::assertInstanceOf(FilesystemBucketsCache::class, $config->cache); + static::assertSame(64, $config->bucketsCount); + static::assertSame(1000, $config->batchSize); + } + + public function test_injected_cache_wins_over_the_default(): void + { + $cache = new InMemoryBucketsCache(); + + $config = (new JoinConfigBuilder()) + ->cache($cache) + ->build(fstab(), Path::realpath(__DIR__)); + + static::assertSame($cache, $config->cache); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Function/ParameterTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Function/ParameterTest.php index 8270b4c995..8fed3decfe 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Function/ParameterTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Function/ParameterTest.php @@ -9,7 +9,6 @@ use Flow\Doctrine\Bulk\SQLParametersStyle; use Flow\ETL\Function\Parameter; use Flow\ETL\Function\ScalarFunction\ScalarResult; -use Flow\ETL\Row\Entry\StringEntry; use Flow\ETL\String\StringStyles; use Flow\ETL\Tests\FlowTestCase; use Flow\Types\Type\Native\BooleanType; @@ -22,6 +21,7 @@ use function Flow\ETL\DSL\flow_context; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\lit; +use function Flow\ETL\DSL\null_entry; use function Flow\ETL\DSL\ref; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\str_entry; @@ -341,11 +341,11 @@ public function test_as_string(mixed $input, ?string $default, ?string $expected static::assertSame($expected, $parameter->asString(row(), flow_context(), $default)); } - public function test_as_type_when_handling_string_entry_created_from_null(): void + public function test_as_type_when_handling_null_entry(): void { $parameter = new Parameter(ref('value')); - static::assertEquals(type_null(), $parameter->asType(row(StringEntry::fromNull('value')), flow_context())); + static::assertEquals(type_null(), $parameter->asType(row(null_entry('value')), flow_context())); } public function test_as_type_with_literal_value(): void diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/Comparison/EqualTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/Comparison/EqualTest.php index 765b8cbe31..dace01f0bc 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/Comparison/EqualTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/Comparison/EqualTest.php @@ -9,7 +9,9 @@ use Flow\ETL\Tests\FlowTestCase; use function Flow\ETL\DSL\datetime_entry; +use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; +use function Flow\ETL\DSL\uuid_entry; final class EqualTest extends FlowTestCase { @@ -21,6 +23,30 @@ public function test_failure(): void )); } + public function test_object_and_scalar_are_not_equal(): void + { + static::assertFalse((new Equal('id', 'id'))->compare( + row(uuid_entry('id', 'f47ac10b-58cc-4372-a567-0e02b2c3d479')), + row(int_entry('id', 1)), + )); + } + + public function test_uuid_objects_with_different_values_are_not_equal(): void + { + static::assertFalse((new Equal('id', 'id'))->compare( + row(uuid_entry('id', 'f47ac10b-58cc-4372-a567-0e02b2c3d479')), + row(uuid_entry('id', '00000000-0000-4000-8000-000000000000')), + )); + } + + public function test_uuid_objects_with_same_value_are_equal(): void + { + static::assertTrue((new Equal('id', 'id'))->compare( + row(uuid_entry('id', 'f47ac10b-58cc-4372-a567-0e02b2c3d479')), + row(uuid_entry('id', 'f47ac10b-58cc-4372-a567-0e02b2c3d479')), + )); + } + public function test_success(): void { static::assertTrue((new Equal('datetime', 'datetime'))->compare( diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/BucketSpillerTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/BucketSpillerTest.php new file mode 100644 index 0000000000..feadd69c43 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/BucketSpillerTest.php @@ -0,0 +1,75 @@ +add(3, row(int_entry('id', 1))); + $spiller->flush(); + + static::assertSame([3 => 'join-run-right-bucket-3'], $spiller->bucketIds()); + } + + public function test_flush_writes_remaining_rows(): void + { + $cache = new MemoryBucketsCache(); + $spiller = new BucketSpiller($cache, 'join-run-left-bucket-', 10); + + $spiller->add(0, row(int_entry('id', 1))); + $spiller->add(0, row(int_entry('id', 2))); + $spiller->add(1, row(int_entry('id', 3))); + + static::assertSame([], $spiller->bucketIds()); + + $spiller->flush(); + + static::assertCount(2, iterator_to_array($cache->get('join-run-left-bucket-0'), false)); + static::assertCount(1, iterator_to_array($cache->get('join-run-left-bucket-1'), false)); + } + + public function test_total_buffer_cap_flushes_all_buckets(): void + { + $cache = new MemoryBucketsCache(); + $spiller = new BucketSpiller($cache, 'join-run-left-bucket-', 4); + + $spiller->add(0, row(int_entry('id', 1))); + $spiller->add(1, row(int_entry('id', 2))); + $spiller->add(0, row(int_entry('id', 3))); + $spiller->add(2, row(int_entry('id', 4))); + + static::assertSame(1, $cache->appendCalls['join-run-left-bucket-0']); + static::assertSame(1, $cache->appendCalls['join-run-left-bucket-1']); + static::assertSame(1, $cache->appendCalls['join-run-left-bucket-2']); + static::assertCount(2, iterator_to_array($cache->get('join-run-left-bucket-0'), false)); + } + + public function test_rows_are_appended_in_batches(): void + { + $cache = new MemoryBucketsCache(); + $spiller = new BucketSpiller($cache, 'join-run-left-bucket-', 2); + + $spiller->add(0, row(int_entry('id', 1))); + $spiller->add(0, row(int_entry('id', 2))); + $spiller->add(0, row(int_entry('id', 3))); + $spiller->add(0, row(int_entry('id', 4))); + $spiller->add(0, row(int_entry('id', 5))); + $spiller->flush(); + + static::assertSame(3, $cache->appendCalls['join-run-left-bucket-0']); + static::assertCount(5, iterator_to_array($cache->get('join-run-left-bucket-0'), false)); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/EqualityJoinKeysTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/EqualityJoinKeysTest.php new file mode 100644 index 0000000000..a7e6a7a0eb --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/EqualityJoinKeysTest.php @@ -0,0 +1,150 @@ +leftHash(row(int_entry('id', 1), str_entry('country', 'PL'))), + $keys->rightHash(row(int_entry('user_id', 1), str_entry('country_code', 'PL'))), + ); + static::assertNotSame( + $keys->leftHash(row(int_entry('id', 1), str_entry('country', 'PL'))), + $keys->rightHash(row(int_entry('user_id', 1), str_entry('country_code', 'US'))), + ); + } + + public function test_any_comparison_is_not_equality_based(): void + { + static::assertNull(EqualityJoinKeys::fromComparison( + new Any(new Equal('id', 'id'), new Equal('email', 'email')), + )); + static::assertNull(EqualityJoinKeys::fromComparison( + new All(new Equal('id', 'id'), new Any(new Equal('a', 'a'), new Equal('b', 'b'))), + )); + } + + public function test_boolean_does_not_collide_with_numeric(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('flag', 'flag')); + + static::assertNotNull($keys); + static::assertNotSame( + $keys->leftHash(row(bool_entry('flag', true))), + $keys->rightHash(row(int_entry('flag', 1))), + ); + } + + public function test_datetime_instants_hash_equal_across_timezones(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('date', 'date')); + + static::assertNotNull($keys); + static::assertSame( + $keys->leftHash(row(datetime_entry( + 'date', + new DateTimeImmutable('2024-01-01 12:00:00', new DateTimeZone('UTC')), + ))), + $keys->rightHash(row(datetime_entry( + 'date', + new DateTimeImmutable('2024-01-01 13:00:00', new DateTimeZone('+01:00')), + ))), + ); + } + + public function test_different_values_hash_differently(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + + static::assertNotNull($keys); + static::assertNotSame($keys->leftHash(row(int_entry('id', 1))), $keys->rightHash(row(int_entry('user_id', 2)))); + } + + public function test_identical_comparison_is_equality_based(): void + { + $keys = EqualityJoinKeys::fromComparison(new Identical('id', 'user_id')); + + static::assertNotNull($keys); + static::assertSame($keys->leftHash(row(int_entry('id', 1))), $keys->rightHash(row(int_entry('user_id', 1)))); + } + + public function test_left_and_right_hashes_use_their_own_references(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + + static::assertNotNull($keys); + static::assertSame( + $keys->leftHash(row(int_entry('id', 5), str_entry('noise', 'left'))), + $keys->rightHash(row(int_entry('user_id', 5), str_entry('other_noise', 'right'))), + ); + } + + public function test_normalize_collapses_negative_zero(): void + { + static::assertSame(EqualityJoinKeys::normalize(-0.0), EqualityJoinKeys::normalize(0.0)); + } + + public function test_null_values_hash_equal(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + + static::assertNotNull($keys); + static::assertSame( + $keys->leftHash(row(int_entry('id', null))), + $keys->rightHash(row(int_entry('user_id', null))), + ); + } + + public function test_numeric_values_hash_equal_across_types(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + + static::assertNotNull($keys); + static::assertSame( + $keys->leftHash(row(int_entry('id', 1))), + $keys->rightHash(row(float_entry('user_id', 1.0))), + ); + static::assertSame($keys->leftHash(row(int_entry('id', 1))), $keys->rightHash(row(str_entry('user_id', '1')))); + } + + public function test_uuid_objects_hash_by_their_string_representation(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'id')); + + static::assertNotNull($keys); + static::assertSame( + $keys->leftHash(row(uuid_entry('id', 'f47ac10b-58cc-4372-a567-0e02b2c3d479'))), + $keys->rightHash(row(uuid_entry('id', 'f47ac10b-58cc-4372-a567-0e02b2c3d479'))), + ); + static::assertNotSame( + $keys->leftHash(row(uuid_entry('id', 'f47ac10b-58cc-4372-a567-0e02b2c3d479'))), + $keys->rightHash(row(uuid_entry('id', '00000000-0000-4000-8000-000000000000'))), + ); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/HashTableTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/HashTableTest.php new file mode 100644 index 0000000000..976a71d55f --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/HashTableTest.php @@ -0,0 +1,87 @@ +add(row(int_entry('user_id', 1), str_entry('name', 'Alice'))); + $hashTable->add(row(int_entry('user_id', 2), str_entry('name', 'Bob'))); + + $candidates = $hashTable->candidatesFor(row(int_entry('id', 1))); + + static::assertCount(1, $candidates); + static::assertSame('Alice', $candidates[0]->valueOf('name')); + } + + public function test_duplicated_rows_are_preserved(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + static::assertNotNull($keys); + + $hashTable = new HashTable($keys); + $hashTable->add(row(int_entry('user_id', 1), str_entry('name', 'Alice'))); + $hashTable->add(row(int_entry('user_id', 1), str_entry('name', 'Alice'))); + + static::assertSame(2, $hashTable->count()); + static::assertCount(2, $hashTable->candidatesFor(row(int_entry('id', 1)))); + } + + public function test_no_candidates_for_unknown_key(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + static::assertNotNull($keys); + + $hashTable = new HashTable($keys); + $hashTable->add(row(int_entry('user_id', 1))); + + static::assertSame([], $hashTable->candidatesFor(row(int_entry('id', 404)))); + } + + public function test_unmatched_rows_tracking(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + static::assertNotNull($keys); + + $hashTable = new HashTable($keys, trackUnmatched: true); + $hashTable->add(row(int_entry('user_id', 1), str_entry('name', 'Alice'))); + $hashTable->add(row(int_entry('user_id', 2), str_entry('name', 'Bob'))); + $hashTable->add(row(int_entry('user_id', 3), str_entry('name', 'Cid'))); + + $hashTable->matched(1); + + $unmatched = iterator_to_array($hashTable->unmatchedRows(), false); + + static::assertCount(2, $unmatched); + static::assertSame('Alice', $unmatched[0]->valueOf('name')); + static::assertSame('Cid', $unmatched[1]->valueOf('name')); + } + + public function test_unmatched_rows_without_tracking_are_empty(): void + { + $keys = EqualityJoinKeys::fromComparison(new Equal('id', 'user_id')); + static::assertNotNull($keys); + + $hashTable = new HashTable($keys); + $hashTable->add(row(int_entry('user_id', 1))); + + static::assertSame([], iterator_to_array($hashTable->unmatchedRows(), false)); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/JoinerTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/JoinerTest.php new file mode 100644 index 0000000000..495596e477 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/JoinerTest.php @@ -0,0 +1,274 @@ +join( + $batches(rows( + row(int_entry('id', 1), str_entry('email', 'alice@flow.php')), + row(int_entry('id', 2), str_entry('email', 'bob@flow.php')), + )), + $batches(rows( + row(int_entry('user_id', 5), str_entry('contact', 'alice@flow.php'), str_entry('name', 'Alice')), + row(int_entry('user_id', 2), str_entry('contact', 'other@flow.php'), str_entry('name', 'Bob')), + )), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame( + [ + [ + 'id' => 1, + 'email' => 'alice@flow.php', + 'user_id' => 5, + 'contact' => 'alice@flow.php', + 'name' => 'Alice', + ], + ['id' => 2, 'email' => 'bob@flow.php', 'user_id' => 2, 'contact' => 'other@flow.php', 'name' => 'Bob'], + ], + $joined, + ); + } + + public function test_duplicated_right_rows_are_all_joined(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $joined = []; + + $joiner = new Joiner(join_on(['id' => 'user_id']), Join::inner); + + foreach ($joiner->join( + $batches(rows(row(int_entry('id', 1)))), + $batches(rows( + row(int_entry('user_id', 1), str_entry('name', 'Alice')), + row(int_entry('user_id', 1), str_entry('name', 'Alice')), + )), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertCount(2, $joined); + } + + public function test_inner_join_emits_every_matching_right_row(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $joined = []; + + $joiner = new Joiner(join_on(['id' => 'user_id']), Join::inner); + + foreach ($joiner->join( + $batches(rows(row(int_entry('id', 1), int_entry('amount', 100)))), + $batches(rows( + row(int_entry('user_id', 1), str_entry('role', 'admin')), + row(int_entry('user_id', 1), str_entry('role', 'writer')), + row(int_entry('user_id', 2), str_entry('role', 'reader')), + )), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame( + [ + ['id' => 1, 'amount' => 100, 'user_id' => 1, 'role' => 'admin'], + ['id' => 1, 'amount' => 100, 'user_id' => 1, 'role' => 'writer'], + ], + $joined, + ); + } + + public function test_inner_join_drops_duplicated_right_join_columns(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $joined = []; + + $joiner = new Joiner(join_on(['id' => 'id']), Join::inner); + + foreach ($joiner->join( + $batches(rows(row(int_entry('id', 1), int_entry('amount', 100)))), + $batches(rows(row(int_entry('id', 1), str_entry('name', 'Alice')))), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame([['id' => 1, 'amount' => 100, 'name' => 'Alice']], $joined); + } + + public function test_left_anti_join_keeps_left_row_on_hash_hit_without_match(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $joined = []; + + // int 1 and string "1" hash into the same bucket but are not identical + $joiner = new Joiner(Expression::on(new Identical('id', 'user_id')), Join::left_anti); + + foreach ($joiner->join( + $batches(rows(row(int_entry('id', 1)), row(int_entry('id', 2)))), + $batches(rows(row(str_entry('user_id', '1')), row(int_entry('user_id', 2)))), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame([['id' => 1]], $joined); + } + + public function test_left_join_keeps_left_row_on_hash_hit_without_match(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $joined = []; + + // int 1 and string "1" hash into the same bucket but are not identical + $joiner = new Joiner(Expression::on(new Identical('id', 'user_id')), Join::left); + + foreach ($joiner->join( + $batches(rows(row(int_entry('id', 1), int_entry('amount', 100)))), + $batches(rows(row(str_entry('user_id', '1'), str_entry('name', 'Alice')))), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame([['id' => 1, 'amount' => 100, 'user_id' => null, 'name' => null]], $joined); + } + + public function test_left_join_pads_unmatched_left_rows_with_nulls(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $joined = []; + + $joiner = new Joiner(join_on(['id' => 'user_id']), Join::left); + + foreach ($joiner->join( + $batches(rows( + row(int_entry('id', 1), int_entry('amount', 100)), + row(int_entry('id', 404), int_entry('amount', 200)), + )), + $batches(rows(row(int_entry('user_id', 1), str_entry('name', 'Alice')))), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame( + [ + ['id' => 1, 'amount' => 100, 'user_id' => 1, 'name' => 'Alice'], + ['id' => 404, 'amount' => 200, 'user_id' => null, 'name' => null], + ], + $joined, + ); + } + + public function test_prefix_collision_suggests_different_prefix(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $this->expectException(DuplicatedEntriesException::class); + $this->expectExceptionMessage('try to use a different join prefix than: "left_"'); + + $joiner = new Joiner(join_on(['id' => 'user_id'], join_prefix: 'left_'), Join::inner); + + foreach ($joiner->join( + $batches(rows(row(int_entry('id', 1), str_entry('left_name', 'collision')))), + $batches(rows(row(int_entry('user_id', 1), str_entry('name', 'Alice')))), + ) as $batch) { + $batch->count(); + } + } + + public function test_right_join_emits_unmatched_right_rows_with_null_left_entries(): void + { + $batches = static function (Rows $rows): Generator { + yield $rows; + }; + + $joined = []; + + $joiner = new Joiner(join_on(['id' => 'user_id']), Join::right); + + foreach ($joiner->join( + $batches(rows(row(int_entry('id', 1), int_entry('amount', 100)))), + $batches(rows( + row(int_entry('user_id', 1), str_entry('name', 'Alice')), + row(int_entry('user_id', 2), str_entry('name', 'Bob')), + )), + ) as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame( + [ + ['id' => 1, 'amount' => 100, 'user_id' => 1, 'name' => 'Alice'], + ['id' => null, 'amount' => null, 'user_id' => 2, 'name' => 'Bob'], + ], + $joined, + ); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/NullRowBuilderTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/NullRowBuilderTest.php new file mode 100644 index 0000000000..eeeaac8f81 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/NullRowBuilderTest.php @@ -0,0 +1,50 @@ +collect(row(int_entry('id', 1), str_entry('name', 'Alice'))); + $builder->collect(row(int_entry('id', 2), str_entry('country', 'PL'))); + + static::assertSame(['id' => null, 'name' => null, 'country' => null], $builder->row()->toArray()); + } + + public function test_definitions_are_nullable(): void + { + $builder = new NullRowBuilder(new EntryFactory()); + + $builder->collect(row(int_entry('id', 1))); + + static::assertTrue($builder->row()->get('id')->definition()->isNullable()); + } + + public function test_empty_builder_produces_empty_row(): void + { + static::assertSame([], (new NullRowBuilder(new EntryFactory()))->row()->toArray()); + } + + public function test_first_seen_definition_wins(): void + { + $builder = new NullRowBuilder(new EntryFactory()); + + $builder->collect(row(int_entry('id', 1))); + $builder->collect(row(str_entry('id', 'one'))); + + static::assertSame('integer', $builder->row()->get('id')->definition()->type()->toString()); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/RowMergerTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/RowMergerTest.php new file mode 100644 index 0000000000..6e60e2f3cf --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/RowMergerTest.php @@ -0,0 +1,119 @@ +expectException(DuplicatedEntriesException::class); + $this->expectExceptionMessage('Merged entries names must be unique'); + + (new RowMerger())->merge(row(int_entry('id', 1), str_entry('name', 'left')), row(str_entry('name', 'right'))); + } + + public function test_drop_left_skips_duplicated_join_columns(): void + { + $merger = new RowMerger('', dropLeft: ['id']); + + static::assertSame( + ['amount' => 100, 'id' => 1, 'name' => 'Alice'], + $merger + ->merge( + row(int_entry('id', 1), int_entry('amount', 100)), + row(int_entry('id', 1), str_entry('name', 'Alice')), + ) + ->toArray(), + ); + } + + public function test_drop_right_skips_duplicated_join_columns(): void + { + $merger = new RowMerger('', dropRight: ['id']); + + static::assertSame( + ['id' => 1, 'amount' => 100, 'name' => 'Alice'], + $merger + ->merge( + row(int_entry('id', 1), int_entry('amount', 100)), + row(int_entry('id', 1), str_entry('name', 'Alice')), + ) + ->toArray(), + ); + } + + public function test_merge_without_prefix_keeps_right_names(): void + { + static::assertSame( + ['id' => 1, 'name' => 'Alice'], + (new RowMerger()) + ->merge(row(int_entry('id', 1)), row(str_entry('name', 'Alice'))) + ->toArray(), + ); + } + + public function test_prefix_collision_with_left_name_throws(): void + { + $this->expectException(DuplicatedEntriesException::class); + + (new RowMerger('left_'))->merge(row(str_entry('left_name', 'left')), row(str_entry('name', 'right'))); + } + + public function test_prefix_renames_every_right_entry(): void + { + static::assertSame( + ['id' => 1, 'right_id' => 1, 'right_name' => 'Alice'], + (new RowMerger('right_')) + ->merge(row(int_entry('id', 1)), row(int_entry('id', 1), str_entry('name', 'Alice'))) + ->toArray(), + ); + } + + public function test_renamed_definition_cache_survives_changing_definitions(): void + { + $merger = new RowMerger('r_'); + + $first = $merger->merge(row(int_entry('id', 1)), row(str_entry('x', 'a'))); + $second = $merger->merge(row(int_entry('id', 2)), row(int_entry('x', 5))); + + static::assertSame('string', $first->get('r_x')->definition()->type()->toString()); + static::assertSame('integer', $second->get('r_x')->definition()->type()->toString()); + } + + public function test_renamed_entries_carry_renamed_definitions(): void + { + $merged = (new RowMerger('r_'))->merge(row(int_entry('id', 1)), row(str_entry('name', 'Alice'))); + + static::assertSame('Alice', $merged->get('r_name')->value()); + static::assertSame('r_name', $merged->get('r_name')->name()); + static::assertSame('r_name', $merged->get('r_name')->definition()->entry()->name()); + } + + public function test_reused_merger_handles_rows_with_different_entry_sets(): void + { + $merger = new RowMerger(); + + static::assertSame( + ['id' => 1, 'name' => 'Alice'], + $merger->merge(row(int_entry('id', 1)), row(str_entry('name', 'Alice')))->toArray(), + ); + static::assertSame( + ['id' => 2, 'name' => 'Bob', 'age' => 30], + $merger->merge(row(int_entry('id', 2)), row(str_entry('name', 'Bob'), int_entry('age', 30)))->toArray(), + ); + static::assertSame( + ['id' => 3, 'name' => 'Cid'], + $merger->merge(row(int_entry('id', 3)), row(str_entry('name', 'Cid')))->toArray(), + ); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/SingleBucketJoinKeysTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/SingleBucketJoinKeysTest.php new file mode 100644 index 0000000000..6c3d18479c --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Join/HashJoin/SingleBucketJoinKeysTest.php @@ -0,0 +1,25 @@ +leftHash(row(int_entry('id', 1)))); + static::assertSame('', $keys->leftHash(row(str_entry('name', 'anything')))); + static::assertSame('', $keys->rightHash(row(int_entry('id', 42)))); + static::assertSame('', $keys->rightHash(row(str_entry('name', 'other')))); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Processor/HashJoin/HashTableTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Processor/HashJoin/HashTableTest.php deleted file mode 100644 index c27b7e7c7a..0000000000 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Processor/HashJoin/HashTableTest.php +++ /dev/null @@ -1,65 +0,0 @@ -add(row(int_entry('id', 1), str_entry('value', '1')), refs('id')); - $hashTable->add(row(int_entry('id', 1), str_entry('value', '2')), refs('id')); - $hashTable->add(row(int_entry('id', 1), str_entry('value', '3')), refs('id')); - - $hashTable->add(row(int_entry('id', 2)), refs('id')); - $hashTable->add(row(int_entry('id', 2)), refs('id')); - - $hashTable->add(row(int_entry('id', 3), str_entry('value', '1')), refs('id')); - $hashTable->add(row(int_entry('id', 3), str_entry('value', '2')), refs('id')); - $hashTable->add(row(int_entry('id', 3), str_entry('value', '1')), refs('id')); - - $bucket1 = $hashTable->bucketFor(row(int_entry('id', 1)), refs('id')); - static::assertNotNull($bucket1); - static::assertCount(3, $bucket1); - - $bucket2 = $hashTable->bucketFor(row(int_entry('id', 2)), refs('id')); - static::assertNotNull($bucket2); - static::assertCount(1, $bucket2); - - $bucket3 = $hashTable->bucketFor(row(int_entry('id', 3)), refs('id')); - static::assertNotNull($bucket3); - static::assertCount(2, $bucket3); - static::assertNull($hashTable->bucketFor(row(int_entry('id', 4)), refs('id'))); - } - - public function test_using_different_references_to_hash_row(): void - { - $hashTable = new HashTable(new PlainText()); - - $hashTable->add(row(int_entry('id', 1)), refs('id')); - $hashTable->add(row(int_entry('id', 1)), refs('id')); - - $hashTable->add(row(int_entry('id', 2), str_entry('value', '1')), refs('id')); - $hashTable->add(row(int_entry('id', 2), str_entry('value', '2')), refs('id')); - - $bucket4 = $hashTable->bucketFor(row(int_entry('identifier', 1)), refs('identifier')); - static::assertNotNull($bucket4); - static::assertCount(1, $bucket4); - - $bucket5 = $hashTable->bucketFor(row(int_entry('identifier', 2)), refs('identifier')); - static::assertNotNull($bucket5); - static::assertCount(2, $bucket5); - } -} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Processor/HashJoinProcessorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Processor/HashJoinProcessorTest.php index 10acba6820..14f6ab2378 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Processor/HashJoinProcessorTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Processor/HashJoinProcessorTest.php @@ -8,8 +8,10 @@ use Flow\ETL\Join\Join; use Flow\ETL\Processor\HashJoinProcessor; use Flow\ETL\Rows; +use Flow\ETL\Sort\ExternalSort\BucketsCache\InMemoryBucketsCache; use Flow\ETL\Tests\FlowTestCase; +use function Flow\ETL\DSL\config_builder; use function Flow\ETL\DSL\df; use function Flow\ETL\DSL\flow_context; use function Flow\ETL\DSL\from_rows; @@ -17,9 +19,64 @@ use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; +use function usort; final class HashJoinProcessorTest extends FlowTestCase { + public function test_on_disk_cache_produces_the_same_rows_as_the_in_memory_cache(): void + { + $leftRows = rows( + row(int_entry('id', 1), int_entry('amount', 100)), + row(int_entry('id', 2), int_entry('amount', 200)), + row(int_entry('id', 404), int_entry('amount', 300)), + ); + $rightRows = rows( + row(int_entry('user_id', 1), str_entry('name', 'Alice')), + row(int_entry('user_id', 2), str_entry('name', 'Bob')), + row(int_entry('user_id', 3), str_entry('name', 'Cid')), + ); + + $results = []; + + foreach ([config_builder()->joinCache(new InMemoryBucketsCache()), config_builder()] as $configBuilder) { + $processor = new HashJoinProcessor( + df()->read(from_rows($rightRows)), + Expression::on(['id' => 'user_id']), + Join::left, + ); + + $generator = (static function () use ($leftRows) { + yield $leftRows; + })(); + + $joined = []; + + $context = flow_context($configBuilder->build()); + + /** @var list $batches */ + $batches = iterator_to_array($processor->process($generator, $context)); + + foreach ($batches as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + usort($joined, static fn(array $left, array $right): int => (int) $left['id'] <=> (int) $right['id']); + $results[] = $joined; + } + + static::assertSame( + [ + ['id' => 1, 'amount' => 100, 'user_id' => 1, 'name' => 'Alice'], + ['id' => 2, 'amount' => 200, 'user_id' => 2, 'name' => 'Bob'], + ['id' => 404, 'amount' => 300, 'user_id' => null, 'name' => null], + ], + $results[0], + ); + static::assertSame($results[0], $results[1]); + } + public function test_handles_empty_left_side(): void { $rightDf = df()->read(from_rows(rows(row(int_entry('user_id', 1), str_entry('name', 'Alice'))))); @@ -93,6 +150,63 @@ public function test_inner_join(): void static::assertEquals('Bob', $allRows[1]['name']); } + public function test_inner_join_emits_every_matching_right_row(): void + { + $rightDf = df()->read(from_rows(rows( + row(int_entry('user_id', 1), str_entry('role', 'admin')), + row(int_entry('user_id', 1), str_entry('role', 'writer')), + ))); + + $processor = new HashJoinProcessor($rightDf, Expression::on(['id' => 'user_id']), Join::inner); + + $generator = (static function () { + yield rows(row(int_entry('id', 1))); + })(); + + $joined = []; + + /** @var list $batches */ + $batches = iterator_to_array($processor->process($generator, flow_context())); + + foreach ($batches as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame( + [ + ['id' => 1, 'user_id' => 1, 'role' => 'admin'], + ['id' => 1, 'user_id' => 1, 'role' => 'writer'], + ], + $joined, + ); + } + + public function test_left_anti_join(): void + { + $rightDf = df()->read(from_rows(rows(row(int_entry('user_id', 1))))); + + $processor = new HashJoinProcessor($rightDf, Expression::on(['id' => 'user_id']), Join::left_anti); + + $generator = (static function () { + yield rows(row(int_entry('id', 1)), row(int_entry('id', 2))); + })(); + + $joined = []; + + /** @var list $batches */ + $batches = iterator_to_array($processor->process($generator, flow_context())); + + foreach ($batches as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame([['id' => 2]], $joined); + } + public function test_left_join(): void { $rightDf = df()->read(from_rows(rows(row(int_entry('user_id', 1), str_entry('name', 'Alice'))))); @@ -121,4 +235,37 @@ public function test_left_join(): void static::assertEquals('Alice', $allRows[0]['name']); static::assertNull($allRows[1]['name']); } + + public function test_right_join(): void + { + $rightDf = df()->read(from_rows(rows( + row(int_entry('user_id', 1), str_entry('name', 'Alice')), + row(int_entry('user_id', 2), str_entry('name', 'Bob')), + ))); + + $processor = new HashJoinProcessor($rightDf, Expression::on(['id' => 'user_id']), Join::right); + + $generator = (static function () { + yield rows(row(int_entry('id', 1), int_entry('amount', 100))); + })(); + + $joined = []; + + /** @var list $batches */ + $batches = iterator_to_array($processor->process($generator, flow_context())); + + foreach ($batches as $batch) { + foreach ($batch->toArray() as $rowData) { + $joined[] = $rowData; + } + } + + static::assertSame( + [ + ['id' => 1, 'amount' => 100, 'user_id' => 1, 'name' => 'Alice'], + ['id' => null, 'amount' => null, 'user_id' => 2, 'name' => 'Bob'], + ], + $joined, + ); + } } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/AdaptiveRowHydratorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/AdaptiveRowHydratorTest.php new file mode 100644 index 0000000000..c807bb81d5 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/AdaptiveRowHydratorTest.php @@ -0,0 +1,48 @@ +hydrate( + [new RawRowValues(['id' => 1, 'name' => 'flow']), new RawRowValues(['id' => 2, 'name' => null])], + schema(int_schema('id'), str_schema('name', nullable: true)), + ); + + static::assertSame(2, $rows->count()); + static::assertSame(1, $rows->first()->valueOf('id')); + static::assertNull($rows->all()[1]->valueOf('name')); + } + + public function test_dehydrate_turns_rows_into_typed_values(): void + { + $dehydrated = (new AdaptiveRowHydrator())->dehydrate(rows(row(int_entry('id', 1), str_entry('name', 'flow')))); + + static::assertCount(1, $dehydrated); + static::assertSame(['id' => 1, 'name' => 'flow'], $dehydrated[0]->values); + } + + public function test_cast_infers_rows_without_a_schema(): void + { + $rows = (new AdaptiveRowHydrator())->cast([new RawRowValues(['id' => 1, 'name' => 'x'])]); + + static::assertSame(1, $rows->first()->valueOf('id')); + static::assertSame('x', $rows->first()->valueOf('name')); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/ArrayToRowTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/ArrayToRowTest.php index 28486cd1ba..1eed9a6982 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/ArrayToRowTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/ArrayToRowTest.php @@ -31,7 +31,7 @@ final class ArrayToRowTest extends FlowTestCase { public function test_building_array_to_row_with_entry_that_is_list_of_strings(): void { - $row = array_to_row(['data' => ['a', 'b', 'c', 'd']], flow_context(config())->entryFactory()); + $row = array_to_row(['data' => ['a', 'b', 'c', 'd']], flow_context(config())->hydrator()); static::assertEquals(row(list_entry('data', ['a', 'b', 'c', 'd'], type_list(type_string()))), $row); } @@ -41,7 +41,7 @@ public function test_building_single_row_from_array_with_rows_fails(): void $row = array_to_row([ ['id' => 1234, 'deleted' => false, 'phase' => null], ['id' => 4321, 'deleted' => true, 'phase' => 'launch'], - ], flow_context(config())->entryFactory()); + ], flow_context(config())->hydrator()); static::assertEquals( row(struct_entry('e00', ['id' => 1234, 'deleted' => false, 'phase' => null], type_structure([ @@ -61,7 +61,7 @@ public function test_building_single_row_from_array_with_schema_and_additional_f { $row = array_to_row( ['id' => 1234, 'deleted' => false, 'phase' => null], - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), schema: schema(int_schema('id'), bool_schema('deleted')), ); @@ -72,7 +72,7 @@ public function test_building_single_row_from_array_with_schema_but_entries_not_ { $row = array_to_row( ['id' => 1234, 'deleted' => false], - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), schema: schema(int_schema('id'), bool_schema('deleted'), str_schema('phase', true)), ); @@ -85,7 +85,7 @@ public function test_building_single_row_from_flat_array(): void 'id' => 1234, 'deleted' => false, 'phase' => null, - ], flow_context(config())->entryFactory()); + ], flow_context(config())->hydrator()); static::assertEquals(row(int_entry('id', 1234), bool_entry('deleted', false), null_entry('phase')), $row); } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/Entry/NullEntryTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/Entry/NullEntryTest.php new file mode 100644 index 0000000000..249c27c600 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/Entry/NullEntryTest.php @@ -0,0 +1,86 @@ +definition()); + } + + public function test_empty_name_throws(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Entry name cannot be empty'); + + null_entry(''); + } + + public function test_is_equal_to_another_null_entry_with_the_same_name(): void + { + static::assertTrue(null_entry('e')->isEqual(null_entry('e'))); + } + + public function test_is_not_equal_to_a_non_null_entry(): void + { + static::assertFalse(null_entry('e')->isEqual(int_entry('e', 1))); + } + + public function test_is_not_equal_to_a_null_entry_with_a_different_name(): void + { + static::assertFalse(null_entry('e')->isEqual(null_entry('other'))); + } + + public function test_metadata_is_carried_into_the_definition(): void + { + static::assertTrue(null_entry('e', Metadata::with('k', 'v'))->definition()->metadata()->has('k')); + static::assertSame('v', null_entry('e', Metadata::with('k', 'v'))->definition()->metadata()->get('k')); + } + + public function test_name(): void + { + static::assertSame('e', null_entry('e')->name()); + } + + public function test_rename_keeps_metadata(): void + { + $renamed = null_entry('e', Metadata::with('k', 'v'))->rename('renamed'); + + static::assertSame('renamed', $renamed->name()); + static::assertTrue($renamed->definition()->metadata()->has('k')); + } + + public function test_to_string_is_empty(): void + { + static::assertSame('', null_entry('e')->toString()); + static::assertSame('', (string) null_entry('e')); + } + + public function test_type_is_null_type(): void + { + static::assertInstanceOf(NullType::class, null_entry('e')->type()); + } + + public function test_value_is_null(): void + { + static::assertNull(null_entry('e')->value()); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/EntryFactoryParityTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/EntryFactoryParityTest.php new file mode 100644 index 0000000000..17bf1a7a76 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/EntryFactoryParityTest.php @@ -0,0 +1,71 @@ + [1, type_integer()]; + yield 'string' => ['flow', type_string()]; + yield 'datetime' => [new DateTimeImmutable('2024-04-01 10:00:00 UTC'), type_datetime()]; + yield 'time' => [new DateInterval('PT1H'), type_time()]; + yield 'uuid' => [new FlowUuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'), type_uuid()]; + yield 'json object' => [new Json('{"id":1}'), type_json()]; + yield 'json array' => [new Json('[1,2,3]'), type_json()]; + yield 'list of int' => [[1, 2, 3], type_list(type_integer())]; + yield 'map' => [['a' => 1, 'b' => 2], type_map(type_string(), type_integer())]; + yield 'structure' => [ + ['id' => 1, 'name' => 'flow'], + type_structure(['id' => type_integer(), 'name' => type_string()]), + ]; + yield 'nested structure' => [ + ['geo' => ['lat' => 1, 'lon' => 2], 'name' => 'flow'], + type_structure([ + 'geo' => type_map(type_string(), type_integer()), + 'name' => type_string(), + ]), + ]; + } + + /** + * @param Type $type + */ + #[DataProvider('provide_native_values')] + public function test_trusted_create_matches_casting_coerce(mixed $value, Type $type): void + { + $factory = new EntryFactory(); + + static::assertEquals($factory->cast('e', $value, $type), $factory->create('e', $value, $type)); + } + + public function test_trusted_create_fails_loudly_for_a_value_that_does_not_match_the_type(): void + { + $this->expectException(InvalidArgumentException::class); + + (new EntryFactory())->create('e', '2024-01-01 10:00:00 UTC', type_datetime()); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/EntryFactoryTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/EntryFactoryTest.php index 814c1e3681..e5eb8a367e 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/EntryFactoryTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/EntryFactoryTest.php @@ -11,26 +11,23 @@ use Dom\HTMLDocument; use DOMDocument; use Flow\ETL\Exception\InvalidArgumentException; -use Flow\ETL\Exception\SchemaDefinitionNotFoundException; use Flow\ETL\Row\Entry; -use Flow\ETL\Row\Entry\StringEntry; use Flow\ETL\Row\Entry\TimeEntry; use Flow\ETL\Row\EntryFactory; use Flow\ETL\Schema\Definition; use Flow\ETL\Schema\Metadata; use Flow\ETL\Tests\Fixtures\Enum\BackedIntEnum; +use Flow\ETL\Tests\FlowTestCase; use Flow\Types\Value\Json; use Flow\Types\Value\Uuid as FlowUuid; use Generator; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\RequiresPhp; -use PHPUnit\Framework\TestCase; use Ramsey\Uuid\Uuid; use function class_exists; use function Flow\ETL\DSL\bool_entry; use function Flow\ETL\DSL\bool_schema; -use function Flow\ETL\DSL\config; use function Flow\ETL\DSL\date_entry; use function Flow\ETL\DSL\date_schema; use function Flow\ETL\DSL\datetime_entry; @@ -39,7 +36,6 @@ use function Flow\ETL\DSL\enum_schema; use function Flow\ETL\DSL\float_entry; use function Flow\ETL\DSL\float_schema; -use function Flow\ETL\DSL\flow_context; use function Flow\ETL\DSL\html_element_entry; use function Flow\ETL\DSL\html_element_schema; use function Flow\ETL\DSL\html_entry; @@ -53,7 +49,7 @@ use function Flow\ETL\DSL\list_schema; use function Flow\ETL\DSL\map_entry; use function Flow\ETL\DSL\map_schema; -use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\null_entry; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\string_entry; use function Flow\ETL\DSL\string_schema; @@ -71,17 +67,13 @@ use function Flow\Types\DSL\type_integer; use function Flow\Types\DSL\type_list; use function Flow\Types\DSL\type_map; -use function Flow\Types\DSL\type_null; use function Flow\Types\DSL\type_string; use function Flow\Types\DSL\type_structure; -use function Flow\Types\DSL\type_time_zone; use function Flow\Types\DSL\type_union; -final class EntryFactoryTest extends TestCase +final class EntryFactoryTest extends FlowTestCase { - private EntryFactory $entryFactory; - - public static function provide_instantiate_cases(): Generator + public static function provide_definition_cases(): Generator { yield 'boolean' => [bool_schema('e'), true, bool_entry('e', true)]; yield 'date' => [date_schema('e'), $date = new DateTimeImmutable('2024-04-01'), date_entry('e', $date)]; @@ -129,10 +121,7 @@ enum_entry('e', BackedIntEnum::one), public static function provide_recognized_data(): Generator { - yield 'json' => [ - $json = '{"id":1}', - string_entry('e', $json), - ]; + yield 'json' => ['{"id":1}', string_entry('e', '{"id":1}')]; yield 'xml' => [ $xml = '123', string_entry('e', $xml), @@ -149,32 +138,13 @@ public static function provide_recognized_data(): Generator public static function provide_unrecognized_data(): Generator { - yield 'json alike' => [ - '{"id":1', - ]; - yield 'uuid alike' => [ - '00000000-0000-0000-0000-00000', - ]; - yield 'xml alike' => [ - ' [ - ' [ - ' ', - ]; - yield 'new line' => [ - "\n", - ]; - yield 'invisible' => [ - '‎ ', - ]; - } - - protected function setUp(): void - { - $this->entryFactory = flow_context(config())->entryFactory(); + yield 'json alike' => ['{"id":1']; + yield 'uuid alike' => ['00000000-0000-0000-0000-00000']; + yield 'xml alike' => [' [' [' ']; + yield 'new line' => ["\n"]; + yield 'invisible' => ['‎ ']; } public function test_array_structure(): void @@ -182,48 +152,100 @@ public function test_array_structure(): void static::assertEquals(structure_entry('e', ['a' => 1, 'b' => '2'], type_structure([ 'a' => type_integer(), 'b' => type_string(), - ])), $this->entryFactory->create('e', ['a' => 1, 'b' => '2'])); + ])), (new EntryFactory())->create('e', ['a' => 1, 'b' => '2'])); } public function test_bool(): void { - static::assertEquals(bool_entry('e', false), $this->entryFactory->create('e', false)); + static::assertEquals(bool_entry('e', false), (new EntryFactory())->create('e', false)); } - public function test_boolean_with_schema(): void + public function test_boolean_with_definition(): void { - static::assertEquals(bool_entry('e', false), $this->entryFactory->create('e', false, schema(bool_schema('e')))); + $definition = bool_schema('e'); + static::assertEquals( + bool_entry('e', false), + (new EntryFactory())->cast('e', false, $definition->type(), $definition->metadata()), + ); + } + + public function test_coerce_null_with_non_optional_type_keeps_silent_null(): void + { + static::assertEquals(int_entry('e', null), (new EntryFactory())->cast('e', null, type_integer())); + } + + public function test_create_null_with_type_creates_typed_null(): void + { + static::assertEquals(int_entry('e', null), (new EntryFactory())->create('e', null, type_integer())); + } + + public function test_create_trusted_native_value_with_type(): void + { + $datetime = new DateTimeImmutable('2024-04-01 10:00:00 UTC'); + static::assertEquals( + datetime_entry('e', $datetime), + (new EntryFactory())->create('e', $datetime, type_datetime()), + ); + } + + public function test_create_trusted_scalar_with_type(): void + { + static::assertEquals(int_entry('e', 5), (new EntryFactory())->create('e', 5, type_integer())); + } + + public function test_from_definition_instantiates_a_native_value(): void + { + static::assertEquals(int_entry('e', 5), (new EntryFactory())->fromDefinition(integer_schema('e'), 5)); + } + + public function test_from_definition_null_uses_the_nullable_variant(): void + { + $entry = (new EntryFactory())->fromDefinition(integer_schema('e'), null); + + static::assertNull($entry->value()); + static::assertTrue($entry->definition()->isNullable()); + } + + public function test_from_definition_preserves_definition_metadata(): void + { + static::assertEquals( + int_entry('e', null, metadata: Metadata::with('k', 1)), + (new EntryFactory())->fromDefinition(integer_schema('e', true, Metadata::with('k', 1)), null), + ); } public function test_date(): void { static::assertEquals( date_entry('e', '2022-01-01'), - $this->entryFactory->create('e', new DateTimeImmutable('2022-01-01')), + (new EntryFactory())->create('e', new DateTimeImmutable('2022-01-01')), ); } public function test_date_from_int_with_definition(): void { + $definition = date_schema('e'); static::assertEquals( date_entry('e', '1970-01-01'), - $this->entryFactory->create('e', 1, schema(date_schema('e'))), + (new EntryFactory())->cast('e', 1, $definition->type(), $definition->metadata()), ); } public function test_date_from_null_with_definition(): void { + $definition = date_schema('e', true); static::assertEquals( date_entry('e', null), - $this->entryFactory->create('e', null, schema(date_schema('e', true))), + (new EntryFactory())->cast('e', null, $definition->type(), $definition->metadata()), ); } public function test_date_from_string_with_definition(): void { + $definition = date_schema('e'); static::assertEquals( date_entry('e', '2022-01-01'), - $this->entryFactory->create('e', '2022-01-01', schema(date_schema('e'))), + (new EntryFactory())->cast('e', '2022-01-01', $definition->type(), $definition->metadata()), ); } @@ -231,85 +253,95 @@ public function test_datetime(): void { static::assertEquals( datetime_entry('e', $now = new DateTimeImmutable()), - $this->entryFactory->create('e', $now), + (new EntryFactory())->create('e', $now), ); } - public function test_datetime_string_with_schema(): void + public function test_datetime_string_with_definition(): void { + $definition = datetime_schema('e'); static::assertEquals( datetime_entry('e', '2022-01-01 00:00:00 UTC'), - $this->entryFactory->create('e', '2022-01-01 00:00:00 UTC', schema(datetime_schema('e'))), + (new EntryFactory())->cast('e', '2022-01-01 00:00:00 UTC', $definition->type(), $definition->metadata()), ); } - public function test_datetime_with_schema(): void + public function test_datetime_with_definition(): void { + $definition = datetime_schema('e'); static::assertEquals( datetime_entry('e', $datetime = new DateTimeImmutable('now')), - $this->entryFactory->create('e', $datetime, schema(datetime_schema('e'))), + (new EntryFactory())->cast('e', $datetime, $definition->type(), $definition->metadata()), ); } public function test_enum(): void { - static::assertEquals(enum_entry('e', $enum = BackedIntEnum::one), $this->entryFactory->create('e', $enum)); + static::assertEquals(enum_entry('e', $enum = BackedIntEnum::one), (new EntryFactory())->create('e', $enum)); } - public function test_enum_from_string_with_schema(): void + public function test_enum_from_string_with_definition(): void { + $definition = enum_schema('e', BackedIntEnum::class); static::assertEquals( enum_entry('e', BackedIntEnum::one), - $this->entryFactory->create('e', 1, schema(enum_schema('e', BackedIntEnum::class))), + (new EntryFactory())->cast('e', 1, $definition->type(), $definition->metadata()), ); } - public function test_enum_invalid_value_with_schema(): void + public function test_enum_invalid_value_with_definition(): void { + $definition = enum_schema('e', BackedIntEnum::class); $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( 'Entry "e" conversion exception. Can\'t cast "string" into "enum" type', ); - $this->entryFactory->create('e', 'invalid', schema(enum_schema('e', BackedIntEnum::class))); + (new EntryFactory())->cast('e', 'invalid', $definition->type(), $definition->metadata()); } public function test_float(): void { - static::assertEquals(float_entry('e', 1.1), $this->entryFactory->create('e', 1.1)); + static::assertEquals(float_entry('e', 1.1), (new EntryFactory())->create('e', 1.1)); } - public function test_float_with_schema(): void + public function test_float_with_definition(): void { - static::assertEquals(float_entry('e', 1.1), $this->entryFactory->create('e', 1.1, schema(float_schema('e')))); + $definition = float_schema('e'); + static::assertEquals( + float_entry('e', 1.1), + (new EntryFactory())->cast('e', 1.1, $definition->type(), $definition->metadata()), + ); } - public function test_float_with_schema_and_metadata(): void + public function test_float_with_definition_and_metadata(): void { + $definition = float_schema('e', metadata: Metadata::with('test', 1)); static::assertEquals( float_entry('e', 1.1, metadata: Metadata::with('test', 1)), - $this->entryFactory->create('e', 1.1, schema(float_schema('e', metadata: Metadata::with('test', 1)))), + (new EntryFactory())->cast('e', 1.1, $definition->type(), $definition->metadata()), ); } public function test_from_empty_string(): void { - static::assertEquals(str_entry('e', ''), $this->entryFactory->create('e', '')); + static::assertEquals(str_entry('e', ''), (new EntryFactory())->create('e', '')); } public function test_html_element_from_string(): void { static::assertEquals( string_entry('e', $html = '
2

bar

'), - $this->entryFactory->create('e', $html), + (new EntryFactory())->create('e', $html), ); } #[RequiresPhp('>= 8.4.0')] - public function test_html_element_string_with_html_definition_provided(): void + public function test_html_element_string_with_definition(): void { + $definition = html_element_schema('e'); static::assertEquals( html_element_entry('e', $html = '
2

bar

'), - $this->entryFactory->create('e', $html, schema(html_element_schema('e'))), + (new EntryFactory())->cast('e', $html, $definition->type(), $definition->metadata()), ); } @@ -320,7 +352,7 @@ public function test_html_from_dom_html_document(): void $doc = HTMLDocument::createFromString( $html = '
2

3

', ); - static::assertEquals(html_entry('e', $html), $this->entryFactory->create('e', $doc)); + static::assertEquals(html_entry('e', $html), (new EntryFactory())->create('e', $doc)); } public function test_html_from_string(): void @@ -330,140 +362,132 @@ public function test_html_from_string(): void 'e', $html = '
foo

3

', ), - $this->entryFactory->create('e', $html), + (new EntryFactory())->create('e', $html), ); } #[RequiresPhp('>= 8.4.0')] - public function test_html_string_with_html_definition_provided(): void + public function test_html_string_with_definition(): void { // @mago-ignore analysis:unavailable-method $document = HTMLDocument::createFromString( $html = '
2

bar

', ); + $definition = html_schema('e'); static::assertEquals( html_entry('e', $html), - $this->entryFactory->create('e', $document, schema(html_schema('e'))), + (new EntryFactory())->cast('e', $document, $definition->type(), $definition->metadata()), ); } - #[DataProvider('provide_instantiate_cases')] - public function test_instantiate_with_definition(Definition $definition, mixed $value, Entry $expected): void + /** + * @param Definition $definition + * @param Entry $expected + */ + #[DataProvider('provide_definition_cases')] + public function test_coerce_with_definition(Definition $definition, mixed $value, Entry $expected): void { - static::assertEquals($expected, $this->entryFactory->instantiate('e', $value, $definition)); + static::assertEquals($expected, (new EntryFactory())->cast( + 'e', + $value, + $definition->type(), + $definition->metadata(), + )); } - public function test_instantiate_does_not_cast_values(): void + public function test_int(): void { - $datetime = new DateTimeImmutable('2024-04-01 10:00:00 UTC'); - - static::assertSame($datetime, $this->entryFactory->instantiate('e', $datetime, datetime_schema('e'))->value()); + static::assertEquals(int_entry('e', 1), (new EntryFactory())->create('e', 1)); } - public function test_instantiate_preserves_definition_instance(): void + public function test_integer_with_definition(): void { $definition = integer_schema('e'); - - static::assertSame($definition, $this->entryFactory->instantiate('e', 1, $definition)->definition()); - } - - public function test_instantiate_with_schema(): void - { static::assertEquals( - int_entry('id', 1), - $this->entryFactory->instantiate('id', 1, schema(integer_schema('id'), string_schema('name'))), + int_entry('e', 1), + (new EntryFactory())->cast('e', 1, $definition->type(), $definition->metadata()), ); } - public function test_instantiate_with_schema_without_definition_for_entry(): void - { - $this->expectException(SchemaDefinitionNotFoundException::class); - - $this->entryFactory->instantiate('unknown', 1, schema(integer_schema('id'))); - } - - public function test_int(): void - { - static::assertEquals(int_entry('e', 1), $this->entryFactory->create('e', 1)); - } - - public function test_integer_with_schema(): void - { - static::assertEquals(int_entry('e', 1), $this->entryFactory->create('e', 1, schema(integer_schema('e')))); - } - - public function test_integer_with_schema_and_metadata(): void + public function test_integer_with_definition_and_metadata(): void { + $definition = integer_schema('e', metadata: Metadata::with('test', 1)); static::assertEquals( int_entry('e', 1, metadata: Metadata::with('test', 1)), - $this->entryFactory->create('e', 1, schema(integer_schema('e', metadata: Metadata::with('test', 1)))), + (new EntryFactory())->cast('e', 1, $definition->type(), $definition->metadata()), ); } public function test_json(): void { - static::assertEquals(str_entry('e', '{}'), $this->entryFactory->create('e', '{}')); + static::assertEquals(str_entry('e', '{}'), (new EntryFactory())->create('e', '{}')); } public function test_json_object(): void { - static::assertEquals(str_entry('e', '{"id":1}'), $this->entryFactory->create('e', '{"id":1}')); + static::assertEquals(str_entry('e', '{"id":1}'), (new EntryFactory())->create('e', '{"id":1}')); } - public function test_json_object_array_with_schema(): void + public function test_json_object_array_with_definition(): void { + $definition = json_schema('e'); static::assertEquals( json_object_entry('e', ['id' => 1]), - $this->entryFactory->create('e', ['id' => 1], schema(json_schema('e'))), + (new EntryFactory())->cast('e', ['id' => 1], $definition->type(), $definition->metadata()), ); } public function test_json_string(): void { - static::assertEquals(str_entry('e', '{"id": 1}'), $this->entryFactory->create('e', '{"id": 1}')); + static::assertEquals(str_entry('e', '{"id": 1}'), (new EntryFactory())->create('e', '{"id": 1}')); } - public function test_json_string_with_schema(): void + public function test_json_string_with_definition(): void { + $definition = json_schema('e'); static::assertEquals( json_entry('e', '{"id": 1}'), - $this->entryFactory->create('e', '{"id": 1}', schema(json_schema('e'))), + (new EntryFactory())->cast('e', '{"id": 1}', $definition->type(), $definition->metadata()), ); } - public function test_json_with_schema(): void + public function test_json_with_definition(): void { + $definition = json_schema('e'); static::assertEquals( json_entry('e', [['id' => 1]]), - $this->entryFactory->create('e', [['id' => 1]], schema(json_schema('e'))), + (new EntryFactory())->cast('e', [['id' => 1]], $definition->type(), $definition->metadata()), ); } - public function test_list_int_with_schema(): void + public function test_list_int_with_definition(): void { + $definition = list_schema('e', type_list(type_integer())); static::assertEquals( list_entry('e', [1, 2, 3], type_list(type_integer())), - $this->entryFactory->create('e', [1, 2, 3], schema(list_schema('e', type_list(type_integer())))), + (new EntryFactory())->cast('e', [1, 2, 3], $definition->type(), $definition->metadata()), ); } - public function test_list_int_with_schema_but_string_list(): void + public function test_list_int_with_definition_but_string_list(): void { + $definition = list_schema('e', type_list(type_string())); static::assertEquals( list_entry('e', ['false', 'true', 'true'], type_list(type_string())), - $this->entryFactory->create('e', [false, true, true], schema(list_schema('e', type_list(type_string())))), + (new EntryFactory())->cast('e', [false, true, true], $definition->type(), $definition->metadata()), ); } - public function test_list_of_datetime_with_schema(): void + public function test_list_of_datetime_with_definition(): void { + $definition = list_schema('e', type_list(type_datetime())); static::assertEquals( list_entry( 'e', $list = [new DateTimeImmutable('now'), new DateTimeImmutable('tomorrow')], type_list(type_datetime()), ), - $this->entryFactory->create('e', $list, schema(list_schema('e', type_list(type_datetime())))), + (new EntryFactory())->cast('e', $list, $definition->type(), $definition->metadata()), ); } @@ -471,7 +495,7 @@ public function test_list_of_datetimes(): void { static::assertEquals( list_entry('e', $list = [new DateTimeImmutable(), new DateTimeImmutable()], type_list(type_datetime())), - $this->entryFactory->create('e', $list), + (new EntryFactory())->create('e', $list), ); } @@ -479,7 +503,7 @@ public function test_list_of_scalars(): void { static::assertEquals( list_entry('e', [1, 2], type_list(type_integer())), - $this->entryFactory->create('e', [1, 2]), + (new EntryFactory())->create('e', [1, 2]), ); } @@ -504,7 +528,7 @@ public function test_nested_structure(): void 'zip' => type_string(), ]), ), - $this->entryFactory->create('address', [ + (new EntryFactory())->create('address', [ 'city' => 'Krakow', 'geo' => [ 'lat' => 50.06143, @@ -516,17 +540,18 @@ public function test_nested_structure(): void ); } - public function test_null_type_handled(): void + public function test_null_without_definition_creates_null_entry(): void { - static::assertEquals(StringEntry::fromNull('e'), $this->entryFactory->createAs('e', null, type_null())); + static::assertEquals(null_entry('e'), (new EntryFactory())->create('e', null)); } public function test_object(): void { + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( "e: object can't be converted to any known Entry, please normalize that object first", ); - $this->entryFactory->create('e', new ArrayIterator([1, 2])); + (new EntryFactory())->create('e', new ArrayIterator([1, 2])); } /** @@ -535,19 +560,20 @@ public function test_object(): void #[DataProvider('provide_recognized_data')] public function test_recognized_data_set_same_as_provided(string $input, Entry $entry): void { - static::assertEquals($entry, $this->entryFactory->create('e', $input)); + static::assertEquals($entry, (new EntryFactory())->create('e', $input)); } public function test_string(): void { - static::assertEquals(str_entry('e', 'test'), $this->entryFactory->create('e', 'test')); + static::assertEquals(str_entry('e', 'test'), (new EntryFactory())->create('e', 'test')); } - public function test_string_with_schema(): void + public function test_string_with_definition(): void { + $definition = string_schema('e'); static::assertEquals( str_entry('e', 'string'), - $this->entryFactory->create('e', 'string', schema(string_schema('e'))), + (new EntryFactory())->cast('e', 'string', $definition->type(), $definition->metadata()), ); } @@ -564,7 +590,7 @@ public function test_structure(): void 'zip' => type_string(), ]), ), - $this->entryFactory->create('address', [ + (new EntryFactory())->create('address', [ 'id' => 1, 'city' => 'Krakow', 'street' => 'Floriańska', @@ -575,113 +601,90 @@ public function test_structure(): void public function test_time(): void { - static::assertEquals(TimeEntry::fromDays('e', 1), $this->entryFactory->create('e', new DateInterval('P1D'))); + static::assertEquals(TimeEntry::fromDays('e', 1), (new EntryFactory())->create('e', new DateInterval('P1D'))); } public function test_time_from_null_with_definition(): void { + $definition = time_schema('e', true); static::assertEquals( time_entry('e', null), - $this->entryFactory->create('e', null, schema(time_schema('e', true))), + (new EntryFactory())->cast('e', null, $definition->type(), $definition->metadata()), ); } public function test_time_from_string_with_definition(): void { + $definition = time_schema('e'); static::assertEquals( time_entry('e', new DateInterval('P10D')), - $this->entryFactory->create('e', 'P10D', schema(time_schema('e'))), + (new EntryFactory())->cast('e', 'P10D', $definition->type(), $definition->metadata()), ); } public function test_timezone_creates_string_entry(): void { - static::assertEquals( - str_entry('e', 'UTC'), - $this->entryFactory->createAs('e', new DateTimeZone('UTC'), type_time_zone()), - ); - } - - public function test_timezone_from_string_creates_string_entry(): void - { - static::assertEquals( - str_entry('e', 'America/New_York'), - $this->entryFactory->createAs('e', 'America/New_York', type_time_zone()), - ); + static::assertEquals(str_entry('e', 'UTC'), (new EntryFactory())->create('e', new DateTimeZone('UTC'))); } - public function test_union_with_schema_falls_back_to_first_castable_member(): void + public function test_union_with_definition_falls_back_to_first_castable_member(): void { + $definition = union_schema('e', type_union(type_integer(), type_string())); static::assertEquals( int_entry('e', 1), - $this->entryFactory->create( - 'e', - true, - schema(union_schema('e', type_union(type_integer(), type_string()))), - ), + (new EntryFactory())->cast('e', true, $definition->type(), $definition->metadata()), ); } - public function test_union_with_schema_keeps_numeric_string_as_string(): void + public function test_union_with_definition_keeps_numeric_string_as_string(): void { + $definition = union_schema('e', type_union(type_integer(), type_string())); static::assertEquals( str_entry('e', '123'), - $this->entryFactory->create( - 'e', - '123', - schema(union_schema('e', type_union(type_integer(), type_string()))), - ), + (new EntryFactory())->cast('e', '123', $definition->type(), $definition->metadata()), ); } - public function test_union_with_schema_resolves_to_complex_member(): void + public function test_union_with_definition_resolves_to_complex_member(): void { + $definition = union_schema('e', type_union(type_list(type_integer()), type_string())); static::assertEquals( list_entry('e', [1, 2, 3], type_list(type_integer())), - $this->entryFactory->create( - 'e', - [1, 2, 3], - schema(union_schema('e', type_union(type_list(type_integer()), type_string()))), - ), + (new EntryFactory())->cast('e', [1, 2, 3], $definition->type(), $definition->metadata()), ); } - public function test_union_with_schema_resolves_to_integer(): void + public function test_union_with_definition_resolves_to_integer(): void { + $definition = union_schema('e', type_union(type_integer(), type_string())); static::assertEquals( int_entry('e', 1), - $this->entryFactory->create('e', 1, schema(union_schema('e', type_union(type_integer(), type_string())))), + (new EntryFactory())->cast('e', 1, $definition->type(), $definition->metadata()), ); } - public function test_union_with_schema_resolves_to_string(): void + public function test_union_with_definition_resolves_to_string(): void { + $definition = union_schema('e', type_union(type_integer(), type_string())); static::assertEquals( str_entry('e', 'flow'), - $this->entryFactory->create( - 'e', - 'flow', - schema(union_schema('e', type_union(type_integer(), type_string()))), - ), + (new EntryFactory())->cast('e', 'flow', $definition->type(), $definition->metadata()), ); } - public function test_union_with_schema_with_null_value_creates_first_member_entry(): void + public function test_union_with_definition_with_null_value_creates_first_member_entry(): void { + $definition = union_schema('e', type_union(type_integer(), type_string()), true); static::assertEquals( int_entry('e', null), - $this->entryFactory->create( - 'e', - null, - schema(union_schema('e', type_union(type_integer(), type_string()), true)), - ), + (new EntryFactory())->cast('e', null, $definition->type(), $definition->metadata()), ); } #[DataProvider('provide_unrecognized_data')] public function test_unrecognized_data_set_same_as_provided(string $input): void { - static::assertEquals(str_entry('e', $input), $this->entryFactory->create('e', $input)); + static::assertEquals(str_entry('e', $input), (new EntryFactory())->create('e', $input)); } public function test_uuid_from_ramsey_uuid_library(): void @@ -690,22 +693,23 @@ public function test_uuid_from_ramsey_uuid_library(): void static::markTestSkipped("Package 'ramsey/uuid' is required for this test."); } $uuidObject = Uuid::uuid4(); - static::assertEquals(uuid_entry('e', $uuidObject->toString()), $this->entryFactory->create('e', $uuidObject)); + static::assertEquals(uuid_entry('e', $uuidObject->toString()), (new EntryFactory())->create('e', $uuidObject)); } public function test_uuid_from_string(): void { static::assertEquals( string_entry('e', $uuid = '00000000-0000-0000-0000-000000000000'), - $this->entryFactory->create('e', $uuid), + (new EntryFactory())->create('e', $uuid), ); } - public function test_uuid_string_with_uuid_definition_provided(): void + public function test_uuid_string_with_definition(): void { + $definition = uuid_schema('e'); static::assertEquals( uuid_entry('e', $uuid = '00000000-0000-0000-0000-000000000000'), - $this->entryFactory->create('e', $uuid, schema(uuid_schema('e'))), + (new EntryFactory())->cast('e', $uuid, $definition->type(), $definition->metadata()), ); } @@ -713,42 +717,31 @@ public function test_uuid_type(): void { static::assertEquals( string_entry('e', '00000000-0000-0000-0000-000000000000'), - $this->entryFactory->create('e', '00000000-0000-0000-0000-000000000000'), + (new EntryFactory())->create('e', '00000000-0000-0000-0000-000000000000'), ); } - public function test_with_empty_schema(): void - { - $this->expectException(SchemaDefinitionNotFoundException::class); - $this->entryFactory->create('e', '1', schema()); - } - - public function test_with_schema_for_different_entry(): void - { - $this->expectException(SchemaDefinitionNotFoundException::class); - $this->entryFactory->create('diff', '1', schema(string_schema('e'))); - } - public function test_xml_from_dom_document(): void { $doc = new DOMDocument(); $doc->loadXML($xml = '123'); - static::assertEquals(xml_entry('e', $xml), $this->entryFactory->create('e', $doc)); + static::assertEquals(xml_entry('e', $xml), (new EntryFactory())->create('e', $doc)); } public function test_xml_from_string(): void { static::assertEquals( string_entry('e', $xml = '123'), - $this->entryFactory->create('e', $xml), + (new EntryFactory())->create('e', $xml), ); } - public function test_xml_string_with_xml_definition_provided(): void + public function test_xml_string_with_definition(): void { + $definition = xml_schema('e'); static::assertEquals( xml_entry('e', $xml = '123'), - $this->entryFactory->create('e', $xml, schema(xml_schema('e'))), + (new EntryFactory())->cast('e', $xml, $definition->type(), $definition->metadata()), ); } } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/NativeRowHydratorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/NativeRowHydratorTest.php new file mode 100644 index 0000000000..4137ab3ade --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/NativeRowHydratorTest.php @@ -0,0 +1,562 @@ +}> + */ + public static function serializable_datasets(): Generator + { + yield 'scalars over multiple rows' => [ + schema(int_schema('id'), str_schema('name', nullable: true), float_schema('p'), bool_schema('a')), + [ + new RawRowValues(['id' => 1, 'name' => 'x', 'p' => 1.5, 'a' => true]), + new RawRowValues(['id' => 2, 'name' => null, 'p' => -0.25, 'a' => false]), + new RawRowValues(['id' => 3, 'name' => 'z', 'p' => 0.0, 'a' => true]), + ], + ]; + + yield 'null on a non-nullable column across rows' => [ + schema(int_schema('id'), str_schema('name')), + [ + new RawRowValues(['id' => 1, 'name' => null]), + new RawRowValues(['id' => 2, 'name' => null]), + ], + ]; + + yield 'absent columns are skipped' => [ + schema(int_schema('id'), str_schema('name', nullable: true), bool_schema('flag', nullable: true)), + [ + new RawRowValues(['id' => 1]), + new RawRowValues(['id' => 2, 'name' => 'y']), + ], + ]; + + yield 'per-value metadata divergence across rows' => [ + schema(int_schema('id')), + [ + new RawRowValues(['id' => 1], ['id' => Metadata::fromArray(['k' => 'v1'])]), + new RawRowValues(['id' => 2], ['id' => Metadata::fromArray(['k' => 'v2'])]), + ], + ]; + + yield 'per-value metadata together with a null non-nullable value' => [ + schema(int_schema('id')), + [new RawRowValues(['id' => null], ['id' => Metadata::fromArray(['k' => 'v'])])], + ]; + + yield 'temporal and uuid values' => [ + schema(datetime_schema('at'), date_schema('d'), time_schema('t'), uuid_schema('u')), + [new RawRowValues([ + 'at' => new DateTimeImmutable('2025-01-01 12:00:00.123456', new DateTimeZone('Europe/Warsaw')), + 'd' => new DateTimeImmutable('2025-03-01'), + 't' => new DateInterval('PT2H30M5S'), + 'u' => new Uuid('01234567-89ab-4def-8123-456789abcdef'), + ])], + ]; + + yield 'containers and json' => [ + schema( + list_schema('l', type_list(type_integer())), + map_schema('m', type_map(type_string(), type_integer())), + structure_schema('st', type_structure(['a' => type_integer(), 'b' => type_string()])), + list_schema('opt', type_list(type_optional(type_integer()))), + json_schema('j'), + ), + [new RawRowValues([ + 'l' => [1, 2, 3], + 'm' => ['a' => 1], + 'st' => ['a' => 1, 'b' => 'kept'], + 'opt' => [1, null], + 'j' => Json::fromArray(['x' => 1]), + ])], + ]; + + yield 'enum values including a null variant' => [ + schema(enum_schema('s', ParitySuit::class)), + [ + new RawRowValues(['s' => ParitySuit::Hearts]), + new RawRowValues(['s' => ParitySuit::Spades]), + new RawRowValues(['s' => null]), + ], + ]; + + yield 'null definition column' => [ + schema(null_schema('n'), int_schema('id', nullable: true)), + [ + new RawRowValues(['n' => null, 'id' => null]), + new RawRowValues(['n' => null, 'id' => 5]), + ], + ]; + + yield 'empty batch' => [schema(int_schema('id')), []]; + } + + /** + * @return \Generator}> + */ + public static function castable_datasets(): Generator + { + yield 'scalar columns from raw strings and coercion edges' => [ + schema(int_schema('id'), float_schema('price'), bool_schema('active'), str_schema('name')), + [ + new RawRowValues(['id' => '42', 'price' => '3.14', 'active' => 'yes', 'name' => 7]), + new RawRowValues(['id' => ' 7', 'price' => '1e3', 'active' => 'OFF', 'name' => 1.5]), + new RawRowValues(['id' => 'abc', 'price' => '0x1A', 'active' => 'weird', 'name' => true]), + new RawRowValues(['id' => '12abc', 'price' => true, 'active' => 0, 'name' => false]), + new RawRowValues(['id' => '9223372036854775808', 'price' => 7, 'active' => 3.5, 'name' => null]), + new RawRowValues(['id' => 5, 'price' => 2.5, 'active' => true, 'name' => 'text']), + ], + ]; + + yield 'nested positive integer and string family elements' => [ + schema( + list_schema('counts', type_list(type_positive_integer())), + structure_schema('labels', type_structure(['label' => type_non_empty_string()])), + structure_schema('codes', type_structure(['code' => type_numeric_string()])), + ), + [ + new RawRowValues([ + 'counts' => [5, 7], + 'labels' => ['label' => 'x'], + 'codes' => ['code' => '42'], + ]), + new RawRowValues([ + 'counts' => ['5', 8], + 'labels' => ['label' => 9], + 'codes' => ['code' => 42], + ]), + new RawRowValues([ + 'counts' => [], + 'labels' => ['label' => 1.5], + 'codes' => ['code' => '3.14'], + ]), + new RawRowValues([ + 'counts' => [1], + 'labels' => ['label' => true], + 'codes' => ['code' => 42.5], + ]), + ], + ]; + + $shared = new DateTimeImmutable('2025-01-01 12:00:00.123456', new DateTimeZone('Europe/Warsaw')); + + yield 'temporal columns preserving object identity topology' => [ + schema(datetime_schema('at'), datetime_schema('at2'), date_schema('d')), + [ + new RawRowValues(['at' => $shared, 'at2' => $shared, 'd' => $shared]), + new RawRowValues([ + 'at' => $shared, + 'at2' => '2024-03-01 10:20:30', + 'd' => new DateTimeImmutable('2025-03-01'), + ]), + new RawRowValues(['at' => 1700000000, 'at2' => 1700000000.5, 'd' => '2024-03-05 08:30:00']), + new RawRowValues(['at' => '2024-02-29T12:00:00+02:00', 'at2' => '2024-06-01', 'd' => 1700000000]), + ], + ]; + + yield 'uuid and json columns from raw values' => [ + schema(uuid_schema('u'), json_schema('j')), + [ + new RawRowValues(['u' => '01234567-89ab-4def-8123-456789abcdef', 'j' => '["a","b"]']), + new RawRowValues(['u' => new Uuid('01234567-89ab-4def-8123-456789abcdef'), 'j' => '{"a":1}']), + new RawRowValues(['u' => null, 'j' => ['a' => 1]]), + new RawRowValues(['u' => '11234567-89ab-4def-8123-456789abcdef', 'j' => []]), + new RawRowValues(['u' => '21234567-89ab-4def-8123-456789abcdef', 'j' => Json::fromArray(['x' => 1])]), + ], + ]; + + /** @var StructureType $allowExtraStructure */ + $allowExtraStructure = type_structure(['a' => type_integer()], ['b' => type_string()], true); + + yield 'containers from raw values' => [ + schema( + list_schema('l', type_list(type_integer())), + list_schema('ll', type_list(type_list(type_integer()))), + map_schema('m', type_map(type_string(), type_integer())), + map_schema('mi', type_map(type_integer(), type_string())), + list_schema('lo', type_list(type_optional(type_integer()))), + structure_schema('st', type_structure(['a' => type_integer()], ['b' => type_string()])), + structure_schema('se', $allowExtraStructure), + ), + [ + new RawRowValues([ + 'l' => ['1', 2, '3'], + 'll' => [['1', '2'], [3]], + 'm' => ['a' => '1', 'b' => 2], + 'mi' => [0 => 'x', 5 => 7], + 'lo' => ['1', null, 3], + 'st' => ['a' => '5', 'extra' => 'dropped'], + 'se' => ['a' => 1, 'b' => 'kept', 'other' => 'dropped'], + ]), + new RawRowValues([ + 'l' => [], + 'll' => [], + 'm' => [], + 'mi' => [], + 'lo' => [], + 'st' => ['a' => 1, 'b' => 'present'], + 'se' => ['a' => 2], + ]), + ], + ]; + + yield 'exotic columns cast through the per-value fallback' => [ + schema(enum_schema('s', ParitySuit::class), xml_schema('x'), time_schema('t')), + [ + new RawRowValues([ + 's' => ParitySuit::Hearts, + 'x' => 'v', + 't' => new DateInterval('PT2H30M5S'), + ]), + new RawRowValues(['s' => 'h', 'x' => '', 't' => 'PT2H']), + ], + ]; + + yield 'metadata variants fill-missing and extra raw keys' => [ + schema(int_schema('id'), str_schema('name', nullable: true), bool_schema('flag')), + [ + new RawRowValues(['id' => '1'], ['id' => Metadata::fromArray(['k' => 'v1'])]), + new RawRowValues([]), + new RawRowValues(['id' => 2, 'name' => null, 'unknown' => 'dropped', 'flag' => 'on']), + new RawRowValues(['id' => null], ['id' => Metadata::fromArray(['k' => 'v2'])]), + ], + ]; + + yield 'empty cast batch' => [schema(int_schema('id')), []]; + } + + /** + * @return \Generator}> + */ + public static function throwing_cast_datasets(): Generator + { + yield 'invalid uuid string' => [ + schema(uuid_schema('u')), + [new RawRowValues(['u' => 'not-a-uuid'])], + ]; + + yield 'uppercase uuid string' => [ + schema(uuid_schema('u')), + [new RawRowValues(['u' => '01234567-89AB-4DEF-8123-456789ABCDEF'])], + ]; + + yield 'json from a scalar' => [ + schema(json_schema('j')), + [new RawRowValues(['j' => 5])], + ]; + + yield 'json from an invalid json string' => [ + schema(json_schema('j')), + [new RawRowValues(['j' => '{oops'])], + ]; + + yield 'json from a plain string' => [ + schema(json_schema('j')), + [new RawRowValues(['j' => 'plain'])], + ]; + + yield 'datetime from garbage' => [ + schema(datetime_schema('at')), + [new RawRowValues(['at' => 'not-a-date'])], + ]; + + yield 'datetime from an array' => [ + schema(datetime_schema('at')), + [new RawRowValues(['at' => ['nope']])], + ]; + + yield 'date from garbage' => [ + schema(date_schema('d')), + [new RawRowValues(['d' => 'not-a-date'])], + ]; + + yield 'string map with integer keys' => [ + schema(map_schema('m', type_map(type_string(), type_integer()))), + [new RawRowValues(['m' => [5 => 1]])], + ]; + + yield 'list with non-sequential keys' => [ + schema(list_schema('l', type_list(type_integer()))), + [new RawRowValues(['l' => [1 => 'x']])], + ]; + + yield 'positive integer list from a non-numeric string' => [ + schema(list_schema('l', type_list(type_positive_integer()))), + [new RawRowValues(['l' => ['abc']])], + ]; + + yield 'positive integer list from a negative int' => [ + schema(list_schema('l', type_list(type_positive_integer()))), + [new RawRowValues(['l' => [-3]])], + ]; + + yield 'all-optional structure with no matching keys' => [ + schema(structure_schema('st', type_structure([], ['b' => type_string()]))), + [new RawRowValues(['st' => ['other' => 1]])], + ]; + } + + /** + * @param list $batch + */ + #[DataProvider('serializable_datasets')] + public function test_native_hydrate_is_serialize_identical_to_php(Schema $schema, array $batch): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + static::assertSame( + serialize((new PhpRowHydrator())->hydrate($batch, $schema)), + serialize((new NativeRowHydrator())->hydrate($batch, $schema)), + ); + } + + /** + * @param list $batch + */ + #[DataProvider('serializable_datasets')] + public function test_native_dehydrate_is_serialize_identical_to_php(Schema $schema, array $batch): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + $php = new PhpRowHydrator(); + $rows = $php->hydrate($batch, $schema); + + static::assertSame(serialize($php->dehydrate($rows)), serialize((new NativeRowHydrator())->dehydrate($rows))); + } + + /** + * @param list $batch + */ + #[DataProvider('castable_datasets')] + public function test_native_cast_is_serialize_identical_to_php(Schema $schema, array $batch): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + static::assertSame( + serialize((new PhpRowHydrator())->cast($batch, $schema)), + serialize((new NativeRowHydrator())->cast($batch, $schema)), + ); + } + + /** + * @param list $batch + */ + #[DataProvider('throwing_cast_datasets')] + public function test_native_cast_exception_parity(Schema $schema, array $batch): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + $phpException = null; + + try { + (new PhpRowHydrator())->cast($batch, $schema); + } catch (Throwable $e) { + $phpException = $e; + } + + $nativeException = null; + + try { + (new NativeRowHydrator())->cast($batch, $schema); + } catch (Throwable $e) { + $nativeException = $e; + } + + static::assertNotNull($phpException); + static::assertNotNull($nativeException); + static::assertSame($phpException::class, $nativeException::class); + static::assertSame($phpException->getMessage(), $nativeException->getMessage()); + } + + /** + * @param list $batch + */ + #[DataProvider('castable_datasets')] + public function test_native_cast_is_idempotent_on_already_cast_values(Schema $schema, array $batch): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + $php = new PhpRowHydrator(); + $recastBatch = []; + + foreach ($php->cast($batch, $schema) as $row) { + $values = []; + + foreach ($row->entries()->all() as $entry) { + $values[$entry->name()] = $entry->value(); + } + + $recastBatch[] = new RawRowValues($values); + } + + static::assertSame( + serialize($php->cast($recastBatch, $schema)), + serialize((new NativeRowHydrator())->cast($recastBatch, $schema)), + ); + } + + public function test_native_cast_without_schema_delegates_to_php_inference(): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + $batch = [ + new RawRowValues(['id' => 1, 'name' => 'a', 'price' => 1.5]), + new RawRowValues(['id' => 2, 'name' => null, 'price' => 0.25]), + ]; + + static::assertSame( + serialize((new PhpRowHydrator())->cast($batch)), + serialize((new NativeRowHydrator())->cast($batch)), + ); + } + + public function test_native_cast_follows_in_place_schema_mutations(): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + $schema = schema(int_schema('id'), str_schema('name')); + $php = new PhpRowHydrator(); + $native = new NativeRowHydrator(); + + $batch = [new RawRowValues(['id' => '1', 'name' => 7])]; + static::assertSame(serialize($php->cast($batch, $schema)), serialize($native->cast($batch, $schema))); + + $schema->add(bool_schema('active', nullable: true)); + + $batch = [new RawRowValues(['id' => '2', 'name' => 'b', 'active' => 'yes'])]; + static::assertSame(serialize($php->cast($batch, $schema)), serialize($native->cast($batch, $schema))); + + $schema->makeNullable(); + + $batch = [new RawRowValues(['id' => null, 'name' => null, 'active' => null])]; + static::assertSame(serialize($php->cast($batch, $schema)), serialize($native->cast($batch, $schema))); + } + + public function test_native_moves_markup_values_verbatim(): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + $document = new DOMDocument(); + $document->loadXML('v'); + + $rows = rows(row(xml_entry('doc', $document))); + + $php = new PhpRowHydrator(); + $native = new NativeRowHydrator(); + + $phpDehydrated = $php->dehydrate($rows); + $nativeDehydrated = $native->dehydrate($rows); + + static::assertSame($phpDehydrated[0]->values['doc'], $nativeDehydrated[0]->values['doc']); + static::assertEquals($phpDehydrated[0]->types['doc'], $nativeDehydrated[0]->types['doc']); + } + + public function test_native_hydrate_follows_in_place_schema_mutations(): void + { + if (!NativeRowHydrator::isSupported()) { + static::markTestSkipped('flow_php extension with the native hydrator is not loaded.'); + } + + $schema = schema(int_schema('id'), str_schema('name')); + $php = new PhpRowHydrator(); + $native = new NativeRowHydrator(); + + $batch = [new RawRowValues(['id' => 1, 'name' => 'a'])]; + static::assertSame(serialize($php->hydrate($batch, $schema)), serialize($native->hydrate($batch, $schema))); + + $schema->add(bool_schema('active', nullable: true)); + + $batch = [new RawRowValues(['id' => 2, 'name' => 'b', 'active' => true])]; + static::assertSame(serialize($php->hydrate($batch, $schema)), serialize($native->hydrate($batch, $schema))); + + $schema->makeNullable(); + + $batch = [new RawRowValues(['id' => null, 'name' => null, 'active' => null])]; + static::assertSame(serialize($php->hydrate($batch, $schema)), serialize($native->hydrate($batch, $schema))); + } + + public function test_supports_extension_requires_the_native_class(): void + { + static::assertSame( + extension_loaded('flow_php') && class_exists(RustRowHydratorNative::class, false), + NativeRowHydrator::isSupported(), + ); + } +} + +enum ParitySuit: string +{ + case Hearts = 'h'; + case Spades = 's'; +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/PhpRowHydratorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/PhpRowHydratorTest.php new file mode 100644 index 0000000000..71312adab3 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/PhpRowHydratorTest.php @@ -0,0 +1,291 @@ +cast( + [new RawRowValues(['id' => '1'])], + schema(int_schema('id'), str_schema('name', nullable: true)), + ); + + static::assertTrue($rows->first()->has('name')); + static::assertNull($rows->first()->valueOf('name')); + static::assertInstanceOf(StringEntry::class, $rows->first()->get('name')); + static::assertTrue($rows->first()->get('name')->definition()->isNullable()); + static::assertSame(['id' => 1, 'name' => null], $rows->first()->toArray()); + } + + public function test_casts_datetime_and_uuid_strings(): void + { + $rows = (new PhpRowHydrator())->cast( + [new RawRowValues([ + 'created_at' => '2024-01-01 12:00:00 UTC', + 'uuid' => 'f47ac10b-58cc-4372-a567-0e02b2c3d479', + ])], + schema(datetime_schema('created_at'), uuid_schema('uuid')), + ); + + $uuid = $rows->first()->valueOf('uuid'); + + static::assertInstanceOf(DateTimeImmutable::class, $rows->first()->valueOf('created_at')); + static::assertInstanceOf(Uuid::class, $uuid); + static::assertSame('f47ac10b-58cc-4372-a567-0e02b2c3d479', $uuid->toString()); + } + + public function test_casts_raw_scalar_strings_to_schema_types(): void + { + $rows = (new PhpRowHydrator())->cast( + [new RawRowValues(['id' => '1', 'price' => '9.99', 'active' => 'true', 'name' => 'Alice'])], + schema(int_schema('id'), float_schema('price'), bool_schema('active'), str_schema('name')), + ); + + static::assertSame( + ['id' => 1, 'price' => 9.99, 'active' => true, 'name' => 'Alice'], + $rows->first()->toArray(), + ); + } + + public function test_columns_absent_from_the_schema_are_dropped(): void + { + $rows = (new PhpRowHydrator())->cast([new RawRowValues([ + 'id' => '1', + 'extra' => 'raw', + ])], schema(int_schema('id'))); + + static::assertFalse($rows->first()->has('extra')); + static::assertSame(['id' => 1], $rows->first()->toArray()); + } + + public function test_dehydrate_returns_typed_values_keyed_by_entry_name(): void + { + $hydrator = new PhpRowHydrator(); + $schema = schema(int_schema('id'), str_schema('name', nullable: true)); + + $batch = [ + new RawRowValues(['id' => 1, 'name' => 'Alice']), + new RawRowValues(['id' => 2, 'name' => null]), + ]; + + static::assertEquals( + [ + new TypedRowValues(['id' => 1, 'name' => 'Alice'], ['id' => type_integer(), 'name' => type_string()]), + new TypedRowValues(['id' => 2, 'name' => null], ['id' => type_integer(), 'name' => type_string()]), + ], + $hydrator->dehydrate($hydrator->cast($batch, $schema)), + ); + } + + public function test_empty_batch_produces_empty_rows(): void + { + static::assertCount(0, (new PhpRowHydrator())->cast([], schema(int_schema('id')))); + } + + public function test_cast_keeps_native_typed_values(): void + { + $rows = (new PhpRowHydrator())->cast( + [ + new RawRowValues(['id' => 1, 'name' => 'Alice']), + new RawRowValues(['id' => 2, 'name' => 'Bob']), + ], + schema(int_schema('id'), str_schema('name')), + ); + + static::assertSame( + [ + ['id' => 1, 'name' => 'Alice'], + ['id' => 2, 'name' => 'Bob'], + ], + $rows->toArray(), + ); + } + + public function test_cast_keeps_native_uuid_value_objects(): void + { + $rows = (new PhpRowHydrator())->cast([new RawRowValues([ + 'id' => new Uuid('f47ac10b-58cc-4372-a567-0e02b2c3d479'), + ])], schema(uuid_schema('id'))); + + $value = $rows->first()->valueOf('id'); + + static::assertInstanceOf(Uuid::class, $value); + static::assertSame('f47ac10b-58cc-4372-a567-0e02b2c3d479', $value->toString()); + } + + public function test_cast_with_null_schema_infers_each_entry(): void + { + $rows = (new PhpRowHydrator())->cast([new RawRowValues([ + 'id' => 1, + 'name' => 'Alice', + 'missing' => null, + ])]); + + static::assertInstanceOf(IntegerEntry::class, $rows->first()->get('id')); + static::assertInstanceOf(StringEntry::class, $rows->first()->get('name')); + static::assertInstanceOf(NullEntry::class, $rows->first()->get('missing')); + static::assertNull($rows->first()->valueOf('missing')); + static::assertSame(['id' => 1, 'name' => 'Alice', 'missing' => null], $rows->first()->toArray()); + } + + public function test_null_value_in_non_nullable_column_hydrates_with_nullable_definition(): void + { + $rows = (new PhpRowHydrator())->cast( + [new RawRowValues(['id' => 1, 'name' => null])], + schema(int_schema('id'), str_schema('name')), + ); + + static::assertNull($rows->first()->valueOf('name')); + static::assertTrue($rows->first()->get('name')->definition()->isNullable()); + static::assertFalse($rows->first()->get('id')->definition()->isNullable()); + } + + public function test_null_value_keeps_the_schema_definition(): void + { + $rows = (new PhpRowHydrator())->cast( + [new RawRowValues(['id' => 1, 'name' => null])], + schema(int_schema('id'), str_schema('name', nullable: true)), + ); + + static::assertNull($rows->first()->valueOf('name')); + static::assertTrue($rows->first()->get('name')->definition()->isNullable()); + } + + public function test_plan_is_rebuilt_when_the_schema_changes(): void + { + $hydrator = new PhpRowHydrator(); + + $ids = $hydrator->cast([new RawRowValues(['id' => '1'])], schema(int_schema('id'))); + $prices = $hydrator->cast([new RawRowValues(['id' => '1'])], schema(float_schema('id'))); + + static::assertSame(['id' => 1], $ids->first()->toArray()); + static::assertSame(['id' => 1.0], $prices->first()->toArray()); + } + + public function test_rows_share_the_plans_definition_instances(): void + { + $rows = (new PhpRowHydrator())->cast([ + new RawRowValues(['id' => 1]), + new RawRowValues(['id' => 2]), + ], schema(int_schema('id'))); + + static::assertSame($rows->first()->get('id')->definition(), $rows->all()[1]->get('id')->definition()); + } + + public function test_hydrate_requires_a_schema(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('PhpRowHydrator::hydrate() requires a schema'); + + (new PhpRowHydrator())->hydrate([new RawRowValues(['id' => 1])]); + } + + public function test_hydrate_does_not_cast_native_values(): void + { + $createdAt = new DateTimeImmutable('2024-01-01 12:00:00 UTC'); + + $rows = (new PhpRowHydrator())->hydrate( + [new RawRowValues(['id' => 1, 'created_at' => $createdAt])], + schema(int_schema('id'), datetime_schema('created_at')), + ); + + static::assertSame(1, $rows->first()->valueOf('id')); + static::assertSame($createdAt, $rows->first()->valueOf('created_at')); + } + + public function test_hydrate_does_not_cast_nested_list_map_and_structure(): void + { + $rows = (new PhpRowHydrator())->hydrate( + [new RawRowValues([ + 'tags' => ['a', 'b'], + 'counts' => ['x' => 1, 'y' => 2], + 'address' => ['city' => 'NYC', 'zip' => 10001], + ])], + schema( + list_schema('tags', type_list(type_string())), + map_schema('counts', type_map(type_string(), type_integer())), + structure_schema('address', type_structure(['city' => type_string(), 'zip' => type_integer()])), + ), + ); + + static::assertInstanceOf(ListEntry::class, $rows->first()->get('tags')); + static::assertInstanceOf(MapEntry::class, $rows->first()->get('counts')); + static::assertInstanceOf(StructureEntry::class, $rows->first()->get('address')); + static::assertSame(['a', 'b'], $rows->first()->valueOf('tags')); + static::assertSame(['x' => 1, 'y' => 2], $rows->first()->valueOf('counts')); + static::assertSame(['city' => 'NYC', 'zip' => 10001], $rows->first()->valueOf('address')); + } + + public function test_hydrate_skips_columns_absent_from_the_values(): void + { + $rows = (new PhpRowHydrator())->hydrate( + [new RawRowValues(['id' => 1])], + schema(int_schema('id'), str_schema('name', nullable: true)), + ); + + static::assertTrue($rows->first()->has('id')); + static::assertFalse($rows->first()->has('name')); + } + + public function test_hydrate_present_null_uses_the_nullable_definition(): void + { + $rows = (new PhpRowHydrator())->hydrate( + [new RawRowValues(['id' => 1, 'name' => null])], + schema(int_schema('id'), str_schema('name')), + ); + + static::assertNull($rows->first()->valueOf('name')); + static::assertTrue($rows->first()->get('name')->definition()->isNullable()); + } + + public function test_hydrate_matches_cast_for_native_values(): void + { + $schema = schema(int_schema('id'), str_schema('name'), datetime_schema('created_at')); + $values = new RawRowValues([ + 'id' => 1, + 'name' => 'Alice', + 'created_at' => new DateTimeImmutable('2024-01-01 00:00:00 UTC'), + ]); + + $hydrator = new PhpRowHydrator(); + + static::assertSame( + serialize($hydrator->cast([$values], $schema)), + serialize($hydrator->hydrate([$values], $schema)), + ); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/RawRowValuesTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/RawRowValuesTest.php new file mode 100644 index 0000000000..1b14ffeb16 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/RawRowValuesTest.php @@ -0,0 +1,29 @@ + 1]); + + static::assertSame(['id' => 1], $rowValues->values); + static::assertSame([], $rowValues->metadata); + } + + public function test_carries_per_value_metadata(): void + { + $metadata = Metadata::with('source', 'decoder'); + $rowValues = new RawRowValues(['id' => null], ['id' => $metadata]); + + static::assertSame(['id' => null], $rowValues->values); + static::assertSame(['id' => $metadata], $rowValues->metadata); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/TypedRowValuesTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/TypedRowValuesTest.php new file mode 100644 index 0000000000..9ae895ab45 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Row/TypedRowValuesTest.php @@ -0,0 +1,33 @@ + 1], ['id' => type_integer()]); + + static::assertSame(['id' => 1], $rowValues->values); + static::assertEquals(['id' => type_integer()], $rowValues->types); + static::assertSame([], $rowValues->metadata); + } + + public function test_carries_per_value_types_and_metadata(): void + { + $metadata = Metadata::with('source', 'decoder'); + $rowValues = new TypedRowValues(['id' => null], ['id' => type_integer()], ['id' => $metadata]); + + static::assertSame(['id' => null], $rowValues->values); + static::assertEquals(['id' => type_integer()], $rowValues->types); + static::assertSame(['id' => $metadata], $rowValues->metadata); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Rows/ArrayToRowsTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Rows/ArrayToRowsTest.php index 79bbf34787..6e8254f189 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Rows/ArrayToRowsTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Rows/ArrayToRowsTest.php @@ -30,7 +30,7 @@ public function test_building_array_to_rows_with_entry_that_is_list_of_strings() $rows = array_to_rows([ ['data' => ['a', 'b', 'c', 'd']], ['data' => ['e', 'f', 'g', 'd']], - ], flow_context(config())->entryFactory()); + ], flow_context(config())->hydrator()); static::assertEquals( rows( @@ -45,7 +45,7 @@ public function test_building_array_to_rows_with_entry_that_is_list_of_strings_w { $rows = array_to_rows([ ['data' => ['e', 'f', 'g', 'd']], - ], flow_context(config())->entryFactory()); + ], flow_context(config())->hydrator()); static::assertEquals(rows(row(list_entry('data', ['e', 'f', 'g', 'd'], type_list(type_string())))), $rows); } @@ -54,7 +54,7 @@ public function test_building_row_from_array_with_schema_and_additional_fields_n { $rows = array_to_rows( ['id' => 1234, 'deleted' => false, 'phase' => null], - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), schema: schema(int_schema('id'), bool_schema('deleted')), ); @@ -65,7 +65,7 @@ public function test_building_row_from_array_with_schema_but_entries_not_availab { $rows = array_to_rows( ['id' => 1234, 'deleted' => false], - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), schema: schema(int_schema('id'), bool_schema('deleted'), str_schema('phase', true)), ); @@ -80,7 +80,7 @@ public function test_building_rows_from_array(): void $rows = array_to_rows([ ['id' => 1234, 'deleted' => false, 'phase' => null], ['id' => 4321, 'deleted' => true, 'phase' => 'launch'], - ], flow_context(config())->entryFactory()); + ], flow_context(config())->hydrator()); static::assertEquals( rows( @@ -98,7 +98,7 @@ public function test_building_rows_from_array_with_schema_and_additional_fields_ ['id' => 1234, 'deleted' => false, 'phase' => null], ['id' => 4321, 'deleted' => true, 'phase' => 'launch'], ], - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), schema: schema(int_schema('id'), bool_schema('deleted')), ); @@ -118,7 +118,7 @@ public function test_building_rows_from_array_with_schema_but_entries_not_availa ['id' => 1234, 'deleted' => false], ['id' => 4321, 'deleted' => true], ], - flow_context(config())->entryFactory(), + flow_context(config())->hydrator(), schema: schema(int_schema('id'), bool_schema('deleted'), str_schema('phase', true)), ); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/RowsJoinTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/RowsJoinTest.php index aa8c9c9b13..262dc32e62 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/RowsJoinTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/RowsJoinTest.php @@ -173,6 +173,26 @@ public function test_inner_join(): void ); } + public function test_inner_join_emits_every_matching_right_row(): void + { + $joined = rows(row(int_entry('id', 1), str_entry('country', 'PL'))) + ->joinInner( + rows( + row(int_entry('code', 1), str_entry('city', 'Warsaw')), + row(int_entry('code', 1), str_entry('city', 'Cracow')), + ), + join_on(['id' => 'code']), + ); + + static::assertSame( + [ + ['id' => 1, 'country' => 'PL', 'code' => 1, 'city' => 'Warsaw'], + ['id' => 1, 'country' => 'PL', 'code' => 1, 'city' => 'Cracow'], + ], + $joined->toArray(), + ); + } + public function test_inner_join_into_empty(): void { $left = rows(); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/BooleanDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/BooleanDefinitionTest.php index 590c2b9b9d..0609da3a72 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/BooleanDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/BooleanDefinitionTest.php @@ -17,6 +17,7 @@ use function Flow\ETL\DSL\bool_entry; use function Flow\ETL\DSL\bool_schema; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; final class BooleanDefinitionTest extends FlowTestCase @@ -168,36 +169,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = bool_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = bool_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = bool_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(BooleanDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = bool_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = bool_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(BooleanDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = bool_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(bool_schema('col', false)); static::assertInstanceOf(BooleanDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateDefinitionTest.php index 6b5c7a89e3..8a0f83c716 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateDefinitionTest.php @@ -19,6 +19,7 @@ use function Flow\ETL\DSL\date_schema; use function Flow\ETL\DSL\datetime_schema; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\time_schema; @@ -200,36 +201,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = date_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = date_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = date_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(DateDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = date_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = date_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(DateDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = date_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(date_schema('col', false)); static::assertInstanceOf(DateDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateTimeDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateTimeDefinitionTest.php index 1bc9d49fbf..ea037ca627 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateTimeDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/DateTimeDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\datetime_entry; use function Flow\ETL\DSL\datetime_schema; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\time_schema; @@ -199,36 +200,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = datetime_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = datetime_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = datetime_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(DateTimeDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = datetime_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = datetime_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(DateTimeDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = datetime_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(datetime_schema('col', false)); static::assertInstanceOf(DateTimeDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/EnumDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/EnumDefinitionTest.php index 1ef15ac436..3c2110db90 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/EnumDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/EnumDefinitionTest.php @@ -20,6 +20,7 @@ use function Flow\ETL\DSL\enum_entry; use function Flow\ETL\DSL\enum_schema; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; final class EnumDefinitionTest extends FlowTestCase @@ -178,38 +179,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = enum_schema('col', BackedStringEnum::class, true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = enum_schema('col', BackedStringEnum::class, true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = enum_schema('col', BackedStringEnum::class, false)->merge(null_schema('col')); static::assertInstanceOf(EnumDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = enum_schema('col', BackedStringEnum::class, true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def = enum_schema('col', BackedStringEnum::class, false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(EnumDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = enum_schema('col', BackedStringEnum::class, false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(enum_schema('col', BackedStringEnum::class, false)); static::assertInstanceOf(EnumDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/FloatDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/FloatDefinitionTest.php index f9b052c06f..17799a1b02 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/FloatDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/FloatDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\float_schema; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; final class FloatDefinitionTest extends FlowTestCase @@ -192,36 +193,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = float_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = float_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = float_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(FloatDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = float_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = float_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(FloatDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = float_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(float_schema('col', false)); static::assertInstanceOf(FloatDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLDefinitionTest.php index 35a826b7f4..cd05be5b12 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\html_entry; use function Flow\ETL\DSL\html_schema; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; final class HTMLDefinitionTest extends FlowTestCase @@ -171,36 +172,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = html_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = html_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = html_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(HTMLDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = html_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = html_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(HTMLDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = html_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(html_schema('col', false)); static::assertInstanceOf(HTMLDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLElementDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLElementDefinitionTest.php index e69872970f..27cd653bd8 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLElementDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/HTMLElementDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\html_element_entry; use function Flow\ETL\DSL\html_element_schema; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; final class HTMLElementDefinitionTest extends FlowTestCase @@ -171,36 +172,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = html_element_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = html_element_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = html_element_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(HTMLElementDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = html_element_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = html_element_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(HTMLElementDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = html_element_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(html_element_schema('col', false)); static::assertInstanceOf(HTMLElementDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/IntegerDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/IntegerDefinitionTest.php index 8fbb62527f..0c7fba9e62 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/IntegerDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/IntegerDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\float_schema; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\string_schema; @@ -193,36 +194,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = int_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = int_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = int_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(IntegerDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = int_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = int_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(IntegerDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = int_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(int_schema('col', false)); static::assertInstanceOf(IntegerDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/JsonDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/JsonDefinitionTest.php index 5de1feeebb..1bd8ecfb4e 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/JsonDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/JsonDefinitionTest.php @@ -17,6 +17,7 @@ use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\json_entry; use function Flow\ETL\DSL\json_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; final class JsonDefinitionTest extends FlowTestCase @@ -168,36 +169,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = json_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = json_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = json_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(JsonDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = json_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = json_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(JsonDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = json_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(json_schema('col', false)); static::assertInstanceOf(JsonDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/ListDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/ListDefinitionTest.php index 4e08d59e40..ae20f41224 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/ListDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/ListDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\list_entry; use function Flow\ETL\DSL\list_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\Types\DSL\type_float; use function Flow\Types\DSL\type_integer; @@ -208,38 +209,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = list_schema('col', type_list(type_integer()), true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = list_schema('col', type_list(type_integer()), true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = list_schema('col', type_list(type_integer()), false)->merge(null_schema('col')); static::assertInstanceOf(ListDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = list_schema('col', type_list(type_integer()), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def = list_schema('col', type_list(type_integer()), false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(ListDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = list_schema('col', type_list(type_integer()), false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(list_schema('col', type_list(type_integer()), false)); static::assertInstanceOf(ListDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/MapDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/MapDefinitionTest.php index 00c936deca..655202075a 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/MapDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/MapDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\map_entry; use function Flow\ETL\DSL\map_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\Types\DSL\type_integer; use function Flow\Types\DSL\type_map; @@ -211,42 +212,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = map_schema('col', type_map(type_string(), type_integer()), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def2 = map_schema('col', type_map(type_string(), type_integer()), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - - $merged = $def1->merge($def2); + $merged = map_schema('col', type_map(type_string(), type_integer()), false)->merge(null_schema('col')); static::assertInstanceOf(MapDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = map_schema('col', type_map(type_string(), type_integer()), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def = map_schema('col', type_map(type_string(), type_integer()), false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(MapDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = map_schema('col', type_map(type_string(), type_integer()), false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(map_schema('col', type_map(type_string(), type_integer()), false)); static::assertInstanceOf(MapDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/NullDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/NullDefinitionTest.php new file mode 100644 index 0000000000..b01e7d4869 --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/NullDefinitionTest.php @@ -0,0 +1,183 @@ +addMetadata('key', 'value'); + + static::assertTrue($withMeta->metadata()->has('key')); + static::assertSame('value', $withMeta->metadata()->get('key')); + } + + public function test_entry(): void + { + static::assertSame('id', null_schema('id')->entry()->name()); + } + + public function test_entry_class_is_null_entry(): void + { + static::assertSame(NullEntry::class, null_schema('id')->entryClass()); + } + + public function test_is_always_nullable(): void + { + static::assertTrue(null_schema('id')->isNullable()); + static::assertTrue(null_schema('id')->makeNullable(false)->isNullable()); + } + + public function test_is_compatible_with_another_null_definition(): void + { + static::assertTrue(null_schema('id')->isCompatible(null_schema('id'))); + } + + public function test_is_not_compatible_with_a_different_name(): void + { + static::assertFalse(null_schema('id')->isCompatible(null_schema('other'))); + } + + public function test_is_not_compatible_with_a_different_type(): void + { + static::assertFalse(null_schema('id')->isCompatible(int_schema('id'))); + } + + public function test_is_not_same_when_metadata_differs(): void + { + static::assertFalse(null_schema('id', Metadata::with('k', 'v1'))->isSame(null_schema('id', Metadata::with( + 'k', + 'v2', + )))); + } + + public function test_is_not_same_when_the_other_is_not_nullable(): void + { + static::assertFalse(null_schema('id')->isSame(int_schema('id', false))); + } + + public function test_is_same_with_an_identical_definition(): void + { + static::assertTrue(null_schema('id', Metadata::with('k', 'v'))->isSame(null_schema('id', Metadata::with( + 'k', + 'v', + )))); + } + + public function test_make_nullable_returns_a_nullable_definition(): void + { + static::assertTrue(null_schema('id')->makeNullable()->isNullable()); + } + + public function test_matches_a_null_entry_with_the_same_name(): void + { + static::assertTrue(null_schema('id')->matches(null_entry('id'))); + } + + public function test_matches_any_entry_with_the_same_name(): void + { + static::assertTrue(null_schema('id')->matches(int_entry('id', 1))); + } + + public function test_does_not_match_an_entry_with_a_different_name(): void + { + static::assertFalse(null_schema('id')->matches(null_entry('other'))); + } + + public function test_merge_of_two_null_definitions_stays_a_null_definition(): void + { + $merged = null_schema('id')->merge(null_schema('id')); + + static::assertInstanceOf(NullDefinition::class, $merged); + static::assertTrue($merged->isNullable()); + } + + public function test_merge_of_two_null_definitions_merges_metadata(): void + { + $merged = null_schema('id', Metadata::with('a', 1))->merge(null_schema('id', Metadata::with('b', 2))); + + static::assertTrue($merged->metadata()->has('a')); + static::assertTrue($merged->metadata()->has('b')); + } + + public function test_merge_with_a_typed_definition_produces_that_type_made_nullable(): void + { + $merged = null_schema('id')->merge(int_schema('id', false)); + + static::assertInstanceOf(IntegerDefinition::class, $merged); + static::assertTrue($merged->isNullable()); + } + + public function test_merge_with_a_typed_definition_merges_metadata(): void + { + $merged = null_schema('id', Metadata::with('a', 1))->merge(int_schema('id', false, Metadata::with('b', 2))); + + static::assertInstanceOf(IntegerDefinition::class, $merged); + static::assertTrue($merged->metadata()->has('a')); + static::assertTrue($merged->metadata()->has('b')); + } + + public function test_typed_definition_merged_with_null_definition_becomes_nullable(): void + { + $merged = int_schema('id', false)->merge(null_schema('id')); + + static::assertInstanceOf(IntegerDefinition::class, $merged); + static::assertTrue($merged->isNullable()); + } + + public function test_merge_with_a_different_name_throws(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Cannot merge different definitions, id and other'); + + null_schema('id')->merge(null_schema('other')); + } + + public function test_normalize(): void + { + static::assertSame( + [ + 'ref' => 'id', + 'type' => ['type' => 'null'], + 'nullable' => true, + 'metadata' => ['k' => 'v'], + ], + null_schema('id', Metadata::with('k', 'v'))->normalize(), + ); + } + + public function test_rename(): void + { + $renamed = null_schema('id')->rename('new_id'); + + static::assertSame('new_id', $renamed->entry()->name()); + static::assertInstanceOf(NullDefinition::class, $renamed); + } + + public function test_set_metadata(): void + { + $metadata = Metadata::with('key', 'value'); + + static::assertTrue(null_schema('id')->setMetadata($metadata)->metadata()->isEqual($metadata)); + } + + public function test_type_is_null_type(): void + { + static::assertInstanceOf(NullType::class, null_schema('id')->type()); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StringDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StringDefinitionTest.php index 56b9577770..53c3953722 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StringDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StringDefinitionTest.php @@ -15,6 +15,7 @@ use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\string_schema; @@ -167,34 +168,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_two_assumed_nulls_keeps_from_null_metadata(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $nullDef1 = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $nullDef2 = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $nullDef1->merge($nullDef2); - - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_when_this_is_from_null(): void - { - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = string_schema('col', false); - - $merged = $nullDef->merge($def); + $merged = string_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(StringDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_with_assumed_null_keeps_original_type(): void + public function test_merge_when_this_is_null_definition(): void { - $def = string_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(string_schema('col', false)); static::assertInstanceOf(StringDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StructureDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StructureDefinitionTest.php index 7828549add..7b1e604836 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StructureDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/StructureDefinitionTest.php @@ -16,6 +16,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\structure_entry; use function Flow\ETL\DSL\structure_schema; @@ -234,42 +235,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = structure_schema('col', type_structure(['name' => type_string()]), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def2 = structure_schema('col', type_structure(['name' => type_string()]), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - - $merged = $def1->merge($def2); + $merged = structure_schema('col', type_structure(['name' => type_string()]), false)->merge(null_schema('col')); static::assertInstanceOf(StructureDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = structure_schema('col', type_structure(['name' => type_string()]), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def = structure_schema('col', type_structure(['name' => type_string()]), false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(StructureDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = structure_schema('col', type_structure(['name' => type_string()]), false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(structure_schema('col', type_structure(['name' => type_string()]), false)); static::assertInstanceOf(StructureDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/TimeDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/TimeDefinitionTest.php index 6eff8580bf..7795cc7af0 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/TimeDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/TimeDefinitionTest.php @@ -18,6 +18,7 @@ use function Flow\ETL\DSL\date_schema; use function Flow\ETL\DSL\datetime_schema; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\time_entry; use function Flow\ETL\DSL\time_schema; @@ -200,36 +201,17 @@ public function test_merge_produces_expected_type( static::assertInstanceOf($expectedClass, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = time_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = time_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = time_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(TimeDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = time_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = time_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(TimeDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = time_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(time_schema('col', false)); static::assertInstanceOf(TimeDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UnionDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UnionDefinitionTest.php index e89ea81a5f..668b6b80ed 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UnionDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UnionDefinitionTest.php @@ -6,6 +6,7 @@ use Flow\ETL\Exception\RuntimeException; use Flow\ETL\Row\Entry\IntegerEntry; +use Flow\ETL\Row\Entry\NullEntry; use Flow\ETL\Row\Entry\StringEntry; use Flow\ETL\Schema\Definition; use Flow\ETL\Schema\Definition\BooleanDefinition; @@ -20,6 +21,7 @@ use function Flow\ETL\DSL\definition_from_array; use function Flow\ETL\DSL\definition_from_type; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\union_schema; @@ -130,11 +132,9 @@ public function test_entry_class_taken_from_left_union_member(): void ); } - public function test_entry_class_with_left_union_member_without_related_entry_class(): void + public function test_entry_class_with_null_left_union_member(): void { - $this->expectException(RuntimeException::class); - - union_schema('col', type_union(type_null(), type_string()))->entryClass(); + static::assertSame(NullEntry::class, union_schema('col', type_union(type_null(), type_string()))->entryClass()); } public function test_entry_class_with_optional_left_union_member(): void @@ -216,42 +216,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = union_schema('col', type_union(type_string(), type_integer()), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def2 = union_schema('col', type_union(type_string(), type_integer()), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - - $merged = $def1->merge($def2); + $merged = union_schema('col', type_union(type_string(), type_integer()), false)->merge(null_schema('col')); static::assertInstanceOf(UnionDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = union_schema('col', type_union(type_string(), type_integer()), true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ])); - $def = union_schema('col', type_union(type_string(), type_integer()), false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(UnionDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = union_schema('col', type_union(type_string(), type_integer()), false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(union_schema('col', type_union(type_string(), type_integer()), false)); static::assertInstanceOf(UnionDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UuidDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UuidDefinitionTest.php index 605e97fb2b..b5e0c2919c 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UuidDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/UuidDefinitionTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\uuid_entry; use function Flow\ETL\DSL\uuid_schema; @@ -168,36 +169,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = uuid_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = uuid_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = uuid_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(UuidDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = uuid_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = uuid_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(UuidDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = uuid_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(uuid_schema('col', false)); static::assertInstanceOf(UuidDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLDefinitionTest.php index 64e88605df..2edf72aaf1 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLDefinitionTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\xml_entry; use function Flow\ETL\DSL\xml_schema; @@ -168,36 +169,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = xml_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = xml_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = xml_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(XMLDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = xml_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = xml_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(XMLDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = xml_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(xml_schema('col', false)); static::assertInstanceOf(XMLDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLElementDefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLElementDefinitionTest.php index fcadc188a4..83c24b9e63 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLElementDefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/Definition/XMLElementDefinitionTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\xml_element_entry; use function Flow\ETL\DSL\xml_element_schema; @@ -168,36 +169,17 @@ public function test_merge(Definition $definition, Definition $other, Definition static::assertEquals($expected, $definition->merge($other)); } - public function test_merge_when_both_are_from_null(): void + public function test_merge_with_null_definition_keeps_original_type(): void { - $def1 = xml_element_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def2 = xml_element_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def1->merge($def2); + $merged = xml_element_schema('col', false)->merge(null_schema('col')); static::assertInstanceOf(XMLElementDefinition::class, $merged); static::assertTrue($merged->isNullable()); - static::assertTrue($merged->metadata()->has(Metadata::FROM_NULL)); } - public function test_merge_when_this_is_from_null(): void + public function test_merge_when_this_is_null_definition(): void { - $nullDef = xml_element_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - $def = xml_element_schema('col', false); - - $merged = $nullDef->merge($def); - - static::assertInstanceOf(XMLElementDefinition::class, $merged); - static::assertTrue($merged->isNullable()); - static::assertFalse($merged->metadata()->has(Metadata::FROM_NULL)); - } - - public function test_merge_with_assumed_null_keeps_original_type(): void - { - $def = xml_element_schema('col', false); - $nullDef = string_schema('col', true, Metadata::fromArray([Metadata::FROM_NULL => true])); - - $merged = $def->merge($nullDef); + $merged = null_schema('col')->merge(xml_element_schema('col', false)); static::assertInstanceOf(XMLElementDefinition::class, $merged); static::assertTrue($merged->isNullable()); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/DefinitionTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/DefinitionTest.php index b6e3c235ee..7de4defacc 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/DefinitionTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/DefinitionTest.php @@ -5,6 +5,7 @@ namespace Flow\ETL\Tests\Unit\Schema; use Flow\ETL\Exception\RuntimeException; +use Flow\ETL\Schema\Definition\NullDefinition; use Flow\ETL\Schema\Metadata; use Flow\ETL\Tests\FlowTestCase; @@ -19,6 +20,7 @@ use function Flow\ETL\DSL\json_schema; use function Flow\ETL\DSL\list_schema; use function Flow\ETL\DSL\map_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\string_schema; use function Flow\ETL\DSL\struct_entry; @@ -85,32 +87,12 @@ public function test_merge_nullable_with_non_nullable_dateime_definitions(): voi static::assertEquals(datetime_schema('col'), datetime_schema('col')->merge(datetime_schema('col'))); } - public function test_merging_anything_and_assumed_string(): void + public function test_merging_anything_and_null(): void { - static::assertEquals( - integer_schema('id', true), - integer_schema('id', false)->merge(string_schema('id', true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ]))), - ); - static::assertEquals( - float_schema('id', true), - float_schema('id', false)->merge(string_schema('id', true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ]))), - ); - static::assertEquals( - bool_schema('id', true), - bool_schema('id', false)->merge(string_schema('id', true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ]))), - ); - static::assertEquals( - datetime_schema('id', true), - datetime_schema('id', false)->merge(string_schema('id', true, Metadata::fromArray([ - Metadata::FROM_NULL => true, - ]))), - ); + static::assertEquals(integer_schema('id', true), integer_schema('id', false)->merge(null_schema('id'))); + static::assertEquals(float_schema('id', true), float_schema('id', false)->merge(null_schema('id'))); + static::assertEquals(bool_schema('id', true), bool_schema('id', false)->merge(null_schema('id'))); + static::assertEquals(datetime_schema('id', true), datetime_schema('id', false)->merge(null_schema('id'))); } public function test_merging_anything_and_string(): void @@ -165,14 +147,12 @@ public function test_merging_time_with_datetime(): void static::assertEquals(datetime_schema('datetime'), datetime_schema('datetime')->merge(time_schema('datetime'))); } - public function test_merging_two_definitions_created_from_null(): void + public function test_merging_two_null_definitions(): void { - static::assertTrue( - string_schema('id', true, Metadata::fromArray([Metadata::FROM_NULL => true])) - ->merge(string_schema('id', true, Metadata::fromArray([Metadata::FROM_NULL => true]))) - ->metadata() - ->has(Metadata::FROM_NULL), - ); + $merged = null_schema('id')->merge(null_schema('id')); + + static::assertInstanceOf(NullDefinition::class, $merged); + static::assertTrue($merged->isNullable()); } public function test_merging_two_different_lists(): void diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/EvolvingValidatorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/EvolvingValidatorTest.php index 86bd93941b..88eec61dab 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/EvolvingValidatorTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/EvolvingValidatorTest.php @@ -16,16 +16,25 @@ final class EvolvingValidatorTest extends FlowTestCase { - public function test_given_having_less_definitions_than_expected(): void + public function test_adding_a_new_non_nullable_column_is_invalid(): void { $expected = schema(int_schema('id'), str_schema('name')); - $given = schema(int_schema('id')); + $given = schema(int_schema('id'), str_schema('name'), bool_schema('active')); static::assertFalse(schema_validate($expected, $given, schema_evolving_validator())->isValid()); } - public function test_context_collects_missing_and_mismatched_definitions_ignoring_added_fields(): void + public function test_adding_a_new_nullable_column_is_valid(): void + { + $expected = schema(int_schema('id'), str_schema('name')); + + $given = schema(int_schema('id'), str_schema('name'), bool_schema('active', nullable: true)); + + static::assertTrue(schema_validate($expected, $given, schema_evolving_validator())->isValid()); + } + + public function test_context_collects_missing_mismatched_and_unexpected_required_definitions(): void { $context = schema_validate( expected: schema(int_schema('id'), str_schema('name', nullable: true), bool_schema('active')), @@ -36,70 +45,76 @@ public function test_context_collects_missing_and_mismatched_definitions_ignorin static::assertFalse($context->isValid()); static::assertEquals([int_schema('id')], $context->missingDefinitions()); static::assertEquals( - [ - new MismatchedDefinition(str_schema('name', nullable: true), str_schema('name')), - new MismatchedDefinition(bool_schema('active'), str_schema('active')), - ], + [new MismatchedDefinition(bool_schema('active'), str_schema('active'))], $context->mismatchedDefinitions(), ); - static::assertSame([], $context->unexpectedDefinitions()); + static::assertEquals([bool_schema('extra')], $context->unexpectedDefinitions()); } - public function test_given_having_same_number_of_definitions_but_different_names(): void + public function test_omitting_a_non_nullable_column_is_invalid(): void { $expected = schema(int_schema('id'), str_schema('name')); - $given = schema(int_schema('id'), str_schema('surname')); + $given = schema(int_schema('id')); static::assertFalse(schema_validate($expected, $given, schema_evolving_validator())->isValid()); } - public function test_given_schema_adding_new_field(): void + public function test_omitting_a_nullable_column_is_valid(): void { - $expected = schema(int_schema('id'), str_schema('name')); + $expected = schema(int_schema('id'), str_schema('name', nullable: true)); - $given = schema(int_schema('id'), str_schema('name'), bool_schema('active')); + $given = schema(int_schema('id')); static::assertTrue(schema_validate($expected, $given, schema_evolving_validator())->isValid()); } - public function test_given_schema_changing_nullable_field_to_non_nullable(): void + public function test_given_having_same_number_of_definitions_but_different_names(): void + { + $expected = schema(int_schema('id'), str_schema('name')); + + $given = schema(int_schema('id'), str_schema('surname')); + + static::assertFalse(schema_validate($expected, $given, schema_evolving_validator())->isValid()); + } + + public function test_narrowing_a_nullable_expected_column_to_non_nullable_is_valid(): void { $expected = schema(int_schema('id'), str_schema('name', nullable: true)); $given = schema(int_schema('id'), str_schema('name')); - static::assertFalse(schema_validate($expected, $given, schema_evolving_validator())->isValid()); + static::assertTrue(schema_validate($expected, $given, schema_evolving_validator())->isValid()); } - public function test_given_schema_changing_type_of_field(): void + public function test_widening_a_non_nullable_expected_column_to_nullable_is_invalid(): void { $expected = schema(int_schema('id'), str_schema('name')); - $given = schema(int_schema('id'), bool_schema('name')); + $given = schema(int_schema('id'), str_schema('name', nullable: true)); static::assertFalse(schema_validate($expected, $given, schema_evolving_validator())->isValid()); } - public function test_given_schema_is_the_same_as_expected_schema(): void + public function test_changing_the_type_of_a_column_is_invalid(): void { $expected = schema(int_schema('id'), str_schema('name')); - $given = schema(int_schema('id'), str_schema('name')); + $given = schema(int_schema('id'), bool_schema('name')); - static::assertTrue(schema_validate($expected, $given, schema_evolving_validator())->isValid()); + static::assertFalse(schema_validate($expected, $given, schema_evolving_validator())->isValid()); } - public function test_given_schema_making_non_nullable_field_into_nullable(): void + public function test_identical_schema_is_valid(): void { $expected = schema(int_schema('id'), str_schema('name')); - $given = schema(int_schema('id'), str_schema('name', nullable: true)); + $given = schema(int_schema('id'), str_schema('name')); static::assertTrue(schema_validate($expected, $given, schema_evolving_validator())->isValid()); } - public function test_given_totally_different(): void + public function test_totally_different_schema_is_invalid(): void { $expected = schema(int_schema('id'), str_schema('name')); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/SelectiveValidatorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/SelectiveValidatorTest.php index f95484e7ae..f28ba5bd37 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/SelectiveValidatorTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/SelectiveValidatorTest.php @@ -4,13 +4,13 @@ namespace Flow\ETL\Tests\Unit\Schema; -use Flow\ETL\Schema\Metadata; use Flow\ETL\Schema\Validator\MismatchedDefinition; use Flow\ETL\Schema\Validator\SelectiveValidator; use Flow\ETL\Tests\FlowTestCase; use function Flow\ETL\DSL\bool_schema; use function Flow\ETL\DSL\integer_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\schema; use function Flow\ETL\DSL\schema_selective_validator; use function Flow\ETL\DSL\schema_validate; @@ -79,14 +79,11 @@ public function test_schema_with_an_extra_entry(): void ); } - public function test_schema_with_from_null_metadata(): void + public function test_schema_with_null_definition(): void { static::assertTrue( (new SelectiveValidator()) - ->validate( - schema(integer_schema('id', nullable: true)), - schema(string_schema('id', nullable: true, metadata: Metadata::with(Metadata::FROM_NULL, true))), - ) + ->validate(schema(integer_schema('id', nullable: true)), schema(null_schema('id'))) ->isValid(), ); @@ -97,16 +94,13 @@ public function test_schema_with_from_null_metadata(): void ); } - public function test_schema_with_multiple_columns_with_from_null_metadata(): void + public function test_schema_with_multiple_columns_including_null_definition(): void { static::assertTrue( (new SelectiveValidator()) ->validate( expected: schema(integer_schema('id', nullable: true), string_schema('name')), - given: schema( - string_schema('id', nullable: true, metadata: Metadata::with(Metadata::FROM_NULL, true)), - string_schema('name'), - ), + given: schema(null_schema('id'), string_schema('name')), ) ->isValid(), ); @@ -142,18 +136,11 @@ public function test_schema_with_single_invalid_column(): void ); } - public function test_with_from_null_metadata_but_non_string_type(): void + public function test_null_definition_against_non_nullable_expected(): void { static::assertFalse( (new SelectiveValidator()) - ->validate( - expected: schema(integer_schema('id', nullable: true)), - given: schema(bool_schema( - 'id', - nullable: true, - metadata: Metadata::with(Metadata::FROM_NULL, true), - )), - ) + ->validate(expected: schema(integer_schema('id')), given: schema(null_schema('id'))) ->isValid(), ); } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/StrictValidatorTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/StrictValidatorTest.php index f4c1558c75..8635cba7fe 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/StrictValidatorTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Schema/StrictValidatorTest.php @@ -4,13 +4,13 @@ namespace Flow\ETL\Tests\Unit\Schema; -use Flow\ETL\Schema\Metadata; use Flow\ETL\Schema\Validator\MismatchedDefinition; use Flow\ETL\Tests\FlowTestCase; use function Flow\ETL\DSL\bool_schema; use function Flow\ETL\DSL\integer_schema; use function Flow\ETL\DSL\list_schema; +use function Flow\ETL\DSL\null_schema; use function Flow\ETL\DSL\schema; use function Flow\ETL\DSL\schema_strict_validator; use function Flow\ETL\DSL\schema_validate; @@ -157,12 +157,12 @@ public function test_rows_with_an_extra_entry(): void ); } - public function test_rows_with_from_null_metadata(): void + public function test_given_schema_with_null_definition(): void { static::assertTrue( schema_validate( expected: schema(integer_schema('id', nullable: true)), - given: schema(string_schema('id', nullable: true, metadata: Metadata::with(Metadata::FROM_NULL, true))), + given: schema(null_schema('id')), validator: schema_strict_validator(), )->isValid(), ); @@ -176,7 +176,7 @@ public function test_rows_with_from_null_metadata(): void ); } - public function test_rows_with_multiple_columns_with_from_null_metadata(): void + public function test_given_schema_with_multiple_columns_including_null_definition(): void { static::assertFalse( schema_validate( @@ -189,21 +189,18 @@ public function test_rows_with_multiple_columns_with_from_null_metadata(): void static::assertTrue( schema_validate( expected: schema(integer_schema('id', nullable: true), string_schema('name')), - given: schema( - string_schema('id', nullable: true, metadata: Metadata::with(Metadata::FROM_NULL, true)), - string_schema('name'), - ), + given: schema(null_schema('id'), string_schema('name')), validator: schema_strict_validator(), )->isValid(), ); } - public function test_with_from_null_metadata_but_non_string_type(): void + public function test_given_null_definition_against_non_nullable_expected(): void { static::assertFalse( schema_validate( - expected: schema(integer_schema('id', nullable: true)), - given: schema(bool_schema('id', nullable: true, metadata: Metadata::with(Metadata::FROM_NULL, true))), + expected: schema(integer_schema('id')), + given: schema(null_schema('id')), validator: schema_strict_validator(), )->isValid(), ); diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Sort/ExternalSort/BucketsCache/InMemoryBucketsCacheTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Sort/ExternalSort/BucketsCache/InMemoryBucketsCacheTest.php new file mode 100644 index 0000000000..b8de08442f --- /dev/null +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Sort/ExternalSort/BucketsCache/InMemoryBucketsCacheTest.php @@ -0,0 +1,66 @@ +append('bucket', rows(row(int_entry('id', 1)))); + $cache->append('bucket', rows(row(int_entry('id', 2)))); + + /** @var list<\Flow\ETL\Row> $bucketRows */ + $bucketRows = iterator_to_array($cache->get('bucket'), false); + + static::assertCount(2, $bucketRows); + static::assertSame(1, $bucketRows[0]->valueOf('id')); + static::assertSame(2, $bucketRows[1]->valueOf('id')); + } + + public function test_get_unknown_bucket_yields_nothing(): void + { + static::assertSame([], iterator_to_array((new InMemoryBucketsCache())->get('unknown'), false)); + } + + public function test_is_resident(): void + { + static::assertInstanceOf(ResidentBucketsCache::class, new InMemoryBucketsCache()); + } + + public function test_remove_drops_the_bucket(): void + { + $cache = new InMemoryBucketsCache(); + + $cache->append('bucket', rows(row(int_entry('id', 1)))); + $cache->remove('bucket'); + + static::assertSame([], iterator_to_array($cache->get('bucket'), false)); + } + + public function test_set_replaces_previous_rows(): void + { + $cache = new InMemoryBucketsCache(); + + $cache->append('bucket', rows(row(int_entry('id', 1)))); + $cache->set('bucket', rows(row(int_entry('id', 42)))); + + /** @var list<\Flow\ETL\Row> $bucketRows */ + $bucketRows = iterator_to_array($cache->get('bucket'), false); + + static::assertCount(1, $bucketRows); + static::assertSame(42, $bucketRows[0]->valueOf('id')); + } +} diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/AutoCastTransformerTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/AutoCastTransformerTest.php index 7c37a1f242..28f2ce3b74 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/AutoCastTransformerTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/AutoCastTransformerTest.php @@ -29,7 +29,7 @@ public function test_transforming_row(): void 'null' => 'null', 'nil' => 'nil', ], - ], flow_context(config())->entryFactory()); + ], flow_context(config())->hydrator()); static::assertEquals( [ diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/DropPartitionsTransformerTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/DropPartitionsTransformerTest.php index 5f797798f6..f4e2dab288 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/DropPartitionsTransformerTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/DropPartitionsTransformerTest.php @@ -27,7 +27,7 @@ public function test_dropping_partitions(): void ['id' => 8, 'name' => 'eight', 'category' => 'b'], ['id' => 9, 'name' => 'nine', 'category' => 'b'], ['id' => 10, 'name' => 'ten', 'category' => 'b'], - ], flow_context(config())->entryFactory())->partitionBy(ref('category')); + ], flow_context(config())->hydrator())->partitionBy(ref('category')); foreach ($partitioned as $rows) { static::assertTrue($rows->isPartitioned()); @@ -51,7 +51,7 @@ public function test_dropping_partitions_with_columns(): void ['id' => 8, 'name' => 'eight', 'category' => 'b'], ['id' => 9, 'name' => 'nine', 'category' => 'b'], ['id' => 10, 'name' => 'ten', 'category' => 'b'], - ], flow_context(config())->entryFactory())->partitionBy(ref('category')); + ], flow_context(config())->hydrator())->partitionBy(ref('category')); foreach ($partitioned as $rows) { static::assertTrue($rows->isPartitioned()); @@ -76,7 +76,7 @@ public function test_transforming_not_partitioned_rows(): void ['id' => 8, 'name' => 'eight', 'category' => 'b'], ['id' => 9, 'name' => 'nine', 'category' => 'b'], ['id' => 10, 'name' => 'ten', 'category' => 'b'], - ], flow_context(config())->entryFactory()); + ], flow_context(config())->hydrator()); static::assertSame($rows, (new DropPartitionsTransformer())->transform($rows, flow_context())); } diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/SerializeTransformerTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/SerializeTransformerTest.php index 343370d761..4bb7d17e60 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/SerializeTransformerTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/SerializeTransformerTest.php @@ -16,6 +16,7 @@ use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; +use function Flow\Serializer\DSL\serialize_to_string; use function Flow\Types\DSL\type_list; use function Flow\Types\DSL\type_string; @@ -31,7 +32,7 @@ public function test_serializing_empty_row_under_one_entry(): void static::assertEquals( [ [ - 'serialized' => (new Base64Serializer(new FloeSerializer()))->serialize($row1), + 'serialized' => serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row1)), ], ], $transformedRows->toArray(), @@ -66,14 +67,14 @@ public function test_serializing_row_under_one_entry(): void 'name' => 'John', 'active' => true, 'tags' => ['tag1', 'tag2'], - 'serialized' => (new Base64Serializer(new FloeSerializer()))->serialize($row1), + 'serialized' => serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row1)), ], [ 'id' => 2, 'name' => 'Jane', 'active' => false, 'tags' => ['tag3', 'tag4'], - 'serialized' => (new Base64Serializer(new FloeSerializer()))->serialize($row2), + 'serialized' => serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row2)), ], ], $transformedRows->toArray(), @@ -104,10 +105,10 @@ public function test_serializing_row_under_standalone_entry(): void static::assertEquals( [ [ - 'serialized' => (new Base64Serializer(new FloeSerializer()))->serialize($row1), + 'serialized' => serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row1)), ], [ - 'serialized' => (new Base64Serializer(new FloeSerializer()))->serialize($row2), + 'serialized' => serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row2)), ], ], $transformedRows->toArray(), diff --git a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/UnserializeTransformerTest.php b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/UnserializeTransformerTest.php index 3cf16ad327..0eae107ac2 100644 --- a/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/UnserializeTransformerTest.php +++ b/src/core/etl/tests/Flow/ETL/Tests/Unit/Transformer/UnserializeTransformerTest.php @@ -16,6 +16,7 @@ use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; +use function Flow\Serializer\DSL\serialize_to_string; use function Flow\Types\DSL\type_list; use function Flow\Types\DSL\type_string; @@ -37,8 +38,8 @@ public function test_unserializing_row_from_entry(): void ); $rows = rows( - row(str_entry('serialized', (new Base64Serializer(new FloeSerializer()))->serialize($row1))), - row(str_entry('serialized', (new Base64Serializer(new FloeSerializer()))->serialize($row2))), + row(str_entry('serialized', serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row1)))), + row(str_entry('serialized', serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row2)))), ); $transformer = new UnserializeTransformer('serialized'); @@ -48,14 +49,14 @@ public function test_unserializing_row_from_entry(): void static::assertEquals( [ [ - 'serialized' => (new Base64Serializer(new FloeSerializer()))->serialize($row1), + 'serialized' => serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row1)), 'id' => 1, 'name' => 'John', 'active' => true, 'tags' => ['tag1', 'tag2'], ], [ - 'serialized' => (new Base64Serializer(new FloeSerializer()))->serialize($row2), + 'serialized' => serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row2)), 'id' => 2, 'name' => 'Jane', 'active' => false, @@ -77,6 +78,37 @@ public function test_unserializing_something_that_is_not_serialized_row(): void static::assertEquals($rows, $transformedRows); } + public function test_unserializing_row_without_source_column_is_unchanged(): void + { + $rows = rows(row(int_entry('id', 1))); + + $transformer = new UnserializeTransformer('serialized'); + + static::assertEquals($rows, $transformer->transform($rows, flow_context())); + } + + public function test_unserializing_non_string_value_is_unchanged(): void + { + $rows = rows(row(int_entry('serialized', 123))); + + $transformer = new UnserializeTransformer('serialized'); + + static::assertEquals($rows, $transformer->transform($rows, flow_context())); + } + + public function test_unserializing_multi_row_payload_returns_row_unchanged(): void + { + $payload = serialize_to_string( + new Base64Serializer(new FloeSerializer()), + rows(row(int_entry('id', 1)), row(int_entry('id', 2))), + ); + $rows = rows(row(str_entry('serialized', $payload))); + + $transformer = new UnserializeTransformer('serialized'); + + static::assertEquals($rows, $transformer->transform($rows, flow_context())); + } + public function test_unserializing_without_merge(): void { $row1 = row( @@ -93,8 +125,8 @@ public function test_unserializing_without_merge(): void ); $rows = rows( - row(str_entry('serialized', (new Base64Serializer(new FloeSerializer()))->serialize($row1))), - row(str_entry('serialized', (new Base64Serializer(new FloeSerializer()))->serialize($row2))), + row(str_entry('serialized', serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row1)))), + row(str_entry('serialized', serialize_to_string(new Base64Serializer(new FloeSerializer()), rows($row2)))), ); $transformer = new UnserializeTransformer('serialized', false); diff --git a/src/core/etl/tests/Flow/Floe/Tests/Context/FloeEngineContext.php b/src/core/etl/tests/Flow/Floe/Tests/Context/FloeEngineContext.php new file mode 100644 index 0000000000..756145722b --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Context/FloeEngineContext.php @@ -0,0 +1,52 @@ + $batches + */ + public static function writeAll(FloeWriter $writer, Path $path, array $batches): void + { + $writer->create($path); + + foreach ($batches as $batch) { + $writer->write($batch); + } + + $writer->close(); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Context/FloeSchemaContext.php b/src/core/etl/tests/Flow/Floe/Tests/Context/FloeSchemaContext.php new file mode 100644 index 0000000000..45ecd468c8 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Context/FloeSchemaContext.php @@ -0,0 +1,19 @@ +normalize(), JSON_THROW_ON_ERROR); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Context/FloeFileContext.php b/src/core/etl/tests/Flow/Floe/Tests/Context/FloeStreamReaderContext.php similarity index 94% rename from src/core/etl/tests/Flow/Floe/Tests/Context/FloeFileContext.php rename to src/core/etl/tests/Flow/Floe/Tests/Context/FloeStreamReaderContext.php index 4d995c264b..e023042d5a 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Context/FloeFileContext.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Context/FloeStreamReaderContext.php @@ -4,7 +4,6 @@ namespace Flow\Floe\Tests\Context; -use Flow\ETL\Row; use Flow\ETL\Rows; use Flow\ETL\Schema\Metadata; use Flow\Filesystem\Filesystem; @@ -14,7 +13,6 @@ use Flow\Floe\Footer; use Flow\Floe\Format; use Flow\Floe\FrameReader; -use Flow\Floe\RowsValueMapper; use function Flow\ETL\DSL\rows; use function Flow\Filesystem\DSL\memory_filesystem; @@ -27,7 +25,7 @@ * Byte-level access to written Floe files, so writer tests can assert the wire * layout without going through FloeReader. */ -final class FloeFileContext +final class FloeStreamReaderContext { public static function footer(Filesystem $filesystem, Path $path): Footer { @@ -85,9 +83,9 @@ public static function frameTypes(Filesystem $filesystem, Path $path): array } /** - * Reads a written Floe file back into the original Row|Rows the cache stored. + * Reads a written Floe file back into the original Rows the cache stored. */ - public static function reconstruct(Filesystem $filesystem, Path $path): Row|Rows + public static function reconstruct(Filesystem $filesystem, Path $path): Rows { $file = (new FloeReader($filesystem))->read($path); $rows = []; @@ -98,7 +96,7 @@ public static function reconstruct(Filesystem $filesystem, Path $path): Row|Rows } } - return RowsValueMapper::reconstructFrom($rows, $file->footer()); + return $file->footer()->reconstructRows($rows); } /** diff --git a/src/core/etl/tests/Flow/Floe/Tests/Double/ClosingSpySourceStream.php b/src/core/etl/tests/Flow/Floe/Tests/Double/ClosingSpySourceStream.php new file mode 100644 index 0000000000..e2a1044f6b --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Double/ClosingSpySourceStream.php @@ -0,0 +1,59 @@ +closeCount++; + $this->stream->close(); + } + + public function content(): string + { + return $this->stream->content(); + } + + public function isOpen(): bool + { + return $this->stream->isOpen(); + } + + public function iterate(int $length = 1): Generator + { + return $this->stream->iterate($length); + } + + public function path(): Path + { + return $this->stream->path(); + } + + public function read(int $length, int $offset): string + { + return $this->stream->read($length, $offset); + } + + public function readLines(string $separator = "\n", ?int $length = null): Generator + { + return $this->stream->readLines($separator, $length); + } + + public function size(): ?int + { + return $this->stream->size(); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Double/SpyHydrator.php b/src/core/etl/tests/Flow/Floe/Tests/Double/SpyHydrator.php new file mode 100644 index 0000000000..8acf1b0100 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Double/SpyHydrator.php @@ -0,0 +1,32 @@ +cast($batch, $schema); + } + + public function dehydrate(Rows $rows): array + { + $this->dehydrateCalls++; + + return (new AdaptiveRowHydrator())->dehydrate($rows); + } + + public function hydrate(array $batch, ?Schema $schema = null): Rows + { + return (new AdaptiveRowHydrator())->hydrate($batch, $schema); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeMergeDSLTest.php b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeMergeDSLTest.php index 44174458ff..c9c47ce1c6 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeMergeDSLTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeMergeDSLTest.php @@ -5,7 +5,7 @@ namespace Flow\Floe\Tests\Integration; use Flow\ETL\Tests\FlowIntegrationTestCase; -use Flow\Floe\Tests\Context\FloeFileContext; +use Flow\Floe\Tests\Context\FloeStreamReaderContext; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; @@ -20,14 +20,14 @@ public function test_merge_floe_compact_over_path_objects(): void $b = $this->cacheDir->suffix('mc-b.floe'); $out = $this->cacheDir->suffix('mc-out.floe'); - FloeFileContext::write($this->fs(), $a, rows(row(int_entry('id', 1)))); - FloeFileContext::write($this->fs(), $b, rows(row(int_entry('id', 2)))); + FloeStreamReaderContext::write($this->fs(), $a, rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write($this->fs(), $b, rows(row(int_entry('id', 2)))); merge_floe([$a, $b], $out, compact: true); static::assertEquals( rows(row(int_entry('id', 1)), row(int_entry('id', 2))), - FloeFileContext::readAll($this->fs(), $out), + FloeStreamReaderContext::readAll($this->fs(), $out), ); } @@ -37,14 +37,14 @@ public function test_merge_floe_splices_local_files_from_string_paths(): void $b = $this->cacheDir->suffix('ms-b.floe'); $out = $this->cacheDir->suffix('ms-out.floe'); - FloeFileContext::write($this->fs(), $a, rows(row(int_entry('id', 1)))); - FloeFileContext::write($this->fs(), $b, rows(row(int_entry('id', 2)))); + FloeStreamReaderContext::write($this->fs(), $a, rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write($this->fs(), $b, rows(row(int_entry('id', 2)))); merge_floe([$a->path(), $b->path()], $out->path()); static::assertEquals( rows(row(int_entry('id', 1)), row(int_entry('id', 2))), - FloeFileContext::readAll($this->fs(), $out), + FloeStreamReaderContext::readAll($this->fs(), $out), ); } } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeReaderExtensionParityTest.php b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeReaderExtensionParityTest.php index f72729befd..1291309310 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeReaderExtensionParityTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeReaderExtensionParityTest.php @@ -4,21 +4,29 @@ namespace Flow\Floe\Tests\Integration; +use Flow\ETL\Row\PhpRowHydrator; use Flow\ETL\Rows; use Flow\ETL\Tests\FlowIntegrationTestCase; -use Flow\Floe\FloeReader; +use Flow\Filesystem\Partition; +use Flow\Floe\Codec; +use Flow\Floe\Codec\NoopCodec; +use Flow\Floe\FloeMerger; use Flow\Floe\FloeWriter; use Flow\Floe\Format; -use Flow\Floe\RowEncoder; -use Flow\Floe\Tests\Context\FloeFileContext; +use Flow\Floe\NativeFloeEncoder; +use Flow\Floe\PhpFloeEncoder; +use Flow\Floe\Tests\Context\FloeEngineContext; +use Flow\Floe\Tests\Context\FloeSchemaContext; +use Flow\Floe\Tests\Context\FloeStreamReaderContext; +use Flow\Floe\Tests\Double\PrefixingCodecStub; use Flow\Floe\Tests\Mother\RowsMother; use Override; use PHPUnit\Framework\Attributes\DataProvider; -use function extension_loaded; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; +use function Flow\ETL\DSL\schema_from_json; use function Flow\ETL\DSL\str_entry; use function iterator_to_array; use function pack; @@ -45,8 +53,8 @@ protected function setUp(): void { parent::setUp(); - if (!extension_loaded('flow_php')) { - self::markTestSkipped('flow_php extension is not loaded.'); + if (!NativeFloeEncoder::isSupported()) { + self::markTestSkipped('flow_php extension with the RawRowValues pipeline is not loaded.'); } } @@ -61,16 +69,8 @@ public function test_extension_and_pure_php_hydrate_identical_rows(Rows $rows): $writer->close(); static::assertEquals( - iterator_to_array( - (new FloeReader($this->fs(), useExtension: false)) - ->read($path) - ->rows(), - ), - iterator_to_array( - (new FloeReader($this->fs(), useExtension: true)) - ->read($path) - ->rows(), - ), + iterator_to_array(FloeEngineContext::phpReader($this->fs())->read($path)->rows()), + iterator_to_array(FloeEngineContext::nativeReader($this->fs())->read($path)->rows()), ); } @@ -91,16 +91,8 @@ public function test_extension_and_pure_php_seek_offset_identically(): void $writer->close(); static::assertEquals( - iterator_to_array( - (new FloeReader($this->fs(), useExtension: false)) - ->read($path) - ->rows(1000, 2, 3), - ), - iterator_to_array( - (new FloeReader($this->fs(), useExtension: true)) - ->read($path) - ->rows(1000, 2, 3), - ), + iterator_to_array(FloeEngineContext::phpReader($this->fs())->read($path)->rows(1000, 2, 3)), + iterator_to_array(FloeEngineContext::nativeReader($this->fs())->read($path)->rows(1000, 2, 3)), ); } @@ -115,16 +107,8 @@ public function test_extension_and_pure_php_recover_identical_rows(Rows $rows): $writer->close(); static::assertEquals( - iterator_to_array( - (new FloeReader($this->fs(), useExtension: false)) - ->read($path) - ->recover(), - ), - iterator_to_array( - (new FloeReader($this->fs(), useExtension: true)) - ->read($path) - ->recover(), - ), + iterator_to_array(FloeEngineContext::phpReader($this->fs())->read($path)->recover()), + iterator_to_array(FloeEngineContext::nativeReader($this->fs())->read($path)->recover()), ); } @@ -132,23 +116,15 @@ public function test_extension_and_pure_php_recover_a_torn_file_identically(): v { $path = $this->cacheDir->suffix('parity-recover-torn.floe'); - FloeFileContext::writeWithoutFooter( + FloeStreamReaderContext::writeWithoutFooter( $this->fs(), $path, rows(row(int_entry('id', 1)), row(int_entry('id', 2), str_entry('email', 'x')), row(int_entry('id', 3))), ); static::assertEquals( - iterator_to_array( - (new FloeReader($this->fs(), useExtension: false)) - ->read($path) - ->recover(), - ), - iterator_to_array( - (new FloeReader($this->fs(), useExtension: true)) - ->read($path) - ->recover(), - ), + iterator_to_array(FloeEngineContext::phpReader($this->fs())->read($path)->recover()), + iterator_to_array(FloeEngineContext::nativeReader($this->fs())->read($path)->recover()), ); } @@ -156,32 +132,31 @@ public function test_extension_and_pure_php_salvage_rows_before_a_corrupt_row_id { $path = $this->cacheDir->suffix('parity-recover-corrupt.floe'); - $plan = FloeWriter::growSectionPlan(null, row(int_entry('id', 1))); - $rowEncoder = new RowEncoder(); + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); + $encoder = new PhpFloeEncoder(schema_from_json($schemaBody)); + $hydrator = new PhpRowHydrator(); $stream = $this->fs()->writeTo($path); $stream->append( Format::header(0x00) - . Format::frame(Format::FRAME_SCHEMA, $plan->schemaBody) - . Format::frame(Format::FRAME_ROW, $rowEncoder->encode($plan, row(int_entry('id', 1)))) - . Format::frame(Format::FRAME_ROW, $rowEncoder->encode($plan, row(int_entry('id', 2)))) + . Format::frame(Format::FRAME_SCHEMA, $schemaBody) + . Format::frame( + Format::FRAME_ROW, + $encoder->encode($hydrator->dehydrate(rows(row(int_entry('id', 1)))))[0], + ) + . Format::frame( + Format::FRAME_ROW, + $encoder->encode($hydrator->dehydrate(rows(row(int_entry('id', 2)))))[0], + ) . Format::frame(Format::FRAME_ROW, "\xEE"), ); $stream->close(); - $pure = iterator_to_array( - (new FloeReader($this->fs(), useExtension: false)) - ->read($path) - ->recover(), - ); + $pure = iterator_to_array(FloeEngineContext::phpReader($this->fs())->read($path)->recover()); static::assertEquals( $pure, - iterator_to_array( - (new FloeReader($this->fs(), useExtension: true)) - ->read($path) - ->recover(), - ), + iterator_to_array(FloeEngineContext::nativeReader($this->fs())->read($path)->recover()), ); static::assertCount(1, $pure); static::assertCount(2, $pure[0]->all()); @@ -191,63 +166,140 @@ public function test_extension_and_pure_php_recover_rows_around_a_late_partition { $path = $this->cacheDir->suffix('parity-recover-late-partitions.floe'); - $plan = FloeWriter::growSectionPlan(null, row(int_entry('id', 1))); - $rowEncoder = new RowEncoder(); + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); + $encoder = new PhpFloeEncoder(schema_from_json($schemaBody)); + $hydrator = new PhpRowHydrator(); $partitionsBody = pack('V', 1) . pack('V', 1) . 'g' . pack('V', 1) . 'a'; $stream = $this->fs()->writeTo($path); $stream->append( Format::header(0x00) - . Format::frame(Format::FRAME_SCHEMA, $plan->schemaBody) - . Format::frame(Format::FRAME_ROW, $rowEncoder->encode($plan, row(int_entry('id', 1)))) + . Format::frame(Format::FRAME_SCHEMA, $schemaBody) + . Format::frame( + Format::FRAME_ROW, + $encoder->encode($hydrator->dehydrate(rows(row(int_entry('id', 1)))))[0], + ) . Format::frame(Format::FRAME_PARTITIONS, $partitionsBody) - . Format::frame(Format::FRAME_ROW, $rowEncoder->encode($plan, row(int_entry('id', 2)))), + . Format::frame( + Format::FRAME_ROW, + $encoder->encode($hydrator->dehydrate(rows(row(int_entry('id', 2)))))[0], + ), ); $stream->close(); - $pure = iterator_to_array( - (new FloeReader($this->fs(), useExtension: false)) - ->read($path) - ->recover(), - ); + $pure = iterator_to_array(FloeEngineContext::phpReader($this->fs())->read($path)->recover()); static::assertEquals( $pure, - iterator_to_array( - (new FloeReader($this->fs(), useExtension: true)) - ->read($path) - ->recover(), - ), + iterator_to_array(FloeEngineContext::nativeReader($this->fs())->read($path)->recover()), ); - static::assertCount(1, $pure); - static::assertCount(2, $pure[0]->all()); + // the partition change splits the rows into two batches so no batch mixes combinations + static::assertCount(2, $pure); + static::assertCount(1, $pure[0]->all()); + static::assertSame([], $pure[0]->partitions()->toArray()); + static::assertCount(1, $pure[1]->all()); + static::assertEquals([new Partition('g', 'a')], $pure[1]->partitions()->toArray()); + } + + /** + * @return array + */ + public static function codec_matrix(): array + { + return [ + 'noop codec' => [new NoopCodec()], + 'transforming codec' => [new PrefixingCodecStub()], + ]; + } + + #[DataProvider('rows_datasets')] + public function test_extension_and_pure_php_read_identical_rows_with_transforming_codec(Rows $rows): void + { + $codec = new PrefixingCodecStub(); + $path = $this->cacheDir->suffix('read-codec.floe'); + + $writer = new FloeWriter($this->fs(), $codec); + $writer->create($path); + $writer->write($rows); + $writer->close(); + + static::assertEquals( + iterator_to_array(FloeEngineContext::phpReader($this->fs(), $codec)->read($path)->rows()), + iterator_to_array(FloeEngineContext::nativeReader($this->fs(), $codec)->read($path)->rows()), + ); + } + + /** + * Full write->read parity across the engine switch for both codecs and for + * plain, partitioned and schema-evolving files: a pure-PHP round-trip and a + * native round-trip must yield identical rows in every cell. + */ + #[DataProvider('codec_matrix')] + public function test_round_trip_matrix_matches_across_engines(Codec $codec): void + { + $cases = [ + 'plain' => static function (FloeWriter $writer): void { + $writer->write(RowsMother::heterogeneous()); + }, + 'partitioned' => static function (FloeWriter $writer): void { + $writer->write(RowsMother::partitioned()); + }, + 'multi-write' => static function (FloeWriter $writer): void { + $writer->write(rows(row(int_entry('id', 1), str_entry('email', 'a')))); + $writer->write(rows(row(int_entry('id', 2), str_entry('email', 'x')))); + }, + ]; + + foreach ($cases as $name => $write) { + $purePath = $this->cacheDir->suffix("matrix-{$name}-pure.floe"); + $extPath = $this->cacheDir->suffix("matrix-{$name}-ext.floe"); + + foreach ([[$purePath, false], [$extPath, true]] as [$path, $native]) { + $writer = $native + ? FloeEngineContext::nativeWriter($this->fs(), $codec) + : FloeEngineContext::phpWriter($this->fs(), $codec); + $writer->create($path); + $write($writer); + $writer->close(); + } + + static::assertSame( + $this->fs()->readFrom($purePath)->content(), + $this->fs()->readFrom($extPath)->content(), + "byte-identity failed for {$name}", + ); + + static::assertEquals( + iterator_to_array(FloeEngineContext::phpReader($this->fs(), $codec)->read($purePath)->rows()), + iterator_to_array(FloeEngineContext::nativeReader($this->fs(), $codec)->read($extPath)->rows()), + "row parity failed for {$name}", + ); + } } - public function test_extension_and_pure_php_pad_evolved_sections_identically(): void + public function test_extension_and_pure_php_pad_merged_sections_identically(): void { + // a merged file re-encodes to one union schema; base rows lack email and must pad + // identically across engines on read $path = $this->cacheDir->suffix('parity-evolved.floe'); + $base = $this->cacheDir->suffix('parity-base.floe'); + $evolved = $this->cacheDir->suffix('parity-new.floe'); $writer = new FloeWriter($this->fs()); - $writer->create($path); + $writer->create($base); $writer->write(rows(row(int_entry('id', 1)))); $writer->close(); $writer = new FloeWriter($this->fs()); - $writer->append($path); + $writer->create($evolved); $writer->write(rows(row(int_entry('id', 2), str_entry('email', null)))); $writer->close(); + (new FloeMerger($this->fs()))->merge([$base, $evolved], $path); + static::assertEquals( - iterator_to_array( - (new FloeReader($this->fs(), useExtension: false)) - ->read($path) - ->rows(), - ), - iterator_to_array( - (new FloeReader($this->fs(), useExtension: true)) - ->read($path) - ->rows(), - ), + iterator_to_array(FloeEngineContext::phpReader($this->fs())->read($path)->rows()), + iterator_to_array(FloeEngineContext::nativeReader($this->fs())->read($path)->rows()), ); } } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeSerializerExtensionParityTest.php b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeSerializerExtensionParityTest.php deleted file mode 100644 index aa890b3227..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeSerializerExtensionParityTest.php +++ /dev/null @@ -1,58 +0,0 @@ - [RowsMother::withAllEntryTypes()], - 'heterogeneous' => [RowsMother::heterogeneous()], - 'partitioned' => [RowsMother::partitioned()], - 'empty' => [rows()], - 'single row' => [row(int_entry('id', 1))], - ]; - } - - #[Override] - protected function setUp(): void - { - parent::setUp(); - - if (!extension_loaded('flow_php')) { - self::markTestSkipped('flow_php extension is not loaded.'); - } - } - - #[DataProvider('value_datasets')] - public function test_extension_and_pure_php_unserialize_identical_value(Row|Rows $value): void - { - $serialized = (new FloeSerializer())->serialize($value); - - static::assertEquals( - (new FloeSerializer(useExtension: false))->unserialize($serialized, [Row::class, Rows::class]), - (new FloeSerializer(useExtension: true))->unserialize($serialized, [Row::class, Rows::class]), - ); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeFileTest.php b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeStreamReaderTest.php similarity index 87% rename from src/core/etl/tests/Flow/Floe/Tests/Integration/FloeFileTest.php rename to src/core/etl/tests/Flow/Floe/Tests/Integration/FloeStreamReaderTest.php index afbd7a4a13..9d9c54fa1d 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeFileTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeStreamReaderTest.php @@ -5,6 +5,7 @@ namespace Flow\Floe\Tests\Integration; use Flow\ETL\Tests\FlowIntegrationTestCase; +use Flow\Floe\FloeMerger; use Flow\Floe\FloeReader; use Flow\Floe\FloeWriter; use Flow\Floe\Tests\Mother\RowsMother; @@ -18,27 +19,33 @@ use function strlen; use function substr; -final class FloeFileTest extends FlowIntegrationTestCase +final class FloeStreamReaderTest extends FlowIntegrationTestCase { - public function test_append_after_append_with_evolution_reads_seamlessly(): void + public function test_merged_multi_schema_file_reads_seamlessly(): void { + // schema evolution lives in FloeMerger; a merged multi-schema file must read seamlessly $path = $this->cacheDir->suffix('evolving.floe'); + $fileOne = $this->cacheDir->suffix('evolving-1.floe'); + $fileTwo = $this->cacheDir->suffix('evolving-2.floe'); + $fileThree = $this->cacheDir->suffix('evolving-3.floe'); $writer = new FloeWriter($this->fs()); - $writer->create($path); + $writer->create($fileOne); $writer->write(rows(row(int_entry('id', 1)))); $writer->close(); $writer = new FloeWriter($this->fs()); - $writer->append($path); + $writer->create($fileTwo); $writer->write(rows(row(int_entry('id', 2), str_entry('email', null)))); $writer->close(); $writer = new FloeWriter($this->fs()); - $writer->append($path); + $writer->create($fileThree); $writer->write(rows(row(int_entry('id', 3), str_entry('email', 'third@flow.php')))); $writer->close(); + (new FloeMerger($this->fs()))->merge([$fileOne, $fileTwo, $fileThree], $path); + $reader = (new FloeReader($this->fs()))->read($path); static::assertSame(3, $reader->totalRows()); diff --git a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeValueSerializerExtensionParityTest.php b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeValueSerializerExtensionParityTest.php deleted file mode 100644 index ee4a3469b0..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeValueSerializerExtensionParityTest.php +++ /dev/null @@ -1,111 +0,0 @@ - [RowsMother::withAllEntryTypes()], - 'heterogeneous' => [RowsMother::heterogeneous()], - 'partitioned' => [RowsMother::partitioned()], - 'empty' => [rows()], - 'single row' => [row(int_entry('id', 1))], - ]; - } - - #[Override] - protected function setUp(): void - { - parent::setUp(); - - if (!extension_loaded('flow_php')) { - self::markTestSkipped('flow_php extension is not loaded.'); - } - } - - #[DataProvider('value_datasets')] - public function test_extension_and_pure_php_decode_identically(Row|Rows $value): void - { - $bytes = (new FloeValueSerializer(useExtension: false))->encode($value); - - static::assertEquals( - (new FloeValueSerializer(useExtension: false))->decode($bytes), - (new FloeValueSerializer(useExtension: true))->decode($bytes), - ); - } - - #[DataProvider('value_datasets')] - public function test_extension_encodes_byte_identical_to_pure_php(Row|Rows $value): void - { - static::assertSame( - (new FloeValueSerializer(useExtension: false))->encode($value), - (new FloeValueSerializer(useExtension: true))->encode($value), - ); - } - - public function test_extension_decode_failure_is_wrapped_as_floe_exception(): void - { - $bytes = (new FloeValueSerializer(useExtension: false))->encode(rows(row(int_entry('id', 1)))); - // corrupt the first frame type (SCHEMA -> unknown 0x7F); the footer at the end stays intact - $bytes[6] = "\x7F"; - - $this->expectException(FloeException::class); - - (new FloeValueSerializer(useExtension: true))->decode($bytes); - } - - public function test_extension_encode_failure_is_wrapped_as_floe_exception(): void - { - $this->expectException(FloeException::class); - - (new FloeValueSerializer(useExtension: true))->encode(rows(row(datetime_entry( - 'd', - new CustomDateTime('2025-01-01 00:00:00'), - )))); - } - - #[DataProvider('value_datasets')] - public function test_streaming_mode_decodes_identically_on_both_engines(Row|Rows $value): void - { - $bytes = (new FloeValueSerializer(useExtension: false))->encode($value); - - static::assertEquals( - (new FloeValueSerializer(2, useExtension: false))->decode($bytes), - (new FloeValueSerializer(2, useExtension: true))->decode($bytes), - ); - } - - #[DataProvider('value_datasets')] - public function test_streaming_mode_encodes_byte_identical_on_both_engines_and_to_bulk(Row|Rows $value): void - { - $bulk = (new FloeValueSerializer(useExtension: true))->encode($value); - - static::assertSame($bulk, (new FloeValueSerializer(2, useExtension: false))->encode($value)); - static::assertSame($bulk, (new FloeValueSerializer(2, useExtension: true))->encode($value)); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeWriterExtensionParityTest.php b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeWriterExtensionParityTest.php index 26127cc1c7..3433623d0e 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeWriterExtensionParityTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Integration/FloeWriterExtensionParityTest.php @@ -8,12 +8,13 @@ use Flow\ETL\Tests\Fixtures\CustomDateTime; use Flow\ETL\Tests\FlowIntegrationTestCase; use Flow\Floe\Exception\FloeException; -use Flow\Floe\FloeWriter; +use Flow\Floe\NativeFloeEncoder; +use Flow\Floe\Tests\Context\FloeEngineContext; +use Flow\Floe\Tests\Double\PrefixingCodecStub; use Flow\Floe\Tests\Mother\RowsMother; use Override; use PHPUnit\Framework\Attributes\DataProvider; -use function extension_loaded; use function Flow\ETL\DSL\datetime_entry; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; @@ -22,8 +23,8 @@ /** * With the flow_php extension loaded, FloeWriter encodes ROW frame bodies through - * the extension's RowsEncoder. These tests pin the pure-PHP RowEncoder as the - * canonical reference and assert the extension writes byte-identical files. + * NativeFloeEncoder. These tests pin PhpFloeEncoder as the canonical reference and + * assert the native engine writes byte-identical files. */ final class FloeWriterExtensionParityTest extends FlowIntegrationTestCase { @@ -42,7 +43,7 @@ protected function setUp(): void { parent::setUp(); - if (!extension_loaded('flow_php')) { + if (!NativeFloeEncoder::isSupported()) { self::markTestSkipped('flow_php extension is not loaded.'); } } @@ -51,9 +52,13 @@ public function test_extension_and_pure_php_reject_datetime_subclass_identically { $rows = rows(row(datetime_entry('at', new CustomDateTime('2025-01-01 00:00:00 UTC')))); - foreach ([false, true] as $useExtension) { - $writer = new FloeWriter($this->fs(), useExtension: $useExtension); - $writer->create($this->cacheDir->suffix('subclass-' . ($useExtension ? 'ext' : 'php') . '.floe')); + $writers = [ + 'php' => FloeEngineContext::phpWriter($this->fs()), + 'ext' => FloeEngineContext::nativeWriter($this->fs()), + ]; + + foreach ($writers as $engine => $writer) { + $writer->create($this->cacheDir->suffix('subclass-' . $engine . '.floe')); try { $writer->write($rows); @@ -70,15 +75,8 @@ public function test_extension_and_pure_php_write_byte_identical_files(Rows $row $purePath = $this->cacheDir->suffix('write-pure.floe'); $extPath = $this->cacheDir->suffix('write-ext.floe'); - $pure = new FloeWriter($this->fs(), useExtension: false); - $pure->create($purePath); - $pure->write($rows); - $pure->close(); - - $ext = new FloeWriter($this->fs(), useExtension: true); - $ext->create($extPath); - $ext->write($rows); - $ext->close(); + FloeEngineContext::writeAll(FloeEngineContext::phpWriter($this->fs()), $purePath, [$rows]); + FloeEngineContext::writeAll(FloeEngineContext::nativeWriter($this->fs()), $extPath, [$rows]); static::assertSame($this->fs()->readFrom($purePath)->content(), $this->fs()->readFrom($extPath)->content()); } @@ -86,24 +84,35 @@ public function test_extension_and_pure_php_write_byte_identical_files(Rows $row public function test_extension_and_pure_php_write_byte_identical_files_across_multiple_writes(): void { $batches = [ - rows(row(int_entry('id', 1)), row(int_entry('id', 2))), - rows(row(int_entry('id', 3))), - rows(row(int_entry('id', 4), str_entry('name', 'x')), row(int_entry('id', 5))), + rows(row(int_entry('id', 1), str_entry('name', 'a')), row(int_entry('id', 2), str_entry('name', 'b'))), + rows(row(int_entry('id', 3), str_entry('name', 'c'))), + rows(row(int_entry('id', 4), str_entry('name', 'd')), row(int_entry('id', 5), str_entry('name', 'e'))), ]; $purePath = $this->cacheDir->suffix('multi-write-pure.floe'); $extPath = $this->cacheDir->suffix('multi-write-ext.floe'); - foreach ([[$purePath, false], [$extPath, true]] as [$path, $useExtension]) { - $writer = new FloeWriter($this->fs(), useExtension: $useExtension); - $writer->create($path); + FloeEngineContext::writeAll(FloeEngineContext::phpWriter($this->fs()), $purePath, $batches); + FloeEngineContext::writeAll(FloeEngineContext::nativeWriter($this->fs()), $extPath, $batches); - foreach ($batches as $batch) { - $writer->write($batch); - } + static::assertSame($this->fs()->readFrom($purePath)->content(), $this->fs()->readFrom($extPath)->content()); + } - $writer->close(); - } + /** + * A transforming (non-identity) codec must not fork the engine: the native + * body-encode produces the same ROW bodies as the PHP engine, the codec runs + * in PHP either way, so the files stay byte-identical (the A1 fix). + */ + #[DataProvider('rows_datasets')] + public function test_extension_and_pure_php_write_byte_identical_files_with_transforming_codec(Rows $rows): void + { + $codec = new PrefixingCodecStub(); + + $purePath = $this->cacheDir->suffix('write-codec-pure.floe'); + $extPath = $this->cacheDir->suffix('write-codec-ext.floe'); + + FloeEngineContext::writeAll(FloeEngineContext::phpWriter($this->fs(), $codec), $purePath, [$rows]); + FloeEngineContext::writeAll(FloeEngineContext::nativeWriter($this->fs(), $codec), $extPath, [$rows]); static::assertSame($this->fs()->readFrom($purePath)->content(), $this->fs()->readFrom($extPath)->content()); } @@ -113,16 +122,20 @@ public function test_extension_and_pure_php_append_byte_identically(): void $purePath = $this->cacheDir->suffix('append-pure.floe'); $extPath = $this->cacheDir->suffix('append-ext.floe'); - foreach ([[$purePath, false], [$extPath, true]] as [$path, $useExtension]) { - $writer = new FloeWriter($this->fs(), useExtension: $useExtension); - $writer->create($path); - $writer->write(rows(row(int_entry('id', 1), str_entry('email', null)))); - $writer->close(); - - $writer = new FloeWriter($this->fs(), useExtension: $useExtension); - $writer->append($path); - $writer->write(rows(row(int_entry('id', 2), str_entry('email', 'x')))); - $writer->close(); + foreach ([[$purePath, false], [$extPath, true]] as [$path, $native]) { + $create = $native + ? FloeEngineContext::nativeWriter($this->fs()) + : FloeEngineContext::phpWriter($this->fs()); + $create->create($path); + $create->write(rows(row(int_entry('id', 1), str_entry('email', null)))); + $create->close(); + + $append = $native + ? FloeEngineContext::nativeWriter($this->fs()) + : FloeEngineContext::phpWriter($this->fs()); + $append->append($path); + $append->write(rows(row(int_entry('id', 2), str_entry('email', 'x')))); + $append->close(); } static::assertSame($this->fs()->readFrom($purePath)->content(), $this->fs()->readFrom($extPath)->content()); diff --git a/src/core/etl/tests/Flow/Floe/Tests/Mother/FooterMother.php b/src/core/etl/tests/Flow/Floe/Tests/Mother/FooterMother.php index 2bb48d2338..1c377001ad 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Mother/FooterMother.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Mother/FooterMother.php @@ -10,29 +10,23 @@ final class FooterMother { /** - * @param array $schemas raw normalized schema lists, e.g. [$schema->normalize()] - * @param array $fileSchema raw normalized schema, e.g. $schema->normalize() + * @param array $schema raw normalized schema, e.g. $schema->normalize() * @param array $sections - * @param array $partitions + * @param array> $partitions * @param array|bool|float|int|string> $metadata */ public static function footer( - array $schemas = [], - array $fileSchema = [], + array $schema = [], array $sections = [], array $partitions = [], int $totalRows = 0, array $metadata = [], ): Footer { - /** - * @var array>> $schemas - * @var array> $fileSchema - */ + /** @var array> $schema */ return new Footer( 1, 'test-writer', - $schemas, - $fileSchema, + $schema, $sections, $partitions, $totalRows, diff --git a/src/core/etl/tests/Flow/Floe/Tests/Mother/RowsMother.php b/src/core/etl/tests/Flow/Floe/Tests/Mother/RowsMother.php index 3422baf533..85fa55bf08 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Mother/RowsMother.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Mother/RowsMother.php @@ -9,7 +9,6 @@ use DateTimeImmutable; use DateTimeZone; use Flow\ETL\Row; -use Flow\ETL\Row\Entry\StringEntry; use Flow\ETL\Rows; use Flow\ETL\Tests\Fixtures\Enum\BackedStringEnum; use Flow\ETL\Tests\Fixtures\Enum\BasicEnum; @@ -25,6 +24,7 @@ use function Flow\ETL\DSL\json_object_entry; use function Flow\ETL\DSL\list_entry; use function Flow\ETL\DSL\map_entry; +use function Flow\ETL\DSL\null_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; @@ -77,7 +77,7 @@ public static function withAllEntryTypes(): Rows str_entry('string_binary', "line\nbreak\x00null\xFFbyte"), str_entry('string_unicode', 'zażółć gęślą jaźń 🚀'), str_entry('string_null', null), - StringEntry::fromNull('string_from_null'), + null_entry('string_from_null'), datetime_entry( 'datetime_immutable', new DateTimeImmutable('2025-06-15 12:30:45.123456', new DateTimeZone('Europe/Warsaw')), diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/AdaptiveFloeEncoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/AdaptiveFloeEncoderTest.php new file mode 100644 index 0000000000..0ec1031620 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/AdaptiveFloeEncoderTest.php @@ -0,0 +1,36 @@ +first()->schema()))); + + $decoded = $encoder->decode($encoder->encode((new PhpRowHydrator())->dehydrate($data))); + + static::assertEquals( + [new RawRowValues(['id' => 1, 'name' => 'flow']), new RawRowValues(['id' => 2, 'name' => null])], + $decoded, + ); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/ExtRowFrameEncoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/ExtRowFrameEncoderTest.php deleted file mode 100644 index ccc4059ea5..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/ExtRowFrameEncoderTest.php +++ /dev/null @@ -1,66 +0,0 @@ -encode($batch), (new ExtRowFrameEncoder())->encode($batch)); - } - - public function test_new_column_segments_are_identical_to_the_pure_php_engine(): void - { - $batch = rows(row(int_entry('id', 1)), row(int_entry('id', 2), str_entry('name', 'flow'))); - - static::assertEquals((new PhpRowFrameEncoder())->encode($batch), (new ExtRowFrameEncoder())->encode($batch)); - } - - public function test_narrower_row_segments_are_identical_to_the_pure_php_engine(): void - { - $batch = rows(row(int_entry('id', 1), str_entry('name', 'flow')), row(int_entry('id', 2))); - - static::assertEquals((new PhpRowFrameEncoder())->encode($batch), (new ExtRowFrameEncoder())->encode($batch)); - } - - public function test_continuation_across_calls_is_identical_to_the_pure_php_engine(): void - { - $first = rows(row(int_entry('id', 1))); - $second = rows(row(int_entry('id', 2))); - - $php = new PhpRowFrameEncoder(); - $ext = new ExtRowFrameEncoder(); - - static::assertEquals($php->encode($first), $ext->encode($first)); - static::assertEquals($php->encode($second), $ext->encode($second)); - } - - public function test_empty_rows_produce_no_segments(): void - { - static::assertSame([], (new ExtRowFrameEncoder())->encode(rows())); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeExtractorTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeExtractorTest.php index 5dafb25e7e..5c6291f898 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeExtractorTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeExtractorTest.php @@ -6,16 +6,21 @@ use Flow\ETL\Exception\InvalidArgumentException; use Flow\ETL\Extractor\Signal; +use Flow\ETL\Rows; +use Flow\Filesystem\Partition; use Flow\Filesystem\Path\Filter\Filters; use Flow\Filesystem\Path\Filter\OnlyFiles; +use Flow\Floe\FloeWriter; use PHPUnit\Framework\TestCase; +use function array_map; use function Flow\ETL\DSL\config; use function Flow\ETL\DSL\config_builder; use function Flow\ETL\DSL\flow_context; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; +use function Flow\ETL\DSL\str_entry; use function Flow\Filesystem\DSL\path; use function Flow\Floe\DSL\from_floe; use function Flow\Floe\DSL\to_floe; @@ -126,6 +131,32 @@ public function test_extract_reads_rows(): void static::assertSame([1, 2], $ids); } + public function test_extract_yields_per_batch_partitions_on_a_multi_combination_file(): void + { + $context = flow_context(config()); + $path = path('memory://extract-multi-combination.floe'); + + $writer = new FloeWriter($context->filesystem($path)); + $writer->create($path); + $writer->write(Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )])); + $writer->write(Rows::partitioned([row(int_entry('id', 2), str_entry('country', 'US'))], [new Partition( + 'country', + 'US', + )])); + $writer->close(); + + $combos = []; + + foreach (from_floe($path)->extract($context) as $batch) { + $combos[] = array_map(static fn(Partition $p): string => $p->value, $batch->partitions()->toArray()); + } + + static::assertSame([['PL'], ['US']], $combos); + } + public function test_extract_skips_whole_files_with_offset(): void { $context = flow_context(config()); diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeLoaderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeLoaderTest.php index f6977e2b58..6c2717f952 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeLoaderTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeLoaderTest.php @@ -7,9 +7,11 @@ use Flow\ETL\Exception\RuntimeException; use Flow\ETL\Rows; use Flow\Filesystem\Partition; +use Flow\Floe\Tests\Double\SpyHydrator; use PHPUnit\Framework\TestCase; use function Flow\ETL\DSL\config; +use function Flow\ETL\DSL\config_builder; use function Flow\ETL\DSL\flow_context; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; @@ -42,6 +44,19 @@ public function test_closure_writes_a_readable_non_torn_file(): void static::assertSame([1, 2], $ids); } + public function test_load_honors_the_context_hydrator(): void + { + $hydrator = new SpyHydrator(); + $context = flow_context(config_builder()->hydrator($hydrator)->build()); + $path = path('memory://hydrator.floe'); + + $loader = to_floe($path); + $loader->load(rows(row(int_entry('id', 1)), row(int_entry('id', 2))), $context); + $loader->closure($context); + + static::assertGreaterThan(0, $hydrator->dehydrateCalls); + } + public function test_destination_returns_path(): void { static::assertSame('memory://out.floe', to_floe(path('memory://out.floe'))->destination()->uri()); diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeMergerTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeMergerTest.php index bb5497bc72..9f411b5791 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeMergerTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeMergerTest.php @@ -11,10 +11,11 @@ use Flow\Floe\Exception\IncompatibleSchemaException; use Flow\Floe\FloeMerger; use Flow\Floe\FloeReader; -use Flow\Floe\Tests\Context\FloeFileContext; +use Flow\Floe\Tests\Context\FloeStreamReaderContext; use Flow\Floe\Tests\Double\UnsizedFilesystem; use PHPUnit\Framework\TestCase; +use function array_map; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; @@ -29,8 +30,12 @@ final class FloeMergerTest extends TestCase public function test_compact_reads_identically_to_splice(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 3)))); + FloeStreamReaderContext::write( + $fs, + path('memory://a.floe'), + rows(row(int_entry('id', 1)), row(int_entry('id', 2))), + ); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 3)))); (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://splice.floe')); (new FloeMerger($fs))->merge( @@ -40,16 +45,16 @@ public function test_compact_reads_identically_to_splice(): void ); static::assertEquals( - FloeFileContext::readAll($fs, path('memory://splice.floe')), - FloeFileContext::readAll($fs, path('memory://compact.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://splice.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://compact.floe')), ); } public function test_compact_coalesces_same_schema_sources_into_one_section(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); (new FloeMerger($fs))->merge( [path('memory://a.floe'), path('memory://b.floe')], @@ -60,12 +65,56 @@ public function test_compact_coalesces_same_schema_sources_into_one_section(): v static::assertCount(1, (new FloeReader($fs))->read(path('memory://compact.floe'))->footer()->sections); } + public function test_merge_of_same_columns_in_different_order_re_encodes_instead_of_splicing(): void + { + $fs = memory_filesystem(); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('a', 1), int_entry('b', 100)))); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('b', 200), int_entry('a', 2)))); + + (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); + + static::assertSame( + [ + ['a' => 1, 'b' => 100], + ['a' => 2, 'b' => 200], + ], + FloeStreamReaderContext::readAll($fs, path('memory://out.floe'))->toArray(), + ); + // the compact path coalesces sources into one section - splicing would keep one per source + static::assertCount(1, (new FloeReader($fs))->read(path('memory://out.floe'))->footer()->sections); + } + + public function test_merge_of_same_columns_in_different_order_with_mixed_types_round_trips(): void + { + $fs = memory_filesystem(); + FloeStreamReaderContext::write( + $fs, + path('memory://a.floe'), + rows(row(int_entry('a', 1), str_entry('b', 'one'))), + ); + FloeStreamReaderContext::write( + $fs, + path('memory://b.floe'), + rows(row(str_entry('b', 'two'), int_entry('a', 2))), + ); + + (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); + + static::assertSame( + [ + ['a' => 1, 'b' => 'one'], + ['a' => 2, 'b' => 'two'], + ], + FloeStreamReaderContext::readAll($fs, path('memory://out.floe'))->toArray(), + ); + } + public function test_empty_source_contributes_no_rows(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); - FloeFileContext::write($fs, path('memory://empty.floe'), rows()); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write($fs, path('memory://empty.floe'), rows()); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); (new FloeMerger($fs))->merge([ path('memory://a.floe'), @@ -75,7 +124,7 @@ public function test_empty_source_contributes_no_rows(): void static::assertEquals( rows(row(int_entry('id', 1)), row(int_entry('id', 2))), - FloeFileContext::readAll($fs, path('memory://out.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://out.floe')), ); } @@ -87,36 +136,73 @@ public function test_empty_sources_list_throws(): void (new FloeMerger(memory_filesystem()))->merge([], path('memory://out.floe')); } - public function test_evolving_schema_pads_missing_columns(): void + public function test_merging_a_source_that_adds_a_non_nullable_column_throws(): void + { + $fs = memory_filesystem(); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write( + $fs, + path('memory://b.floe'), + rows(row(int_entry('id', 2), str_entry('email', 'x@y'))), + ); + + // "email" is non-nullable in B but absent from A - padding A's rows with null would + // violate its required contract, so the merge is rejected rather than silently widened. + $this->expectException(IncompatibleSchemaException::class); + $this->expectExceptionMessage('Floe merge cannot reconcile the schema of'); + + (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); + } + + public function test_merging_a_source_that_drops_a_non_nullable_column_throws(): void + { + $fs = memory_filesystem(); + FloeStreamReaderContext::write( + $fs, + path('memory://a.floe'), + rows(row(int_entry('id', 1), str_entry('email', 'x@y'))), + ); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); + + $this->expectException(IncompatibleSchemaException::class); + $this->expectExceptionMessage('Floe merge cannot reconcile the schema of'); + + (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); + } + + public function test_merging_sources_with_a_nullable_column_pads_missing_rows(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2), str_entry('email', 'x@y')))); + FloeStreamReaderContext::write( + $fs, + path('memory://a.floe'), + rows(row(int_entry('id', 1), str_entry('email', null))), + ); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); - // merging A then B must read back exactly like writing A's rows then B's rows to one file: - // the id-only section is padded with a from_null email, same as any heterogeneous Floe file. - FloeFileContext::write( + // "email" is nullable in A, so B's rows are legitimately padded with null on read-back. + FloeStreamReaderContext::write( $fs, path('memory://reference.floe'), - rows(row(int_entry('id', 1)), row(int_entry('id', 2), str_entry('email', 'x@y'))), + rows(row(int_entry('id', 1), str_entry('email', null)), row(int_entry('id', 2))), ); static::assertEquals( - FloeFileContext::readAll($fs, path('memory://reference.floe')), - FloeFileContext::readAll($fs, path('memory://out.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://reference.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://out.floe')), ); } public function test_metadata_is_merged_with_new_keys_winning(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1))), [ + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1))), [ 'a' => '1', 'shared' => 'from-a', ]); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2))), [ + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2))), [ 'b' => '2', 'shared' => 'from-b', ]); @@ -147,8 +233,16 @@ public function test_missing_source_throws(): void public function test_offset_read_after_merge_seeks_across_sources(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 3)), row(int_entry('id', 4)))); + FloeStreamReaderContext::write( + $fs, + path('memory://a.floe'), + rows(row(int_entry('id', 1)), row(int_entry('id', 2))), + ); + FloeStreamReaderContext::write( + $fs, + path('memory://b.floe'), + rows(row(int_entry('id', 3)), row(int_entry('id', 4))), + ); (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); @@ -165,35 +259,87 @@ public function test_offset_read_after_merge_seeks_across_sources(): void static::assertSame([4], $read); } - public function test_partition_combination_mismatch_throws(): void + public function test_differing_partition_combinations_are_preserved(): void { $fs = memory_filesystem(); - FloeFileContext::write( + FloeStreamReaderContext::write( $fs, path('memory://pl.floe'), Rows::partitioned([row(int_entry('id', 1), str_entry('c', 'PL'))], [new Partition('c', 'PL')]), ); - FloeFileContext::write( + FloeStreamReaderContext::write( $fs, path('memory://us.floe'), Rows::partitioned([row(int_entry('id', 2), str_entry('c', 'US'))], [new Partition('c', 'US')]), ); - $this->expectException(IncompatibleSchemaException::class); - $this->expectExceptionMessage('one partition combination'); - (new FloeMerger($fs))->merge([path('memory://pl.floe'), path('memory://us.floe')], path('memory://out.floe')); + + $file = (new FloeReader($fs))->read(path('memory://out.floe')); + + static::assertSame([['c' => 'PL'], ['c' => 'US']], $file->footer()->partitions); + static::assertSame(0, $file->footer()->sections[0]->partitionsId); + static::assertSame(1, $file->footer()->sections[1]->partitionsId); + + $combos = []; + + foreach ($file->rows() as $batch) { + $combos[] = array_map(static fn(Partition $p): string => $p->value, $batch->partitions()->toArray()); + } + + static::assertSame([['PL'], ['US']], $combos); + } + + public function test_unpartitioned_source_after_partitioned_resets_the_reader(): void + { + $fs = memory_filesystem(); + FloeStreamReaderContext::write( + $fs, + path('memory://pl.floe'), + Rows::partitioned([row(int_entry('id', 1), str_entry('c', 'PL'))], [new Partition('c', 'PL')]), + ); + // same schema {id, c} as pl, but written unpartitioned - so the merge exercises the + // partition reset (partitioned -> unpartitioned) without a schema incompatibility + FloeStreamReaderContext::write( + $fs, + path('memory://plain.floe'), + rows(row(int_entry('id', 2), str_entry('c', 'XX'))), + ); + + (new FloeMerger($fs))->merge([ + path('memory://pl.floe'), + path('memory://plain.floe'), + ], path('memory://splice.floe')); + (new FloeMerger($fs))->merge( + [path('memory://pl.floe'), path('memory://plain.floe')], + path('memory://compact.floe'), + compact: true, + ); + + $combos = []; + + foreach ((new FloeReader($fs)) + ->read(path('memory://splice.floe')) + ->rows() as $batch) { + $combos[] = array_map(static fn(Partition $p): string => $p->value, $batch->partitions()->toArray()); + } + + static::assertSame([['PL'], []], $combos); + static::assertEquals( + FloeStreamReaderContext::readAll($fs, path('memory://compact.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://splice.floe')), + ); } public function test_partitioned_sources_merge_and_preserve_partition(): void { $fs = memory_filesystem(); - FloeFileContext::write( + FloeStreamReaderContext::write( $fs, path('memory://a.floe'), Rows::partitioned([row(int_entry('id', 1), str_entry('c', 'PL'))], [new Partition('c', 'PL')]), ); - FloeFileContext::write( + FloeStreamReaderContext::write( $fs, path('memory://b.floe'), Rows::partitioned([row(int_entry('id', 2), str_entry('c', 'PL'))], [new Partition('c', 'PL')]), @@ -203,7 +349,7 @@ public function test_partitioned_sources_merge_and_preserve_partition(): void $file = (new FloeReader($fs))->read(path('memory://out.floe')); - static::assertSame(['c' => 'PL'], $file->footer()->partitions); + static::assertSame([['c' => 'PL']], $file->footer()->partitions); static::assertSame(2, $file->totalRows()); } @@ -211,19 +357,19 @@ public function test_single_source_is_a_copy(): void { $fs = memory_filesystem(); $value = rows(row(int_entry('id', 1)), row(int_entry('id', 2))); - FloeFileContext::write($fs, path('memory://a.floe'), $value); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), $value); (new FloeMerger($fs))->merge([path('memory://a.floe')], path('memory://out.floe')); - static::assertEquals($value, FloeFileContext::readAll($fs, path('memory://out.floe'))); + static::assertEquals($value, FloeStreamReaderContext::readAll($fs, path('memory://out.floe'))); } public function test_splices_three_files(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); - FloeFileContext::write($fs, path('memory://c.floe'), rows(row(int_entry('id', 3)))); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 2)))); + FloeStreamReaderContext::write($fs, path('memory://c.floe'), rows(row(int_entry('id', 3)))); (new FloeMerger($fs))->merge([ path('memory://a.floe'), @@ -233,32 +379,40 @@ public function test_splices_three_files(): void static::assertEquals( rows(row(int_entry('id', 1)), row(int_entry('id', 2)), row(int_entry('id', 3))), - FloeFileContext::readAll($fs, path('memory://out.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://out.floe')), ); } public function test_splices_two_files_with_the_same_schema(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(int_entry('id', 3)), row(int_entry('id', 4)))); + FloeStreamReaderContext::write( + $fs, + path('memory://a.floe'), + rows(row(int_entry('id', 1)), row(int_entry('id', 2))), + ); + FloeStreamReaderContext::write( + $fs, + path('memory://b.floe'), + rows(row(int_entry('id', 3)), row(int_entry('id', 4))), + ); (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); static::assertEquals( rows(row(int_entry('id', 1)), row(int_entry('id', 2)), row(int_entry('id', 3)), row(int_entry('id', 4))), - FloeFileContext::readAll($fs, path('memory://out.floe')), + FloeStreamReaderContext::readAll($fs, path('memory://out.floe')), ); } public function test_type_conflict_throws(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); - FloeFileContext::write($fs, path('memory://b.floe'), rows(row(str_entry('id', 'x')))); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write($fs, path('memory://b.floe'), rows(row(str_entry('id', 'x')))); $this->expectException(IncompatibleSchemaException::class); - $this->expectExceptionMessage('not compatible'); + $this->expectExceptionMessage('Floe merge cannot reconcile the schema of'); (new FloeMerger($fs))->merge([path('memory://a.floe'), path('memory://b.floe')], path('memory://out.floe')); } @@ -266,7 +420,7 @@ public function test_type_conflict_throws(): void public function test_unsized_source_throws(): void { $fs = memory_filesystem(); - FloeFileContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::write($fs, path('memory://a.floe'), rows(row(int_entry('id', 1)))); $this->expectException(FloeException::class); $this->expectExceptionMessage('does not report its size'); @@ -294,7 +448,7 @@ public function test_non_noop_codec_source_throws(): void ->close(); $this->expectException(FloeException::class); - $this->expectExceptionMessage('no-op codec'); + $this->expectExceptionMessage('written with codec 0x05'); (new FloeMerger($fs))->merge([path('memory://codec.floe')], path('memory://out.floe')); } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeReaderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeReaderTest.php index 09b04cbb9b..9d704cc976 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeReaderTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeReaderTest.php @@ -4,15 +4,18 @@ namespace Flow\Floe\Tests\Unit; +use Flow\ETL\Row\AdaptiveRowHydrator; use Flow\ETL\Rows; use Flow\ETL\Schema\Metadata; use Flow\Filesystem\Partition; use Flow\Floe\Exception\FloeException; +use Flow\Floe\FloeMerger; use Flow\Floe\FloeReader; use Flow\Floe\FloeWriter; use Flow\Floe\Format; -use Flow\Floe\RowEncoder; -use Flow\Floe\Tests\Context\FloeFileContext; +use Flow\Floe\PhpFloeEncoder; +use Flow\Floe\Tests\Context\FloeSchemaContext; +use Flow\Floe\Tests\Context\FloeStreamReaderContext; use Flow\Floe\Tests\Double\CodecStub; use Flow\Floe\Tests\Double\UnsizedFilesystem; use Flow\Floe\Tests\Mother\FooterMother; @@ -25,6 +28,7 @@ use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; +use function Flow\ETL\DSL\schema_from_json; use function Flow\ETL\DSL\str_entry; use function Flow\Filesystem\DSL\memory_filesystem; use function Flow\Filesystem\DSL\path; @@ -141,24 +145,36 @@ public function test_limit_stops_within_a_batch(): void public function test_negative_offset_throws(): void { + $filesystem = memory_filesystem(); + $path = path('memory://neg-offset.floe'); + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->close(); + $this->expectException(FloeException::class); $this->expectExceptionMessage('offset must be greater or equal to 0'); iterator_to_array( - (new FloeReader(memory_filesystem())) - ->read(path('memory://neg-offset.floe')) + (new FloeReader($filesystem)) + ->read($path) ->rows(offset: -1), ); } public function test_non_positive_limit_throws(): void { + $filesystem = memory_filesystem(); + $path = path('memory://zero-limit.floe'); + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->close(); + $this->expectException(FloeException::class); $this->expectExceptionMessage('limit must be greater than 0'); iterator_to_array( - (new FloeReader(memory_filesystem())) - ->read(path('memory://zero-limit.floe')) + (new FloeReader($filesystem)) + ->read($path) ->rows(limit: 0), ); } @@ -404,8 +420,8 @@ public function test_corrupt_row_body_throws_wrapped_exception(): void { $filesystem = memory_filesystem(); $path = path('memory://corrupt-row.floe'); - $schemaBody = FloeWriter::growSectionPlan(null, row(int_entry('id', 1)))->schemaBody; - $footerJson = FooterMother::footer()->toJson(); + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); + $footerJson = FooterMother::footer(schema: row(int_entry('id', 1))->schema()->normalize())->toJson(); $stream = $filesystem->writeTo($path); $stream->append( Format::header(0x00) @@ -494,20 +510,25 @@ public function test_evolved_file_rows_conform_to_merged_schema(): void $filesystem = memory_filesystem(); $path = path('memory://evolved.floe'); + // a multi-schema file is what FloeMerger produces (schema evolution lives in merge, not the writer) + $baseFile = path('memory://evolved-base.floe'); + $evolvedFile = path('memory://evolved-new.floe'); + $writer = new FloeWriter($filesystem); - $writer->create($path); + $writer->create($baseFile); $writer->write(rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); $writer->close(); $writer = new FloeWriter($filesystem); - $writer->append($path); + $writer->create($evolvedFile); $writer->write(rows( - // new columns must be nullable on append - the first row of the section defines its schema row(int_entry('id', 3), str_entry('email', null)), row(int_entry('id', 4), str_entry('email', 'x@flow.php')), )); $writer->close(); + (new FloeMerger($filesystem))->merge([$baseFile, $evolvedFile], $path); + $batches = iterator_to_array( (new FloeReader($filesystem)) ->read($path) @@ -522,7 +543,8 @@ public function test_evolved_file_rows_conform_to_merged_schema(): void } static::assertNull($rows[0]->valueOf('email')); - static::assertTrue($rows[0]->get('email')->definition()->metadata()->has(Metadata::FROM_NULL)); + static::assertTrue($rows[0]->get('email')->definition()->isNullable()); + static::assertTrue($rows[0]->get('email')->definition()->metadata()->isEmpty()); static::assertSame('x@flow.php', $rows[3]->valueOf('email')); } @@ -596,10 +618,16 @@ public function test_footer_accessors(): void public function test_open_with_non_noop_codec_throws(): void { + $filesystem = memory_filesystem(); + $path = path('memory://x.floe'); + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->close(); + $this->expectException(FloeException::class); $this->expectExceptionMessage('supports only the no-op codec, got codec 0x09'); - (new FloeReader(memory_filesystem(), new CodecStub(0x09)))->read(path('memory://x.floe')); + (new FloeReader($filesystem, new CodecStub(0x09)))->read($path); } public function test_partitions_are_reattached_to_batches(): void @@ -625,6 +653,93 @@ public function test_partitions_are_reattached_to_batches(): void static::assertEquals([new Partition('country', 'PL')], iterator_to_array($batches[0]->partitions())); } + public function test_multi_combination_file_attaches_per_section_partitions(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://multi-combination.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write(Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )])); + $writer->write(Rows::partitioned([row(int_entry('id', 2), str_entry('country', 'US'))], [new Partition( + 'country', + 'US', + )])); + $writer->write(rows(row(int_entry('id', 3)))); + $writer->close(); + + $combos = []; + $ids = []; + + foreach ((new FloeReader($filesystem)) + ->read($path) + ->rows() as $batch) { + $combos[] = array_map(static fn(Partition $p): string => $p->value, $batch->partitions()->toArray()); + $ids[] = array_map(static fn($row) => $row->valueOf('id'), $batch->all()); + } + + static::assertSame([['PL'], ['US'], []], $combos); + static::assertSame([[1], [2], [3]], $ids); + } + + public function test_offset_read_into_a_later_combination_primes_the_right_partitions(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://offset-multi-combination.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write(Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )])); + $writer->write(Rows::partitioned([row(int_entry('id', 2), str_entry('country', 'US'))], [new Partition( + 'country', + 'US', + )])); + $writer->close(); + + $batches = iterator_to_array( + (new FloeReader($filesystem)) + ->read($path) + ->rows(offset: 1), + ); + + static::assertSame([2], array_map(static fn($row) => $row->valueOf('id'), $batches[0]->all())); + static::assertEquals([new Partition('country', 'US')], iterator_to_array($batches[0]->partitions())); + } + + public function test_recover_tracks_per_section_partitions(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://recover-multi-combination.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write(Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )])); + $writer->write(Rows::partitioned([row(int_entry('id', 2), str_entry('country', 'US'))], [new Partition( + 'country', + 'US', + )])); + $writer->close(); + + $combos = []; + + foreach ((new FloeReader($filesystem)) + ->read($path) + ->recover() as $batch) { + $combos[] = array_map(static fn(Partition $p): string => $p->value, $batch->partitions()->toArray()); + } + + static::assertSame([['PL'], ['US']], $combos); + } + public function test_reader_with_mismatched_codec_flags_throws(): void { $filesystem = memory_filesystem(); @@ -665,7 +780,7 @@ public function test_recover_stops_at_corrupt_row_body(): void { $filesystem = memory_filesystem(); $path = path('memory://recover-corrupt-row.floe'); - $schemaBody = FloeWriter::growSectionPlan(null, row(int_entry('id', 1)))->schemaBody; + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); $stream = $filesystem->writeTo($path); $stream->append( Format::header(0x00) . Format::frame(Format::FRAME_SCHEMA, $schemaBody) @@ -706,7 +821,7 @@ public function test_recover_stops_at_unknown_frame_type(): void $filesystem = memory_filesystem(); $path = path('memory://recover-unknown.floe'); - FloeFileContext::writeWithoutFooter($filesystem, $path, rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::writeWithoutFooter($filesystem, $path, rows(row(int_entry('id', 1)))); $filesystem->appendTo($path)->append(Format::frame(0x55, 'mystery'))->close(); @@ -725,7 +840,7 @@ public function test_recover_reads_partitions_from_frame(): void $filesystem = memory_filesystem(); $path = path('memory://recover-partitions.floe'); - FloeFileContext::writeWithoutFooter( + FloeStreamReaderContext::writeWithoutFooter( $filesystem, $path, Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition('country', 'PL')]), @@ -746,7 +861,11 @@ public function test_recover_salvages_rows_from_file_missing_close(): void $filesystem = memory_filesystem(); $path = path('memory://torn.floe'); - FloeFileContext::writeWithoutFooter($filesystem, $path, rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); + FloeStreamReaderContext::writeWithoutFooter( + $filesystem, + $path, + rows(row(int_entry('id', 1)), row(int_entry('id', 2))), + ); $reader = (new FloeReader($filesystem))->read($path); $batches = iterator_to_array($reader->recover()); @@ -768,7 +887,7 @@ public function test_recover_salvages_complete_frames_from_truncated_tail(): voi $content = $filesystem->readFrom($path)->content(); $truncated = path('memory://truncated.floe'); $stream = $filesystem->writeTo($truncated); - $stream->append(substr($content, 0, strlen($content) - 320)); + $stream->append(substr($content, 0, strlen($content) - 192)); $stream->close(); $salvaged = iterator_to_array( @@ -786,16 +905,22 @@ public function test_recover_yields_rows_as_written_without_padding(): void $filesystem = memory_filesystem(); $path = path('memory://recover-evolved.floe'); + // a multi-schema file is what FloeMerger produces (schema evolution lives in merge, not the writer) + $baseFile = path('memory://recover-base.floe'); + $evolvedFile = path('memory://recover-new.floe'); + $writer = new FloeWriter($filesystem); - $writer->create($path); + $writer->create($baseFile); $writer->write(rows(row(int_entry('id', 1)))); $writer->close(); $writer = new FloeWriter($filesystem); - $writer->append($path); + $writer->create($evolvedFile); $writer->write(rows(row(int_entry('id', 2), str_entry('email', null)))); $writer->close(); + (new FloeMerger($filesystem))->merge([$baseFile, $evolvedFile], $path); + $rows = []; foreach ((new FloeReader($filesystem)) @@ -831,11 +956,13 @@ public function test_recover_stops_at_row_body_longer_than_hydrated_content(): v { $filesystem = memory_filesystem(); $path = path('memory://recover-long-row.floe'); - $plan = FloeWriter::growSectionPlan(null, row(int_entry('id', 1))); - $rowBody = (new RowEncoder())->encode($plan, row(int_entry('id', 1))); + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); + $rowBody = (new PhpFloeEncoder(schema_from_json( + $schemaBody, + )))->encode((new AdaptiveRowHydrator())->dehydrate(rows(row(int_entry('id', 1)))))[0]; $stream = $filesystem->writeTo($path); $stream->append( - Format::header(0x00) . Format::frame(Format::FRAME_SCHEMA, $plan->schemaBody) + Format::header(0x00) . Format::frame(Format::FRAME_SCHEMA, $schemaBody) . Format::frame(Format::FRAME_ROW, $rowBody . 'extra-bytes'), ); $stream->close(); @@ -850,75 +977,6 @@ public function test_recover_stops_at_row_body_longer_than_hydrated_content(): v ); } - public function test_rows_of_file_replaced_after_footer_load_with_different_codec_throws(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://swapped-flags.floe'); - - $writer = new FloeWriter($filesystem); - $writer->create($path); - $writer->write(rows(row(int_entry('id', 1)))); - $writer->close(); - - $reader = (new FloeReader($filesystem))->read($path); - $reader->footer(); - - $stream = $filesystem->writeTo($path); - $stream->append(Format::header(0x05) . Format::frame(Format::FRAME_ROW, 'x')); - $stream->close(); - - $this->expectException(FloeException::class); - $this->expectExceptionMessage('written with codec 0x05'); - - iterator_to_array($reader->rows()); - } - - public function test_rows_of_file_replaced_after_footer_load_with_torn_frame_throws(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://swapped-torn.floe'); - - $writer = new FloeWriter($filesystem); - $writer->create($path); - $writer->write(rows(row(int_entry('id', 1)))); - $writer->close(); - - $reader = (new FloeReader($filesystem))->read($path); - $reader->footer(); - - $stream = $filesystem->writeTo($path); - $stream->append(Format::header(0x00) . "\x02\xFF"); - $stream->close(); - - $this->expectException(FloeException::class); - $this->expectExceptionMessage('frame header is incomplete'); - - iterator_to_array($reader->rows()); - } - - public function test_rows_of_file_truncated_below_header_after_footer_load_throws(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://swapped-short.floe'); - - $writer = new FloeWriter($filesystem); - $writer->create($path); - $writer->write(rows(row(int_entry('id', 1)))); - $writer->close(); - - $reader = (new FloeReader($filesystem))->read($path); - $reader->footer(); - - $stream = $filesystem->writeTo($path); - $stream->append('FLO'); - $stream->close(); - - $this->expectException(FloeException::class); - $this->expectExceptionMessage('header is incomplete'); - - iterator_to_array($reader->rows()); - } - public function test_rows_through_a_custom_identity_codec(): void { $filesystem = memory_filesystem(); @@ -943,13 +1001,15 @@ public function test_rows_through_a_custom_identity_codec_with_long_row_body_thr { $filesystem = memory_filesystem(); $path = path('memory://custom-codec-long-row.floe'); - $plan = FloeWriter::growSectionPlan(null, row(int_entry('id', 1))); - $rowBody = (new RowEncoder())->encode($plan, row(int_entry('id', 1))); - $footerJson = FooterMother::footer()->toJson(); + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); + $rowBody = (new PhpFloeEncoder(schema_from_json( + $schemaBody, + )))->encode((new AdaptiveRowHydrator())->dehydrate(rows(row(int_entry('id', 1)))))[0]; + $footerJson = FooterMother::footer(schema: row(int_entry('id', 1))->schema()->normalize())->toJson(); $stream = $filesystem->writeTo($path); $stream->append( Format::header(0x00) - . Format::frame(Format::FRAME_SCHEMA, $plan->schemaBody) + . Format::frame(Format::FRAME_SCHEMA, $schemaBody) . Format::frame(Format::FRAME_ROW, $rowBody . 'extra-bytes') . Format::frame(Format::FRAME_FOOTER, $footerJson . Format::trailer(strlen($footerJson))), ); @@ -965,7 +1025,7 @@ public function test_rows_through_a_custom_identity_codec_with_long_row_body_thr ); } - public function test_row_frame_before_schema_frame_throws(): void + public function test_row_frame_not_described_by_the_footer_schema_throws(): void { $filesystem = memory_filesystem(); $path = path('memory://row-first.floe'); @@ -978,7 +1038,30 @@ public function test_row_frame_before_schema_frame_throws(): void $stream->close(); $this->expectException(FloeException::class); - $this->expectExceptionMessage('row frame before any schema frame'); + $this->expectExceptionMessage('row frame length does not match its content'); + + iterator_to_array( + (new FloeReader($filesystem)) + ->read($path) + ->rows(), + ); + } + + public function test_schema_frame_not_matching_the_footer_schema_throws(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://drifted-schema-frame.floe'); + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); + $footerJson = FooterMother::footer(schema: row(str_entry('name', 'a'))->schema()->normalize())->toJson(); + $stream = $filesystem->writeTo($path); + $stream->append( + Format::header(0x00) . Format::frame(Format::FRAME_SCHEMA, $schemaBody) + . Format::frame(Format::FRAME_FOOTER, $footerJson . Format::trailer(strlen($footerJson))), + ); + $stream->close(); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('Floe found a schema frame that does not match the file schema'); iterator_to_array( (new FloeReader($filesystem)) @@ -991,13 +1074,15 @@ public function test_row_body_longer_than_hydrated_content_throws(): void { $filesystem = memory_filesystem(); $path = path('memory://long-row.floe'); - $plan = FloeWriter::growSectionPlan(null, row(int_entry('id', 1))); - $rowBody = (new RowEncoder())->encode($plan, row(int_entry('id', 1))); - $footerJson = FooterMother::footer()->toJson(); + $schemaBody = FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema()); + $rowBody = (new PhpFloeEncoder(schema_from_json( + $schemaBody, + )))->encode((new AdaptiveRowHydrator())->dehydrate(rows(row(int_entry('id', 1)))))[0]; + $footerJson = FooterMother::footer(schema: row(int_entry('id', 1))->schema()->normalize())->toJson(); $stream = $filesystem->writeTo($path); $stream->append( Format::header(0x00) - . Format::frame(Format::FRAME_SCHEMA, $plan->schemaBody) + . Format::frame(Format::FRAME_SCHEMA, $schemaBody) . Format::frame(Format::FRAME_ROW, $rowBody . 'extra-bytes') . Format::frame(Format::FRAME_FOOTER, $footerJson . Format::trailer(strlen($footerJson))), ); @@ -1018,7 +1103,7 @@ public function test_torn_file_without_footer_throws_in_strict_mode(): void $filesystem = memory_filesystem(); $path = path('memory://strict-torn.floe'); - FloeFileContext::writeWithoutFooter($filesystem, $path, rows(row(int_entry('id', 1)))); + FloeStreamReaderContext::writeWithoutFooter($filesystem, $path, rows(row(int_entry('id', 1)))); $this->expectException(FloeException::class); $this->expectExceptionMessage('magic'); @@ -1135,6 +1220,9 @@ public function test_head_non_positive_count_throws(): void { $filesystem = memory_filesystem(); $path = path('memory://head-zero.floe'); + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->close(); $this->expectException(FloeException::class); $this->expectExceptionMessage('head count must be greater than 0'); @@ -1275,6 +1363,9 @@ public function test_tail_non_positive_count_throws(): void { $filesystem = memory_filesystem(); $path = path('memory://tail-zero.floe'); + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->close(); $this->expectException(FloeException::class); $this->expectExceptionMessage('tail count must be greater than 0'); diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeSerializerTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeSerializerTest.php index 2ec7eaa2c9..bf40fc465c 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeSerializerTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeSerializerTest.php @@ -6,113 +6,190 @@ use Flow\ETL\Row; use Flow\ETL\Rows; +use Flow\Filesystem\Partition; +use Flow\Floe\Exception\FloeException; use Flow\Floe\FloeSerializer; +use Flow\Floe\Format; use Flow\Floe\Tests\Mother\RowsMother; use Flow\Serializer\Exception\SerializationException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -use stdClass; +use function array_map; use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; +use function Flow\Serializer\DSL\serialize_to_string; +use function Flow\Serializer\DSL\unserialize_from_string; +use function range; +use function str_replace; final class FloeSerializerTest extends TestCase { + /** + * @return array + */ + public static function values(): array + { + return [ + 'single row' => [rows(row(int_entry('id', 1), str_entry('name', 'John')))], + 'rows' => [rows(row(int_entry('id', 1)), row(int_entry('id', 2)))], + 'partitioned rows' => [RowsMother::partitioned()], + 'heterogeneous rows' => [RowsMother::heterogeneous()], + 'all entry types' => [RowsMother::withAllEntryTypes()], + 'empty rows' => [rows()], + 'empty partitioned rows' => [Rows::partitioned([], [new Partition('country', 'PL')])], + ]; + } + + /** + * Heterogeneous rows no longer round-trip byte-for-type-exact: one write + * session carries one schema, so absent-in-some-row columns widen to nullable. + * That residue is covered by test_heterogeneous_rows_round_trip_unpadded_but_union_widened. + * + * @return array + */ + public static function exactRoundTripValues(): array + { + $values = self::values(); + unset($values['heterogeneous rows']); + + return $values; + } + + #[DataProvider('exactRoundTripValues')] + public function test_serialize_unserialize_round_trip(Rows $value): void + { + $serializer = new FloeSerializer(); + + static::assertEquals($value, unserialize_from_string($serializer, serialize_to_string($serializer, $value))); + } + public function test_streaming_mode_round_trip(): void { $serializer = new FloeSerializer(2); $value = RowsMother::withAllEntryTypes(); - static::assertEquals($value, $serializer->unserialize( - $serializer->serialize($value), - [Row::class, Rows::class], - )); + static::assertEquals($value, unserialize_from_string($serializer, serialize_to_string($serializer, $value))); } public function test_streaming_serialization_is_byte_identical_to_bulk(): void { $value = RowsMother::heterogeneous(); - static::assertSame((new FloeSerializer(1))->serialize($value), (new FloeSerializer())->serialize($value)); + static::assertSame( + serialize_to_string(new FloeSerializer(1), $value), + serialize_to_string(new FloeSerializer(), $value), + ); } - public function test_round_trip_all_entry_types(): void + public function test_heterogeneous_rows_round_trip_unpadded_but_union_widened(): void { $serializer = new FloeSerializer(); - $value = RowsMother::withAllEntryTypes(); + // one write session = one schema: rows keep their own columns (unpadded) but + // entry types widen to the batch union - id and name become nullable because + // each is absent from some row. Values are unchanged; only nullability widens. + $value = rows( + row(int_entry('id', 1)), + row(int_entry('id', 2), str_entry('name', 'John')), + row(str_entry('name', 'Jane')), + ); + + $result = unserialize_from_string($serializer, serialize_to_string($serializer, $value)); + + static::assertSame($value->toArray(), $result->toArray()); + static::assertTrue($result->schema()->findDefinition('id')?->isNullable()); + static::assertTrue($result->schema()->findDefinition('name')?->isNullable()); + } - static::assertEquals($value, $serializer->unserialize( - $serializer->serialize($value), - [Row::class, Rows::class], - )); + #[DataProvider('values')] + public function test_batch_size_does_not_change_bytes(Rows $value): void + { + static::assertSame( + serialize_to_string(new FloeSerializer(1), $value), + serialize_to_string(new FloeSerializer(), $value), + ); } - public function test_round_trip_empty_rows(): void + #[DataProvider('exactRoundTripValues')] + public function test_batch_sizes_decode_each_others_bytes(Rows $value): void { - $serializer = new FloeSerializer(); + $small = new FloeSerializer(1); + $default = new FloeSerializer(); - static::assertEquals(rows(), $serializer->unserialize( - $serializer->serialize(rows()), - [Row::class, Rows::class], - )); + static::assertEquals($value, unserialize_from_string($default, serialize_to_string($small, $value))); + static::assertEquals($value, unserialize_from_string($small, serialize_to_string($default, $value))); } - public function test_round_trip_partitioned_rows(): void + public function test_batch_size_smaller_than_row_count(): void { - $serializer = new FloeSerializer(); - $value = RowsMother::partitioned(); + $serializer = new FloeSerializer(3); + $value = rows(...array_map(static fn(int $id): Row => row(int_entry('id', $id)), range(1, 10))); - static::assertEquals($value, $serializer->unserialize( - $serializer->serialize($value), - [Row::class, Rows::class], - )); + static::assertSame(serialize_to_string(new FloeSerializer(), $value), serialize_to_string($serializer, $value)); + static::assertEquals($value, unserialize_from_string($serializer, serialize_to_string($serializer, $value))); } - public function test_round_trip_row(): void + public function test_batch_size_larger_than_row_count(): void { - $serializer = new FloeSerializer(); - $value = row(int_entry('id', 1), str_entry('name', 'John')); + $serializer = new FloeSerializer(100); + $value = rows(row(int_entry('id', 1)), row(int_entry('id', 2))); + + static::assertEquals($value, unserialize_from_string($serializer, serialize_to_string($serializer, $value))); + } - $result = $serializer->unserialize($serializer->serialize($value), [Row::class, Rows::class]); + public function test_batch_size_below_one_throws(): void + { + $this->expectException(FloeException::class); + $this->expectExceptionMessage('Serializer batch size must be at least 1'); - static::assertInstanceOf(Row::class, $result); - static::assertEquals($value, $result); + // @mago-ignore analysis:invalid-argument + new FloeSerializer(0); } - public function test_round_trip_rows(): void + public function test_unserialize_rejects_torn_bytes(): void { - $serializer = new FloeSerializer(); - $value = rows(row(int_entry('id', 1)), row(int_entry('id', 2))); + $this->expectException(SerializationException::class); - static::assertEquals($value, $serializer->unserialize( - $serializer->serialize($value), - [Row::class, Rows::class], - )); + unserialize_from_string(new FloeSerializer(), 'not a valid floe payload'); } - public function test_serialize_rejects_other_objects(): void + public function test_unserialize_rejects_empty_payload(): void { $this->expectException(SerializationException::class); - $this->expectExceptionMessage('FloeSerializer supports only Rows and Row'); + $this->expectExceptionMessage('too small'); - (new FloeSerializer())->serialize(new stdClass()); + unserialize_from_string(new FloeSerializer(), ''); } - public function test_unserialize_rejects_torn_bytes(): void + public function test_unserialize_rejects_row_count_mismatch(): void { + $bytes = serialize_to_string(new FloeSerializer(), rows(row(int_entry('id', 1)))); + // inflate the footer's totalRows while the body still holds a single row; the JSON + // byte-length is unchanged (1 -> 2) so the trailer stays valid and the read reaches + // the whole-value row-count guard + $corrupted = str_replace('"totalRows":1', '"totalRows":2', $bytes); + $this->expectException(SerializationException::class); + $this->expectExceptionMessage('decoded 1 of 2 rows'); - (new FloeSerializer())->unserialize('not a floe file', [Row::class, Rows::class]); + unserialize_from_string(new FloeSerializer(), $corrupted); } - public function test_unserialize_rejects_unexpected_class(): void + public function test_unserialize_rejects_payload_smaller_than_header_and_trailer(): void { - $serializer = new FloeSerializer(); + $this->expectException(SerializationException::class); + $this->expectExceptionMessage('too small'); + + unserialize_from_string(new FloeSerializer(), 'tiny'); + } + public function test_unserialize_rejects_footer_that_does_not_fit(): void + { $this->expectException(SerializationException::class); - $this->expectExceptionMessage('must return instance of'); + $this->expectExceptionMessage('footer does not fit'); - $serializer->unserialize($serializer->serialize(rows(row(int_entry('id', 1)))), [Row::class]); + unserialize_from_string(new FloeSerializer(), Format::header(0x00) . Format::trailer(1000)); } } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeStreamWriterTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeStreamWriterTest.php new file mode 100644 index 0000000000..0eb3a599f2 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeStreamWriterTest.php @@ -0,0 +1,245 @@ +create($viaCreate); + $create->write($data); + $create->close(); + + $onStream = new FloeStreamWriter(); + $onStream->create($filesystem->writeTo($viaStream)); + $onStream->write($data); + $onStream->close(); + + static::assertSame($filesystem->readFrom($viaCreate)->content(), $filesystem->readFrom($viaStream)->content()); + } + + public function test_small_buffer_size_produces_byte_identical_output(): void + { + $filesystem = memory_filesystem(); + $default = path('memory://default-buffer.floe'); + $tiny = path('memory://tiny-buffer.floe'); + $data = rows( + row(int_entry('id', 1), str_entry('name', 'alpha')), + row(int_entry('id', 2), str_entry('name', 'beta')), + row(int_entry('id', 3), str_entry('name', 'gamma')), + ); + + $defaultWriter = new FloeStreamWriter(); + $defaultWriter->create($filesystem->writeTo($default)); + $defaultWriter->write($data); + $defaultWriter->close(); + + $tinyWriter = new FloeStreamWriter(bufferSize: 4); + $tinyWriter->create($filesystem->writeTo($tiny)); + $tinyWriter->write($data); + $tinyWriter->close(); + + static::assertSame($filesystem->readFrom($default)->content(), $filesystem->readFrom($tiny)->content()); + } + + public function test_create_on_stream_round_trips(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://on-stream.floe'); + + $writer = new FloeStreamWriter(); + $writer->create($filesystem->writeTo($path), Metadata::fromArray(['source' => 'stream'])); + $writer->write(rows(row(int_entry('id', 1)), row(int_entry('id', 2)), row(int_entry('id', 3)))); + $writer->close(); + + $footer = FloeStreamReaderContext::footer($filesystem, $path); + + static::assertSame(3, $footer->totalRows); + static::assertSame(['source' => 'stream'], $footer->metadata->normalize()); + static::assertSame( + [Format::FRAME_SCHEMA, Format::FRAME_ROW, Format::FRAME_ROW, Format::FRAME_ROW, Format::FRAME_FOOTER], + FloeStreamReaderContext::frameTypes($filesystem, $path), + ); + } + + public function test_construct_with_non_noop_codec_throws(): void + { + $this->expectException(FloeException::class); + $this->expectExceptionMessage('supports only the no-op codec, got codec 0x05'); + + new FloeStreamWriter(new CodecStub(0x05)); + } + + public function test_creating_a_second_session_throws(): void + { + $writer = new FloeStreamWriter(); + $writer->create(memory_filesystem()->writeTo(path('memory://first.floe'))); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('Floe writer session is already open'); + + $writer->create(memory_filesystem()->writeTo(path('memory://second.floe'))); + } + + public function test_write_before_create_throws(): void + { + $writer = new FloeStreamWriter(); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('Floe writer session is not open'); + + $writer->write(rows(row(int_entry('id', 1)))); + } + + public function test_aligned_multi_batch_session_is_byte_identical_to_a_single_batch(): void + { + $filesystem = memory_filesystem(); + $multi = path('memory://multi-batch.floe'); + $single = path('memory://single-batch.floe'); + + $multiWriter = new FloeStreamWriter(); + $multiWriter->create($filesystem->writeTo($multi)); + $multiWriter->write(rows(row(int_entry('id', 1), str_entry('name', 'a')))); + $multiWriter->write(rows(row(int_entry('id', 2), str_entry('name', 'b')))); + $multiWriter->close(); + + $singleWriter = new FloeStreamWriter(); + $singleWriter->create($filesystem->writeTo($single)); + $singleWriter->write(rows( + row(int_entry('id', 1), str_entry('name', 'a')), + row(int_entry('id', 2), str_entry('name', 'b')), + )); + $singleWriter->close(); + + static::assertSame($filesystem->readFrom($single)->content(), $filesystem->readFrom($multi)->content()); + + $footer = FloeStreamReaderContext::footer($filesystem, $multi); + static::assertNotSame([], $footer->schema); + static::assertCount(1, $footer->sections); + } + + public function test_subset_column_batch_is_accepted_and_round_trips(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://subset.floe'); + + $writer = new FloeStreamWriter(); + $writer->create($filesystem->writeTo($path)); + $writer->write(rows(row(int_entry('id', 1), str_entry('name', 'a')))); + $writer->write(rows(row(int_entry('id', 2)))); + $writer->close(); + + $footer = FloeStreamReaderContext::footer($filesystem, $path); + static::assertSame(2, $footer->totalRows); + static::assertNotSame([], $footer->schema); + static::assertCount(2, FloeStreamReaderContext::readAll($filesystem, $path)->all()); + } + + public function test_batch_introducing_a_new_column_throws_naming_the_column(): void + { + $writer = new FloeStreamWriter(); + $writer->create(memory_filesystem()->writeTo(path('memory://new-column.floe'))); + $writer->write(rows(row(int_entry('id', 1)))); + + $this->expectException(IncompatibleSchemaException::class); + $this->expectExceptionMessage('new column "email"'); + + $writer->write(rows(row(int_entry('id', 2), str_entry('email', 'x')))); + } + + public function test_batch_with_an_incompatible_type_throws_naming_the_column(): void + { + $writer = new FloeStreamWriter(); + $writer->create(memory_filesystem()->writeTo(path('memory://type-drift.floe'))); + $writer->write(rows(row(int_entry('id', 1)))); + + $this->expectException(IncompatibleSchemaException::class); + $this->expectExceptionMessage('column "id"'); + + $writer->write(rows(row(str_entry('id', 'x')))); + } + + public function test_new_column_message_hints_at_data_frame_match(): void + { + $writer = new FloeStreamWriter(); + $writer->create(memory_filesystem()->writeTo(path('memory://hint.floe'))); + $writer->write(rows(row(int_entry('id', 1)))); + + $this->expectException(IncompatibleSchemaException::class); + $this->expectExceptionMessage('DataFrame::match'); + + $writer->write(rows(row(int_entry('id', 2), str_entry('email', 'x')))); + } + + public function test_explicit_session_schema_is_used_for_the_footer(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://explicit-schema.floe'); + + $writer = new FloeStreamWriter(); + $writer->create($filesystem->writeTo($path), schema: schema(int_schema('id'), str_schema('name'))); + $writer->write(rows(row(int_entry('id', 1), str_entry('name', 'a')))); + $writer->close(); + + $fileSchema = FloeStreamReaderContext::footer($filesystem, $path)->schema(); + static::assertNotNull($fileSchema->findDefinition('id')); + static::assertNotNull($fileSchema->findDefinition('name')); + } + + public function test_empty_batch_writes_no_schema_or_section(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://empty.floe'); + + $writer = new FloeStreamWriter(); + $writer->create($filesystem->writeTo($path)); + $writer->write(rows()); + $writer->close(); + + static::assertSame([Format::FRAME_FOOTER], FloeStreamReaderContext::frameTypes($filesystem, $path)); + + $footer = FloeStreamReaderContext::footer($filesystem, $path); + static::assertSame(0, $footer->totalRows); + static::assertSame([], $footer->schema); + static::assertCount(0, $footer->sections); + } + + public function test_writing_a_column_name_with_invalid_utf8_throws(): void + { + $writer = new FloeStreamWriter(); + $writer->create(memory_filesystem()->writeTo(path('memory://bad-name.floe'))); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('failed to encode schema as JSON'); + + $writer->write(rows(row(str_entry("bad\xFFname", 'x')))); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeValueRoundTripTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeValueRoundTripTest.php index d8952844c4..b48093bbfa 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeValueRoundTripTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeValueRoundTripTest.php @@ -9,10 +9,9 @@ use DateTimeImmutable; use DateTimeZone; use Flow\ETL\Row; -use Flow\ETL\Row\Entry\StringEntry; use Flow\ETL\Tests\Fixtures\Enum\BackedStringEnum; use Flow\ETL\Tests\Fixtures\Enum\BasicEnum; -use Flow\Floe\Tests\Context\FloeFileContext; +use Flow\Floe\Tests\Context\FloeStreamReaderContext; use Flow\Types\Value\Json; use Flow\Types\Value\Uuid; use PHPUnit\Framework\Attributes\RequiresPhp; @@ -29,6 +28,7 @@ use function Flow\ETL\DSL\json_object_entry; use function Flow\ETL\DSL\list_entry; use function Flow\ETL\DSL\map_entry; +use function Flow\ETL\DSL\null_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; @@ -76,7 +76,7 @@ public function test_datetime_entries(): void datetime_entry('before_epoch', new DateTimeImmutable('1969-07-20 20:17:00 UTC')), date_entry('date', new DateTimeImmutable('2025-06-15', new DateTimeZone('Europe/Warsaw'))), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -87,7 +87,7 @@ public function test_entries_with_null_values(): void float_entry('float', null), bool_entry('bool', null), str_entry('str', null), - StringEntry::fromNull('from_null'), + null_entry('from_null'), list_entry('list', null, type_list(type_integer())), map_entry('map', null, type_map(type_string(), type_integer())), json_entry('json', null), @@ -98,14 +98,14 @@ enum_entry('enum', null), xml_entry('xml', null), )); - static::assertEquals($rows, FloeFileContext::roundTrip($rows)); + static::assertEquals($rows, FloeStreamReaderContext::roundTrip($rows)); } public function test_enum_entries(): void { static::assertEquals( $rows = rows(row(enum_entry('backed', BackedStringEnum::two), enum_entry('basic', BasicEnum::three))), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -116,7 +116,7 @@ public function test_html_entries(): void static::assertSame( $rows->first()->entries()['html']->toString(), - FloeFileContext::roundTrip($rows)->first()->entries()['html']->toString(), + FloeStreamReaderContext::roundTrip($rows)->first()->entries()['html']->toString(), ); } @@ -137,7 +137,7 @@ public function test_interval_entries(): void time_entry('fractional', $fractional), time_entry('days', new DateInterval('P3D')), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -150,7 +150,7 @@ public function test_json_entries(): void json_object_entry('empty_object', '{}'), json_entry('empty_list', '[]'), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -168,7 +168,7 @@ public function test_list_entries(): void list_entry('mixed', [1, 'two', 3.5, null, true, ['nested' => 'array']], type_list(type_mixed())), list_entry('list_of_lists', [[1, 2], [3]], type_list(type_list(type_integer()))), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -185,7 +185,7 @@ public function test_map_entries(): void ), map_entry('empty', [], type_map(type_string(), type_integer())), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -201,7 +201,7 @@ public function test_mixed_values_with_uuid_json_and_datetime(): void ], type_list(type_mixed()), ))), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -221,7 +221,7 @@ public function test_scalar_entries(): void str_entry('string_binary', "line\nbreak\x00null\xFFbyte"), str_entry('string_unicode', 'zażółć gęślą jaźń 🚀'), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -263,7 +263,7 @@ public function test_structure_entries(): void ])), structure_entry('with_null_type', ['nothing' => null], type_structure(['nothing' => type_null()])), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -271,7 +271,7 @@ public function test_uuid_entries(): void { static::assertEquals( $rows = rows(row(uuid_entry('uuid', '0196aecb-b568-7e57-a381-8ec8d3e4a531'))), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } @@ -282,7 +282,7 @@ public function test_xml_entries(): void xml_entry('xml', 'text & entity'), xml_element_entry('element', 'value'), )), - FloeFileContext::roundTrip($rows), + FloeStreamReaderContext::roundTrip($rows), ); } } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeValueSerializerTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeValueSerializerTest.php deleted file mode 100644 index 50a233d913..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeValueSerializerTest.php +++ /dev/null @@ -1,163 +0,0 @@ - - */ - public static function values(): array - { - return [ - 'row' => [row(int_entry('id', 1), str_entry('name', 'John'))], - 'rows' => [rows(row(int_entry('id', 1)), row(int_entry('id', 2)))], - 'partitioned rows' => [RowsMother::partitioned()], - 'heterogeneous rows' => [RowsMother::heterogeneous()], - 'all entry types' => [RowsMother::withAllEntryTypes()], - 'empty rows' => [rows()], - 'empty partitioned rows' => [Rows::partitioned([], [new Partition('country', 'PL')])], - ]; - } - - #[DataProvider('values')] - public function test_batch_size_does_not_change_bytes(Row|Rows $value): void - { - static::assertSame((new FloeValueSerializer(1))->encode($value), (new FloeValueSerializer())->encode($value)); - } - - #[DataProvider('values')] - public function test_batch_sizes_decode_each_others_bytes(Row|Rows $value): void - { - $small = new FloeValueSerializer(1); - $default = new FloeValueSerializer(); - - static::assertEquals($value, $default->decode($small->encode($value))); - static::assertEquals($value, $small->decode($default->encode($value))); - } - - public function test_decode_rejects_torn_bytes(): void - { - $this->expectException(FloeException::class); - - (new FloeValueSerializer())->decode('not a valid floe payload'); - } - - public function test_decode_rejects_payload_smaller_than_header_and_trailer(): void - { - $this->expectException(FloeException::class); - $this->expectExceptionMessage('too small'); - - (new FloeValueSerializer())->decode('tiny'); - } - - public function test_decode_rejects_footer_that_does_not_fit(): void - { - $this->expectException(FloeException::class); - $this->expectExceptionMessage('footer does not fit'); - - (new FloeValueSerializer())->decode(Format::header(0x00) . Format::trailer(1000)); - } - - public function test_batch_size_smaller_than_row_count(): void - { - $codec = new FloeValueSerializer(3); - $value = rows(...array_map(static fn(int $id): Row => row(int_entry('id', $id)), range(1, 10))); - - static::assertSame((new FloeValueSerializer())->encode($value), $codec->encode($value)); - static::assertEquals($value, $codec->decode($codec->encode($value))); - } - - public function test_batch_size_larger_than_row_count(): void - { - $codec = new FloeValueSerializer(100); - $value = rows(row(int_entry('id', 1)), row(int_entry('id', 2))); - - static::assertEquals($value, $codec->decode($codec->encode($value))); - } - - #[DataProvider('values')] - public function test_round_trip(Row|Rows $value): void - { - $codec = new FloeValueSerializer(); - - static::assertEquals($value, $codec->decode($codec->encode($value))); - } - - public function test_heterogeneous_rows_round_trip_exactly_unpadded(): void - { - $codec = new FloeValueSerializer(); - // rows with different schemas must come back as written - NOT padded to a merged schema - $value = rows( - row(int_entry('id', 1)), - row(int_entry('id', 2), str_entry('name', 'John')), - row(str_entry('name', 'Jane')), - ); - - static::assertEquals($value, $codec->decode($codec->encode($value))); - } - - public function test_round_trip_all_entry_types(): void - { - $codec = new FloeValueSerializer(); - $value = RowsMother::withAllEntryTypes(); - - static::assertEquals($value, $codec->decode($codec->encode($value))); - } - - public function test_round_trip_empty_rows(): void - { - $codec = new FloeValueSerializer(); - - static::assertEquals(rows(), $codec->decode($codec->encode(rows()))); - } - - public function test_round_trip_partitioned_rows(): void - { - $codec = new FloeValueSerializer(); - $value = RowsMother::partitioned(); - - static::assertEquals($value, $codec->decode($codec->encode($value))); - } - - public function test_round_trip_row(): void - { - $codec = new FloeValueSerializer(); - $value = row(int_entry('id', 1), str_entry('name', 'John')); - - $result = $codec->decode($codec->encode($value)); - - static::assertInstanceOf(Row::class, $result); - static::assertEquals($value, $result); - } - - public function test_round_trip_rows(): void - { - $codec = new FloeValueSerializer(); - $value = rows(row(int_entry('id', 1)), row(int_entry('id', 2))); - - $result = $codec->decode($codec->encode($value)); - - static::assertInstanceOf(Rows::class, $result); - static::assertEquals($value, $result); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeWriterTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeWriterTest.php index 6b0172c9e8..3b3d307054 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeWriterTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FloeWriterTest.php @@ -11,17 +11,16 @@ use Flow\Floe\Exception\IncompatibleSchemaException; use Flow\Floe\FloeWriter; use Flow\Floe\Format; -use Flow\Floe\Tests\Context\FloeFileContext; +use Flow\Floe\Tests\Context\FloeStreamReaderContext; use Flow\Floe\Tests\Double\CodecStub; use Flow\Floe\Tests\Double\UnsizedFilesystem; use PHPUnit\Framework\TestCase; -use function array_map; -use function array_values; -use function Flow\ETL\DSL\float_entry; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\int_schema; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\rows; +use function Flow\ETL\DSL\schema; use function Flow\ETL\DSL\str_entry; use function Flow\Filesystem\DSL\memory_filesystem; use function Flow\Filesystem\DSL\path; @@ -30,6 +29,49 @@ final class FloeWriterTest extends TestCase { + public function test_create_for_stream_is_byte_identical_to_create_by_path(): void + { + $filesystem = memory_filesystem(); + $viaPath = path('memory://via-path.floe'); + $viaStream = path('memory://via-stream.floe'); + $data = rows(row(int_entry('id', 1), str_entry('name', 'a')), row(int_entry('id', 2), str_entry('name', 'b'))); + + $byPath = new FloeWriter($filesystem); + $byPath->create($viaPath); + $byPath->write($data); + $byPath->close(); + + $byStream = new FloeWriter($filesystem); + $byStream->createForStream($filesystem->writeTo($viaStream)); + $byStream->write($data); + $byStream->close(); + + static::assertSame($filesystem->readFrom($viaPath)->content(), $filesystem->readFrom($viaStream)->content()); + } + + public function test_buffer_size_only_changes_flush_cadence_not_bytes(): void + { + $filesystem = memory_filesystem(); + $default = path('memory://default-buffer.floe'); + $tiny = path('memory://tiny-buffer.floe'); + $data = rows( + row(int_entry('id', 1), str_entry('name', 'alpha')), + row(int_entry('id', 2), str_entry('name', 'beta')), + ); + + $defaultWriter = new FloeWriter($filesystem); + $defaultWriter->create($default); + $defaultWriter->write($data); + $defaultWriter->close(); + + $tinyWriter = new FloeWriter($filesystem, bufferSize: 4); + $tinyWriter->create($tiny); + $tinyWriter->write($data); + $tinyWriter->close(); + + static::assertSame($filesystem->readFrom($default)->content(), $filesystem->readFrom($tiny)->content()); + } + public function test_append_on_missing_file_behaves_like_create(): void { $filesystem = memory_filesystem(); @@ -40,7 +82,7 @@ public function test_append_on_missing_file_behaves_like_create(): void $writer->write(rows(row(int_entry('id', 1)))); $writer->close(); - static::assertSame(1, FloeFileContext::footer($filesystem, $path)->totalRows); + static::assertSame(1, FloeStreamReaderContext::footer($filesystem, $path)->totalRows); } public function test_append_on_empty_file_behaves_like_create(): void @@ -54,7 +96,57 @@ public function test_append_on_empty_file_behaves_like_create(): void $writer->write(rows(row(int_entry('id', 1)))); $writer->close(); - static::assertSame(1, FloeFileContext::footer($filesystem, $path)->totalRows); + static::assertSame(1, FloeStreamReaderContext::footer($filesystem, $path)->totalRows); + } + + public function test_append_to_a_closed_zero_row_file_derives_the_schema_from_the_first_batch(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://zero-rows.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->close(); + + $writer = new FloeWriter($filesystem); + $writer->append($path); + $writer->write(rows(row(int_entry('id', 1)))); + $writer->close(); + + static::assertSame([['id' => 1]], FloeStreamReaderContext::readAll($filesystem, $path)->toArray()); + } + + public function test_append_to_a_zero_row_file_with_an_explicit_schema_validates_against_it(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://zero-rows-schema.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path, schema: schema(int_schema('id'))); + $writer->close(); + + $writer = new FloeWriter($filesystem); + $writer->append($path); + + $this->expectException(IncompatibleSchemaException::class); + $this->expectExceptionMessage('new column "name"'); + + $writer->write(rows(row(str_entry('name', 'flow')))); + } + + public function test_create_with_an_explicit_schema_and_no_writes_records_the_schema_in_the_footer(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://schema-only.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path, schema: schema(int_schema('id'))); + $writer->close(); + + $footer = FloeStreamReaderContext::footer($filesystem, $path); + + static::assertSame(0, $footer->totalRows); + static::assertTrue($footer->schema()->isSame(schema(int_schema('id')))); } public function test_append_over_unsized_stream_throws(): void @@ -100,7 +192,7 @@ public function test_append_metadata_merges_over_existing_footer_metadata(): voi static::assertSame( ['source' => 'append', 'kept' => 'yes'], - FloeFileContext::footer($filesystem, $path)->metadata->normalize(), + FloeStreamReaderContext::footer($filesystem, $path)->metadata->normalize(), ); } @@ -167,7 +259,7 @@ public function test_append_with_incompatible_schema_keeps_previous_rows_readabl $writer->close(); - $footer = FloeFileContext::footer($filesystem, $path); + $footer = FloeStreamReaderContext::footer($filesystem, $path); static::assertSame(1, $footer->totalRows); static::assertCount(1, $footer->sections); @@ -184,14 +276,14 @@ public function test_append_with_new_non_nullable_column_throws(): void $writer->close(); $this->expectException(IncompatibleSchemaException::class); - $this->expectExceptionMessage('adds new column "email" which must be nullable'); + $this->expectExceptionMessage('new column "email"'); $writer = new FloeWriter($filesystem); $writer->append($path); $writer->write(rows(row(int_entry('id', 2), str_entry('email', 'x')))); } - public function test_append_with_new_nullable_column_merges_file_schema(): void + public function test_append_with_new_nullable_column_throws(): void { $filesystem = memory_filesystem(); $path = path('memory://merge.floe'); @@ -203,17 +295,11 @@ public function test_append_with_new_nullable_column_merges_file_schema(): void $writer = new FloeWriter($filesystem); $writer->append($path); - $writer->write(rows(row(int_entry('id', 2), str_entry('email', null)))); - $writer->close(); - $footer = FloeFileContext::footer($filesystem, $path); - $email = $footer->fileSchema()->findDefinition('email'); + $this->expectException(IncompatibleSchemaException::class); + $this->expectExceptionMessage('new column "email"'); - static::assertSame(2, $footer->totalRows); - static::assertCount(2, $footer->schemas); - static::assertCount(2, $footer->sections); - static::assertNotNull($email); - static::assertTrue($email->isNullable()); + $writer->write(rows(row(int_entry('id', 2), str_entry('email', null)))); } public function test_append_with_same_schema_starts_section_without_schema_frame(): void @@ -233,15 +319,14 @@ public function test_append_with_same_schema_starts_section_without_schema_frame static::assertSame( [Format::FRAME_SCHEMA, Format::FRAME_ROW, Format::FRAME_FOOTER, Format::FRAME_ROW, Format::FRAME_FOOTER], - FloeFileContext::frameTypes($filesystem, $path), + FloeStreamReaderContext::frameTypes($filesystem, $path), ); - $footer = FloeFileContext::footer($filesystem, $path); + $footer = FloeStreamReaderContext::footer($filesystem, $path); static::assertSame(2, $footer->totalRows); - static::assertCount(1, $footer->schemas); + static::assertNotSame([], $footer->schema); static::assertCount(2, $footer->sections); - static::assertSame($footer->sections[0]->schemaId, $footer->sections[1]->schemaId); } public function test_close_twice_throws(): void @@ -276,14 +361,13 @@ public function test_closing_empty_file_writes_header_and_footer_only(): void $writer->create($path); $writer->close(); - static::assertSame([Format::FRAME_FOOTER], FloeFileContext::frameTypes($filesystem, $path)); + static::assertSame([Format::FRAME_FOOTER], FloeStreamReaderContext::frameTypes($filesystem, $path)); - $footer = FloeFileContext::footer($filesystem, $path); + $footer = FloeStreamReaderContext::footer($filesystem, $path); static::assertSame(0, $footer->totalRows); static::assertSame([], $footer->sections); - static::assertSame([], $footer->schemas); - static::assertSame([], $footer->fileSchema); + static::assertSame([], $footer->schema); static::assertSame([], $footer->partitions); } @@ -295,56 +379,27 @@ public function test_create_with_non_noop_codec_throws(): void (new FloeWriter(memory_filesystem(), new CodecStub(0x05)))->create(path('memory://codec.floe')); } - public function test_open_on_stream_is_byte_identical_to_create(): void - { - $filesystem = memory_filesystem(); - $viaCreate = path('memory://via-create.floe'); - $viaStream = path('memory://via-stream.floe'); - $data = rows(row(int_entry('id', 1), str_entry('name', 'a')), row(int_entry('id', 2), str_entry('name', 'b'))); - - $create = new FloeWriter($filesystem); - $create->create($viaCreate); - $create->write($data); - $create->close(); - - $onStream = new FloeWriter($filesystem); - $onStream->createOnStream($filesystem->writeTo($viaStream)); - $onStream->write($data); - $onStream->close(); - - static::assertSame($filesystem->readFrom($viaCreate)->content(), $filesystem->readFrom($viaStream)->content()); - } - - public function test_open_on_stream_round_trips(): void + public function test_two_writes_with_the_same_schema_in_one_session_emit_a_single_schema_frame(): void { $filesystem = memory_filesystem(); - $path = path('memory://on-stream.floe'); + $path = path('memory://continuation.floe'); $writer = new FloeWriter($filesystem); - $writer->createOnStream($filesystem->writeTo($path), Metadata::fromArray(['source' => 'stream'])); - $writer->write(rows(row(int_entry('id', 1)), row(int_entry('id', 2)), row(int_entry('id', 3)))); + $writer->create($path); + $writer->write(rows(row(int_entry('id', 1)))); + $writer->write(rows(row(int_entry('id', 2)))); $writer->close(); - $footer = FloeFileContext::footer($filesystem, $path); + $footer = FloeStreamReaderContext::footer($filesystem, $path); - static::assertSame(3, $footer->totalRows); - static::assertSame(['source' => 'stream'], $footer->metadata->normalize()); + static::assertSame(2, $footer->totalRows); + static::assertCount(1, $footer->sections); static::assertSame( - [Format::FRAME_SCHEMA, Format::FRAME_ROW, Format::FRAME_ROW, Format::FRAME_ROW, Format::FRAME_FOOTER], - FloeFileContext::frameTypes($filesystem, $path), + [Format::FRAME_SCHEMA, Format::FRAME_ROW, Format::FRAME_ROW, Format::FRAME_FOOTER], + FloeStreamReaderContext::frameTypes($filesystem, $path), ); } - public function test_open_on_stream_with_non_noop_codec_throws(): void - { - $this->expectException(FloeException::class); - $this->expectExceptionMessage('supports only the no-op codec, got codec 0x05'); - - (new FloeWriter(memory_filesystem(), new CodecStub(0x05)))->createOnStream(memory_filesystem()->writeTo(path( - 'memory://on-stream-codec.floe', - ))); - } - public function test_nothing_reaches_the_stream_before_buffer_fills_or_close(): void { $filesystem = memory_filesystem(); @@ -376,30 +431,84 @@ public function test_partitioned_rows_write_partitions_frame_after_header(): voi static::assertSame( [Format::FRAME_PARTITIONS, Format::FRAME_SCHEMA, Format::FRAME_ROW, Format::FRAME_FOOTER], - FloeFileContext::frameTypes($filesystem, $path), + FloeStreamReaderContext::frameTypes($filesystem, $path), ); - static::assertSame(['country' => 'PL'], FloeFileContext::footer($filesystem, $path)->partitions); + static::assertSame([['country' => 'PL']], FloeStreamReaderContext::footer($filesystem, $path)->partitions); } - public function test_partitions_fixed_empty_reject_partitioned_writes(): void + public function test_a_partition_change_starts_a_new_section_with_its_own_partitions_id(): void { - $writer = new FloeWriter(memory_filesystem()); - $writer->create(path('memory://fixed-empty.floe')); - $writer->write(rows(row(int_entry('id', 1)))); + $filesystem = memory_filesystem(); + $path = path('memory://multi-combination.floe'); - $this->expectException(FloeException::class); - $this->expectExceptionMessage('one partition combination'); + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write(Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )])); + $writer->write(Rows::partitioned([row(int_entry('id', 2), str_entry('country', 'US'))], [new Partition( + 'country', + 'US', + )])); + $writer->close(); + $footer = FloeStreamReaderContext::footer($filesystem, $path); + + static::assertSame([['country' => 'PL'], ['country' => 'US']], $footer->partitions); + static::assertCount(2, $footer->sections); + static::assertSame(0, $footer->sections[0]->partitionsId); + static::assertSame(1, $footer->sections[1]->partitionsId); + static::assertSame( + [ + Format::FRAME_PARTITIONS, + Format::FRAME_SCHEMA, + Format::FRAME_ROW, + Format::FRAME_PARTITIONS, + Format::FRAME_ROW, + Format::FRAME_FOOTER, + ], + FloeStreamReaderContext::frameTypes($filesystem, $path), + ); + } + + public function test_consecutive_writes_with_the_same_partition_reuse_the_id_and_emit_no_second_frame(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://same-combination.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write(Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )])); $writer->write(Rows::partitioned([row(int_entry('id', 2), str_entry('country', 'PL'))], [new Partition( 'country', 'PL', )])); + $writer->close(); + + $footer = FloeStreamReaderContext::footer($filesystem, $path); + + static::assertSame([['country' => 'PL']], $footer->partitions); + static::assertCount(1, $footer->sections); + static::assertSame( + [ + Format::FRAME_PARTITIONS, + Format::FRAME_SCHEMA, + Format::FRAME_ROW, + Format::FRAME_ROW, + Format::FRAME_FOOTER, + ], + FloeStreamReaderContext::frameTypes($filesystem, $path), + ); } - public function test_partitions_mismatch_on_append_throws(): void + public function test_a_change_back_to_unpartitioned_emits_an_empty_partitions_frame(): void { $filesystem = memory_filesystem(); - $path = path('memory://append-partitions.floe'); + $path = path('memory://back-to-unpartitioned.floe'); $writer = new FloeWriter($filesystem); $writer->create($path); @@ -407,10 +516,59 @@ public function test_partitions_mismatch_on_append_throws(): void 'country', 'PL', )])); + $writer->write(rows(row(int_entry('id', 2)))); $writer->close(); - $this->expectException(FloeException::class); - $this->expectExceptionMessage('one partition combination'); + $footer = FloeStreamReaderContext::footer($filesystem, $path); + + static::assertSame([['country' => 'PL'], []], $footer->partitions); + static::assertSame(0, $footer->sections[0]->partitionsId); + static::assertSame(1, $footer->sections[1]->partitionsId); + static::assertSame( + [ + Format::FRAME_PARTITIONS, + Format::FRAME_SCHEMA, + Format::FRAME_ROW, + Format::FRAME_PARTITIONS, + Format::FRAME_ROW, + Format::FRAME_FOOTER, + ], + FloeStreamReaderContext::frameTypes($filesystem, $path), + ); + } + + public function test_empty_write_records_the_empty_combination_without_a_section(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://empty-partitioned.floe'); + + // a zero-row partitioned Rows collapses to empty-unpartitioned at the core level + // (Rows::partitioned drops partitions when there are no rows), so the write records + // only the empty combination and creates no section + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write(Rows::partitioned([], [new Partition('country', 'PL')])); + $writer->close(); + + $footer = FloeStreamReaderContext::footer($filesystem, $path); + + static::assertSame([[]], $footer->partitions); + static::assertSame([], $footer->sections); + static::assertSame([Format::FRAME_FOOTER], FloeStreamReaderContext::frameTypes($filesystem, $path)); + } + + public function test_append_with_a_different_partition_preserves_both_combinations(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://append-partitions.floe'); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write(Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )])); + $writer->close(); $writer = new FloeWriter($filesystem); $writer->append($path); @@ -418,9 +576,17 @@ public function test_partitions_mismatch_on_append_throws(): void 'country', 'US', )])); + $writer->close(); + + $footer = FloeStreamReaderContext::footer($filesystem, $path); + + static::assertSame([['country' => 'PL'], ['country' => 'US']], $footer->partitions); + static::assertCount(2, $footer->sections); + static::assertSame(0, $footer->sections[0]->partitionsId); + static::assertSame(1, $footer->sections[1]->partitionsId); } - public function test_a_new_column_grows_a_section_and_narrower_rows_ride_it(): void + public function test_within_batch_heterogeneous_rows_encode_under_one_union_schema(): void { $filesystem = memory_filesystem(); $path = path('memory://sections.floe'); @@ -428,26 +594,25 @@ public function test_a_new_column_grows_a_section_and_narrower_rows_ride_it(): v $writer = new FloeWriter($filesystem); $writer->create($path); $writer->write(rows( - // section {a,b}; then c is new -> grow to section {a,b,c}; then {a,b} fits it (c absent) + // one write session = one schema; the batch encodes under its union {a,b,c} row(int_entry('a', 1), str_entry('b', 'x')), row(int_entry('a', 2), str_entry('c', 'y')), row(int_entry('a', 3), str_entry('b', 'z')), )); $writer->close(); - $footer = FloeFileContext::footer($filesystem, $path); + $footer = FloeStreamReaderContext::footer($filesystem, $path); - static::assertCount(2, $footer->schemas); - static::assertCount(2, $footer->sections); - static::assertSame([0, 1], [ - $footer->sections[0]->schemaId, - $footer->sections[1]->schemaId, - ]); - static::assertSame([1, 2], [ - $footer->sections[0]->rowCount, - $footer->sections[1]->rowCount, - ]); + static::assertNotSame([], $footer->schema); + static::assertCount(1, $footer->sections); static::assertSame(3, $footer->totalRows); + static::assertSame(3, $footer->sections[0]->rowCount); + + $fileSchema = $footer->schema(); + static::assertNotNull($fileSchema->findDefinition('a')); + static::assertTrue($fileSchema->findDefinition('b')?->isNullable()); + static::assertTrue($fileSchema->findDefinition('c')?->isNullable()); + static::assertCount(3, FloeStreamReaderContext::readAll($filesystem, $path)->all()); } public function test_section_offsets_point_at_frames(): void @@ -460,7 +625,7 @@ public function test_section_offsets_point_at_frames(): void $writer->write(rows(row(int_entry('a', 1)), row(str_entry('b', 'x')))); $writer->close(); - $footer = FloeFileContext::footer($filesystem, $path); + $footer = FloeStreamReaderContext::footer($filesystem, $path); $source = $filesystem->readFrom($path); static::assertSame(Format::HEADER_LENGTH, $footer->sections[0]->offset); @@ -481,32 +646,4 @@ public function test_write_after_close_throws(): void $writer->write(rows(row(int_entry('id', 1)))); } - - public function test_grow_section_plan_from_null_uses_the_row_schema(): void - { - $plan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1), str_entry('b', 'x'))); - - static::assertSame(['a', 'b'], array_values(array_map(static fn($column) => $column->name, $plan->columns))); - } - - public function test_grow_section_plan_grows_the_union_preserving_order(): void - { - $base = FloeWriter::growSectionPlan(null, row(int_entry('a', 1), str_entry('b', 'x'))); - - $grown = FloeWriter::growSectionPlan($base->schemaBody, row(int_entry('a', 2), float_entry('c', 1.5))); - - static::assertSame( - ['a', 'b', 'c'], - array_values(array_map(static fn($column) => $column->name, $grown->columns)), - ); - } - - public function test_grow_section_plan_rides_a_narrower_row_without_growing(): void - { - $base = FloeWriter::growSectionPlan(null, row(int_entry('a', 1), str_entry('b', 'x'))); - - $grown = FloeWriter::growSectionPlan($base->schemaBody, row(int_entry('a', 2))); - - static::assertSame($base->schemaBody, $grown->schemaBody); - } } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FooterReaderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FooterReaderTest.php new file mode 100644 index 0000000000..ce6bc98911 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FooterReaderTest.php @@ -0,0 +1,115 @@ +create($path); + $writer->write(rows(row(int_entry('id', 1)), row(int_entry('id', 2)))); + $writer->close(); + + $location = (new FooterReader())->read($fs->readFrom($path), new NoopCodec()); + + static::assertSame(2, $location->footer->totalRows); + static::assertGreaterThan(Format::HEADER_LENGTH, $location->footerFrameStart); + static::assertSame(Format::FRAME_FOOTER, ord($fs->readFrom($path)->read(1, $location->footerFrameStart))); + } + + public function test_unsized_stream_throws(): void + { + $fs = memory_filesystem(); + $path = path('memory://unsized.floe'); + $writer = new FloeWriter($fs); + $writer->create($path); + $writer->close(); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('requires a sized stream'); + + (new FooterReader())->read(new UnsizedSourceStream($fs->readFrom($path)), new NoopCodec()); + } + + public function test_stream_too_small_throws(): void + { + $this->expectException(FloeException::class); + $this->expectExceptionMessage('too small'); + + (new FooterReader())->read(new MemorySourceStream('FLOE'), new NoopCodec()); + } + + public function test_codec_mismatch_throws(): void + { + $this->expectException(FloeException::class); + $this->expectExceptionMessage('written with codec 0x05, expected 0x00'); + + (new FooterReader())->read(new MemorySourceStream("FLOE\x01\x05" . str_repeat("\0", 10)), new NoopCodec()); + } + + public function test_footer_that_does_not_fit_throws(): void + { + $fs = memory_filesystem(); + $path = path('memory://torn.floe'); + $fs + ->writeTo($path) + ->append(Format::header(0x00) . Format::trailer(9999)) + ->close(); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('footer does not fit inside the file'); + + (new FooterReader())->read($fs->readFrom($path), new NoopCodec()); + } + + public function test_leaves_the_source_open_on_success(): void + { + $fs = memory_filesystem(); + $path = path('memory://close-ok.floe'); + $writer = new FloeWriter($fs); + $writer->create($path); + $writer->write(rows(row(int_entry('id', 1)))); + $writer->close(); + + $spy = new ClosingSpySourceStream($fs->readFrom($path)); + + (new FooterReader())->read($spy, new NoopCodec()); + + static::assertSame(0, $spy->closeCount); + } + + public function test_leaves_the_source_open_on_error(): void + { + $spy = new ClosingSpySourceStream(new MemorySourceStream('FLOE')); + + try { + (new FooterReader())->read($spy, new NoopCodec()); + } catch (FloeException) { + } + + static::assertSame(0, $spy->closeCount); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FooterTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FooterTest.php index b12b929f7f..e19f8df751 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FooterTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FooterTest.php @@ -4,15 +4,26 @@ namespace Flow\Floe\Tests\Unit; +use Flow\ETL\Rows; +use Flow\Filesystem\Partition; use Flow\Floe\Exception\FloeException; +use Flow\Floe\FloeWriter; use Flow\Floe\Footer; use Flow\Floe\Section; +use Flow\Floe\Tests\Context\FloeStreamReaderContext; use Flow\Floe\Tests\Mother\FooterMother; use PHPUnit\Framework\TestCase; +use function array_map; +use function Flow\ETL\DSL\int_entry; use function Flow\ETL\DSL\int_schema; +use function Flow\ETL\DSL\row; +use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\schema; +use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\str_schema; +use function Flow\Filesystem\DSL\memory_filesystem; +use function Flow\Filesystem\DSL\path; use function Flow\Types\DSL\type_integer; use function json_decode; use function json_encode; @@ -25,27 +36,25 @@ public function test_empty_footer_encodes_maps_as_json_objects(): void { $json = FooterMother::footer()->toJson(); - static::assertStringContainsString('"partitions":{}', $json); + static::assertStringContainsString('"partitions":[]', $json); static::assertStringContainsString('"metadata":{}', $json); - static::assertStringContainsString('"schemas":[]', $json); + static::assertStringContainsString('"schema":[]', $json); static::assertStringContainsString('"sections":[]', $json); } public function test_file_schema_round_trips_through_schema_object(): void { $schema = schema(int_schema('id'), str_schema('name', nullable: true)); - $footer = FooterMother::footer(fileSchema: $schema->normalize()); + $footer = FooterMother::footer(schema: $schema->normalize()); - static::assertTrue($schema->isSame(Footer::fromJson($footer->toJson())->fileSchema())); + static::assertTrue($schema->isSame(Footer::fromJson($footer->toJson())->schema())); } public function test_from_json_requires_all_fields(): void { $this->expectException(FloeException::class); - Footer::fromJson( - '{"version":1,"writer":"x","schemas":[],"fileSchema":[],"partitions":{},"totalRows":0,"metadata":{}}', - ); + Footer::fromJson('{"version":1,"writer":"x","schema":[],"partitions":{},"totalRows":0,"metadata":{}}'); } public function test_from_json_with_malformed_json_throws(): void @@ -118,40 +127,175 @@ public function test_from_json_with_non_scalar_metadata_value_throws(): void $this->expectExceptionMessage('metadata is malformed'); Footer::fromJson( - '{"version":1,"writer":"x","schemas":[],"fileSchema":[],"sections":[],"partitions":{},"totalRows":0,"metadata":{"bad":null}}', + '{"version":1,"writer":"x","schema":[],"sections":[],"partitions":{},"totalRows":0,"metadata":{"bad":null}}', ); } public function test_schema_body_re_encodes_stored_schema(): void { $schema = schema(int_schema('id')); - $footer = FooterMother::footer(schemas: [$schema->normalize()]); + $footer = FooterMother::footer(schema: $schema->normalize()); static::assertJsonStringEqualsJsonString( json_encode($schema->normalize(), JSON_THROW_ON_ERROR), - Footer::fromJson($footer->toJson())->schemaBody(0), + Footer::fromJson($footer->toJson())->schemaBody(), ); } - public function test_schema_body_with_unknown_id_throws(): void + public function test_partitions_for_reads_stored_combination(): void + { + $footer = FooterMother::footer(partitions: [[], ['country' => 'PL']]); + + static::assertSame([], $footer->partitionsFor(0)); + static::assertSame(['country' => 'PL'], $footer->partitionsFor(1)); + } + + public function test_partitions_for_with_unknown_id_throws(): void { $this->expectException(FloeException::class); - $this->expectExceptionMessage('does not hold schema with id 3'); + $this->expectExceptionMessage('does not hold partitions with id 2'); - FooterMother::footer()->schemaBody(3); + FooterMother::footer()->partitionsFor(2); } public function test_to_json_round_trips_every_field(): void { $footer = FooterMother::footer( - schemas: [schema(int_schema('id'))->normalize()], - fileSchema: schema(int_schema('id'))->normalize(), + schema: schema(int_schema('id'))->normalize(), sections: [new Section(6, 0, 2), new Section(120, 0, 3)], - partitions: ['country' => 'PL'], + partitions: [['country' => 'PL']], totalRows: 5, metadata: ['source' => 'test'], ); static::assertEquals($footer, Footer::fromJson($footer->toJson())); } + + public function test_normalize_round_trips_through_from_array(): void + { + $footer = FooterMother::footer( + schema: schema(int_schema('id'))->normalize(), + sections: [new Section(6, 0, 2), new Section(120, 0, 3)], + partitions: [['country' => 'PL']], + totalRows: 5, + metadata: ['source' => 'test'], + ); + + static::assertEquals($footer, Footer::fromArray($footer->normalize())); + } + + public function test_file_partitions_reads_combination_from_the_first_section(): void + { + $footer = FooterMother::footer( + sections: [new Section(6, 0, 1)], + partitions: [['country' => 'PL', 'year' => '2025']], + totalRows: 1, + ); + + static::assertEquals( + [new Partition('country', 'PL'), new Partition('year', '2025')], + $footer->filePartitions(), + ); + } + + public function test_file_partitions_unpartitioned_returns_empty(): void + { + $footer = FooterMother::footer(sections: [new Section(6, 0, 1)], partitions: [[]], totalRows: 1); + + static::assertSame([], $footer->filePartitions()); + } + + public function test_file_partitions_zero_section_value_reads_the_last_non_empty_table_entry(): void + { + $footer = FooterMother::footer(partitions: [['country' => 'PL']]); + + static::assertEquals([new Partition('country', 'PL')], $footer->filePartitions()); + } + + public function test_file_partitions_unknown_id_throws(): void + { + $footer = FooterMother::footer(sections: [new Section(6, 5, 1)], totalRows: 1); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('does not hold partitions with id 5'); + + $footer->filePartitions(); + } + + public function test_reconstruct_rows_builds_rows_from_decoded_rows(): void + { + $footer = FooterMother::footer(totalRows: 1); + + static::assertEquals(rows(row(int_entry('id', 1))), $footer->reconstructRows([row(int_entry('id', 1))])); + } + + public function test_reconstruct_rows_round_trips_unpartitioned_rows(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://footer-rows.floe'); + $value = rows(row(int_entry('id', 1)), row(int_entry('id', 2))); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write($value); + $writer->close(); + + static::assertEquals($value, FloeStreamReaderContext::reconstruct($filesystem, $path)); + } + + public function test_reconstruct_rows_round_trips_empty_rows(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://footer-empty.floe'); + $value = rows(); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write($value); + $writer->close(); + + static::assertEquals($value, FloeStreamReaderContext::reconstruct($filesystem, $path)); + } + + public function test_reconstruct_rows_round_trips_partitioned_rows(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://footer-partitioned.floe'); + $value = Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( + 'country', + 'PL', + )]); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write($value); + $writer->close(); + + static::assertEquals($value, FloeStreamReaderContext::reconstruct($filesystem, $path)); + } + + public function test_reconstruct_rows_preserves_non_alphabetical_partition_order(): void + { + $filesystem = memory_filesystem(); + $path = path('memory://footer-partition-order.floe'); + $value = Rows::partitioned([row( + int_entry('id', 1), + str_entry('year', '2020'), + str_entry('day', '15'), + str_entry('month', '03'), + )], [new Partition('year', '2020'), new Partition('day', '15'), new Partition('month', '03')]); + + $writer = new FloeWriter($filesystem); + $writer->create($path); + $writer->write($value); + $writer->close(); + + $result = FloeStreamReaderContext::reconstruct($filesystem, $path); + + static::assertSame( + ['year', 'day', 'month'], + array_map(static fn(Partition $p): string => $p->name, $result->partitions()->toArray()), + ); + static::assertEquals($value, $result); + } } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FrameSegmentTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FrameSegmentTest.php deleted file mode 100644 index e8341301e2..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/FrameSegmentTest.php +++ /dev/null @@ -1,29 +0,0 @@ -schemaBody); - static::assertSame("\x02\x03\x00\x00\x00abc", $segment->frames); - static::assertSame(1, $segment->rowCount); - } - - public function test_exposes_a_continuation_segment(): void - { - $segment = new FrameSegment(null, '', 0); - - static::assertNull($segment->schemaBody); - static::assertSame('', $segment->frames); - static::assertSame(0, $segment->rowCount); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/FrameWriterTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/FrameWriterTest.php new file mode 100644 index 0000000000..c3d87df9c9 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/FrameWriterTest.php @@ -0,0 +1,135 @@ +header(); + $writer->flush(); + + static::assertSame(Format::header(0x00), $sink->content()); + static::assertSame(Format::HEADER_LENGTH, $writer->position()); + } + + public function test_row_frame_is_type_length_prefixed_body(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00); + + $writer->row('abc'); + $writer->flush(); + + static::assertSame(chr(Format::FRAME_ROW) . pack('V', 3) . 'abc', $sink->content()); + static::assertSame(Format::FRAME_HEADER_LENGTH + 3, $writer->position()); + } + + public function test_schema_frame_matches_format_frame(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00); + + $writer->schema('{"x":1}'); + $writer->flush(); + + static::assertSame(Format::frame(Format::FRAME_SCHEMA, '{"x":1}'), $sink->content()); + } + + public function test_empty_combination_emits_count_zero_partitions_frame(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00); + + $writer->partitions([]); + $writer->flush(); + + static::assertSame(Format::frame(Format::FRAME_PARTITIONS, pack('V', 0)), $sink->content()); + } + + public function test_populated_combination_packs_name_and_value_pairs(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00); + + $writer->partitions(['country' => 'PL']); + $writer->flush(); + + $body = pack('V', 1) . pack('V', 7) . 'country' . pack('V', 2) . 'PL'; + static::assertSame(Format::frame(Format::FRAME_PARTITIONS, $body), $sink->content()); + } + + public function test_footer_appends_trailer_and_flushes(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00); + + $writer->footer('{"v":1}'); + + static::assertSame( + Format::frame(Format::FRAME_FOOTER, '{"v":1}' . Format::trailer(strlen('{"v":1}'))), + $sink->content(), + ); + } + + public function test_raw_appends_bytes_verbatim_and_advances_position(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00); + + $writer->raw('already-framed-bytes'); + $writer->flush(); + + static::assertSame('already-framed-bytes', $sink->content()); + static::assertSame(strlen('already-framed-bytes'), $writer->position()); + } + + public function test_start_position_seeds_the_logical_position(): void + { + $writer = new FrameWriter(new StringDestinationStream(path('memory://frame.floe')), 0x00, startPosition: 128); + + static::assertSame(128, $writer->position()); + + $writer->row('x'); + + static::assertSame(128 + Format::FRAME_HEADER_LENGTH + 1, $writer->position()); + } + + public function test_buffer_flushes_when_it_reaches_buffer_size(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00, bufferSize: 8); + + $writer->raw('1234'); + static::assertSame('', $sink->content()); + + $writer->raw('5678'); + static::assertSame('12345678', $sink->content()); + } + + public function test_close_flushes_pending_bytes(): void + { + $sink = new StringDestinationStream(path('memory://frame.floe')); + $writer = new FrameWriter($sink, 0x00); + + $writer->row('pending'); + $writer->close(); + + static::assertSame(chr(Format::FRAME_ROW) . pack('V', 7) . 'pending', $sink->content()); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/NativeFloeEncoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/NativeFloeEncoderTest.php new file mode 100644 index 0000000000..e8b1fb42a7 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/NativeFloeEncoderTest.php @@ -0,0 +1,88 @@ +schema()), + ); + + $encoded = [new TypedRowValues(['id' => 1, 'name' => 'flow'], [ + 'id' => type_integer(), + 'name' => type_string(), + ])]; + + static::assertSame( + (new PhpFloeEncoder($schema))->encode($encoded), + (new NativeFloeEncoder($schema))->encode($encoded), + ); + } + + public function test_native_decode_matches_the_php_engine(): void + { + $data = rows( + row(int_entry('id', 1), str_entry('name', 'flow')), + row(int_entry('id', 2), str_entry('name', null)), + ); + + $schema = schema_from_json(FloeSchemaContext::schemaBody($data->first()->schema())); + $bodies = (new PhpFloeEncoder($schema))->encode((new PhpRowHydrator())->dehydrate($data)); + + static::assertEquals( + (new PhpFloeEncoder($schema))->decode($bodies), + (new NativeFloeEncoder($schema))->decode($bodies), + ); + } + + public function test_native_metadata_bearing_frames_match_the_php_engine(): void + { + $schema = schema_from_json( + FloeSchemaContext::schemaBody(row(int_entry('id', 1), str_entry('name', 'x'))->schema()), + ); + + $encoded = [new TypedRowValues( + ['id' => 2, 'name' => null], + ['id' => type_integer(), 'name' => type_string()], + ['id' => Metadata::fromArray(['source' => 'trusted', 'weight' => 3])], + )]; + + $bodies = (new PhpFloeEncoder($schema))->encode($encoded); + + static::assertEquals( + (new PhpFloeEncoder($schema))->decode($bodies), + (new NativeFloeEncoder($schema))->decode($bodies), + ); + static::assertSame( + (new PhpFloeEncoder($schema))->encode($encoded), + (new NativeFloeEncoder($schema))->encode($encoded), + ); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/PhpFloeEncoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/PhpFloeEncoderTest.php new file mode 100644 index 0000000000..09f180a069 --- /dev/null +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/PhpFloeEncoderTest.php @@ -0,0 +1,159 @@ +first()->schema()))); + + $decoded = $encoder->decode($encoder->encode((new PhpRowHydrator())->dehydrate($original))); + + static::assertSame(['id' => 1, 'name' => 'flow', 'price' => 1.5], $decoded[0]->values); + static::assertSame([], $decoded[0]->metadata); + static::assertSame(['id' => 2, 'name' => null, 'price' => 0.5], $decoded[1]->values); + } + + public function test_encode_from_dehydrated_rows_round_trips(): void + { + $original = rows( + row(int_entry('id', 1), str_entry('name', 'flow')), + row(int_entry('id', 2), str_entry('name', null)), + ); + + $encoder = new PhpFloeEncoder(schema_from_json(FloeSchemaContext::schemaBody($original->first()->schema()))); + + $decoded = $encoder->decode($encoder->encode((new PhpRowHydrator())->dehydrate($original))); + + static::assertEquals( + [ + new RawRowValues(['id' => 1, 'name' => 'flow']), + new RawRowValues(['id' => 2, 'name' => null]), + ], + $decoded, + ); + } + + public function test_encode_decode_round_trip_preserves_flags(): void + { + $schema = schema_from_json( + FloeSchemaContext::schemaBody(row(int_entry('id', 1), str_entry('name', 'flow'))->schema()), + ); + + $encoder = new PhpFloeEncoder($schema); + + $types = ['id' => type_integer(), 'name' => type_string()]; + $encoded = [ + new TypedRowValues(['id' => 1, 'name' => 'flow'], $types), + new TypedRowValues(['id' => 2, 'name' => null], $types), + new TypedRowValues(['id' => 3, 'name' => null], $types, ['name' => Metadata::fromArray(['tag' => 'x'])]), + new TypedRowValues(['id' => 4], ['id' => type_integer()]), + ]; + + $decoded = $encoder->decode($encoder->encode($encoded)); + + static::assertEquals( + [ + new RawRowValues(['id' => 1, 'name' => 'flow']), + new RawRowValues(['id' => 2, 'name' => null]), + new RawRowValues(['id' => 3, 'name' => null], ['name' => Metadata::fromArray(['tag' => 'x'])]), + new RawRowValues(['id' => 4]), + ], + $decoded, + ); + static::assertSame('x', $decoded[2]->metadata['name']->get('tag')); + static::assertArrayNotHasKey('name', $decoded[3]->values); + } + + public function test_encode_decode_round_trip_preserves_arbitrary_metadata(): void + { + $schema = schema_from_json( + FloeSchemaContext::schemaBody(row(int_entry('id', 1), str_entry('name', 'flow'))->schema()), + ); + + $encoder = new PhpFloeEncoder($schema); + + $metadata = ['name' => Metadata::fromArray(['source' => 'trusted', 'weight' => 3])]; + $encoded = [ + new TypedRowValues( + ['id' => 1, 'name' => 'flow'], + ['id' => type_integer(), 'name' => type_string()], + $metadata, + ), + ]; + + $decoded = $encoder->decode($encoder->encode($encoded)); + + static::assertEquals([new RawRowValues(['id' => 1, 'name' => 'flow'], $metadata)], $decoded); + static::assertSame('trusted', $decoded[0]->metadata['name']->get('source')); + static::assertSame(3, $decoded[0]->metadata['name']->get('weight')); + } + + public function test_null_entry_in_a_typed_column_encodes_as_a_plain_null(): void + { + $schema = schema_from_json( + FloeSchemaContext::schemaBody(row(int_entry('id', 1), str_entry('name', 'x'))->schema()), + ); + + $encoder = new PhpFloeEncoder($schema); + $body = $encoder->encode((new PhpRowHydrator())->dehydrate(rows(row( + int_entry('id', 2), + null_entry('name'), + ))))[0]; + + $decoded = $encoder->decode([$body]); + + static::assertNull($decoded[0]->values['name']); + static::assertArrayNotHasKey('name', $decoded[0]->metadata); + } + + public function test_row_body_with_trailing_garbage_throws(): void + { + $schema = schema_from_json(FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema())); + + $encoder = new PhpFloeEncoder($schema); + $body = $encoder->encode((new PhpRowHydrator())->dehydrate(rows(row(int_entry('id', 1)))))[0]; + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('Floe row frame length does not match its content'); + + $encoder->decode([$body . "\x00"]); + } + + public function test_unknown_value_flag_throws(): void + { + $schema = schema_from_json(FloeSchemaContext::schemaBody(row(int_entry('id', 1))->schema())); + + $this->expectException(FloeException::class); + $this->expectExceptionMessage('unknown value flag'); + + (new PhpFloeEncoder($schema))->decode(["\xEF"]); + } +} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/PhpRowFrameEncoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/PhpRowFrameEncoderTest.php deleted file mode 100644 index 653a51adfc..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/PhpRowFrameEncoderTest.php +++ /dev/null @@ -1,131 +0,0 @@ -encode($plan, $first); - $secondBody = (new RowEncoder())->encode($plan, $second); - - $segments = (new PhpRowFrameEncoder())->encode(rows($first, $second)); - - static::assertCount(1, $segments); - static::assertSame($plan->schemaBody, $segments[0]->schemaBody); - static::assertSame(2, $segments[0]->rowCount); - static::assertSame( - chr(Format::FRAME_ROW) - . pack('V', strlen($firstBody)) - . $firstBody - . chr(Format::FRAME_ROW) - . pack('V', strlen($secondBody)) - . $secondBody, - $segments[0]->frames, - ); - } - - public function test_new_column_starts_a_new_segment_with_the_grown_union(): void - { - $first = row(int_entry('id', 1)); - $second = row(int_entry('id', 2), str_entry('name', 'flow')); - - $firstPlan = FloeWriter::growSectionPlan(null, $first); - $secondPlan = FloeWriter::growSectionPlan($firstPlan->schemaBody, $second); - $firstBody = (new RowEncoder())->encode($firstPlan, $first); - $secondBody = (new RowEncoder())->encode($secondPlan, $second); - - $segments = (new PhpRowFrameEncoder())->encode(rows($first, $second)); - - static::assertCount(2, $segments); - static::assertSame($firstPlan->schemaBody, $segments[0]->schemaBody); - static::assertSame(1, $segments[0]->rowCount); - static::assertSame(chr(Format::FRAME_ROW) . pack('V', strlen($firstBody)) . $firstBody, $segments[0]->frames); - static::assertSame($secondPlan->schemaBody, $segments[1]->schemaBody); - static::assertSame(1, $segments[1]->rowCount); - static::assertSame(chr(Format::FRAME_ROW) . pack('V', strlen($secondBody)) . $secondBody, $segments[1]->frames); - } - - public function test_narrower_row_rides_the_current_section(): void - { - $first = row(int_entry('id', 1), str_entry('name', 'flow')); - $second = row(int_entry('id', 2)); - - $plan = FloeWriter::growSectionPlan(null, $first); - $firstBody = (new RowEncoder())->encode($plan, $first); - $secondBody = (new RowEncoder())->encode($plan, $second); - - $segments = (new PhpRowFrameEncoder())->encode(rows($first, $second)); - - static::assertCount(1, $segments); - static::assertSame($plan->schemaBody, $segments[0]->schemaBody); - static::assertSame(2, $segments[0]->rowCount); - static::assertSame( - chr(Format::FRAME_ROW) - . pack('V', strlen($firstBody)) - . $firstBody - . chr(Format::FRAME_ROW) - . pack('V', strlen($secondBody)) - . $secondBody, - $segments[0]->frames, - ); - } - - public function test_continuation_across_calls_yields_a_null_schema_body_segment(): void - { - $first = row(int_entry('id', 1)); - $second = row(int_entry('id', 2)); - - $plan = FloeWriter::growSectionPlan(null, $first); - $secondBody = (new RowEncoder())->encode($plan, $second); - - $encoder = new PhpRowFrameEncoder(); - $encoder->encode(rows($first)); - - $segments = $encoder->encode(rows($second)); - - static::assertCount(1, $segments); - static::assertNull($segments[0]->schemaBody); - static::assertSame(1, $segments[0]->rowCount); - static::assertSame(chr(Format::FRAME_ROW) . pack('V', strlen($secondBody)) . $secondBody, $segments[0]->frames); - } - - public function test_codec_is_applied_to_each_row_body(): void - { - $row = row(int_entry('id', 1)); - - $plan = FloeWriter::growSectionPlan(null, $row); - $body = "\xFF" . (new RowEncoder())->encode($plan, $row); - - $segments = (new PhpRowFrameEncoder(new PrefixingCodecStub()))->encode(rows($row)); - - static::assertCount(1, $segments); - static::assertSame(chr(Format::FRAME_ROW) . pack('V', strlen($body)) . $body, $segments[0]->frames); - } - - public function test_empty_rows_produce_no_segments(): void - { - static::assertSame([], (new PhpRowFrameEncoder())->encode(rows())); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/RowHydratorTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/RowHydratorTest.php deleted file mode 100644 index b5b6e3121e..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/RowHydratorTest.php +++ /dev/null @@ -1,70 +0,0 @@ -encode($encoderPlan, $original); - - $hydratorPlan = (new SchemaDecoder(new ValueDecoder(), new Instantiators()))->decode($encoderPlan->schemaBody); - $position = 0; - $hydrated = (new RowHydrator())->hydrate($hydratorPlan, $body, $position); - - static::assertEquals($original, $hydrated); - static::assertSame(strlen($body), $position); - static::assertSame(serialize($original), serialize($hydrated)); - } - - public function test_hydrated_definitions_are_not_shared_between_rows(): void - { - $original = row(int_entry('id', 1)); - - $encoderPlan = FloeWriter::growSectionPlan(null, $original); - $body = (new RowEncoder())->encode($encoderPlan, $original); - - $hydratorPlan = (new SchemaDecoder(new ValueDecoder(), new Instantiators()))->decode($encoderPlan->schemaBody); - $hydrator = new RowHydrator(); - - $position = 0; - $first = $hydrator->hydrate($hydratorPlan, $body, $position); - $position = 0; - $second = $hydrator->hydrate($hydratorPlan, $body, $position); - - static::assertNotSame($first->entries()['id']->definition(), $second->entries()['id']->definition()); - } - - public function test_hydrating_row_with_unknown_value_flag_throws(): void - { - $original = row(int_entry('id', 1)); - $schemaJson = FloeWriter::growSectionPlan(null, $original)->schemaBody; - $hydratorPlan = (new SchemaDecoder(new ValueDecoder(), new Instantiators()))->decode($schemaJson); - $position = 0; - - $this->expectException(SerializationException::class); - $this->expectExceptionMessage('unknown value flag'); - - (new RowHydrator())->hydrate($hydratorPlan, "\xEF", $position); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/RowPaddingTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/RowPaddingTest.php index 7e12e9d3cf..f136ff853d 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/RowPaddingTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/RowPaddingTest.php @@ -5,10 +5,10 @@ namespace Flow\Floe\Tests\Unit; use Flow\ETL\Row\Entry\Instantiators; -use Flow\ETL\Schema\Metadata; use Flow\Floe\RowPadding; use Flow\Floe\SchemaDecoder; use Flow\Floe\ValueDecoder; +use Flow\Types\Type\Native\StringType; use PHPUnit\Framework\TestCase; use function Flow\ETL\DSL\int_entry; @@ -20,7 +20,7 @@ final class RowPaddingTest extends TestCase { - public function test_absent_columns_are_padded_with_from_null_entries(): void + public function test_absent_columns_are_padded_with_typed_nullable_nulls(): void { $padding = RowPadding::forFileSchema( schema(int_schema('id'), str_schema('email', nullable: true)), @@ -33,8 +33,9 @@ public function test_absent_columns_are_padded_with_from_null_entries(): void static::assertSame(['id', 'email'], $padded->entries()->names()); static::assertSame(1, $padded->get('id')->value()); static::assertNull($email->value()); + static::assertInstanceOf(StringType::class, $email->definition()->type()); static::assertTrue($email->definition()->isNullable()); - static::assertTrue($email->definition()->metadata()->has(Metadata::FROM_NULL)); + static::assertTrue($email->definition()->metadata()->isEmpty()); } public function test_padding_entries_are_shared_between_rows(): void diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/RowsValueMapperTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/RowsValueMapperTest.php deleted file mode 100644 index 1e9f424653..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/RowsValueMapperTest.php +++ /dev/null @@ -1,195 +0,0 @@ - 'row'], - RowsValueMapper::metadataFor(row(int_entry('id', 1)))->normalize(), - ); - } - - public function test_metadata_tags_rows(): void - { - static::assertSame( - [RowsValueMapper::VALUE_TYPE_KEY => 'rows'], - RowsValueMapper::metadataFor(rows(row(int_entry('id', 1))))->normalize(), - ); - } - - public function test_partitions_from_follows_footer_order_without_order_metadata(): void - { - $footer = new Footer(1, 'test', [], [], [], ['country' => 'PL', 'year' => '2025'], 0, Metadata::empty()); - - static::assertEquals( - [new Partition('country', 'PL'), new Partition('year', '2025')], - RowsValueMapper::partitionsFrom($footer), - ); - } - - public function test_partitions_from_rejects_malformed_order_metadata(): void - { - $footer = new Footer( - 1, - 'test', - [], - [], - [], - ['country' => 'PL'], - 0, - Metadata::with('flow.cache.partition_order', ['not' => 'a-list']), - ); - - $this->expectException(FloeException::class); - $this->expectExceptionMessage('partition order metadata is malformed'); - - RowsValueMapper::partitionsFrom($footer); - } - - public function test_reconstruct_defaults_to_rows_without_value_type_metadata(): void - { - $footer = new Footer(1, 'test', [], [], [], [], 1, Metadata::empty()); - - static::assertEquals( - rows(row(int_entry('id', 1))), - RowsValueMapper::reconstructFrom([row(int_entry('id', 1))], $footer), - ); - } - - public function test_reconstruct_rejects_row_tagged_payload_without_rows(): void - { - $footer = new Footer(1, 'test', [], [], [], [], 0, Metadata::with(RowsValueMapper::VALUE_TYPE_KEY, 'row')); - - $this->expectException(FloeException::class); - $this->expectExceptionMessage('contained no rows'); - - RowsValueMapper::reconstructFrom([], $footer); - } - - public function test_reconstruct_empty_rows(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://codec-empty.floe'); - $value = rows(); - - $writer = new FloeWriter($filesystem); - $writer->create($path, RowsValueMapper::metadataFor($value)); - $writer->write(RowsValueMapper::wrap($value)); - $writer->close(); - - static::assertEquals($value, FloeFileContext::reconstruct($filesystem, $path)); - } - - public function test_reconstruct_partitioned_rows(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://codec-partitioned.floe'); - $value = Rows::partitioned([row(int_entry('id', 1), str_entry('country', 'PL'))], [new Partition( - 'country', - 'PL', - )]); - - $writer = new FloeWriter($filesystem); - $writer->create($path, RowsValueMapper::metadataFor($value)); - $writer->write(RowsValueMapper::wrap($value)); - $writer->close(); - - static::assertEquals($value, FloeFileContext::reconstruct($filesystem, $path)); - } - - public function test_reconstruct_preserves_non_alphabetical_partition_order(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://codec-partition-order.floe'); - $value = Rows::partitioned([row( - int_entry('id', 1), - str_entry('year', '2020'), - str_entry('day', '15'), - str_entry('month', '03'), - )], [new Partition('year', '2020'), new Partition('day', '15'), new Partition('month', '03')]); - - $writer = new FloeWriter($filesystem); - $writer->create($path, RowsValueMapper::metadataFor($value)); - $writer->write(RowsValueMapper::wrap($value)); - $writer->close(); - - $result = FloeFileContext::reconstruct($filesystem, $path); - - static::assertInstanceOf(Rows::class, $result); - static::assertSame( - ['year', 'day', 'month'], - array_map(static fn(Partition $p): string => $p->name, $result->partitions()->toArray()), - ); - static::assertEquals($value, $result); - } - - public function test_reconstruct_row(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://codec-row.floe'); - $value = row(int_entry('id', 1), str_entry('name', 'John')); - - $writer = new FloeWriter($filesystem); - $writer->create($path, RowsValueMapper::metadataFor($value)); - $writer->write(RowsValueMapper::wrap($value)); - $writer->close(); - - $result = FloeFileContext::reconstruct($filesystem, $path); - - static::assertInstanceOf(Row::class, $result); - static::assertEquals($value, $result); - } - - public function test_reconstruct_rows(): void - { - $filesystem = memory_filesystem(); - $path = path('memory://codec-rows.floe'); - $value = rows(row(int_entry('id', 1)), row(int_entry('id', 2))); - - $writer = new FloeWriter($filesystem); - $writer->create($path, RowsValueMapper::metadataFor($value)); - $writer->write(RowsValueMapper::wrap($value)); - $writer->close(); - - $result = FloeFileContext::reconstruct($filesystem, $path); - - static::assertInstanceOf(Rows::class, $result); - static::assertEquals($value, $result); - } - - public function test_wrap_keeps_rows(): void - { - $value = rows(row(int_entry('id', 1))); - - static::assertSame($value, RowsValueMapper::wrap($value)); - } - - public function test_wrap_lifts_a_row_into_rows(): void - { - static::assertEquals(rows(row(int_entry('id', 1))), RowsValueMapper::wrap(row(int_entry('id', 1)))); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaDecoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaDecoderTest.php index bf80cce44a..b1c9b99d01 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaDecoderTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaDecoderTest.php @@ -5,50 +5,47 @@ namespace Flow\Floe\Tests\Unit; use Flow\ETL\Row\Entry\Instantiators; -use Flow\ETL\Row\Entry\StringEntry; +use Flow\ETL\Schema\Definition\NullDefinition; use Flow\ETL\Schema\Metadata; use Flow\Floe\Exception\FloeException; -use Flow\Floe\FloeWriter; use Flow\Floe\SchemaDecoder; +use Flow\Floe\Tests\Context\FloeSchemaContext; use Flow\Floe\ValueDecoder; use PHPUnit\Framework\TestCase; use function Flow\ETL\DSL\int_entry; +use function Flow\ETL\DSL\null_entry; use function Flow\ETL\DSL\row; use function Flow\ETL\DSL\str_entry; final class SchemaDecoderTest extends TestCase { - public function test_decoded_plan_provides_nullable_and_from_null_definition_variants(): void + public function test_decoded_plan_provides_the_base_definition(): void { - $schemaJson = FloeWriter::growSectionPlan(null, row(str_entry('name', 'x')))->schemaBody; + $schemaJson = FloeSchemaContext::schemaBody(row(str_entry('name', 'x'))->schema()); $plan = (new SchemaDecoder(new ValueDecoder(), new Instantiators()))->decode($schemaJson); static::assertCount(1, $plan); static::assertSame('name', $plan[0]->name); static::assertFalse($plan[0]->definition->isNullable()); - static::assertTrue($plan[0]->nullableDefinition->isNullable()); - static::assertTrue($plan[0]->fromNullDefinition->isNullable()); - static::assertTrue($plan[0]->fromNullDefinition->metadata()->has(Metadata::FROM_NULL)); - static::assertFalse($plan[0]->nullableDefinition->metadata()->has(Metadata::FROM_NULL)); } - public function test_decoded_plan_strips_from_null_marker_from_base_definition(): void + public function test_decoded_plan_maps_a_null_column_to_a_null_definition(): void { - $schemaJson = FloeWriter::growSectionPlan(null, row(StringEntry::fromNull('name')))->schemaBody; + $schemaJson = FloeSchemaContext::schemaBody(row(null_entry('name'))->schema()); $plan = (new SchemaDecoder(new ValueDecoder(), new Instantiators()))->decode($schemaJson); - static::assertFalse($plan[0]->definition->metadata()->has(Metadata::FROM_NULL)); - static::assertTrue($plan[0]->fromNullDefinition->metadata()->has(Metadata::FROM_NULL)); + static::assertInstanceOf(NullDefinition::class, $plan[0]->definition); + static::assertTrue($plan[0]->definition->isNullable()); } public function test_decoded_plan_preserves_custom_metadata(): void { - $schemaJson = FloeWriter::growSectionPlan(null, row(int_entry('id', 1, Metadata::fromArray([ + $schemaJson = FloeSchemaContext::schemaBody(row(int_entry('id', 1, Metadata::fromArray([ 'custom' => 'meta', - ]))))->schemaBody; + ])))->schema()); $plan = (new SchemaDecoder(new ValueDecoder(), new Instantiators()))->decode($schemaJson); diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaEncoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaEncoderTest.php deleted file mode 100644 index ecfc0a6ba5..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaEncoderTest.php +++ /dev/null @@ -1,39 +0,0 @@ -encodeSchema(schema(int_schema('id'), str_schema('name'))); - - static::assertSame(['id', 'name'], array_keys($plan->columns)); - static::assertSame( - ['id', 'name'], - array_values(array_map(static fn($column) => $column->name, $plan->columns)), - ); - } - - public function test_column_name_with_invalid_utf8_throws(): void - { - $this->expectException(FloeException::class); - $this->expectExceptionMessage('failed to encode schema as JSON'); - - (new SchemaEncoder(new ValueEncoder()))->encodeSchema(schema(str_schema("bad\xFFname"))); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaEvolutionTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaEvolutionTest.php deleted file mode 100644 index 56ae9d85c4..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaEvolutionTest.php +++ /dev/null @@ -1,88 +0,0 @@ -expectNotToPerformAssertions(); - - (new SchemaEvolution())->validate( - schema(int_schema('id'), str_schema('name')), - schema(int_schema('id'), str_schema('name')), - ); - } - - public function test_narrowing_nullable_column_to_non_nullable_is_valid(): void - { - $this->expectNotToPerformAssertions(); - - (new SchemaEvolution())->validate(schema(str_schema('name', nullable: true)), schema(str_schema('name'))); - } - - public function test_new_non_nullable_column_throws(): void - { - $this->expectException(IncompatibleSchemaException::class); - $this->expectExceptionMessage('adds new column "email" which must be nullable'); - - (new SchemaEvolution())->validate(schema(int_schema('id')), schema(int_schema('id'), str_schema('email'))); - } - - public function test_new_nullable_column_is_valid(): void - { - $this->expectNotToPerformAssertions(); - - (new SchemaEvolution())->validate( - schema(int_schema('id')), - schema(int_schema('id'), str_schema('email', nullable: true)), - ); - } - - public function test_nullable_incoming_column_on_non_nullable_file_column_throws(): void - { - $this->expectException(IncompatibleSchemaException::class); - $this->expectExceptionMessage('changes column "id"'); - - (new SchemaEvolution())->validate(schema(int_schema('id')), schema(int_schema('id', nullable: true))); - } - - public function test_omitting_non_nullable_column_throws(): void - { - $this->expectException(IncompatibleSchemaException::class); - $this->expectExceptionMessage('omits column "id" which is not nullable'); - - (new SchemaEvolution())->validate( - schema(int_schema('id'), str_schema('name', nullable: true)), - schema(str_schema('name', nullable: true)), - ); - } - - public function test_omitting_nullable_column_is_valid(): void - { - $this->expectNotToPerformAssertions(); - - (new SchemaEvolution())->validate( - schema(int_schema('id'), str_schema('name', nullable: true)), - schema(int_schema('id')), - ); - } - - public function test_type_change_throws(): void - { - $this->expectException(IncompatibleSchemaException::class); - $this->expectExceptionMessage('changes column "id" from integer to string'); - - (new SchemaEvolution())->validate(schema(int_schema('id')), schema(str_schema('id'))); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaTrackerTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaTrackerTest.php deleted file mode 100644 index cb6524ea6a..0000000000 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/SchemaTrackerTest.php +++ /dev/null @@ -1,129 +0,0 @@ -fits($plan, $row)); - } - - public function test_row_with_same_entries_fits(): void - { - $plan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1), str_entry('b', 'x'))); - $row = row(int_entry('a', 2), str_entry('b', 'y')); - - static::assertTrue((new SchemaTracker())->fits($plan, $row)); - } - - public function test_row_with_a_new_column_does_not_fit(): void - { - $plan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1))); - $row = row(int_entry('a', 2), int_entry('b', 3)); - - static::assertFalse((new SchemaTracker())->fits($plan, $row)); - } - - public function test_row_with_a_column_absent_from_the_plan_does_not_fit(): void - { - $plan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1))); - $row = row(int_entry('b', 2)); - - static::assertFalse((new SchemaTracker())->fits($plan, $row)); - } - - public function test_row_with_an_incompatible_type_does_not_fit(): void - { - $plan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1))); - $row = row(str_entry('a', 'x')); - - static::assertFalse((new SchemaTracker())->fits($plan, $row)); - } - - public function test_row_with_a_different_list_element_type_does_not_fit(): void - { - $plan = FloeWriter::growSectionPlan(null, row(list_entry('a', [1], type_list(type_integer())))); - $row = row(list_entry('a', ['x'], type_list(type_string()))); - - static::assertFalse((new SchemaTracker())->fits($plan, $row)); - } - - public function test_row_with_equal_but_not_identical_list_type_fits(): void - { - $plan = FloeWriter::growSectionPlan(null, row(list_entry('a', [1], type_list(type_integer())))); - - $tracker = new SchemaTracker(); - $row = row(list_entry('a', [2, 3], type_list(type_integer()))); - - static::assertTrue($tracker->fits($plan, $row)); - static::assertTrue($tracker->fits($plan, $row)); - } - - public function test_cached_scalar_fingerprint_does_not_mask_a_type_change(): void - { - $plan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1))); - - $tracker = new SchemaTracker(); - - static::assertTrue($tracker->fits($plan, row(int_entry('a', 2)))); - static::assertTrue($tracker->fits($plan, row(int_entry('a', 3)))); - static::assertFalse($tracker->fits($plan, row(str_entry('a', 'x')))); - } - - public function test_row_with_custom_metadata_still_fits(): void - { - // documented limitation: column metadata is captured once per schema frame, - // per-row metadata drift does not force a new section - $plan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1))); - $row = row(int_entry('a', 2, Metadata::fromArray(['custom' => 'meta']))); - - static::assertTrue((new SchemaTracker())->fits($plan, $row)); - } - - public function test_row_with_numeric_column_name_fits(): void - { - // a numeric column name coerces to an int key in the name-keyed plan; - // the lookup key coerces identically, so the column still matches - $plan = FloeWriter::growSectionPlan(null, row(int_entry('123', 1))); - - static::assertTrue((new SchemaTracker())->fits($plan, row(int_entry('123', 2)))); - static::assertFalse((new SchemaTracker())->fits($plan, row(str_entry('123', 'x')))); - } - - public function test_row_with_from_null_string_entry_fits_plain_string_plan(): void - { - $plan = FloeWriter::growSectionPlan(null, row(str_entry('a', 'value'))); - $row = row(StringEntry::fromNull('a')); - - static::assertTrue((new SchemaTracker())->fits($plan, $row)); - } - - public function test_row_with_null_value_still_fits(): void - { - $plan = FloeWriter::growSectionPlan(null, row(str_entry('a', 'value'))); - $row = row(str_entry('a', null)); - - static::assertTrue((new SchemaTracker())->fits($plan, $row)); - } -} diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/SectionTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/SectionTest.php index c24510b808..8646563ab3 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/SectionTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/SectionTest.php @@ -14,28 +14,28 @@ public function test_from_array_with_missing_field_throws(): void { $this->expectException(FloeException::class); - Section::fromArray(['offset' => 6, 'schemaId' => 0]); + Section::fromArray(['offset' => 6, 'partitionsId' => 0]); } public function test_from_array_with_non_integer_field_throws(): void { $this->expectException(FloeException::class); - Section::fromArray(['offset' => '6', 'schemaId' => 0, 'rowCount' => 1]); + Section::fromArray(['offset' => '6', 'partitionsId' => 0, 'rowCount' => 1]); } - public function test_from_array_with_non_integer_schema_id_throws(): void + public function test_from_array_with_non_integer_partitions_id_throws(): void { $this->expectException(FloeException::class); - Section::fromArray(['offset' => 6, 'schemaId' => '0', 'rowCount' => 1]); + Section::fromArray(['offset' => 6, 'partitionsId' => '0', 'rowCount' => 1]); } public function test_normalize_round_trips(): void { - $section = new Section(6, 0, 100); + $section = new Section(6, 2, 100); static::assertEquals($section, Section::fromArray($section->normalize())); - static::assertSame(['offset' => 6, 'schemaId' => 0, 'rowCount' => 100], $section->normalize()); + static::assertSame(['offset' => 6, 'partitionsId' => 2, 'rowCount' => 100], $section->normalize()); } } diff --git a/src/core/etl/tests/Flow/Floe/Tests/Unit/ValueEncoderTest.php b/src/core/etl/tests/Flow/Floe/Tests/Unit/ValueEncoderTest.php index 9ed67a0f0c..995ad89c12 100644 --- a/src/core/etl/tests/Flow/Floe/Tests/Unit/ValueEncoderTest.php +++ b/src/core/etl/tests/Flow/Floe/Tests/Unit/ValueEncoderTest.php @@ -18,9 +18,14 @@ use stdClass; use function Flow\Types\DSL\type_callable; +use function Flow\Types\DSL\type_date; +use function Flow\Types\DSL\type_datetime; use function Flow\Types\DSL\type_integer; +use function Flow\Types\DSL\type_json; use function Flow\Types\DSL\type_list; use function Flow\Types\DSL\type_mixed; +use function Flow\Types\DSL\type_time_zone; +use function Flow\Types\DSL\type_uuid; use function ord; use function pack; @@ -110,6 +115,17 @@ public function test_integer_list_fast_path_is_bulk_packed(): void static::assertSame(pack('V', 0), $encoder->encode([])); } + public function test_stateful_encoders_are_shared_across_calls(): void + { + $factory = new ValueEncoder(); + + static::assertSame($factory->encoderFor(type_datetime()), $factory->encoderFor(type_datetime())); + static::assertSame($factory->encoderFor(type_datetime()), $factory->encoderFor(type_date())); + static::assertSame($factory->encoderFor(type_time_zone()), $factory->encoderFor(type_time_zone())); + static::assertSame($factory->encoderFor(type_uuid()), $factory->encoderFor(type_uuid())); + static::assertSame($factory->encoderFor(type_json()), $factory->encoderFor(type_json())); + } + public function test_round_trip_of_dynamic_values(): void { $encoder = new DynamicEncoder(); diff --git a/src/core/etl/tests/Flow/Serializer/Tests/Unit/Base64SerializerTest.php b/src/core/etl/tests/Flow/Serializer/Tests/Unit/Base64SerializerTest.php index b396fa13d1..3bef029532 100644 --- a/src/core/etl/tests/Flow/Serializer/Tests/Unit/Base64SerializerTest.php +++ b/src/core/etl/tests/Flow/Serializer/Tests/Unit/Base64SerializerTest.php @@ -6,8 +6,8 @@ use DateTimeImmutable; use Flow\ETL\Row; -use Flow\ETL\Rows; use Flow\Serializer\Base64Serializer; +use Flow\Serializer\Exception\SerializationException; use Flow\Serializer\NativePHPSerializer; use PHPUnit\Framework\TestCase; @@ -20,6 +20,8 @@ use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\struct_entry; +use function Flow\Serializer\DSL\serialize_to_string; +use function Flow\Serializer\DSL\unserialize_from_string; use function Flow\Types\DSL\type_integer; use function Flow\Types\DSL\type_string; use function Flow\Types\DSL\type_structure; @@ -47,10 +49,16 @@ public function test_serializing_rows(): void $serializer = new Base64Serializer(new NativePHPSerializer()); - $serialized = $serializer->serialize($rows); + $serialized = serialize_to_string($serializer, $rows); - $unserialized = $serializer->unserialize($serialized, [Rows::class]); + static::assertEquals($rows, unserialize_from_string($serializer, $serialized)); + } + + public function test_unserialize_of_invalid_base64_throws(): void + { + $this->expectException(SerializationException::class); + $this->expectExceptionMessage('failed to decode string'); - static::assertEquals($rows, $unserialized); + unserialize_from_string(new Base64Serializer(new NativePHPSerializer()), '@@@ not base64 @@@'); } } diff --git a/src/core/etl/tests/Flow/Serializer/Tests/Unit/CompressingSerializerTest.php b/src/core/etl/tests/Flow/Serializer/Tests/Unit/CompressingSerializerTest.php index 3f84487b46..633e0244b6 100644 --- a/src/core/etl/tests/Flow/Serializer/Tests/Unit/CompressingSerializerTest.php +++ b/src/core/etl/tests/Flow/Serializer/Tests/Unit/CompressingSerializerTest.php @@ -6,7 +6,6 @@ use DateTimeImmutable; use Flow\ETL\Row; -use Flow\ETL\Rows; use Flow\Serializer\CompressingSerializer; use Flow\Serializer\NativePHPSerializer; use PHPUnit\Framework\TestCase; @@ -20,6 +19,8 @@ use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\struct_entry; +use function Flow\Serializer\DSL\serialize_to_string; +use function Flow\Serializer\DSL\unserialize_from_string; use function Flow\Types\DSL\type_integer; use function Flow\Types\DSL\type_string; use function Flow\Types\DSL\type_structure; @@ -55,10 +56,8 @@ public function test_serializing_rows(): void $serializer = new CompressingSerializer(new NativePHPSerializer()); - $serialized = $serializer->serialize($rows); + $serialized = serialize_to_string($serializer, $rows); - $unserialized = $serializer->unserialize($serialized, [Rows::class]); - - static::assertEquals($rows, $unserialized); + static::assertEquals($rows, unserialize_from_string($serializer, $serialized)); } } diff --git a/src/core/etl/tests/Flow/Serializer/Tests/Unit/NativePHPSerializerTest.php b/src/core/etl/tests/Flow/Serializer/Tests/Unit/NativePHPSerializerTest.php index f0da224b09..9fab2554c0 100644 --- a/src/core/etl/tests/Flow/Serializer/Tests/Unit/NativePHPSerializerTest.php +++ b/src/core/etl/tests/Flow/Serializer/Tests/Unit/NativePHPSerializerTest.php @@ -6,7 +6,7 @@ use DateTimeImmutable; use Flow\ETL\Row; -use Flow\ETL\Rows; +use Flow\Serializer\Exception\SerializationException; use Flow\Serializer\NativePHPSerializer; use PHPUnit\Framework\TestCase; @@ -19,10 +19,13 @@ use function Flow\ETL\DSL\rows; use function Flow\ETL\DSL\str_entry; use function Flow\ETL\DSL\struct_entry; +use function Flow\Serializer\DSL\serialize_to_string; +use function Flow\Serializer\DSL\unserialize_from_string; use function Flow\Types\DSL\type_integer; use function Flow\Types\DSL\type_string; use function Flow\Types\DSL\type_structure; use function range; +use function serialize; final class NativePHPSerializerTest extends TestCase { @@ -46,8 +49,16 @@ public function test_serializing_rows(): void $serializer = new NativePHPSerializer(); - $serialized = $serializer->serialize($rows); + $serialized = serialize_to_string($serializer, $rows); - static::assertEquals($rows, $serializer->unserialize($serialized, [Rows::class])); + static::assertEquals($rows, unserialize_from_string($serializer, $serialized)); + } + + public function test_unserialize_of_non_rows_payload_throws(): void + { + $this->expectException(SerializationException::class); + $this->expectExceptionMessage('must return instance of'); + + unserialize_from_string(new NativePHPSerializer(), serialize('just a string')); } } diff --git a/src/extension/flow-php-ext/Cargo.toml b/src/extension/flow-php-ext/Cargo.toml index 74d620099c..0750f0acaf 100644 --- a/src/extension/flow-php-ext/Cargo.toml +++ b/src/extension/flow-php-ext/Cargo.toml @@ -10,4 +10,4 @@ crate-type = ["cdylib"] [dependencies] ext-php-rs = "0.15" serde = { version = "1", features = ["derive"] } -serde_json = "1" +serde_json = { version = "1", features = ["raw_value"] } diff --git a/src/extension/flow-php-ext/README.md b/src/extension/flow-php-ext/README.md index 8795b21169..e56869c4de 100644 --- a/src/extension/flow-php-ext/README.md +++ b/src/extension/flow-php-ext/README.md @@ -1,39 +1,15 @@ -# Flow PHP - Native Extension +# Extension: Flow PHP -A PHP extension written in Rust ([ext-php-rs](https://github.com/extphprs/ext-php-rs)) providing -native implementations for performance-critical parts of the Flow DataFrame framework. It encodes and -decodes the frames of the Flow **Floe** binary format (`.floe`; the canonical PHP implementation -lives in `Flow\Floe` in `flow-php/etl`). `Flow\Floe\FloeReader`/`FloeWriter` keep file header/footer -assembly in PHP and delegate frame work to the extension: +A Rust-powered PHP extension using [ext-php-rs](https://github.com/extphprs/ext-php-rs) providing native +implementations for performance-critical parts of the Flow DataFrame framework: encoding and decoding of the +Floe binary format frames and row hydration/casting against a schema. The extension is optional — the pure-PHP +implementations in `flow-php/etl` are the canonical behavior reference, and Flow routes to the native ones +automatically when the extension is loaded. -```php -$decoder = new Flow\Floe\RowsDecoder(); -$decoder->schema($schemaFrameBody); -$row = $decoder->row($rowFrameBody); // Flow\ETL\Row -$rows = $decoder->rows([$rowFrameBody, ...]); // batched: Flow\ETL\Rows +> [!IMPORTANT] +> This repository is a subtree split from our monorepo. If you'd like to contribute, please visit our main monorepo [flow-php/flow](https://github.com/flow-php/flow). -$encoder = new Flow\Floe\RowsEncoder(); -$encoder->schema($schemaFrameBody); -$rowFrameBody = $encoder->row($row); // byte-identical to Flow\Floe\RowEncoder -$segments = $encoder->rows($rows); // batched: framed ROW bytes per section, - // list of Flow\Floe\FrameSegment -``` - -The extension is always optional: `FloeReader`/`FloeWriter` route to it automatically when `flow_php` -is loaded, and behavior is identical with or without it. Extension errors surface as -`Flow\Floe\Exception\ExtensionException` — there is no silent fallback. All 17 entry types are -covered; xml/xml_element/html/html_element values delegate DOM (de)construction to the pure-PHP -`Flow\Floe\ValueDecoder`/`ValueEncoder` static methods. Only `DateTime`/`DateTimeImmutable` are -supported — datetime subclasses throw. - -## Build - -```bash -nix-shell --arg with-rust true --run "cd src/extension/flow-php-ext && make build" -``` - -## Test - -```bash -nix-shell --arg with-rust true --run "cd src/extension/flow-php-ext && make test" -``` +- 📜 [Documentation](https://flow-php.com/documentation/components/extensions/flow-php-ext/) +- ➡️ [Installation](https://flow-php.com/documentation/installation/packages/flow-php-ext/) +- 🛠️ [Contributing](https://flow-php.com/documentation/contributing/) +- 🚧 [Upgrading](https://flow-php.com/documentation/upgrading/) diff --git a/src/extension/flow-php-ext/composer.json b/src/extension/flow-php-ext/composer.json index af377f33df..e78a7ed00f 100644 --- a/src/extension/flow-php-ext/composer.json +++ b/src/extension/flow-php-ext/composer.json @@ -9,6 +9,7 @@ }, "autoload": { "psr-4": { + "Flow\\ETL\\Row\\": "php/Flow/ETL/Row/", "Flow\\Floe\\": "php/Flow/Floe/" } }, diff --git a/src/extension/flow-php-ext/php/Flow/Floe/RowsDecoder.php b/src/extension/flow-php-ext/php/Flow/ETL/Row/RustRowHydratorNative.php similarity index 51% rename from src/extension/flow-php-ext/php/Flow/Floe/RowsDecoder.php rename to src/extension/flow-php-ext/php/Flow/ETL/Row/RustRowHydratorNative.php index 7d8f4a6d7f..c5ca5f8848 100644 --- a/src/extension/flow-php-ext/php/Flow/Floe/RowsDecoder.php +++ b/src/extension/flow-php-ext/php/Flow/ETL/Row/RustRowHydratorNative.php @@ -2,11 +2,10 @@ declare(strict_types=1); -namespace Flow\Floe; +namespace Flow\ETL\Row; -use Flow\ETL\Row; use Flow\ETL\Rows; -use Flow\Floe\Exception\ExtensionException; +use Flow\ETL\Schema; use RuntimeException; use function extension_loaded; @@ -15,11 +14,7 @@ return; } -/** - * Stateful Floe frame decoder for streaming reads - the PHP side keeps - * buffering/framing and hands over bare SCHEMA/ROW frame bodies. - */ -final class RowsDecoder +final class RustRowHydratorNative { public function __construct() { @@ -27,27 +22,25 @@ public function __construct() } /** - * @throws ExtensionException + * @param list $batch */ - public function row(string $frameBody): Row + public function cast(array $batch, Schema $schema): Rows { throw new RuntimeException('flow_php extension is not loaded'); } /** - * @param array $frameBodies - * - * @throws ExtensionException + * @param list $batch */ - public function rows(array $frameBodies): Rows + public function hydrate(array $batch, ?Schema $schema = null): Rows { throw new RuntimeException('flow_php extension is not loaded'); } /** - * @throws ExtensionException + * @return list */ - public function schema(string $frameBody): void + public function dehydrate(Rows $rows): array { throw new RuntimeException('flow_php extension is not loaded'); } diff --git a/src/extension/flow-php-ext/php/Flow/Floe/RowsEncoder.php b/src/extension/flow-php-ext/php/Flow/Floe/RowsEncoder.php deleted file mode 100644 index 927ef4c5ee..0000000000 --- a/src/extension/flow-php-ext/php/Flow/Floe/RowsEncoder.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ - public function rows(Rows $rows): array - { - throw new RuntimeException('flow_php extension is not loaded'); - } - - /** - * @throws ExtensionException - */ - public function schema(string $frameBody): void - { - throw new RuntimeException('flow_php extension is not loaded'); - } -} diff --git a/src/extension/flow-php-ext/php/Flow/Floe/RustFloeEncoderNative.php b/src/extension/flow-php-ext/php/Flow/Floe/RustFloeEncoderNative.php new file mode 100644 index 0000000000..2c9b5a6bca --- /dev/null +++ b/src/extension/flow-php-ext/php/Flow/Floe/RustFloeEncoderNative.php @@ -0,0 +1,50 @@ + $batch + * @param string $schemaBody SCHEMA frame body (JSON list of normalized definitions) + * + * @throws ExtensionException + * + * @return list bare ROW frame bodies + */ + public function encode(array $batch, string $schemaBody): array + { + throw new RuntimeException('flow_php extension is not loaded'); + } + + /** + * @param list $frameBodies + * @param string $schemaBody SCHEMA frame body (JSON list of normalized definitions) + * + * @throws ExtensionException + * + * @return list + */ + public function decode(array $frameBodies, string $schemaBody): array + { + throw new RuntimeException('flow_php extension is not loaded'); + } +} diff --git a/src/extension/flow-php-ext/src/cast.rs b/src/extension/flow-php-ext/src/cast.rs new file mode 100644 index 0000000000..01bd97e147 --- /dev/null +++ b/src/extension/flow-php-ext/src/cast.rs @@ -0,0 +1,830 @@ +use ext_php_rs::boxed::ZBox; +use ext_php_rs::exception::PhpException; +use ext_php_rs::flags::DataType; +use ext_php_rs::types::{ZendHashTable, ZendObject, ZendStr, Zval}; +use ext_php_rs::zend::Function; + +use crate::ctx::{ + array_key_index, call_handle, call_handle_on, call_handle_transparent, ce_method_ref, + construct_with_zvals, ht_find_key, ht_insert, ht_insert_key, write_slot, zval_long, zval_str, + Ctx, HtKey, +}; +use crate::encode::{expect_object, ht_for_each, read_slot}; +use crate::exception::ext_exception; +use crate::hydrate::{ + build_hydrate_plan, resolve_entry_definition, AssemblyClasses, DefRareFnCache, EntrySlotCache, + HydratePlan, RowValuesClass, +}; +use crate::plan::{parse_schema_json, TypeJson}; +use crate::values::date_from_free_form; + +extern "C" { + fn zval_get_long_func(op: *const Zval, is_strict: bool) -> i64; + fn zval_get_double_func(op: *const Zval) -> f64; + fn zval_get_string_func(op: *mut Zval) -> *mut ZendStr; +} + +pub(crate) enum MapKeyKind { + Int, + Str, +} + +pub(crate) struct StructureElement { + name: String, + kind: CastKind, + required: bool, +} + +pub(crate) enum CastKind { + Integer, + PositiveInteger, + Float, + Boolean, + String, + NonEmptyString, + DateTime, + Date, + Uuid, + Json, + List(Box), + Map(MapKeyKind, Box), + Structure(Vec), + Optional(Box), + Fallback, +} + +fn build_structure_kind(type_json: &TypeJson) -> CastKind { + let mut elements = Vec::new(); + + let entries = type_json + .required_elements() + .map(|(name, element)| (name, element, true)) + .chain( + type_json + .structure_optional_elements() + .map(|(name, element)| (name, element, false)), + ); + + for (name, element, required) in entries { + // numeric element names would list-coerce the assembled array - + // PHP's final assert has odd edge behavior there, not worth mirroring + if array_key_index(name.as_bytes()).is_some() { + return CastKind::Fallback; + } + + elements.push(StructureElement { + name: name.clone(), + kind: build_cast_kind(element), + required, + }); + } + + if elements.is_empty() { + return CastKind::Fallback; + } + + CastKind::Structure(elements) +} + +fn build_cast_kind(type_json: &TypeJson) -> CastKind { + match type_json.type_.as_str() { + "integer" => CastKind::Integer, + "positive_integer" => CastKind::PositiveInteger, + "float" => CastKind::Float, + "boolean" => CastKind::Boolean, + "string" => CastKind::String, + "non_empty_string" => CastKind::NonEmptyString, + "datetime" => CastKind::DateTime, + "date" => CastKind::Date, + "uuid" => CastKind::Uuid, + "json" => CastKind::Json, + "list" => match type_json.element() { + Some(element) => CastKind::List(Box::new(build_cast_kind(element))), + None => CastKind::Fallback, + }, + "map" => match (type_json.key(), type_json.value()) { + (Some(key), Some(value)) => match key.type_.as_str() { + "integer" => CastKind::Map(MapKeyKind::Int, Box::new(build_cast_kind(value))), + "string" => CastKind::Map(MapKeyKind::Str, Box::new(build_cast_kind(value))), + _ => CastKind::Fallback, + }, + _ => CastKind::Fallback, + }, + "structure" => build_structure_kind(type_json), + "optional" => match type_json.base() { + Some(base) => CastKind::Optional(Box::new(build_cast_kind(base))), + None => CastKind::Fallback, + }, + _ => CastKind::Fallback, + } +} + +struct CastColumn { + kind: CastKind, + /// The retained `$definition->type()` object - the fallback receiver. + type_zv: Zval, + /// `Type::cast` resolved on the concrete type class. + cast_fn: &'static Function, +} + +pub struct CastPlan { + hydrate: HydratePlan, + columns: Vec, +} + +fn build_cast_plan( + schema: &Zval, + entry_slot_cache: &mut EntrySlotCache, + ctx: &mut Ctx, +) -> Result { + let hydrate = build_hydrate_plan(schema, entry_slot_cache)?; + + let schema_obj = expect_object(schema, "a Schema")?; + let schema_ce = unsafe { schema_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve the Schema class"))?; + let normalize_fn = ce_method_ref(schema_ce, "normalize")?; + let normalized = call_handle_on(normalize_fn, schema_obj, &mut [], "normalize a schema")?; + + let json = { + let json_encode = ctx.json_encode()?; + call_handle( + json_encode, + None, + &mut [normalized.shallow_clone()], + "encode a schema as JSON", + )? + }; + let json_bytes = json + .zend_str() + .ok_or_else(|| ext_exception("flow_php expected schema JSON to be a string"))? + .as_bytes(); + + let definitions = parse_schema_json(json_bytes)?; + + if definitions.len() != hydrate.columns.len() { + return Err(ext_exception( + "flow_php normalized schema JSON does not match the schema definitions", + )); + } + + let mut columns = Vec::with_capacity(definitions.len()); + + for (definition, column) in definitions.iter().zip(&hydrate.columns) { + if column.name_zv.zend_str().map(ZendStr::as_bytes) != Some(definition.name.as_bytes()) { + return Err(ext_exception( + "flow_php normalized schema JSON does not match the schema definitions", + )); + } + + let def_obj = column + .base_def + .object() + .ok_or_else(|| ext_exception("flow_php expected a Definition object"))?; + let def_ce = unsafe { def_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a Definition class"))?; + + let type_fn = ce_method_ref(def_ce, "type")?; + let type_zv = call_handle_on(type_fn, def_obj, &mut [], "read a definition type")?; + let type_obj = type_zv + .object() + .ok_or_else(|| ext_exception("flow_php expected a definition type to be an object"))?; + let type_ce = unsafe { type_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a Type class"))?; + + columns.push(CastColumn { + kind: build_cast_kind(&definition.type_), + cast_fn: ce_method_ref(type_ce, "cast")?, + type_zv, + }); + } + + Ok(CastPlan { hydrate, columns }) +} + +/// Same invalidation as `ensure_hydrate_plan`: the Schema `definitions` array +/// address identifies the definition set; retaining it prevents address reuse. +fn ensure_cast_plan( + plan: &mut Option, + schema: &Zval, + entry_slot_cache: &mut EntrySlotCache, + ctx: &mut Ctx, +) -> Result<(), PhpException> { + let schema_obj = expect_object(schema, "a Schema")?; + + let current = plan.as_ref().and_then(|p| { + read_slot(schema_obj, p.hydrate.definitions_slot) + .array() + .zip(p.hydrate.definitions_retained.array()) + }); + + if current.is_some_and(|(definitions, retained)| std::ptr::eq(definitions, retained)) { + return Ok(()); + } + + *plan = Some(build_cast_plan(schema, entry_slot_cache, ctx)?); + + Ok(()) +} + +/// `HASH_FLAG_PACKED` from zend_types.h. +const HASH_FLAG_PACKED: u8 = 1 << 2; + +/// In-order hashtable walk yielding `(string key, numeric key, value)` - the +/// early-exit sibling of `encode::ht_for_each` for the container cast checks. +struct HtEntries<'a> { + ht: &'a ZendHashTable, + packed: bool, + index: u32, +} + +fn ht_entries(ht: &ZendHashTable) -> HtEntries<'_> { + HtEntries { + ht, + packed: unsafe { ht.u.v.flags } & HASH_FLAG_PACKED != 0, + index: 0, + } +} + +impl<'a> Iterator for HtEntries<'a> { + type Item = (Option<&'a ZendStr>, u64, &'a Zval); + + fn next(&mut self) -> Option { + while self.index < self.ht.nNumUsed { + let position = self.index as usize; + self.index += 1; + + if self.packed { + let value = unsafe { &*self.ht.__bindgen_anon_1.arPacked.add(position) }; + + if value.get_type() == DataType::Undef { + continue; + } + + return Some((None, position as u64, value)); + } + + let bucket = unsafe { &*self.ht.__bindgen_anon_1.arData.add(position) }; + + if bucket.val.get_type() == DataType::Undef { + continue; + } + + return Some((unsafe { bucket.key.as_ref() }, bucket.h, &bucket.val)); + } + + None + } +} + +fn engine_long(value: &Zval) -> i64 { + unsafe { zval_get_long_func(std::ptr::from_ref(value), false) } +} + +fn engine_double(value: &Zval) -> f64 { + unsafe { zval_get_double_func(std::ptr::from_ref(value)) } +} + +fn engine_string(value: &Zval) -> Result, PhpException> { + let raw = unsafe { zval_get_string_func(std::ptr::from_ref(value).cast_mut()) }; + + unsafe { raw.as_mut() } + .map(|string| unsafe { ZBox::from_raw(string) }) + .ok_or_else(|| ext_exception("flow_php failed to convert a value to string")) +} + +/// `mb_strtolower` + table match from `BooleanType::cast`. ASCII lowering +/// suffices: no non-ASCII uppercase code point lowercases onto these words. +fn bool_from_str(bytes: &[u8]) -> Option { + if bytes.is_empty() || bytes.len() > 5 { + return None; + } + + let mut lowered = [0u8; 5]; + let lowered = &mut lowered[..bytes.len()]; + + for (target, source) in lowered.iter_mut().zip(bytes) { + *target = source.to_ascii_lowercase(); + } + + match &*lowered { + b"true" | b"1" | b"yes" | b"on" => Some(true), + b"false" | b"0" | b"no" | b"off" => Some(false), + _ => None, + } +} + +/// The `Uuid::UUID_REGEXP` pattern: 8-4-4-4-12 LOWERCASE hex groups. +fn is_uuid(bytes: &[u8]) -> bool { + if bytes.len() != 36 { + return false; + } + + bytes.iter().enumerate().all(|(index, byte)| match index { + 8 | 13 | 18 | 23 => *byte == b'-', + _ => matches!(byte, b'0'..=b'9' | b'a'..=b'f'), + }) +} + +/// The cheap prefix of `Json::isValid`: non-empty + matching `{}`/`[]` pair. +fn json_gate(bytes: &[u8]) -> bool { + bytes.len() >= 2 + && ((bytes[0] == b'{' && bytes[bytes.len() - 1] == b'}') + || (bytes[0] == b'[' && bytes[bytes.len() - 1] == b']')) +} + +fn json_object_from(bytes: &[u8], ctx: &mut Ctx) -> Result { + let (json_ce, value_slot, is_object_slot) = ctx.json()?; + let mut json = ZendObject::new(json_ce); + write_slot(&mut json, value_slot, zval_str(bytes)); + + let mut is_object_zv = Zval::new(); + is_object_zv.set_bool(bytes[0] == b'{' && bytes[bytes.len() - 1] == b'}'); + write_slot(&mut json, is_object_slot, is_object_zv); + + let mut zv = Zval::new(); + zv.set_object(&mut json); + + Ok(zv) +} + +fn null_zval() -> Zval { + let mut zv = Zval::new(); + zv.set_null(); + zv +} + +fn coercible_scalar(value: &Zval) -> bool { + value.is_string() || value.is_bool() || value.is_null() +} + +/// Casts one value natively; `Ok(None)` bails the WHOLE column value to the +/// PHP fallback (`Type::cast`), which reproduces results, exception classes, +/// messages and `previous` chains by re-running the canonical implementation. +/// PHP calls made inside a branch discard their own thrown exceptions and bail +/// instead - mirroring the `catch (Throwable)` wrappers in the PHP casts. +fn cast_value(kind: &CastKind, value: &Zval, ctx: &mut Ctx) -> Result, PhpException> { + Ok(match kind { + CastKind::Integer => { + if value.is_long() { + Some(value.shallow_clone()) + } else if value.is_double() || coercible_scalar(value) { + Some(zval_long(engine_long(value))) + } else { + None + } + } + CastKind::PositiveInteger => match value.long() { + Some(long) if long > 0 => Some(value.shallow_clone()), + _ => None, + }, + CastKind::Float => { + if value.is_double() { + Some(value.shallow_clone()) + } else if value.is_long() || coercible_scalar(value) { + let mut zv = Zval::new(); + zv.set_double(engine_double(value)); + Some(zv) + } else { + None + } + } + CastKind::Boolean => { + if value.is_bool() { + Some(value.shallow_clone()) + } else if let Some(string) = value.zend_str() { + let mut zv = Zval::new(); + zv.set_bool(bool_from_str(string.as_bytes()).unwrap_or_else(|| value.coerce_to_bool())); + Some(zv) + } else if value.is_long() || value.is_double() || value.is_null() { + let mut zv = Zval::new(); + zv.set_bool(value.coerce_to_bool()); + Some(zv) + } else { + None + } + } + CastKind::String => { + if value.is_string() { + Some(value.shallow_clone()) + } else if value.is_long() || value.is_double() { + let mut zv = Zval::new(); + zv.set_zend_string(engine_string(value)?); + Some(zv) + } else if value.is_true() || value.is_false() { + Some(ctx.bool_str(value.is_true())?.shallow_clone()) + } else if value.is_null() { + Some(zval_str(b"")) + } else { + None + } + } + CastKind::NonEmptyString => { + if value.zend_str().is_some_and(|s| !s.as_bytes().is_empty()) { + Some(value.shallow_clone()) + } else if value.is_long() || value.is_double() { + // engine string form of a number is never empty + let mut zv = Zval::new(); + zv.set_zend_string(engine_string(value)?); + Some(zv) + } else if value.is_true() || value.is_false() { + Some(ctx.bool_str(value.is_true())?.shallow_clone()) + } else { + None + } + } + CastKind::DateTime => { + if let Some(object) = value.object() { + let immutable_ce = ctx.datetime_fns(false)?.ce; + + if object.instance_of(immutable_ce) { + Some(value.shallow_clone()) + } else { + None + } + } else if let Some(string) = value.zend_str() { + date_from_free_form(string.as_bytes(), ctx)? + } else if value.is_long() || value.is_double() { + date_from_free_form(×tamp_string(value)?, ctx)? + } else { + None + } + } + CastKind::Date => cast_date(value, ctx)?, + CastKind::Uuid => { + if let Some(object) = value.object() { + let (uuid_ce, _) = ctx.uuid()?; + + if object.instance_of(uuid_ce) { + Some(value.shallow_clone()) + } else { + None + } + } else if let Some(string) = value.zend_str() { + if is_uuid(string.as_bytes()) { + let (uuid_ce, value_slot) = ctx.uuid()?; + let mut uuid = ZendObject::new(uuid_ce); + write_slot(&mut uuid, value_slot, zval_str(string.as_bytes())); + + let mut zv = Zval::new(); + zv.set_object(&mut uuid); + Some(zv) + } else { + None + } + } else { + None + } + } + CastKind::Json => cast_json(value, ctx)?, + CastKind::List(inner) => { + let Some(values) = value.array() else { + return Ok(None); + }; + + let mut out = ZendHashTable::with_capacity(values.len() as u32); + let mut expected = 0u64; + + for (string_key, index, item) in ht_entries(values) { + if string_key.is_some() || index != expected { + return Ok(None); + } + + expected += 1; + + let Some(casted) = cast_value(inner, item, ctx)? else { + return Ok(None); + }; + + out.push(casted).map_err(|e| { + ext_exception(format!("flow_php failed to collect list values: {e:?}")) + })?; + } + + let mut zv = Zval::new(); + zv.set_hashtable(out); + Some(zv) + } + CastKind::Map(key_kind, value_kind) => { + let Some(values) = value.array() else { + return Ok(None); + }; + + let mut out = ZendHashTable::with_capacity(values.len() as u32); + + for (string_key, index, item) in ht_entries(values) { + let key = match (key_kind, string_key) { + (MapKeyKind::Int, None) => HtKey::Index(index as i64), + (MapKeyKind::Str, Some(name)) => HtKey::Str(name), + _ => return Ok(None), + }; + + let Some(casted) = cast_value(value_kind, item, ctx)? else { + return Ok(None); + }; + + ht_insert_key(&mut out, &key, casted); + } + + let mut zv = Zval::new(); + zv.set_hashtable(out); + Some(zv) + } + CastKind::Structure(elements) => { + let Some(values) = value.array() else { + return Ok(None); + }; + + let mut out = ZendHashTable::with_capacity(elements.len() as u32); + let mut matched = 0usize; + + for element in elements { + let Some(item) = values.get(element.name.as_str()) else { + if element.required { + // PHP feeds cast(null) to absent required elements + return Ok(None); + } + + continue; + }; + + let Some(casted) = cast_value(&element.kind, item, ctx)? else { + return Ok(None); + }; + + ht_insert(&mut out, element.name.as_bytes(), casted); + matched += 1; + } + + if matched == 0 { + // an all-optional structure with no matched keys fails PHP's assert + return Ok(None); + } + + let mut zv = Zval::new(); + zv.set_hashtable(out); + Some(zv) + } + CastKind::Optional(inner) => { + if value.is_null() { + Some(null_zval()) + } else { + cast_value(inner, value, ctx)? + } + } + CastKind::Fallback => None, + }) +} + +/// `"@" . $value` with the engine's number-to-string conversion. +fn timestamp_string(value: &Zval) -> Result, PhpException> { + let number = engine_string(value)?; + let mut bytes = Vec::with_capacity(number.as_bytes().len() + 1); + bytes.push(b'@'); + bytes.extend_from_slice(number.as_bytes()); + + Ok(bytes) +} + +fn cast_date(value: &Zval, ctx: &mut Ctx) -> Result, PhpException> { + if let Some(object) = value.object() { + let immutable_ce = ctx.datetime_fns(false)?.ce; + + if !object.instance_of(immutable_ce) { + return Ok(None); + } + + let fns = ctx.datetime_cast_fns(object.ce.cast_const())?; + let (set_time, format) = (fns.set_time, fns.format); + let his = ctx.format_his()?.shallow_clone(); + + // isValid passthrough: midnight keeps the SAME object (serialize + // back-reference topology); a thrown format() bails like PHP's catch + let Ok(formatted) = call_handle_transparent(format, Some(object), &mut [his]) else { + return Ok(None); + }; + + if formatted.zend_str().map(ZendStr::as_bytes) == Some(b"00:00:00") { + return Ok(Some(value.shallow_clone())); + } + + return set_midnight(set_time, object); + } + + let parsed = if let Some(string) = value.zend_str() { + date_from_free_form(string.as_bytes(), ctx)? + } else if value.is_long() || value.is_double() { + date_from_free_form(×tamp_string(value)?, ctx)? + } else { + None + }; + + let Some(datetime) = parsed else { + return Ok(None); + }; + let object = datetime + .object() + .ok_or_else(|| ext_exception("flow_php expected a datetime object"))?; + let set_time = ctx.datetime_cast_fns(object.ce.cast_const())?.set_time; + + set_midnight(set_time, object) +} + +fn set_midnight( + set_time: &'static Function, + object: &ZendObject, +) -> Result, PhpException> { + let mut args = [zval_long(0), zval_long(0), zval_long(0), zval_long(0)]; + + let Ok(result) = call_handle_transparent(set_time, Some(object), &mut args) else { + return Ok(None); + }; + + if !result.is_object() { + return Ok(None); + } + + Ok(Some(result)) +} + +fn cast_json(value: &Zval, ctx: &mut Ctx) -> Result, PhpException> { + if let Some(object) = value.object() { + let (json_ce, _, _) = ctx.json()?; + + if object.instance_of(json_ce) { + return Ok(Some(value.shallow_clone())); + } + + return Ok(None); + } + + if let Some(string) = value.zend_str() { + if !json_gate(string.as_bytes()) { + return Ok(None); + } + + let json_validate = ctx.json_validate()?; + let Ok(valid) = + call_handle_transparent(json_validate, None, &mut [value.shallow_clone()]) + else { + return Ok(None); + }; + + if !valid.bool().unwrap_or(false) { + return Ok(None); + } + + return Ok(Some(json_object_from(string.as_bytes(), ctx)?)); + } + + if value.is_array() { + // Json::fromArray's json_encode, in its non-throwing flavor: `false` + // (or a thrown JsonSerializable) bails to the PHP cast + let json_encode = ctx.json_encode()?; + let Ok(encoded) = call_handle_transparent(json_encode, None, &mut [value.shallow_clone()]) + else { + return Ok(None); + }; + + let Some(string) = encoded.zend_str() else { + return Ok(None); + }; + + if !json_gate(string.as_bytes()) { + return Ok(None); + } + + return Ok(Some(json_object_from(string.as_bytes(), ctx)?)); + } + + Ok(None) +} + +/// Native `PhpRowHydrator::cast`: raw scalars cast against a `Schema` and +/// assembled into `Flow\ETL\Rows` in one pass. Column values cast natively +/// where proven identical, otherwise per value through the retained PHP +/// `Type::cast`; a null value or an absent column yields a typed-null entry +/// (fill-missing), mirroring `instantiate(..., $prepare, fillMissing: true)`. +#[allow(clippy::too_many_arguments)] +pub fn cast_rows( + batch: &Zval, + schema: &Zval, + plan_slot: &mut Option, + raw_class: &RowValuesClass, + assembly: &AssemblyClasses, + entry_slot_cache: &mut EntrySlotCache, + def_rare_cache: &mut DefRareFnCache, + ctx: &mut Ctx, +) -> Result { + ensure_cast_plan(plan_slot, schema, entry_slot_cache, ctx)?; + let plan = plan_slot.as_ref().expect("plan built above"); + + let batch_ht = batch + .array() + .ok_or_else(|| ext_exception("flow_php expected a list of raw row values"))?; + + let mut rows_args: Vec = Vec::with_capacity(batch_ht.len()); + + ht_for_each(batch_ht, |_, _, rv_zv| { + let rv = expect_object(rv_zv, "a RawRowValues")?; + let values_ht = read_slot(rv, raw_class.values_slot) + .array() + .ok_or_else(|| ext_exception("flow_php expected RawRowValues::values to be an array"))?; + let metadata_ht = read_slot(rv, raw_class.metadata_slot).array().ok_or_else(|| { + ext_exception("flow_php expected RawRowValues::metadata to be an array") + })?; + + let mut entries_ht = ZendHashTable::with_capacity(plan.hydrate.columns.len() as u32); + let has_metadata = !metadata_ht.is_empty(); + + for (column, cast_column) in plan.hydrate.columns.iter().zip(&plan.columns) { + let key = column.key(); + + let (definition, entry_ce, entry_slots, casted) = + match ht_find_key(values_ht, &key) { + None => { + // fill-missing: typed-null entry from the ORIGINAL + // definition; per-value metadata is ignored for + // absent columns (PHP checks presence first) + let (definition, entry_ce, entry_slots) = resolve_entry_definition( + column, + None, + true, + entry_slot_cache, + def_rare_cache, + )?; + + (definition, entry_ce, entry_slots, null_zval()) + } + Some(value) => { + let metadata = if has_metadata { + ht_find_key(metadata_ht, &key) + } else { + None + }; + let value_is_null = value.is_null(); + + let (definition, entry_ce, entry_slots) = resolve_entry_definition( + column, + metadata, + value_is_null, + entry_slot_cache, + def_rare_cache, + )?; + + let casted = if value_is_null { + null_zval() + } else { + match cast_value(&cast_column.kind, value, ctx)? { + Some(casted) => casted, + None => { + let type_obj = + cast_column.type_zv.object().ok_or_else(|| { + ext_exception("flow_php expected a Type object") + })?; + + call_handle_transparent( + cast_column.cast_fn, + Some(type_obj), + &mut [value.shallow_clone()], + )? + } + } + }; + + (definition, entry_ce, entry_slots, casted) + } + }; + + let mut entry = ZendObject::new(entry_ce); + write_slot(&mut entry, entry_slots.0, column.name_zv.shallow_clone()); + write_slot(&mut entry, entry_slots.1, casted); + write_slot(&mut entry, entry_slots.2, definition); + + let mut entry_zv = Zval::new(); + entry_zv.set_object(&mut entry); + ht_insert_key(&mut entries_ht, &key, entry_zv); + } + + let mut entries_zv = Zval::new(); + entries_zv.set_hashtable(entries_ht); + let entries = call_handle( + assembly.entries_recreate, + None, + &mut [entries_zv], + "recreate row entries", + )?; + + let mut row = construct_with_zvals(assembly.row_ce, &mut [entries], "a Row")?; + let mut row_zv = Zval::new(); + row_zv.set_object(&mut row); + rows_args.push(row_zv); + + Ok(()) + })?; + + let mut rows = construct_with_zvals(assembly.rows_ce, &mut rows_args, "Rows")?; + let mut zv = Zval::new(); + zv.set_object(&mut rows); + + Ok(zv) +} diff --git a/src/extension/flow-php-ext/src/ctx.rs b/src/extension/flow-php-ext/src/ctx.rs index b9f770298e..445c794730 100644 --- a/src/extension/flow-php-ext/src/ctx.rs +++ b/src/extension/flow-php-ext/src/ctx.rs @@ -7,8 +7,8 @@ use ext_php_rs::boxed::ZBox; use ext_php_rs::convert::IntoZvalDyn; use ext_php_rs::exception::PhpException; use ext_php_rs::ffi::{ - _zend_property_info, zend_call_known_function, zend_hash_index_update, zend_hash_str_find, - zend_hash_str_update, zend_objects_clone_members, zend_ulong, + _zend_property_info, zend_call_known_function, zend_hash_find, zend_hash_index_update, + zend_hash_str_update, zend_hash_update, zend_ulong, }; use ext_php_rs::flags::ClassFlags; use ext_php_rs::types::{ZendHashTable, ZendObject, ZendStr, Zval}; @@ -61,6 +61,54 @@ pub fn ht_insert(ht: &mut ZendHashTable, key: &[u8], mut value: Zval) { std::mem::forget(value); } +/// A PHP array key resolved once per name: numeric-string names use index +/// slots (PHP array-key coercion), everything else keys by an existing +/// zend_string so the engine reuses its cached hash instead of allocating and +/// rehashing per operation (what the `str`-based variants do). +pub enum HtKey<'a> { + Index(i64), + Str(&'a ZendStr), +} + +impl<'a> HtKey<'a> { + pub fn from_zend_str(name: &'a ZendStr) -> Self { + match array_key_index(name.as_bytes()) { + Some(index) => Self::Index(index), + None => Self::Str(name), + } + } +} + +pub fn ht_find_key<'a>(ht: &'a ZendHashTable, key: &HtKey<'_>) -> Option<&'a Zval> { + match key { + HtKey::Index(index) => ht.get_index(*index), + HtKey::Str(name) => unsafe { + zend_hash_find(ht, std::ptr::from_ref(*name).cast_mut()).as_ref() + }, + } +} + +/// [`ht_insert`] for a pre-resolved key; ownership of `value` moves into the +/// table. +pub fn ht_insert_key(ht: &mut ZendHashTable, key: &HtKey<'_>, mut value: Zval) { + unsafe { + match key { + HtKey::Index(index) => { + zend_hash_index_update(ht, *index as u64, std::ptr::from_mut(&mut value)); + } + HtKey::Str(name) => { + zend_hash_update( + ht, + std::ptr::from_ref(*name).cast_mut(), + std::ptr::from_mut(&mut value), + ); + } + } + } + + std::mem::forget(value); +} + pub fn ht_insert_index(ht: &mut ZendHashTable, index: i64, mut value: Zval) { unsafe { zend_hash_index_update(ht, index as u64, std::ptr::from_mut(&mut value)); @@ -106,26 +154,6 @@ pub fn zval_long(value: i64) -> Zval { zv } -pub fn zval_null() -> Zval { - let mut zv = Zval::new(); - zv.set_null(); - zv -} - -pub fn ht_contains(ht: &ZendHashTable, key: &[u8]) -> bool { - match array_key_index(key) { - Some(index) => ht.get_index(index).is_some(), - None => unsafe { - !zend_hash_str_find( - std::ptr::from_ref(ht).cast_mut(), - key.as_ptr().cast(), - key.len(), - ) - .is_null() - }, - } -} - pub fn find_class(name: &str) -> Result<&'static ClassEntry, PhpException> { ClassEntry::try_find(name).ok_or_else(|| { ext_exception(format!( @@ -224,28 +252,6 @@ pub fn read_property(obj: &ZendObject, name: &str) -> Result Ok(value.shallow_clone()) } -/// Clone matching PHP `clone` (`zend_objects_clone_members`, including -/// `__clone`). Only valid for plain userland classes (no `create_object` state). -pub fn clone_object(src: &Zval, context: &str) -> Result, PhpException> { - let src_obj = src - .object() - .ok_or_else(|| ext_exception(format!("flow_php expected {context} to be an object")))?; - - let ce = unsafe { src_obj.ce.as_ref() } - .ok_or_else(|| ext_exception(format!("flow_php failed to resolve {context} class")))?; - - let mut cloned = ZendObject::new(ce); - - unsafe { - zend_objects_clone_members( - std::ptr::from_mut(&mut *cloned), - std::ptr::from_ref(src_obj).cast_mut(), - ); - } - - Ok(cloned) -} - pub fn construct_object( ce: &'static ClassEntry, args: Vec<&dyn IntoZvalDyn>, @@ -260,6 +266,45 @@ pub fn construct_object( Ok(obj) } +/// Constructs a fresh object and calls its `__construct` with already-owned +/// zvals (what `construct_object` can't express - it takes `IntoZvalDyn`). Used +/// to call the canonical `Row`/`Rows` constructors from row-object graphs. +pub fn construct_with_zvals( + ce: &'static ClassEntry, + args: &mut [Zval], + context: &str, +) -> Result, PhpException> { + let mut obj = ZendObject::new(ce); + let constructor = ce_method_ref(ce, "__construct")?; + + call_handle( + constructor, + Some(&mut obj), + args, + &format!("construct {context}"), + )?; + + Ok(obj) +} + +/// Runs an object's engine `clone` handler, mirroring PHP `clone $object`: a +/// shallow copy that shares the readonly sub-objects (ref/type) by refcount, the +/// exact semantics `(clone $definition)->setMetadata(...)` relies on. +pub fn clone_object(object: &ZendObject) -> Result, PhpException> { + let handler = unsafe { object.handlers.as_ref() } + .and_then(|handlers| handlers.clone_obj) + .ok_or_else(|| ext_exception("flow_php failed to resolve a clone handler"))?; + + let cloned = unsafe { handler(std::ptr::from_ref(object).cast_mut()) }; + ensure_no_pending_exception("clone a definition")?; + + if cloned.is_null() { + return Err(ext_exception("flow_php failed to clone a definition")); + } + + Ok(unsafe { ZBox::from_raw(cloned) }) +} + fn method_handle(class: &str, method: &str) -> Result { Function::try_from_method(class, method).ok_or_else(|| { ext_exception(format!( @@ -326,6 +371,44 @@ pub fn call_handle_on( Ok(retval) } +/// [`call_handle`] that surfaces a PHP exception thrown by the callee as the +/// ORIGINAL exception object instead of wrapping it in an `ExtensionException` - +/// the cast paths either propagate it verbatim (`Type::cast` fallback) or +/// discard it and bail (mirroring the `catch (Throwable)` in the PHP casts). +pub fn call_handle_transparent( + func: &Function, + object: Option<&ZendObject>, + args: &mut [Zval], +) -> Result { + let mut retval = Zval::new(); + + let (object_ptr, called_scope) = match object { + Some(obj) => (std::ptr::from_ref(obj).cast_mut(), obj.ce), + None => (std::ptr::null_mut(), unsafe { func.common.scope }), + }; + + unsafe { + zend_call_known_function( + std::ptr::from_ref(func).cast_mut(), + object_ptr, + called_scope, + std::ptr::from_mut(&mut retval), + args.len() as u32, + args.as_mut_ptr(), + std::ptr::null_mut(), + ); + } + + if let Some(mut exception) = ExecutorGlobals::take_exception() { + let mut zv = Zval::new(); + zv.set_object(&mut exception); + + return Err(PhpException::default(String::new()).with_object(zv)); + } + + Ok(retval) +} + /// Calls a pre-resolved function handle. Argument zvals stay caller-owned /// (the engine copies what it keeps), so cached zvals pass as shallow clones. pub fn call_handle( @@ -374,14 +457,6 @@ pub struct IntervalFns { } pub struct Ctx { - pub entries_ce: &'static ClassEntry, - pub row_ce: &'static ClassEntry, - pub rows_ce: &'static ClassEntry, - pub partitions_ce: &'static ClassEntry, - pub entries_entries_slot: u32, - pub row_entries_slot: u32, - pub rows_rows_slot: u32, - pub rows_partitions_slot: u32, uuid_ce: Option<(&'static ClassEntry, u32)>, json_ce: Option<(&'static ClassEntry, u32, u32)>, interval: Option, @@ -395,16 +470,20 @@ pub struct Ctx { fn_constant: Option, value_decoder_statics: HashMap<&'static str, &'static Function>, value_encoder_statics: HashMap<&'static str, &'static Function>, - schema_decoder: Option>, fn_json_encode: Option, - encoder_plan_slots: Option, - encoder_column_slots: Option, + fn_json_decode: Option, + fn_json_validate: Option, + metadata_from_array: Option<&'static Function>, metadata_map_slot: Option, + typed_row_values_slots: Option<(u32, u32)>, timezone_get_name: Option<&'static Function>, datetime_encode: HashMap, + datetime_cast: HashMap, save_html: HashMap, format_u: Option, - frame_segment: Option<(&'static ClassEntry, &'static Function)>, + format_his: Option, + str_true: Option, + str_false: Option, } pub struct DateTimeEncFns { @@ -413,33 +492,14 @@ pub struct DateTimeEncFns { pub get_timezone: &'static Function, } -/// Property-table slot offsets on `Flow\Floe\EncoderPlan`. -pub struct EncoderPlanSlots { - pub schema_body: u32, - pub columns: u32, -} - -/// Property-table slot offsets on `Flow\Floe\EncoderColumn`. -pub struct EncoderColumnSlots { - pub name: u32, - pub type_fingerprint: u32, +pub struct DateTimeCastFns { + pub set_time: &'static Function, + pub format: &'static Function, } impl Ctx { pub fn new() -> Result { - let entries_ce = find_class("Flow\\ETL\\Row\\Entries")?; - let row_ce = find_class("Flow\\ETL\\Row")?; - let rows_ce = find_class("Flow\\ETL\\Rows")?; - Ok(Self { - entries_ce, - row_ce, - rows_ce, - partitions_ce: find_class("Flow\\Filesystem\\Partitions")?, - entries_entries_slot: property_offset(entries_ce, "entries")?, - row_entries_slot: property_offset(row_ce, "entries")?, - rows_rows_slot: property_offset(rows_ce, "rows")?, - rows_partitions_slot: property_offset(rows_ce, "partitions")?, uuid_ce: None, json_ce: None, interval: None, @@ -453,29 +513,32 @@ impl Ctx { fn_constant: None, value_decoder_statics: HashMap::new(), value_encoder_statics: HashMap::new(), - schema_decoder: None, fn_json_encode: None, - encoder_plan_slots: None, - encoder_column_slots: None, + fn_json_decode: None, + fn_json_validate: None, + metadata_from_array: None, metadata_map_slot: None, + typed_row_values_slots: None, timezone_get_name: None, datetime_encode: HashMap::new(), + datetime_cast: HashMap::new(), save_html: HashMap::new(), format_u: None, - frame_segment: None, + format_his: None, + str_true: None, + str_false: None, }) } - /// Cached `Flow\Floe\FrameSegment` class entry + constructor handle. - pub fn frame_segment( - &mut self, - ) -> Result<(&'static ClassEntry, &'static Function), PhpException> { - if self.frame_segment.is_none() { - let ce = find_class("Flow\\Floe\\FrameSegment")?; - self.frame_segment = Some((ce, ce_method_ref(ce, "__construct")?)); + /// Property-table slot offsets `(values, metadata)` on `Flow\ETL\Row\TypedRowValues`. + pub fn typed_row_values_slots(&mut self) -> Result<(u32, u32), PhpException> { + if self.typed_row_values_slots.is_none() { + let ce = find_class("Flow\\ETL\\Row\\TypedRowValues")?; + self.typed_row_values_slots = + Some((property_offset(ce, "values")?, property_offset(ce, "metadata")?)); } - Ok(self.frame_segment.expect("just initialized")) + Ok(self.typed_row_values_slots.expect("just initialized")) } pub fn metadata_map_slot(&mut self) -> Result { @@ -547,6 +610,50 @@ impl Ctx { Ok(self.format_u.as_ref().expect("just initialized")) } + /// Cached `"H:i:s"` format-string zval for the date midnight check. + pub fn format_his(&mut self) -> Result<&Zval, PhpException> { + if self.format_his.is_none() { + self.format_his = Some(zval_str(b"H:i:s")); + } + + Ok(self.format_his.as_ref().expect("just initialized")) + } + + /// Cached `"true"`/`"false"` string zvals for bool-to-string casts. + pub fn bool_str(&mut self, value: bool) -> Result<&Zval, PhpException> { + let slot = if value { + &mut self.str_true + } else { + &mut self.str_false + }; + + if slot.is_none() { + *slot = Some(zval_str(if value { b"true" } else { b"false" })); + } + + Ok(slot.as_ref().expect("just initialized")) + } + + /// Per-datetime-class cast handles (setTime/format), subclass-safe. + pub fn datetime_cast_fns( + &mut self, + ce: *const ClassEntry, + ) -> Result<&DateTimeCastFns, PhpException> { + let key = ce as usize; + + if let std::collections::hash_map::Entry::Vacant(entry) = self.datetime_cast.entry(key) { + let ce_ref = unsafe { ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a datetime class"))?; + + entry.insert(DateTimeCastFns { + set_time: ce_method_ref(ce_ref, "setTime")?, + format: ce_method_ref(ce_ref, "format")?, + }); + } + + Ok(self.datetime_cast.get(&key).expect("just inserted")) + } + /// Cached handles to `ValueEncoder`'s public static markup serializers. pub fn value_encoder_static( &mut self, @@ -741,37 +848,6 @@ impl Ctx { Ok(self.timezones.get(name).expect("just inserted")) } - /// The canonical PHP schema decoder, constructed lazily - schema frames are - /// the cold path and reusing `SchemaDecoder` prevents semantic drift. - pub fn schema_decoder(&mut self) -> Result<&ZBox, PhpException> { - if self.schema_decoder.is_none() { - let mut value_decoder = construct_object( - find_class("Flow\\Floe\\ValueDecoder")?, - vec![], - "Flow\\Floe\\ValueDecoder", - )?; - // Instantiators declares no constructor; defaults apply on init. - let mut instantiators = - ZendObject::new(find_class("Flow\\ETL\\Row\\Entry\\Instantiators")?); - - let mut value_decoder_zv = Zval::new(); - value_decoder_zv.set_object(&mut value_decoder); - let mut instantiators_zv = Zval::new(); - instantiators_zv.set_object(&mut instantiators); - - self.schema_decoder = Some(construct_object( - find_class("Flow\\Floe\\SchemaDecoder")?, - vec![ - &value_decoder_zv as &dyn IntoZvalDyn, - &instantiators_zv as &dyn IntoZvalDyn, - ], - "Flow\\Floe\\SchemaDecoder", - )?); - } - - Ok(self.schema_decoder.as_ref().expect("just initialized")) - } - pub fn json_encode(&mut self) -> Result<&Function, PhpException> { if self.fn_json_encode.is_none() { self.fn_json_encode = Some(function_handle("json_encode")?); @@ -780,30 +856,30 @@ impl Ctx { Ok(self.fn_json_encode.as_ref().expect("just initialized")) } - pub fn encoder_plan_slots(&mut self) -> Result<&EncoderPlanSlots, PhpException> { - if self.encoder_plan_slots.is_none() { - let ce = find_class("Flow\\Floe\\EncoderPlan")?; - self.encoder_plan_slots = Some(EncoderPlanSlots { - schema_body: property_offset(ce, "schemaBody")?, - columns: property_offset(ce, "columns")?, - }); + pub fn json_decode(&mut self) -> Result<&Function, PhpException> { + if self.fn_json_decode.is_none() { + self.fn_json_decode = Some(function_handle("json_decode")?); } - Ok(self.encoder_plan_slots.as_ref().expect("just initialized")) + Ok(self.fn_json_decode.as_ref().expect("just initialized")) } - pub fn encoder_column_slots(&mut self) -> Result<&EncoderColumnSlots, PhpException> { - if self.encoder_column_slots.is_none() { - let ce = find_class("Flow\\Floe\\EncoderColumn")?; - self.encoder_column_slots = Some(EncoderColumnSlots { - name: property_offset(ce, "name")?, - type_fingerprint: property_offset(ce, "typeFingerprint")?, - }); + pub fn json_validate(&mut self) -> Result<&Function, PhpException> { + if self.fn_json_validate.is_none() { + self.fn_json_validate = Some(function_handle("json_validate")?); } - Ok(self - .encoder_column_slots - .as_ref() - .expect("just initialized")) + Ok(self.fn_json_validate.as_ref().expect("just initialized")) + } + + /// Static `Flow\ETL\Schema\Metadata::fromArray` handle - builds a Metadata + /// value object from a decoded per-value metadata map (the rare path). + pub fn metadata_from_array(&mut self) -> Result<&'static Function, PhpException> { + if self.metadata_from_array.is_none() { + self.metadata_from_array = + Some(method_handle_ref("Flow\\ETL\\Schema\\Metadata", "fromArray")?); + } + + Ok(self.metadata_from_array.expect("just initialized")) } } diff --git a/src/extension/flow-php-ext/src/encode.rs b/src/extension/flow-php-ext/src/encode.rs index 95675fc4e5..af9505e937 100644 --- a/src/extension/flow-php-ext/src/encode.rs +++ b/src/extension/flow-php-ext/src/encode.rs @@ -1,19 +1,19 @@ -//! Floe ROW frame-body encoder mirroring `Flow\Floe\RowEncoder::encode` -//! byte-for-byte; entry properties are read through cached slot offsets. +//! Floe ROW frame-body encoder mirroring `Flow\Floe\PhpFloeEncoder::encode` +//! byte-for-byte; values and per-value metadata are read from a `TypedRowValues`. use ext_php_rs::exception::PhpException; use ext_php_rs::ffi::zend_ulong; use ext_php_rs::types::{ZendHashTable, ZendObject, ZendStr, Zval}; use ext_php_rs::zend::ClassEntry; -use crate::ctx::{call_handle, call_handle_on, property_offset, read_property, Ctx}; +use crate::ctx::{call_handle, call_handle_on, read_property, zval_str, Ctx}; use crate::exception::ext_exception; use crate::format::{ write_u32, DATETIME_IMMUTABLE, DATETIME_MUTABLE, KEY_INTEGER, KEY_STRING, TAG_ARRAY, TAG_BOOLEAN, TAG_DATETIME, TAG_FLOAT, TAG_INTEGER, TAG_JSON, TAG_NULL, TAG_STRING, TAG_UUID, - VALUE_ABSENT, VALUE_NULL, VALUE_NULL_FROM_NULL, VALUE_PRESENT, + VALUE_ABSENT, VALUE_NULL, VALUE_NULL_WITH_META, VALUE_PRESENT, VALUE_PRESENT_WITH_META, }; -use crate::plan::{entry_class_for_type, parse_schema_json, TypeJson}; +use crate::plan::{parse_schema_json, TypeJson}; enum EncodeMapKey { Integer, @@ -124,18 +124,18 @@ fn build_encoder(type_json: &TypeJson) -> Result { }) } -struct EncodeColumn { - name: Vec, - value_slot: u32, - definition_slot: u32, +pub(crate) struct EncodeColumn { + pub(crate) name: Vec, encoder: Encoder, - /// (definition ce, `metadata` slot, `type` slot) - resolved lazily from the - /// first definition instance seen for this column. - definition_slots: Option<(*const ClassEntry, u32, u32)>, + /// Canonical PHP `json_encode` of this column's section-schema metadata - the + /// divergence reference. An entry whose metadata JSON differs rides its own + /// metadata beside the value. + plan_metadata_json: Vec, + plan_metadata_empty: bool, } pub struct EncodePlan { - columns: Vec, + pub(crate) columns: Vec, } /// `HASH_FLAG_PACKED` from zend_types.h. @@ -196,104 +196,171 @@ fn write_len_prefixed(out: &mut Vec, bytes: &[u8]) { } /// Builds the encode plan from a SCHEMA frame body (the JSON the PHP -/// `SchemaEncoder` emits) - once built, no PHP call is needed to encode. -pub fn build_encode_plan(schema_json: &[u8]) -> Result { +/// `SchemaEncoder` emits). Each column's section-schema metadata is captured as +/// its canonical PHP `json_encode` so a diverging entry can be detected without +/// re-parsing the schema per row. +pub fn build_encode_plan(schema_json: &[u8], ctx: &mut Ctx) -> Result { let definitions = parse_schema_json(schema_json)?; + let mut assoc_zv = Zval::new(); + assoc_zv.set_bool(true); + let decoded = { + let json_decode = ctx.json_decode()?; + call_handle( + json_decode, + None, + &mut [zval_str(schema_json), assoc_zv], + "decode a schema frame for metadata", + )? + }; + let decoded_ht = decoded + .array() + .ok_or_else(|| ext_exception("flow_php expected a schema frame to decode to a list"))?; + let mut columns = Vec::with_capacity(definitions.len()); - for definition in &definitions { - let entry_ce = entry_class_for_type(&definition.type_)?; + for (index, definition) in definitions.iter().enumerate() { + let plan_metadata_json = column_metadata_json(decoded_ht, index, ctx)?; columns.push(EncodeColumn { name: definition.name.clone().into_bytes(), - value_slot: property_offset(entry_ce, "value")?, - definition_slot: property_offset(entry_ce, "definition")?, encoder: build_encoder(&definition.type_)?, - definition_slots: None, + plan_metadata_empty: plan_metadata_json == b"[]", + plan_metadata_json, }); } Ok(EncodePlan { columns }) } -/// Encodes one Row into a bare ROW frame body (no length prefix, no frame type). -pub fn encode_row_body( - plan: &mut EncodePlan, - row: &Zval, +/// Canonical PHP `json_encode` of the `metadata` map of the `index`th decoded +/// schema definition (`[]` when absent). +fn column_metadata_json( + decoded_ht: &ZendHashTable, + index: usize, ctx: &mut Ctx, ) -> Result, PhpException> { - let row_obj = expect_object(row, "a Row")?; - let entries_obj = expect_object(read_slot(row_obj, ctx.row_entries_slot), "Row entries")?; - let entries_ht = read_slot(entries_obj, ctx.entries_entries_slot) - .array() - .ok_or_else(|| ext_exception("flow_php expected Entries to hold an array"))?; - - let mut out = Vec::with_capacity(1024); - encode_row(plan, entries_ht, &mut out, ctx)?; - - Ok(out) -} - -fn definition_slots( - column: &mut EncodeColumn, - definition: &ZendObject, -) -> Result<(u32, u32), PhpException> { - let ce = definition.ce.cast_const(); - - if let Some((cached_ce, metadata_slot, type_slot)) = column.definition_slots { - if std::ptr::eq(cached_ce, ce) { - return Ok((metadata_slot, type_slot)); - } - } + let definition_ht = decoded_ht + .get_index(index as i64) + .and_then(Zval::array) + .ok_or_else(|| ext_exception("flow_php expected a schema definition to be a map"))?; + + let metadata_zv = match definition_ht.get("metadata") { + Some(zv) => zv.shallow_clone(), + None => return Ok(b"[]".to_vec()), + }; - let ce_ref = unsafe { ce.as_ref() } - .ok_or_else(|| ext_exception("flow_php failed to resolve a definition class"))?; - let metadata_slot = property_offset(ce_ref, "metadata")?; - let type_slot = property_offset(ce_ref, "type")?; - column.definition_slots = Some((ce, metadata_slot, type_slot)); + let json_encode = ctx.json_encode()?; + let encoded = call_handle( + json_encode, + None, + &mut [metadata_zv], + "encode section-schema metadata", + )?; - Ok((metadata_slot, type_slot)) + encoded + .zend_str() + .map(|s| s.as_bytes().to_vec()) + .ok_or_else(|| ext_exception("flow_php expected json_encode to return a string")) } -fn encode_row( - plan: &mut EncodePlan, - entries_ht: &ZendHashTable, - out: &mut Vec, +/// Encodes one `Flow\ETL\Row\TypedRowValues` (its `values` + `metadata` maps) +/// into a bare ROW frame body (no length prefix, no frame type). Byte-identical +/// to `Flow\Floe\PhpFloeEncoder::encode` for the same row. +pub fn encode_typed_row( + plan: &EncodePlan, + values_ht: &ZendHashTable, + metadata_ht: &ZendHashTable, ctx: &mut Ctx, -) -> Result<(), PhpException> { - for column in &mut plan.columns { - let Some(entry_zv) = ht_find(entries_ht, &column.name) else { +) -> Result, PhpException> { + let mut out = Vec::with_capacity(1024); + + for column in &plan.columns { + let Some(value) = ht_find(values_ht, &column.name) else { out.push(VALUE_ABSENT); continue; }; - let entry = expect_object(entry_zv, "a row entry")?; - let value = read_slot(entry, column.value_slot); + let (diverges, entry_metadata_json) = typed_metadata(column, metadata_ht, ctx)?; if value.is_null() { - let definition = - expect_object(read_slot(entry, column.definition_slot), "a definition")?; - let (metadata_slot, _) = definition_slots(column, definition)?; - let metadata = - expect_object(read_slot(definition, metadata_slot), "definition metadata")?; - let map = read_slot(metadata, ctx.metadata_map_slot()?) - .array() - .ok_or_else(|| ext_exception("flow_php expected Metadata to hold an array"))?; - - out.push(if crate::ctx::ht_contains(map, b"from_null") { - VALUE_NULL_FROM_NULL + if diverges { + out.push(VALUE_NULL_WITH_META); + write_len_prefixed(&mut out, &entry_metadata_json); } else { - VALUE_NULL - }); + out.push(VALUE_NULL); + } + + continue; + } + + if diverges { + out.push(VALUE_PRESENT_WITH_META); + write_len_prefixed(&mut out, &entry_metadata_json); } else { out.push(VALUE_PRESENT); - encode_value(&column.encoder, value, out, ctx)?; } + + encode_value(&column.encoder, value, &mut out, ctx)?; } - Ok(()) + Ok(out) +} + +/// Whether a column's per-value metadata diverges from the section-schema +/// reference and, if so, its canonical JSON (the beside-value blob). `metadata_ht` +/// is the `TypedRowValues::metadata` map, which carries only non-empty entries +/// (mirroring `PhpRowHydrator::dehydrate`); an absent key is empty metadata. Fast +/// path: an empty entry against an empty-metadata column never diverges - no PHP call. +fn typed_metadata( + column: &EncodeColumn, + metadata_ht: &ZendHashTable, + ctx: &mut Ctx, +) -> Result<(bool, Vec), PhpException> { + let metadata_zv = ht_find(metadata_ht, &column.name); + + let entry_empty = match metadata_zv { + None => true, + Some(zv) => { + let metadata = expect_object(zv, "per-value metadata")?; + let map_slot = ctx.metadata_map_slot()?; + read_slot(metadata, map_slot) + .array() + .is_none_or(|map| map.is_empty()) + } + }; + + if entry_empty && column.plan_metadata_empty { + return Ok((false, Vec::new())); + } + + let entry_metadata_json = if entry_empty { + b"[]".to_vec() + } else { + let metadata = expect_object( + metadata_zv.expect("Some when the entry is not empty"), + "per-value metadata", + )?; + let map_slot = ctx.metadata_map_slot()?; + let map_owned = read_slot(metadata, map_slot).shallow_clone(); + let json_encode = ctx.json_encode()?; + let encoded = call_handle( + json_encode, + None, + &mut [map_owned], + "encode per-value metadata", + )?; + + encoded + .zend_str() + .map(|s| s.as_bytes().to_vec()) + .ok_or_else(|| ext_exception("flow_php expected json_encode to return a string"))? + }; + + let diverges = entry_metadata_json != column.plan_metadata_json; + + Ok((diverges, entry_metadata_json)) } fn encode_value( diff --git a/src/extension/flow-php-ext/src/format.rs b/src/extension/flow-php-ext/src/format.rs index 2ea9a57c7d..e242025f97 100644 --- a/src/extension/flow-php-ext/src/format.rs +++ b/src/extension/flow-php-ext/src/format.rs @@ -9,12 +9,11 @@ use crate::exception::ext_exception; #[cfg(target_endian = "big")] compile_error!("flow_php only supports little-endian targets"); -pub const FRAME_ROW: u8 = 0x02; - pub const VALUE_NULL: u8 = 0x00; pub const VALUE_PRESENT: u8 = 0x01; -pub const VALUE_NULL_FROM_NULL: u8 = 0x02; +pub const VALUE_NULL_WITH_META: u8 = 0x02; pub const VALUE_ABSENT: u8 = 0x03; +pub const VALUE_PRESENT_WITH_META: u8 = 0x04; pub const DATETIME_IMMUTABLE: u8 = 0x00; pub const DATETIME_MUTABLE: u8 = 0x01; @@ -94,10 +93,3 @@ impl<'a> Reader<'a> { pub fn write_u32(out: &mut Vec, value: u32) { out.extend_from_slice(&value.to_le_bytes()); } - -/// Writes a whole `type:u8 len:u32 body` Floe frame. -pub fn write_frame(out: &mut Vec, frame_type: u8, body: &[u8]) { - out.push(frame_type); - write_u32(out, body.len() as u32); - out.extend_from_slice(body); -} diff --git a/src/extension/flow-php-ext/src/hydrate.rs b/src/extension/flow-php-ext/src/hydrate.rs index 20e5104355..f031821d8c 100644 --- a/src/extension/flow-php-ext/src/hydrate.rs +++ b/src/extension/flow-php-ext/src/hydrate.rs @@ -1,24 +1,82 @@ -//! Object-graph assembly mirroring `Flow\Floe\RowHydrator` and `EntryInstantiator`: -//! constructor-less instantiation with direct property-slot writes. +//! Object-graph assembly mirroring `Flow\ETL\Row\PhpRowHydrator` and +//! `EntryInstantiator`: constructor-less instantiation with direct +//! property-slot writes. + +use std::collections::HashMap; use ext_php_rs::boxed::ZBox; -use ext_php_rs::convert::IntoZval; use ext_php_rs::exception::PhpException; use ext_php_rs::types::{ZendHashTable, ZendObject, Zval}; -use crate::ctx::{clone_object, construct_object, ht_add, write_slot, Ctx}; +use ext_php_rs::zend::{ClassEntry, Function}; + +use crate::ctx::{ + array_key_index, call_handle, call_handle_on, ce_method_ref, clone_object, + construct_with_zvals, find_class, ht_add, ht_find_key, ht_insert, ht_insert_key, + property_offset, write_slot, zval_str, Ctx, HtKey, +}; +use crate::encode::{expect_object, ht_for_each, read_slot}; use crate::exception::ext_exception; -use crate::format::{Reader, VALUE_ABSENT, VALUE_NULL, VALUE_NULL_FROM_NULL, VALUE_PRESENT}; +use crate::format::{ + Reader, VALUE_ABSENT, VALUE_NULL, VALUE_NULL_WITH_META, VALUE_PRESENT, VALUE_PRESENT_WITH_META, +}; use crate::plan::Plan; use crate::values::decode_value; -/// Decodes one ROW frame body into a `Flow\ETL\Row` object. -pub fn hydrate_row( +/// Resolved `Flow\ETL\Row\RawRowValues` class handles, shared by the binary decoder and the hydrator. +pub struct RowValuesClass { + pub ce: &'static ClassEntry, + pub values_slot: u32, + pub metadata_slot: u32, +} + +impl RowValuesClass { + pub fn resolve() -> Result { + let ce = find_class("Flow\\ETL\\Row\\RawRowValues")?; + + Ok(Self { + ce, + values_slot: property_offset(ce, "values")?, + metadata_slot: property_offset(ce, "metadata")?, + }) + } +} + +/// Reads one per-value metadata blob (`u32 len` + JSON) and rebuilds the +/// `Flow\ETL\Schema\Metadata` value object via the canonical PHP +/// `json_decode` + `Metadata::fromArray` - the rare diverging path only. +fn read_metadata(reader: &mut Reader, ctx: &mut Ctx) -> Result { + let length = reader.u32("per-value metadata length")? as usize; + let blob = reader.bytes(length, "per-value metadata")?; + + let json_zv = zval_str(blob); + let mut assoc_zv = Zval::new(); + assoc_zv.set_bool(true); + + let map = { + let json_decode = ctx.json_decode()?; + call_handle( + json_decode, + None, + &mut [json_zv.shallow_clone(), assoc_zv], + "decode per-value metadata", + )? + }; + + let from_array = ctx.metadata_from_array()?; + call_handle(from_array, None, &mut [map], "build per-value metadata") +} + +/// Decodes one ROW frame body into a `Flow\ETL\Row\RawRowValues` object - values keyed by +/// column name, absent columns omitted, diverging per-value metadata recorded in `metadata`. +pub fn decode_row_values( plan: &Plan, reader: &mut Reader, ctx: &mut Ctx, + class: &RowValuesClass, ) -> Result, PhpException> { - let mut entries_ht = ZendHashTable::with_capacity(plan.columns.len() as u32); + let mut values_ht = ZendHashTable::with_capacity(plan.columns.len() as u32); + let mut metadata_ht = ZendHashTable::new(); for column in &plan.columns { let flag = reader.u8("row value flag")?; @@ -27,13 +85,21 @@ pub fn hydrate_row( continue; } - let (value, definition_source) = match flag { - VALUE_PRESENT => ( - decode_value(&column.decoder, reader, ctx)?, - &column.definition, - ), - VALUE_NULL => (Zval::new(), &column.nullable_definition), - VALUE_NULL_FROM_NULL => (Zval::new(), &column.from_null_definition), + let value = match flag { + VALUE_PRESENT => decode_value(&column.decoder, reader, ctx)?, + VALUE_NULL => Zval::new(), + VALUE_PRESENT_WITH_META => { + let metadata = read_metadata(reader, ctx)?; + ht_insert(&mut metadata_ht, column.name.as_bytes(), metadata); + + decode_value(&column.decoder, reader, ctx)? + } + VALUE_NULL_WITH_META => { + let metadata = read_metadata(reader, ctx)?; + ht_insert(&mut metadata_ht, column.name.as_bytes(), metadata); + + Zval::new() + } other => { return Err(ext_exception(format!( "flow_php found unknown value flag 0x{other:02X}" @@ -41,24 +107,7 @@ pub fn hydrate_row( } }; - let definition_zv = clone_object(definition_source, "a column definition")? - .into_zval(false) - .map_err(|e| { - ext_exception(format!("flow_php failed to hydrate a definition: {e:?}")) - })?; - - let mut entry = ZendObject::new(column.entry_ce); - write_slot(&mut entry, column.name_slot, column.name_zv.shallow_clone()); - write_slot(&mut entry, column.value_slot, value); - write_slot(&mut entry, column.definition_slot, definition_zv); - - let entry_zv = entry - .into_zval(false) - .map_err(|e| ext_exception(format!("flow_php failed to collect row entries: {e:?}")))?; - - // `new Entries(...)` rejects duplicated names; a name-keyed hash would - // silently collapse them instead, so duplicates must fail loudly here. - if !ht_add(&mut entries_ht, column.name.as_bytes(), entry_zv) { + if !ht_add(&mut values_ht, column.name.as_bytes(), value) { return Err(ext_exception(format!( "flow_php found duplicated entry name \"{}\" in a row frame", column.name @@ -66,44 +115,577 @@ pub fn hydrate_row( } } - let mut entries = ZendObject::new(ctx.entries_ce); - let mut entries_ht_zv = Zval::new(); - entries_ht_zv.set_hashtable(entries_ht); - write_slot(&mut entries, ctx.entries_entries_slot, entries_ht_zv); + let mut row_values = ZendObject::new(class.ce); + + let mut values_zv = Zval::new(); + values_zv.set_hashtable(values_ht); + write_slot(&mut row_values, class.values_slot, values_zv); + + let mut metadata_zv = Zval::new(); + metadata_zv.set_hashtable(metadata_ht); + write_slot(&mut row_values, class.metadata_slot, metadata_zv); + + Ok(row_values) +} + +/// Resolved property-table slot offsets for the `Rows -> Row -> Entries` graph +/// traversed by `dehydrate`. +pub struct RowsClasses { + pub rows_slot: u32, + pub row_entries_slot: u32, + pub entries_slot: u32, +} + +impl RowsClasses { + pub fn resolve() -> Result { + Ok(Self { + rows_slot: property_offset(find_class("Flow\\ETL\\Rows")?, "rows")?, + row_entries_slot: property_offset(find_class("Flow\\ETL\\Row")?, "entries")?, + entries_slot: property_offset(find_class("Flow\\ETL\\Row\\Entries")?, "entries")?, + }) + } +} + +/// Resolved `Flow\ETL\Row\TypedRowValues` class handle + its three slot offsets. +pub struct TypedRowValuesClass { + pub ce: &'static ClassEntry, + pub values_slot: u32, + pub types_slot: u32, + pub metadata_slot: u32, +} + +impl TypedRowValuesClass { + pub fn resolve() -> Result { + let ce = find_class("Flow\\ETL\\Row\\TypedRowValues")?; + + Ok(Self { + ce, + values_slot: property_offset(ce, "values")?, + types_slot: property_offset(ce, "types")?, + metadata_slot: property_offset(ce, "metadata")?, + }) + } +} + +/// `(name, value, definition)` slot offsets cached per entry class - entry classes +/// declare these three properties in differing orders, so offsets are per-class. +pub type EntrySlotCache = HashMap; + +/// `(type(), metadata())` method handles cached per definition class. +pub type DefFnCache = HashMap; + +pub(crate) fn entry_slots( + cache: &mut EntrySlotCache, + ce: &ClassEntry, +) -> Result<(u32, u32, u32), PhpException> { + let key = std::ptr::from_ref(ce) as usize; + + if let Some(slots) = cache.get(&key) { + return Ok(*slots); + } - let mut row = ZendObject::new(ctx.row_ce); - let entries_zv = entries - .into_zval(false) - .map_err(|e| ext_exception(format!("flow_php failed to hydrate a row: {e:?}")))?; - write_slot(&mut row, ctx.row_entries_slot, entries_zv); + let slots = ( + property_offset(ce, "name")?, + property_offset(ce, "value")?, + property_offset(ce, "definition")?, + ); + cache.insert(key, slots); - Ok(row) + Ok(slots) } -/// Builds a `Flow\ETL\Rows` with empty `Partitions`, matching `new Rows(...$rows)`. -pub fn build_rows(rows: Vec>, ctx: &mut Ctx) -> Result { - let mut rows_ht = ZendHashTable::with_capacity(rows.len() as u32); +pub(crate) fn def_dehydrate_fns( + cache: &mut DefFnCache, + ce: &ClassEntry, +) -> Result<(&'static Function, &'static Function), PhpException> { + let key = std::ptr::from_ref(ce) as usize; - for row in rows { - rows_ht - .push(row) - .map_err(|e| ext_exception(format!("flow_php failed to collect rows: {e:?}")))?; + if let Some(fns) = cache.get(&key) { + return Ok(*fns); } - let partitions_zv = - construct_object(ctx.partitions_ce, vec![], "Flow\\Filesystem\\Partitions")? - .into_zval(false) - .map_err(|e| ext_exception(format!("flow_php failed to hydrate Rows: {e:?}")))?; + let fns = (ce_method_ref(ce, "type")?, ce_method_ref(ce, "metadata")?); + cache.insert(key, fns); + + Ok(fns) +} + +/// Mirrors `PhpRowHydrator::dehydrate` for one row: collects each entry's value +/// (verbatim), `definition()->type()`, and `definition()->metadata()` (only when +/// non-empty), then builds a constructor-less `TypedRowValues`. +fn dehydrate_row( + entries_ht: &ZendHashTable, + class: &TypedRowValuesClass, + entry_slot_cache: &mut EntrySlotCache, + def_fn_cache: &mut DefFnCache, + metadata_map_slot: u32, +) -> Result, PhpException> { + let mut values_ht = ZendHashTable::with_capacity(entries_ht.len() as u32); + let mut types_ht = ZendHashTable::with_capacity(entries_ht.len() as u32); + let mut metadata_ht = ZendHashTable::new(); + + ht_for_each(entries_ht, |_, _, entry_zv| { + let entry = expect_object(entry_zv, "a row entry")?; + let entry_ce = unsafe { entry.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve an entry class"))?; + + let (name_slot, value_slot, definition_slot) = entry_slots(entry_slot_cache, entry_ce)?; + + let name = HtKey::from_zend_str( + read_slot(entry, name_slot) + .zend_str() + .ok_or_else(|| ext_exception("flow_php expected an entry name to be a string"))?, + ); + + let value = read_slot(entry, value_slot).shallow_clone(); + + let definition = read_slot(entry, definition_slot) + .object() + .ok_or_else(|| ext_exception("flow_php expected an entry definition to be an object"))?; + let definition_ce = unsafe { definition.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a definition class"))?; + + let (type_fn, metadata_fn) = def_dehydrate_fns(def_fn_cache, definition_ce)?; + + let type_zv = call_handle_on(type_fn, definition, &mut [], "read a definition type")?; + let metadata_zv = + call_handle_on(metadata_fn, definition, &mut [], "read definition metadata")?; + + ht_insert_key(&mut values_ht, &name, value); + ht_insert_key(&mut types_ht, &name, type_zv); + + let metadata = expect_object(&metadata_zv, "definition metadata")?; + let non_empty = read_slot(metadata, metadata_map_slot) + .array() + .is_some_and(|map| !map.is_empty()); + + if non_empty { + ht_insert_key(&mut metadata_ht, &name, metadata_zv); + } + + Ok(()) + })?; + + let mut row_values = ZendObject::new(class.ce); + + let mut values_zv = Zval::new(); + values_zv.set_hashtable(values_ht); + write_slot(&mut row_values, class.values_slot, values_zv); + + let mut types_zv = Zval::new(); + types_zv.set_hashtable(types_ht); + write_slot(&mut row_values, class.types_slot, types_zv); + + let mut metadata_zv = Zval::new(); + metadata_zv.set_hashtable(metadata_ht); + write_slot(&mut row_values, class.metadata_slot, metadata_zv); + + Ok(row_values) +} + +/// Native `PhpRowHydrator::dehydrate`: turns a `Flow\ETL\Rows` into a list of +/// `Flow\ETL\Row\TypedRowValues`, value zvals moved verbatim (no casting). +pub fn dehydrate_rows( + rows: &Zval, + rows_classes: &RowsClasses, + class: &TypedRowValuesClass, + entry_slot_cache: &mut EntrySlotCache, + def_fn_cache: &mut DefFnCache, + ctx: &mut Ctx, +) -> Result { + let rows_obj = expect_object(rows, "Rows")?; + let rows_ht = read_slot(rows_obj, rows_classes.rows_slot) + .array() + .ok_or_else(|| ext_exception("flow_php expected Rows::rows to be an array"))?; + + let metadata_map_slot = ctx.metadata_map_slot()?; + + let mut out = ZendHashTable::with_capacity(rows_ht.len() as u32); + + ht_for_each(rows_ht, |_, _, row_zv| { + let row = expect_object(row_zv, "a Row")?; + let entries = read_slot(row, rows_classes.row_entries_slot) + .object() + .ok_or_else(|| ext_exception("flow_php expected Row::entries to be an object"))?; + let entries_ht = read_slot(entries, rows_classes.entries_slot) + .array() + .ok_or_else(|| ext_exception("flow_php expected Entries::entries to be an array"))?; + + let row_values = dehydrate_row( + entries_ht, + class, + entry_slot_cache, + def_fn_cache, + metadata_map_slot, + )?; + + out.push(row_values) + .map_err(|e| ext_exception(format!("flow_php failed to collect row values: {e:?}")))?; + + Ok(()) + })?; + + let mut zv = Zval::new(); + zv.set_hashtable(out); + + Ok(zv) +} + +/// `Entries::recreate` handle + the `Row`/`Rows` class entries used to assemble +/// a hydrated `Rows` through the canonical PHP constructors/factory. +pub struct AssemblyClasses { + pub entries_recreate: &'static Function, + pub row_ce: &'static ClassEntry, + pub rows_ce: &'static ClassEntry, +} + +impl AssemblyClasses { + pub fn resolve() -> Result { + Ok(Self { + entries_recreate: ce_method_ref(find_class("Flow\\ETL\\Row\\Entries")?, "recreate")?, + row_ce: find_class("Flow\\ETL\\Row")?, + rows_ce: find_class("Flow\\ETL\\Rows")?, + }) + } +} + +/// Definition method handles used only on the rare hydrate paths, cached per +/// definition class. +#[derive(Clone, Copy)] +pub struct DefRareFns { + is_nullable: &'static Function, + make_nullable: &'static Function, + set_metadata: &'static Function, + entry_class: &'static Function, +} + +pub type DefRareFnCache = HashMap; + +fn def_rare_fns(cache: &mut DefRareFnCache, ce: &ClassEntry) -> Result { + let key = std::ptr::from_ref(ce) as usize; + + if let Some(fns) = cache.get(&key) { + return Ok(*fns); + } + + let fns = DefRareFns { + is_nullable: ce_method_ref(ce, "isNullable")?, + make_nullable: ce_method_ref(ce, "makeNullable")?, + set_metadata: ce_method_ref(ce, "setMetadata")?, + entry_class: ce_method_ref(ce, "entryClass")?, + }; + cache.insert(key, fns); + + Ok(fns) +} + +/// A per-column hydrate plan entry. `base_def` retains the actual schema +/// `Definition` object (refcount++), so the common path shares one instance +/// across every row - matching `PhpRowHydrator`'s object-sharing topology. +pub(crate) struct HydrateColumn { + numeric_key: Option, + pub(crate) name_zv: Zval, + pub(crate) base_def: Zval, + pub(crate) nullable: bool, + pub(crate) entry_ce: &'static ClassEntry, + pub(crate) entry_slots: (u32, u32, u32), +} + +impl HydrateColumn { + pub(crate) fn key(&self) -> HtKey<'_> { + match self.numeric_key { + Some(index) => HtKey::Index(index), + None => HtKey::Str(self.name_zv.zend_str().expect("column names are strings")), + } + } +} + +/// `Schema` is mutated in place (`add()`/`keep()`/`makeNullable()` return +/// `$this`), so object identity cannot key the plan cache. Every structural +/// mutation swaps the `definitions` array (`setDefinitions` builds a fresh one) +/// and copy-on-write separates external writes, so the array's address +/// identifies the definition set; retaining it (refcount++) prevents address +/// reuse. Definition-level `setMetadata` mutates the retained (shared) objects +/// directly and needs no rebuild. +pub struct HydratePlan { + pub(crate) definitions_slot: u32, + pub(crate) definitions_retained: Zval, + pub(crate) columns: Vec, +} + +fn entry_class_ce( + fns: DefRareFns, + def_obj: &ZendObject, +) -> Result<&'static ClassEntry, PhpException> { + let entry_class = call_handle_on(fns.entry_class, def_obj, &mut [], "read an entry class")?; + let name = entry_class + .zend_str() + .and_then(|s| std::str::from_utf8(s.as_bytes()).ok()) + .ok_or_else(|| ext_exception("flow_php expected entryClass to return a string"))? + .to_string(); + + find_class(&name) +} + +/// Builds the per-column hydrate plan from a `Schema` object, reusing the actual +/// `Definition` zvals (no reconstruction in Rust). Method calls are fine here - +/// this runs once per schema, never per row. +pub(crate) fn build_hydrate_plan( + schema: &Zval, + entry_slot_cache: &mut EntrySlotCache, +) -> Result { + let schema_obj = expect_object(schema, "a Schema")?; + let schema_ce = unsafe { schema_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve the Schema class"))?; + + let definitions_slot = property_offset(schema_ce, "definitions")?; + let definitions_fn = ce_method_ref(schema_ce, "definitions")?; + let definitions = call_handle_on( + definitions_fn, + schema_obj, + &mut [], + "read schema definitions", + )?; + let definitions_ht = definitions + .array() + .ok_or_else(|| ext_exception("flow_php expected Schema::definitions to return an array"))?; + + let mut columns = Vec::with_capacity(definitions_ht.len()); + + ht_for_each(definitions_ht, |_, _, def_zv| { + let def_obj = expect_object(def_zv, "a Definition")?; + let def_ce = unsafe { def_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a Definition class"))?; + + let entry_fn = ce_method_ref(def_ce, "entry")?; + let reference = call_handle_on(entry_fn, def_obj, &mut [], "read a definition reference")?; + let reference_obj = expect_object(&reference, "a definition reference")?; + let reference_ce = unsafe { reference_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a Reference class"))?; + let name_fn = ce_method_ref(reference_ce, "name")?; + let name_zv = call_handle_on(name_fn, reference_obj, &mut [], "read a definition name")?; + let numeric_key = array_key_index( + name_zv + .zend_str() + .ok_or_else(|| ext_exception("flow_php expected a definition name to be a string"))? + .as_bytes(), + ); + + let is_nullable_fn = ce_method_ref(def_ce, "isNullable")?; + let nullable = call_handle_on(is_nullable_fn, def_obj, &mut [], "read a definition nullability")? + .bool() + .ok_or_else(|| ext_exception("flow_php expected isNullable to return a bool"))?; + + let entry_class_fn = ce_method_ref(def_ce, "entryClass")?; + let entry_class = call_handle_on(entry_class_fn, def_obj, &mut [], "read an entry class")?; + let entry_class_name = entry_class + .zend_str() + .and_then(|s| std::str::from_utf8(s.as_bytes()).ok()) + .ok_or_else(|| ext_exception("flow_php expected entryClass to return a string"))? + .to_string(); + let entry_ce = find_class(&entry_class_name)?; + let entry_slots = entry_slots(entry_slot_cache, entry_ce)?; + + columns.push(HydrateColumn { + numeric_key, + name_zv, + base_def: def_zv.shallow_clone(), + nullable, + entry_ce, + entry_slots, + }); + + Ok(()) + })?; + + Ok(HydratePlan { + definitions_slot, + definitions_retained: definitions, + columns, + }) +} + +/// Resolves the `(definition, entry class, entry slots)` triple for one column +/// occurrence, mirroring `PhpRowHydrator::instantiate` + `EntryFactory::fromDefinition`: +/// the common path shares the retained base `Definition`; per-value metadata clones +/// it (`(clone $def)->setMetadata(...)`), and a null value on a non-nullable +/// definition produces a fresh `makeNullable()` variant. +pub(crate) fn resolve_entry_definition( + column: &HydrateColumn, + metadata: Option<&Zval>, + value_is_null: bool, + entry_slot_cache: &mut EntrySlotCache, + def_rare_cache: &mut DefRareFnCache, +) -> Result<(Zval, &'static ClassEntry, (u32, u32, u32)), PhpException> { + if metadata.is_none() && (!value_is_null || column.nullable) { + return Ok((column.base_def.shallow_clone(), column.entry_ce, column.entry_slots)); + } + + let base_obj = column + .base_def + .object() + .ok_or_else(|| ext_exception("flow_php expected a Definition object"))?; + + let variant = if let Some(metadata) = metadata { + let metadata = metadata.shallow_clone(); + let mut cloned = clone_object(base_obj)?; + let cloned_ce = unsafe { cloned.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a Definition class"))?; + let fns = def_rare_fns(def_rare_cache, cloned_ce)?; + call_handle( + fns.set_metadata, + Some(&mut cloned), + &mut [metadata], + "set per-value metadata", + )?; + let mut zv = Zval::new(); + zv.set_object(&mut cloned); + zv + } else { + column.base_def.shallow_clone() + }; + + let variant_obj = variant + .object() + .ok_or_else(|| ext_exception("flow_php expected a Definition object"))?; + let variant_ce = unsafe { variant_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a Definition class"))?; + let fns = def_rare_fns(def_rare_cache, variant_ce)?; + + let final_def = if value_is_null + && !call_handle_on(fns.is_nullable, variant_obj, &mut [], "read nullability")? + .bool() + .unwrap_or(false) + { + call_handle_on( + fns.make_nullable, + variant_obj, + &mut [], + "make a definition nullable", + )? + } else { + variant + }; + + let final_obj = final_def + .object() + .ok_or_else(|| ext_exception("flow_php expected a Definition object"))?; + let final_ce = unsafe { final_obj.ce.as_ref() } + .ok_or_else(|| ext_exception("flow_php failed to resolve a Definition class"))?; + let final_fns = def_rare_fns(def_rare_cache, final_ce)?; + let entry_ce = entry_class_ce(final_fns, final_obj)?; + let entry_slots = entry_slots(entry_slot_cache, entry_ce)?; + + Ok((final_def, entry_ce, entry_slots)) +} + +pub(crate) fn ensure_hydrate_plan( + plan: &mut Option, + schema: &Zval, + entry_slot_cache: &mut EntrySlotCache, +) -> Result<(), PhpException> { + let schema_obj = expect_object(schema, "a Schema")?; + + let current = plan.as_ref().and_then(|p| { + read_slot(schema_obj, p.definitions_slot) + .array() + .zip(p.definitions_retained.array()) + }); + + if current.is_some_and(|(definitions, retained)| std::ptr::eq(definitions, retained)) { + return Ok(()); + } + + *plan = Some(build_hydrate_plan(schema, entry_slot_cache)?); + + Ok(()) +} + +/// Native `PhpRowHydrator::hydrate`: builds `Flow\ETL\Rows` from a trusted list +/// of `RawRowValues` against a `Schema`. The common column path (present, +/// non-null-or-nullable, no per-value metadata) is a plain slot write reusing +/// the retained `Definition`; only the null-on-non-nullable and metadata-diverging +/// paths reconstruct a fresh variant, mirroring `EntryFactory::fromDefinition`. +pub fn hydrate_rows( + batch: &Zval, + schema: &Zval, + plan_slot: &mut Option, + raw_class: &RowValuesClass, + assembly: &AssemblyClasses, + entry_slot_cache: &mut EntrySlotCache, + def_rare_cache: &mut DefRareFnCache, +) -> Result { + ensure_hydrate_plan(plan_slot, schema, entry_slot_cache)?; + let plan = plan_slot.as_ref().expect("plan built above"); + + let batch_ht = batch + .array() + .ok_or_else(|| ext_exception("flow_php expected a list of raw row values"))?; + + let mut rows_args: Vec = Vec::with_capacity(batch_ht.len()); + + ht_for_each(batch_ht, |_, _, rv_zv| { + let rv = expect_object(rv_zv, "a RawRowValues")?; + let values_ht = read_slot(rv, raw_class.values_slot) + .array() + .ok_or_else(|| ext_exception("flow_php expected RawRowValues::values to be an array"))?; + let metadata_ht = read_slot(rv, raw_class.metadata_slot).array().ok_or_else(|| { + ext_exception("flow_php expected RawRowValues::metadata to be an array") + })?; + + let mut entries_ht = ZendHashTable::with_capacity(plan.columns.len() as u32); + let has_metadata = !metadata_ht.is_empty(); + + for column in &plan.columns { + let key = column.key(); + + let Some(value) = ht_find_key(values_ht, &key) else { + continue; + }; + + let metadata = if has_metadata { + ht_find_key(metadata_ht, &key) + } else { + None + }; + let (definition, entry_ce, entry_slots) = resolve_entry_definition( + column, + metadata, + value.is_null(), + entry_slot_cache, + def_rare_cache, + )?; + + let mut entry = ZendObject::new(entry_ce); + write_slot(&mut entry, entry_slots.0, column.name_zv.shallow_clone()); + write_slot(&mut entry, entry_slots.1, value.shallow_clone()); + write_slot(&mut entry, entry_slots.2, definition); + + let mut entry_zv = Zval::new(); + entry_zv.set_object(&mut entry); + ht_insert_key(&mut entries_ht, &key, entry_zv); + } + + let mut entries_zv = Zval::new(); + entries_zv.set_hashtable(entries_ht); + let entries = call_handle( + assembly.entries_recreate, + None, + &mut [entries_zv], + "recreate row entries", + )?; - let mut rows_ht_zv = Zval::new(); - rows_ht_zv.set_hashtable(rows_ht); + let mut row = construct_with_zvals(assembly.row_ce, &mut [entries], "a Row")?; + let mut row_zv = Zval::new(); + row_zv.set_object(&mut row); + rows_args.push(row_zv); - let mut rows_obj = ZendObject::new(ctx.rows_ce); - write_slot(&mut rows_obj, ctx.rows_rows_slot, rows_ht_zv); - write_slot(&mut rows_obj, ctx.rows_partitions_slot, partitions_zv); + Ok(()) + })?; + let mut rows = construct_with_zvals(assembly.rows_ce, &mut rows_args, "Rows")?; let mut zv = Zval::new(); - zv.set_object(&mut rows_obj); + zv.set_object(&mut rows); Ok(zv) } diff --git a/src/extension/flow-php-ext/src/lib.rs b/src/extension/flow-php-ext/src/lib.rs index 886a451d9d..c4ddbf5be0 100644 --- a/src/extension/flow-php-ext/src/lib.rs +++ b/src/extension/flow-php-ext/src/lib.rs @@ -1,27 +1,25 @@ +mod cast; mod ctx; mod encode; mod exception; mod format; mod hydrate; mod plan; -mod section; mod values; use std::alloc::System; use ext_php_rs::binary_slice::BinarySlice; -use ext_php_rs::convert::IntoZval; use ext_php_rs::prelude::*; -use ext_php_rs::types::{ZendObject, Zval}; +use ext_php_rs::types::{ZendHashTable, Zval}; use ext_php_rs::zend::ModuleEntry; use ext_php_rs::{info_table_end, info_table_row, info_table_start}; -use crate::ctx::{call_handle_on, zval_long, zval_null, zval_str, Ctx}; -use crate::encode::{encode_row_body, expect_object, ht_for_each, read_slot, EncodePlan}; +use crate::ctx::{zval_str, Ctx}; +use crate::encode::{build_encode_plan, encode_typed_row, expect_object, ht_for_each, read_slot, EncodePlan}; use crate::exception::ext_exception; -use crate::format::{write_frame, Reader, FRAME_ROW}; +use crate::format::Reader; use crate::plan::Plan; -use crate::section::SectionTracker; #[global_allocator] static GLOBAL: System = System; @@ -44,67 +42,122 @@ pub unsafe extern "C" fn module_startup(_type: i32, _module_number: i32) -> i32 0 } -/// Stateful frame decoder for streaming Floe reads (`FloeReader` fast path): -/// the PHP side keeps buffering/framing and hands over bare frame bodies. +/// A built plan together with the schema JSON it was built from; the schema +/// bytes decide when a new schema requires a plan rebuild. Generic over the plan +/// kind so encode (`EncodePlan`) and decode (`Plan`) share one rebind path. +struct BoundPlan

{ + schema: Vec, + plan: P, +} + +/// Rebuilds the bound plan when the schema JSON changed, `Ctx` caches survive rebinds. +fn ensure_plan

( + bound: &mut Option>, + ctx: &mut Ctx, + schema: &[u8], + build: fn(&[u8], &mut Ctx) -> PhpResult

, +) -> PhpResult<()> { + if bound.as_ref().is_some_and(|b| b.schema == schema) { + return Ok(()); + } + + *bound = Some(BoundPlan { + schema: schema.to_vec(), + plan: build(schema, ctx)?, + }); + + Ok(()) +} + +/// Floe's consolidated binary codec, both directions: ROW frame bodies to/from +/// `Flow\ETL\Row\RawRowValues` (decode) and `Flow\ETL\Row\TypedRowValues` (encode). +/// The PHP side keeps buffering/framing/sectioning and hands over bare frame +/// bodies; the extension owns value encode/decode against a primed schema. #[php_class] -#[php(name = "Flow\\Floe\\RowsDecoder")] -pub struct RowsDecoder { +#[php(name = "Flow\\Floe\\RustFloeEncoderNative")] +pub struct RustFloeEncoderNative { ctx: Ctx, - plan: Option, + encode_bound: Option>, + decode_bound: Option>, + row_values_class: hydrate::RowValuesClass, } #[php_impl] -impl RowsDecoder { +impl RustFloeEncoderNative { pub fn __construct() -> PhpResult { Ok(Self { ctx: Ctx::new()?, - plan: None, + encode_bound: None, + decode_bound: None, + row_values_class: hydrate::RowValuesClass::resolve()?, }) } - /// Replaces the current column plan with the given SCHEMA frame body. - pub fn schema(&mut self, frame_body: BinarySlice) -> PhpResult<()> { - self.plan = Some(plan::build_plan(&frame_body, &mut self.ctx)?); + /// Encodes a list of `Flow\ETL\Row\TypedRowValues` into a list of bare ROW + /// frame bodies against the plan bound to `schema_body`. + pub fn encode(&mut self, batch: &Zval, schema_body: BinarySlice) -> PhpResult { + ensure_plan( + &mut self.encode_bound, + &mut self.ctx, + &schema_body, + build_encode_plan, + )?; - Ok(()) - } + let batch_ht = batch + .array() + .ok_or_else(|| ext_exception("flow_php expected a list of typed row values"))?; + + let (values_slot, metadata_slot) = self.ctx.typed_row_values_slots()?; + + let plan = &self.encode_bound.as_ref().expect("plan bound above").plan; + let ctx = &mut self.ctx; + + let mut encoded = ZendHashTable::with_capacity(batch_ht.len() as u32); - /// Decodes one ROW frame body against the current plan into a `Flow\ETL\Row`. - pub fn row(&mut self, frame_body: BinarySlice) -> PhpResult { - let Some(plan) = self.plan.as_ref() else { - return Err(ext_exception( - "flow_php found a row frame before any schema frame", - )); - }; - - let mut reader = Reader::new(&frame_body); - let row = hydrate::hydrate_row(plan, &mut reader, &mut self.ctx)?; - - if !reader.is_eof() { - return Err(ext_exception( - "flow_php row frame length does not match its content", - )); - } - - row.into_zval(false) - .map_err(|e| ext_exception(format!("flow_php failed to return a Row: {e:?}"))) + ht_for_each(batch_ht, |_, _, item_zv| { + let typed = expect_object(item_zv, "a TypedRowValues")?; + + let values_ht = read_slot(typed, values_slot).array().ok_or_else(|| { + ext_exception("flow_php expected TypedRowValues::values to be an array") + })?; + let metadata_ht = read_slot(typed, metadata_slot).array().ok_or_else(|| { + ext_exception("flow_php expected TypedRowValues::metadata to be an array") + })?; + + let body = encode_typed_row(plan, values_ht, metadata_ht, ctx)?; + + encoded.push(zval_str(&body)).map_err(|e| { + ext_exception(format!("flow_php failed to collect a row body: {e:?}")) + })?; + + Ok(()) + })?; + + let mut zv = Zval::new(); + zv.set_hashtable(encoded); + + Ok(zv) } - /// Decodes a list of ROW frame bodies against the current plan into one - /// `Flow\ETL\Rows`, graph-identical to calling `row()` per body. - pub fn rows(&mut self, frame_bodies: &Zval) -> PhpResult { + /// Decodes a list of ROW frame bodies written with the given SCHEMA frame + /// body into `Flow\ETL\Row\RawRowValues` objects. + pub fn decode(&mut self, frame_bodies: &Zval, schema_body: BinarySlice) -> PhpResult { + ensure_plan( + &mut self.decode_bound, + &mut self.ctx, + &schema_body, + plan::build_plan, + )?; + let bodies_ht = frame_bodies .array() .ok_or_else(|| ext_exception("flow_php expected a list of row frame bodies"))?; - let Some(plan) = self.plan.as_ref() else { - return Err(ext_exception( - "flow_php found a row frame before any schema frame", - )); - }; + let plan = &self.decode_bound.as_ref().expect("plan bound above").plan; + let class = &self.row_values_class; let ctx = &mut self.ctx; - let mut rows = Vec::with_capacity(bodies_ht.len()); + let mut decoded = ZendHashTable::with_capacity(bodies_ht.len() as u32); ht_for_each(bodies_ht, |_, _, body_zv| { let bytes = body_zv @@ -113,7 +166,7 @@ impl RowsDecoder { .as_bytes(); let mut reader = Reader::new(bytes); - let row = hydrate::hydrate_row(plan, &mut reader, ctx)?; + let row_values = hydrate::decode_row_values(plan, &mut reader, ctx, class)?; if !reader.is_eof() { return Err(ext_exception( @@ -121,148 +174,94 @@ impl RowsDecoder { )); } - rows.push(row); + decoded.push(row_values).map_err(|e| { + ext_exception(format!("flow_php failed to collect row values: {e:?}")) + })?; Ok(()) })?; - hydrate::build_rows(rows, ctx) + let mut zv = Zval::new(); + zv.set_hashtable(decoded); + + Ok(zv) } } -/// Stateful frame encoder for streaming Floe writes (`FloeWriter` fast path). -/// The `rows()` segment state is independent from the `schema()`/`row()` -/// per-frame state; the two modes must not be mixed on one instance. +/// Native counterpart of `PhpRowHydrator`: `hydrate` builds `Flow\ETL\Rows` from +/// a trusted list of `RawRowValues` against a `Schema` object (values moved +/// verbatim); `cast` does the same from RAW scalars, casting each value against +/// the schema first; `dehydrate` turns `Rows` into a list of `TypedRowValues`. #[php_class] -#[php(name = "Flow\\Floe\\RowsEncoder")] -pub struct RowsEncoder { +#[php(name = "Flow\\ETL\\Row\\RustRowHydratorNative")] +pub struct RustRowHydratorNative { ctx: Ctx, - plan: Option, - stream: SectionTracker, + rows_classes: hydrate::RowsClasses, + typed_row_values_class: hydrate::TypedRowValuesClass, + raw_row_values_class: hydrate::RowValuesClass, + assembly: hydrate::AssemblyClasses, + entry_slots: hydrate::EntrySlotCache, + def_dehydrate_fns: hydrate::DefFnCache, + def_rare_fns: hydrate::DefRareFnCache, + hydrate_plan: Option, + cast_plan: Option, } #[php_impl] -impl RowsEncoder { +impl RustRowHydratorNative { pub fn __construct() -> PhpResult { Ok(Self { ctx: Ctx::new()?, - plan: None, - stream: SectionTracker::new(), + rows_classes: hydrate::RowsClasses::resolve()?, + typed_row_values_class: hydrate::TypedRowValuesClass::resolve()?, + raw_row_values_class: hydrate::RowValuesClass::resolve()?, + assembly: hydrate::AssemblyClasses::resolve()?, + entry_slots: hydrate::EntrySlotCache::new(), + def_dehydrate_fns: hydrate::DefFnCache::new(), + def_rare_fns: hydrate::DefRareFnCache::new(), + hydrate_plan: None, + cast_plan: None, }) } - /// Primes the encode plan from a SCHEMA frame body. - pub fn schema(&mut self, frame_body: BinarySlice) -> PhpResult<()> { - self.plan = Some(encode::build_encode_plan(&frame_body)?); - - Ok(()) - } - - /// Encodes one `Flow\ETL\Row` into a bare ROW frame body against the plan. - pub fn row(&mut self, row: &Zval) -> PhpResult { - let Some(plan) = self.plan.as_mut() else { - return Err(ext_exception( - "flow_php found a row before any schema frame", - )); - }; - - Ok(zval_str(&encode::encode_row_body( - plan, - row, + /// Casts a list of raw-scalar `RawRowValues` against a `Schema` and builds + /// a `Flow\ETL\Rows` in a single pass. + pub fn cast(&mut self, batch: &Zval, schema: &Zval) -> PhpResult { + cast::cast_rows( + batch, + schema, + &mut self.cast_plan, + &self.raw_row_values_class, + &self.assembly, + &mut self.entry_slots, + &mut self.def_rare_fns, &mut self.ctx, - )?)) + ) } - /// Encodes a whole `Flow\ETL\Rows` into a list of `Flow\Floe\FrameSegment` - /// in one call, mirroring `Flow\Floe\PhpRowFrameEncoder`. - pub fn rows(&mut self, rows: &Zval) -> PhpResult { - struct Segment { - schema_body: Option>, - frames: Vec, - row_count: i64, - } - - let rows_obj = expect_object(rows, "Rows")?; - let rows_ht = read_slot(rows_obj, self.ctx.rows_rows_slot) - .array() - .ok_or_else(|| ext_exception("flow_php expected Rows to hold an array"))?; - - let ctx = &mut self.ctx; - let stream = &mut self.stream; - - let mut segments: Vec = Vec::new(); - let mut current: Option = None; - - ht_for_each(rows_ht, |_, _, row_zv| { - let entries_ht = SectionTracker::row_entries(row_zv, ctx)?; - - if let Some(schema_body) = stream.ensure_section(row_zv, entries_ht, ctx)? { - if let Some(segment) = current.take() { - segments.push(segment); - } - - current = Some(Segment { - schema_body: Some(schema_body), - frames: Vec::new(), - row_count: 0, - }); - } else if current.is_none() { - current = Some(Segment { - schema_body: None, - frames: Vec::new(), - row_count: 0, - }); - } - - let body = encode_row_body(stream.plan_mut()?, row_zv, ctx)?; - - let segment = current - .as_mut() - .ok_or_else(|| ext_exception("flow_php has no active segment"))?; - write_frame(&mut segment.frames, FRAME_ROW, &body); - segment.row_count += 1; - - Ok(()) - })?; - - if let Some(segment) = current.take() { - segments.push(segment); - } - - let (segment_ce, segment_ctor) = ctx.frame_segment()?; - let mut out = ext_php_rs::types::ZendHashTable::with_capacity(segments.len() as u32); - - for segment in segments { - let schema_body_zv = match &segment.schema_body { - Some(body) => zval_str(body), - None => zval_null(), - }; - - let obj = ZendObject::new(segment_ce); - call_handle_on( - segment_ctor, - &obj, - &mut [ - schema_body_zv, - zval_str(&segment.frames), - zval_long(segment.row_count), - ], - "construct a FrameSegment", - )?; - - let obj_zv = obj.into_zval(false).map_err(|e| { - ext_exception(format!("flow_php failed to return a FrameSegment: {e:?}")) - })?; - - out.push(obj_zv).map_err(|e| { - ext_exception(format!("flow_php failed to build a segment list: {e:?}")) - })?; - } - - let mut zv = Zval::new(); - zv.set_hashtable(out); + /// Builds a `Flow\ETL\Rows` from a trusted list of `RawRowValues` against a `Schema`. + pub fn hydrate(&mut self, batch: &Zval, schema: &Zval) -> PhpResult { + hydrate::hydrate_rows( + batch, + schema, + &mut self.hydrate_plan, + &self.raw_row_values_class, + &self.assembly, + &mut self.entry_slots, + &mut self.def_rare_fns, + ) + } - Ok(zv) + /// Turns a `Flow\ETL\Rows` into a list of `Flow\ETL\Row\TypedRowValues`. + pub fn dehydrate(&mut self, rows: &Zval) -> PhpResult { + hydrate::dehydrate_rows( + rows, + &self.rows_classes, + &self.typed_row_values_class, + &mut self.entry_slots, + &mut self.def_dehydrate_fns, + &mut self.ctx, + ) } } @@ -271,6 +270,6 @@ impl RowsEncoder { pub fn get_module(module: ModuleBuilder) -> ModuleBuilder { module .info_function(php_module_info) - .class::() - .class::() + .class::() + .class::() } diff --git a/src/extension/flow-php-ext/src/plan.rs b/src/extension/flow-php-ext/src/plan.rs index ce180034b5..960bbf6db5 100644 --- a/src/extension/flow-php-ext/src/plan.rs +++ b/src/extension/flow-php-ext/src/plan.rs @@ -1,90 +1,15 @@ -//! Decode plan built from a SCHEMA frame body via the canonical PHP `SchemaDecoder`. +//! Decode plan built from a SCHEMA frame body (a JSON list of normalized definitions): +//! per column a name and a recursive value `Decoder`, in schema order. use std::fmt; -use ext_php_rs::convert::IntoZvalDyn; use ext_php_rs::exception::PhpException; -use ext_php_rs::types::Zval; -use ext_php_rs::zend::ClassEntry; use serde::de::{MapAccess, Visitor}; use serde::{Deserialize, Deserializer}; -use crate::ctx::{ensure_no_pending_exception, find_class, property_offset, read_property, Ctx}; +use crate::ctx::Ctx; use crate::exception::ext_exception; -/// Mirror of `SchemaDecoder::ENTRY_CLASSES`; dual-engine tests break loudly -/// when either side changes. -const DEFINITION_TO_ENTRY: [(&str, &str); 17] = [ - ( - "Flow\\ETL\\Schema\\Definition\\BooleanDefinition", - "Flow\\ETL\\Row\\Entry\\BooleanEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\DateDefinition", - "Flow\\ETL\\Row\\Entry\\DateEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\DateTimeDefinition", - "Flow\\ETL\\Row\\Entry\\DateTimeEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\EnumDefinition", - "Flow\\ETL\\Row\\Entry\\EnumEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\FloatDefinition", - "Flow\\ETL\\Row\\Entry\\FloatEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\HTMLDefinition", - "Flow\\ETL\\Row\\Entry\\HTMLEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\HTMLElementDefinition", - "Flow\\ETL\\Row\\Entry\\HTMLElementEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\IntegerDefinition", - "Flow\\ETL\\Row\\Entry\\IntegerEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\JsonDefinition", - "Flow\\ETL\\Row\\Entry\\JsonEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\ListDefinition", - "Flow\\ETL\\Row\\Entry\\ListEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\MapDefinition", - "Flow\\ETL\\Row\\Entry\\MapEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\StringDefinition", - "Flow\\ETL\\Row\\Entry\\StringEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\StructureDefinition", - "Flow\\ETL\\Row\\Entry\\StructureEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\TimeDefinition", - "Flow\\ETL\\Row\\Entry\\TimeEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\UuidDefinition", - "Flow\\ETL\\Row\\Entry\\UuidEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\XMLDefinition", - "Flow\\ETL\\Row\\Entry\\XMLEntry", - ), - ( - "Flow\\ETL\\Schema\\Definition\\XMLElementDefinition", - "Flow\\ETL\\Row\\Entry\\XMLElementEntry", - ), -]; - pub enum MapKey { Integer, String, @@ -117,14 +42,6 @@ pub enum Decoder { pub struct Column { pub name: String, - pub name_zv: Zval, - pub entry_ce: &'static ClassEntry, - pub name_slot: u32, - pub value_slot: u32, - pub definition_slot: u32, - pub definition: Zval, - pub nullable_definition: Zval, - pub from_null_definition: Zval, pub decoder: Decoder, } @@ -173,6 +90,17 @@ impl TypeJson { .map(|(name, element)| (name, element)) } + pub fn required_elements(&self) -> impl Iterator { + self.elements.0.iter().map(|(name, element)| (name, element)) + } + + pub fn structure_optional_elements(&self) -> impl Iterator { + self.optional_elements + .0 + .iter() + .map(|(name, element)| (name, element)) + } + pub fn allow_extra(&self) -> bool { self.allow_extra } @@ -309,135 +237,14 @@ fn build_decoder(type_json: &TypeJson) -> Result { }) } -fn definition_class_for_type(type_str: &str) -> Option<&'static str> { - Some(match type_str { - "integer" | "positive_integer" => "Flow\\ETL\\Schema\\Definition\\IntegerDefinition", - "float" => "Flow\\ETL\\Schema\\Definition\\FloatDefinition", - "boolean" => "Flow\\ETL\\Schema\\Definition\\BooleanDefinition", - "string" | "non_empty_string" | "numeric-string" | "class_string" => { - "Flow\\ETL\\Schema\\Definition\\StringDefinition" - } - "date" => "Flow\\ETL\\Schema\\Definition\\DateDefinition", - "datetime" => "Flow\\ETL\\Schema\\Definition\\DateTimeDefinition", - "time" => "Flow\\ETL\\Schema\\Definition\\TimeDefinition", - "json" | "array" => "Flow\\ETL\\Schema\\Definition\\JsonDefinition", - "uuid" => "Flow\\ETL\\Schema\\Definition\\UuidDefinition", - "list" => "Flow\\ETL\\Schema\\Definition\\ListDefinition", - "map" => "Flow\\ETL\\Schema\\Definition\\MapDefinition", - "structure" => "Flow\\ETL\\Schema\\Definition\\StructureDefinition", - "enum" => "Flow\\ETL\\Schema\\Definition\\EnumDefinition", - "html" => "Flow\\ETL\\Schema\\Definition\\HTMLDefinition", - "html_element" => "Flow\\ETL\\Schema\\Definition\\HTMLElementDefinition", - "xml" => "Flow\\ETL\\Schema\\Definition\\XMLDefinition", - "xml_element" => "Flow\\ETL\\Schema\\Definition\\XMLElementDefinition", - _ => return None, - }) -} - -pub fn entry_class_for_type(type_json: &TypeJson) -> Result<&'static ClassEntry, PhpException> { - let definition_class = - definition_class_for_type(type_json.type_.as_str()).ok_or_else(|| { - ext_exception(format!( - "flow_php cannot encode a column of type \"{}\"", - type_json.type_ - )) - })?; - - let entry_class = DEFINITION_TO_ENTRY - .iter() - .find(|(definition_name, _)| *definition_name == definition_class) - .map(|(_, entry_class)| *entry_class) - .ok_or_else(|| { - ext_exception(format!( - "flow_php cannot encode entries for definition \"{definition_class}\"" - )) - })?; - - find_class(entry_class) -} - -fn entry_class_for(definition: &Zval) -> Result<&'static ClassEntry, PhpException> { - let definition_class = definition - .object() - .and_then(|obj| unsafe { obj.ce.as_ref() }) - .and_then(ClassEntry::name) - .ok_or_else(|| ext_exception("flow_php failed to resolve a definition class"))?; - - let entry_class = DEFINITION_TO_ENTRY - .iter() - .find(|(definition_name, _)| *definition_name == definition_class) - .map(|(_, entry_class)| *entry_class) - .ok_or_else(|| { - ext_exception(format!( - "flow_php cannot hydrate entries for definition \"{definition_class}\"" - )) - })?; - - find_class(entry_class) -} - -pub fn build_plan(schema_json: &[u8], ctx: &mut Ctx) -> Result { +pub fn build_plan(schema_json: &[u8], _ctx: &mut Ctx) -> Result { let definitions = parse_schema_json(schema_json)?; - let json_string = std::str::from_utf8(schema_json) - .expect("validated by parse_schema_json") - .to_string(); - let hydrator_columns = ctx - .schema_decoder()? - .try_call_method("decode", vec![&json_string as &dyn IntoZvalDyn]) - .map_err(|e| ext_exception(format!("flow_php failed to decode a schema frame: {e:?}")))?; - ensure_no_pending_exception("decode a schema frame")?; - - let hydrator_columns = hydrator_columns.array().ok_or_else(|| { - ext_exception("flow_php expected SchemaDecoder::decode to return an array") - })?; - - if hydrator_columns.len() != definitions.len() { - return Err(ext_exception( - "flow_php schema JSON and SchemaDecoder disagree on the column count", - )); - } - let mut columns = Vec::with_capacity(definitions.len()); - for (index, definition) in definitions.iter().enumerate() { - let hydrator_column = hydrator_columns - .get_index(index as i64) - .and_then(Zval::object) - .ok_or_else(|| ext_exception("flow_php expected a HydratorColumn object"))?; - - let name_zv = read_property(hydrator_column, "name")?; - let name = name_zv - .zend_str() - .and_then(|s| std::str::from_utf8(s.as_bytes()).ok()) - .ok_or_else(|| ext_exception("flow_php expected column names to be UTF-8 strings"))? - .to_string(); - - let read_definition = |property: &str| -> Result { - let zv = read_property(hydrator_column, property)?; - - if !zv.is_object() { - return Err(ext_exception( - "flow_php expected HydratorColumn definitions to be objects", - )); - } - - Ok(zv) - }; - - let definition_zv = read_definition("definition")?; - let entry_ce = entry_class_for(&definition_zv)?; - + for definition in &definitions { columns.push(Column { - name, - name_zv, - entry_ce, - name_slot: property_offset(entry_ce, "name")?, - value_slot: property_offset(entry_ce, "value")?, - definition_slot: property_offset(entry_ce, "definition")?, - definition: definition_zv, - nullable_definition: read_definition("nullableDefinition")?, - from_null_definition: read_definition("fromNullDefinition")?, + name: definition.name.clone(), decoder: build_decoder(&definition.type_)?, }); } diff --git a/src/extension/flow-php-ext/src/section.rs b/src/extension/flow-php-ext/src/section.rs deleted file mode 100644 index 1bcbace12d..0000000000 --- a/src/extension/flow-php-ext/src/section.rs +++ /dev/null @@ -1,284 +0,0 @@ -use std::collections::HashMap; - -use ext_php_rs::exception::PhpException; -use ext_php_rs::types::{ZendHashTable, ZendObject, Zval}; - -use crate::ctx::{ - call_handle, call_handle_on, ce_method_ref, find_class, property_offset, zval_null, zval_str, - Ctx, -}; -use crate::encode::{build_encode_plan, expect_object, ht_for_each, read_slot, EncodePlan}; -use crate::exception::ext_exception; - -struct Tracking { - columns: HashMap, Vec>, -} - -const CONSTANT_NORMALIZE_TYPES: [&str; 18] = [ - "Flow\\Types\\Type\\Native\\IntegerType", - "Flow\\Types\\Type\\Logical\\PositiveIntegerType", - "Flow\\Types\\Type\\Native\\FloatType", - "Flow\\Types\\Type\\Native\\BooleanType", - "Flow\\Types\\Type\\Native\\StringType", - "Flow\\Types\\Type\\Logical\\NonEmptyStringType", - "Flow\\Types\\Type\\Logical\\NumericStringType", - "Flow\\Types\\Type\\Logical\\ScalarType", - "Flow\\Types\\Type\\Logical\\DateTimeType", - "Flow\\Types\\Type\\Logical\\DateType", - "Flow\\Types\\Type\\Logical\\TimeType", - "Flow\\Types\\Type\\Logical\\HTMLType", - "Flow\\Types\\Type\\Logical\\HTMLElementType", - "Flow\\Types\\Type\\Logical\\TimeZoneType", - "Flow\\Types\\Type\\Logical\\UuidType", - "Flow\\Types\\Type\\Logical\\JsonType", - "Flow\\Types\\Type\\Logical\\XMLType", - "Flow\\Types\\Type\\Logical\\XMLElementType", -]; - -#[derive(Default)] -struct FingerprintCache { - entry_definition_slots: HashMap, - definition_type_slots: HashMap, - fingerprints: HashMap>>, -} - -/// `json_encode($type->normalize())`. -fn compute_fingerprint(type_obj: &ZendObject, ctx: &mut Ctx) -> Result, PhpException> { - let type_ce = unsafe { type_obj.ce.as_ref() } - .ok_or_else(|| ext_exception("flow_php failed to resolve a type class"))?; - - let normalized = call_handle_on( - ce_method_ref(type_ce, "normalize")?, - type_obj, - &mut [], - "normalize a type", - )?; - - let json = call_handle( - ctx.json_encode()?, - None, - &mut [normalized], - "encode a type fingerprint", - )?; - - Ok(json - .zend_str() - .ok_or_else(|| ext_exception("flow_php expected json_encode to return a string"))? - .as_bytes() - .to_vec()) -} - -fn fingerprint_matches( - entry: &ZendObject, - expected: &[u8], - ctx: &mut Ctx, - cache: &mut FingerprintCache, -) -> Result { - let entry_ce_ptr = entry.ce as usize; - let definition_slot = match cache.entry_definition_slots.get(&entry_ce_ptr) { - Some(slot) => *slot, - None => { - let entry_ce = unsafe { entry.ce.as_ref() } - .ok_or_else(|| ext_exception("flow_php failed to resolve an entry class"))?; - let slot = property_offset(entry_ce, "definition")?; - cache.entry_definition_slots.insert(entry_ce_ptr, slot); - slot - } - }; - - let def_obj = expect_object(read_slot(entry, definition_slot), "an entry definition")?; - let def_ce_ptr = def_obj.ce as usize; - let type_slot = match cache.definition_type_slots.get(&def_ce_ptr) { - Some(slot) => *slot, - None => { - let def_ce = unsafe { def_obj.ce.as_ref() } - .ok_or_else(|| ext_exception("flow_php failed to resolve a definition class"))?; - let slot = property_offset(def_ce, "type")?; - cache.definition_type_slots.insert(def_ce_ptr, slot); - slot - } - }; - - let type_obj = expect_object(read_slot(def_obj, type_slot), "a definition type")?; - let type_ce_ptr = type_obj.ce as usize; - - if let Some(cached) = cache.fingerprints.get(&type_ce_ptr) { - return match cached { - Some(fingerprint) => Ok(fingerprint.as_slice() == expected), - None => Ok(compute_fingerprint(type_obj, ctx)?.as_slice() == expected), - }; - } - - let type_ce = unsafe { type_obj.ce.as_ref() } - .ok_or_else(|| ext_exception("flow_php failed to resolve a type class"))?; - let constant = type_ce - .name() - .is_some_and(|name| CONSTANT_NORMALIZE_TYPES.contains(&name)); - let fingerprint = compute_fingerprint(type_obj, ctx)?; - let matches = fingerprint.as_slice() == expected; - - cache - .fingerprints - .insert(type_ce_ptr, constant.then_some(fingerprint)); - - Ok(matches) -} - -/// Mirrors `SchemaTracker::fits`: a narrower row still fits; a new column or an -/// incompatible type forces a new section. -fn fits( - tracking: &Tracking, - entries_ht: &ZendHashTable, - ctx: &mut Ctx, - cache: &mut FingerprintCache, -) -> Result { - let mut fits = true; - - ht_for_each(entries_ht, |key, index, entry_zv| { - if !fits { - return Ok(()); - } - - let index_name; - let name: &[u8] = match key { - Some(name) => name.as_bytes(), - None => { - index_name = (index as i64).to_string(); - index_name.as_bytes() - } - }; - - match tracking.columns.get(name) { - None => fits = false, - Some(expected) => { - let entry = expect_object(entry_zv, "a row entry")?; - - if !fingerprint_matches(entry, expected, ctx, cache)? { - fits = false; - } - } - } - - Ok(()) - })?; - - Ok(fits) -} - -/// Fingerprints come straight from `EncoderColumn::typeFingerprint`, the same -/// value `fits` compares against, so parity with `SchemaTracker::fits` holds. -fn build_tracking(plan_obj: &ZendObject, ctx: &mut Ctx) -> Result { - let columns_slot = ctx.encoder_plan_slots()?.columns; - let (name_slot, fingerprint_slot) = { - let slots = ctx.encoder_column_slots()?; - (slots.name, slots.type_fingerprint) - }; - - let columns_ht = read_slot(plan_obj, columns_slot) - .array() - .ok_or_else(|| ext_exception("flow_php expected EncoderPlan::columns to be an array"))?; - - let mut columns = HashMap::with_capacity(columns_ht.len()); - ht_for_each(columns_ht, |_, _, column_zv| { - let column = expect_object(column_zv, "an EncoderColumn")?; - - let name = read_slot(column, name_slot) - .zend_str() - .ok_or_else(|| ext_exception("flow_php expected EncoderColumn::name to be a string"))? - .as_bytes() - .to_vec(); - let fingerprint = read_slot(column, fingerprint_slot) - .zend_str() - .ok_or_else(|| { - ext_exception("flow_php expected EncoderColumn::typeFingerprint to be a string") - })? - .as_bytes() - .to_vec(); - - columns.insert(name, fingerprint); - - Ok(()) - })?; - - Ok(Tracking { columns }) -} - -pub struct SectionTracker { - tracking: Option, - current_schema_body: Option>, - plan: Option, - fingerprints: FingerprintCache, -} - -impl SectionTracker { - pub fn new() -> Self { - Self { - tracking: None, - current_schema_body: None, - plan: None, - fingerprints: FingerprintCache::default(), - } - } - - /// Reads a Row's entries hashtable through the cached slot offsets. - pub fn row_entries<'a>(row_zv: &'a Zval, ctx: &Ctx) -> Result<&'a ZendHashTable, PhpException> { - let row_obj = expect_object(row_zv, "a Row")?; - let entries_obj = expect_object(read_slot(row_obj, ctx.row_entries_slot), "Row entries")?; - - read_slot(entries_obj, ctx.entries_entries_slot) - .array() - .ok_or_else(|| ext_exception("flow_php expected Entries to hold an array")) - } - - /// Returns the new section's SCHEMA frame body when the row does not fit, - /// grown via `FloeWriter::growSectionPlan`; None when the row rides the section. - pub fn ensure_section( - &mut self, - row_zv: &Zval, - entries_ht: &ZendHashTable, - ctx: &mut Ctx, - ) -> Result>, PhpException> { - let changed = match &self.tracking { - None => true, - Some(current) => !fits(current, entries_ht, ctx, &mut self.fingerprints)?, - }; - - if !changed { - return Ok(None); - } - - let grow_fn = ce_method_ref(find_class("Flow\\Floe\\FloeWriter")?, "growSectionPlan")?; - let body_arg = match &self.current_schema_body { - Some(body) => zval_str(body), - None => zval_null(), - }; - - let plan_zv = call_handle( - grow_fn, - None, - &mut [body_arg, row_zv.shallow_clone()], - "grow a section plan", - )?; - - let plan_obj = expect_object(&plan_zv, "an EncoderPlan")?; - let schema_body = read_slot(plan_obj, ctx.encoder_plan_slots()?.schema_body) - .zend_str() - .ok_or_else(|| { - ext_exception("flow_php expected EncoderPlan::schemaBody to be a string") - })? - .as_bytes() - .to_vec(); - - self.tracking = Some(build_tracking(plan_obj, ctx)?); - self.current_schema_body = Some(schema_body.clone()); - self.plan = Some(build_encode_plan(&schema_body)?); - - Ok(Some(schema_body)) - } - - pub fn plan_mut(&mut self) -> Result<&mut EncodePlan, PhpException> { - self.plan - .as_mut() - .ok_or_else(|| ext_exception("flow_php has no active encode plan")) - } -} diff --git a/src/extension/flow-php-ext/src/values.rs b/src/extension/flow-php-ext/src/values.rs index e0cdb9f7ee..35d6388249 100644 --- a/src/extension/flow-php-ext/src/values.rs +++ b/src/extension/flow-php-ext/src/values.rs @@ -4,6 +4,7 @@ use std::ffi::{c_char, c_int, c_void}; use ext_php_rs::exception::PhpException; use ext_php_rs::types::{ZendHashTable, ZendObject, ZendStr, Zval}; +use ext_php_rs::zend::ExecutorGlobals; use crate::ctx::{ call_handle, ensure_no_pending_exception, ht_insert, ht_insert_index, write_property_raw, @@ -33,6 +34,59 @@ extern "C" { const PHP_DATE_OBJ_STD_OFFSET: usize = std::mem::size_of::<*const c_void>(); +/// `new DateTimeImmutable($str)` through the same C-level timelib parser, in its +/// non-throwing `date_create()` flavor: `Ok(None)` on parse failure, no exception. +pub(crate) fn date_from_free_form( + bytes: &[u8], + ctx: &mut Ctx, +) -> Result, PhpException> { + let ce = ctx.datetime_fns(false)?.ce; + + let mut datetime = Zval::new(); + unsafe { + php_date_instantiate( + std::ptr::from_ref(ce).cast_mut(), + std::ptr::from_mut(&mut datetime), + ); + } + + let datetime_obj = datetime + .object_mut() + .ok_or_else(|| ext_exception("flow_php failed to instantiate a datetime object"))?; + + // timelib reads the byte AFTER the consumed input, so the buffer must be + // NUL-terminated like the zend_strings PHP hands it (length excludes the NUL) + let mut time_str = Vec::with_capacity(bytes.len() + 1); + time_str.extend_from_slice(bytes); + time_str.push(0); + + let initialized = unsafe { + php_date_initialize( + std::ptr::from_mut(datetime_obj) + .cast::() + .sub(PHP_DATE_OBJ_STD_OFFSET) + .cast::(), + time_str.as_mut_ptr().cast::(), + time_str.len() - 1, + std::ptr::null(), + std::ptr::null_mut(), + 0, + ) + }; + + if !initialized { + // date_create() reports parse failures via `false`; discard any engine + // artifact so the caller can fall back to the PHP cast cleanly + drop(ExecutorGlobals::take_exception()); + + return Ok(None); + } + + ensure_no_pending_exception("parse a datetime value")?; + + Ok(Some(datetime)) +} + pub fn decode_value( decoder: &Decoder, reader: &mut Reader, diff --git a/src/extension/flow-php-ext/tests/phpt/001_extension_loaded.phpt b/src/extension/flow-php-ext/tests/phpt/001_extension_loaded.phpt index 7a5c1b0a09..4f5db9b9fc 100644 --- a/src/extension/flow-php-ext/tests/phpt/001_extension_loaded.phpt +++ b/src/extension/flow-php-ext/tests/phpt/001_extension_loaded.phpt @@ -5,12 +5,10 @@ flow_php extension is loaded and symbols are registered --FILE-- --EXPECT-- bool(true) bool(true) bool(true) -bool(true) diff --git a/src/extension/flow-php-ext/tests/phpt/002_scalar_round_trip.phpt b/src/extension/flow-php-ext/tests/phpt/002_scalar_round_trip.phpt index 89f1cb0a6f..d48e5c0ca1 100644 --- a/src/extension/flow-php-ext/tests/phpt/002_scalar_round_trip.phpt +++ b/src/extension/flow-php-ext/tests/phpt/002_scalar_round_trip.phpt @@ -6,7 +6,6 @@ scalar columns round-trip identically to the pure-PHP decoder --FILE-- get('nullable')->value()); var_dump($actual[0]->get('nullable')->definition()->isNullable()); -var_dump($actual[0]->get('nullable')->definition()->metadata()->has(Metadata::FROM_NULL)); -var_dump($actual[0]->get('from_null')->value()); -var_dump($actual[0]->get('from_null')->definition()->isNullable()); -var_dump($actual[0]->get('from_null')->definition()->metadata()->get(Metadata::FROM_NULL)); +var_dump($actual[0]->get('nullable')->type()->toString()); +var_dump($actual[0]->get('null_typed')->value()); +var_dump($actual[0]->get('null_typed')->definition()->isNullable()); +var_dump($actual[0]->get('null_typed')->type()->toString()); var_dump($actual[0]->get('present')->definition()->isNullable()); -var_dump($actual[0]->get('present')->definition()->metadata()->has(Metadata::FROM_NULL)); +var_dump($actual[0]->get('present')->type()->toString()); ?> --EXPECT-- identical NULL bool(true) -bool(false) +string(6) "string" NULL bool(true) -bool(true) -bool(false) +string(4) "null" bool(false) +string(6) "string" diff --git a/src/extension/flow-php-ext/tests/phpt/004_datetime.phpt b/src/extension/flow-php-ext/tests/phpt/004_datetime.phpt index 854d797d2d..137a915888 100644 --- a/src/extension/flow-php-ext/tests/phpt/004_datetime.phpt +++ b/src/extension/flow-php-ext/tests/phpt/004_datetime.phpt @@ -7,7 +7,6 @@ datetime columns: immutable + mutable classes, non-UTC timezone, microseconds require __DIR__ . '/bootstrap.php'; use Flow\ETL\Row\Entry\DateTimeEntry; -use Flow\Floe\RowsDecoder; use function Flow\ETL\DSL\{row, rows, int_entry, datetime_entry}; @@ -25,7 +24,7 @@ $rows = rows( ); $frames = php_frames($rows); -$actual = decoder_decode_frames(new RowsDecoder(), $frames); +$actual = ext_decode_frames($frames); assert_rows_identical(php_decode_frames($frames), $actual); diff --git a/src/extension/flow-php-ext/tests/phpt/005_time_uuid.phpt b/src/extension/flow-php-ext/tests/phpt/005_time_uuid.phpt index 5428a26b68..f964fecae6 100644 --- a/src/extension/flow-php-ext/tests/phpt/005_time_uuid.phpt +++ b/src/extension/flow-php-ext/tests/phpt/005_time_uuid.phpt @@ -6,7 +6,6 @@ time (DateInterval) and uuid columns round-trip identically --FILE-- get('price')->value()); +// row written as (name, id) comes back in the single union schema's column order (id, name) var_dump(implode(',', $actual[3]->entries()->names())); ?> --EXPECT-- int(4) identical float(1.5) -string(7) "name,id" +string(7) "id,name" diff --git a/src/extension/flow-php-ext/tests/phpt/007_empty_rows.phpt b/src/extension/flow-php-ext/tests/phpt/007_empty_rows.phpt index aef6a36959..ed310de252 100644 --- a/src/extension/flow-php-ext/tests/phpt/007_empty_rows.phpt +++ b/src/extension/flow-php-ext/tests/phpt/007_empty_rows.phpt @@ -6,12 +6,11 @@ empty Rows produce no frame bodies and decode to an empty row list schema($schemaBody); - $decoder->rows($rowBodies); +$schema = schema_from_json($schemaBody); + +$cycle = static function () use ($schemaBody, $schema, $rowBodies, $sourceRows): void { + $decoder = new RustFloeEncoderNative(); + $hydrator = new PhpRowHydrator(); + $hydrator->hydrate($decoder->decode($rowBodies, $schemaBody), $schema); foreach ($rowBodies as $body) { - $decoder->row($body); + $hydrator->hydrate($decoder->decode([$body], $schemaBody), $schema); } - $encoder = new RowsEncoder(); - $encoder->schema($schemaBody); - - foreach ($sourceRows as $row) { - $encoder->row($row); - } + $encoder = new RustFloeEncoderNative(); + $encoder->encode($hydrator->dehydrate(new Rows(...$sourceRows)), $schemaBody); }; for ($i = 0; $i < 10; $i++) { diff --git a/src/extension/flow-php-ext/tests/phpt/011_containers.phpt b/src/extension/flow-php-ext/tests/phpt/011_containers.phpt index 10d73e5882..498ffdaf03 100644 --- a/src/extension/flow-php-ext/tests/phpt/011_containers.phpt +++ b/src/extension/flow-php-ext/tests/phpt/011_containers.phpt @@ -6,7 +6,6 @@ list, map and structure columns round-trip identically to the pure-PHP decoder --FILE-- $expectedRow) { - if (serialize($expectedRow) !== serialize($decoded[$i])) { - $identical = false; - echo "FAIL: row {$i} differs\n"; +assert_rows_identical(php_decode_frames($frames), $decoded); + +$schemaBody = null; +$rowBody = null; + +foreach ($frames as $frame) { + if ($frame['type'] === Format::FRAME_SCHEMA) { + if ($schemaBody === null) { + $schemaBody = $frame['body']; + } + } elseif ($rowBody === null && $schemaBody !== null) { + $rowBody = $frame['body']; } } -var_dump($identical); -$fresh = new RowsDecoder(); try { - $fresh->row("\x01"); + (new RustFloeEncoderNative())->decode([$rowBody . "\xEF"], $schemaBody); echo "FAIL: no exception\n"; } catch (Flow\Floe\Exception\ExtensionException $e) { echo $e->getMessage(), "\n"; @@ -42,5 +47,5 @@ try { ?> --EXPECT-- int(4) -bool(true) -flow_php found a row frame before any schema frame +identical +flow_php row frame length does not match its content diff --git a/src/extension/flow-php-ext/tests/phpt/019_html_fallback.phpt b/src/extension/flow-php-ext/tests/phpt/019_html_fallback.phpt index f5a74344f7..7447d01283 100644 --- a/src/extension/flow-php-ext/tests/phpt/019_html_fallback.phpt +++ b/src/extension/flow-php-ext/tests/phpt/019_html_fallback.phpt @@ -9,7 +9,6 @@ if (!class_exists('Dom\HTMLDocument')) die("skip Dom\HTMLDocument requires PHP 8 --FILE-- rows(), ]; -$rowEncoder = new RowEncoder(); -$tracker = new SchemaTracker(); - foreach ($datasets as $label => $data) { - $encoder = new RowsEncoder(); - $plan = null; - $identical = true; - - foreach ($data->all() as $row) { - if ($plan === null || !$tracker->fits($plan, $row)) { - $plan = FloeWriter::growSectionPlan(null, $row); - $encoder->schema($plan->schemaBody); - } - - if ($encoder->row($row) !== $rowEncoder->encode($plan, $row)) { - $identical = false; - } - } - - printf("%-14s bytes-identical:%s\n", $label, $identical ? 'yes' : 'NO'); + printf("%-14s frames-identical:%s\n", $label, php_frames($data) === ext_frames($data) ? 'yes' : 'NO'); } // A row narrower than the primed plan must emit VALUE_ABSENT (0x03) for the -// missing column, byte-identical to the pure-PHP RowEncoder. -$widePlan = FloeWriter::growSectionPlan(null, row(int_entry('a', 1), str_entry('b', 'x'), float_entry('c', 1.5))); +// missing column, byte-identical to PhpFloeEncoder. +$wideBody = json_encode(row(int_entry('a', 1), str_entry('b', 'x'), float_entry('c', 1.5))->schema()->normalize(), JSON_THROW_ON_ERROR); $narrowRow = row(int_entry('a', 7), float_entry('c', 2.5)); -$absentEncoder = new RowsEncoder(); -$absentEncoder->schema($widePlan->schemaBody); -$absentIdentical = $absentEncoder->row($narrowRow) === $rowEncoder->encode($widePlan, $narrowRow); -printf("%-14s bytes-identical:%s\n", 'absent', $absentIdentical ? 'yes' : 'NO'); +$hydrator = new PhpRowHydrator(); +$narrowTyped = $hydrator->dehydrate(new Rows($narrowRow)); + +$php = new PhpFloeEncoder(schema_from_json($wideBody)); +$ext = new RustFloeEncoderNative(); +printf("%-14s frames-identical:%s\n", 'absent', $php->encode($narrowTyped) === $ext->encode($narrowTyped, $wideBody) ? 'yes' : 'NO'); -$badEncoder = new RowsEncoder(); $badRow = row(list_entry('bad', [new SplStack()], type_list(type_mixed()))); -$badEncoder->schema(FloeWriter::growSectionPlan(null, $badRow)->schemaBody); -expect_exception(fn() => $badEncoder->row($badRow)); +$badExt = new RustFloeEncoderNative(); +expect_exception(fn() => $badExt->encode($hydrator->dehydrate(new Rows($badRow)), json_encode($badRow->schema()->normalize(), JSON_THROW_ON_ERROR))); ?> --EXPECT-- -scalar bytes-identical:yes -from_null bytes-identical:yes -datetime bytes-identical:yes -containers bytes-identical:yes -enum_json_xml bytes-identical:yes -heterogeneous bytes-identical:yes -partitioned bytes-identical:yes -empty bytes-identical:yes -absent bytes-identical:yes +scalar frames-identical:yes +from_null frames-identical:yes +datetime frames-identical:yes +containers frames-identical:yes +enum_json_xml frames-identical:yes +heterogeneous frames-identical:yes +partitioned frames-identical:yes +empty frames-identical:yes +absent frames-identical:yes Flow\Floe\Exception\ExtensionException: flow_php does not support values of type "SplStack" in mixed/union context diff --git a/src/extension/flow-php-ext/tests/phpt/021_batched_decode.phpt b/src/extension/flow-php-ext/tests/phpt/021_batched_decode.phpt index 3ee0039f41..a6c680cf11 100644 --- a/src/extension/flow-php-ext/tests/phpt/021_batched_decode.phpt +++ b/src/extension/flow-php-ext/tests/phpt/021_batched_decode.phpt @@ -1,16 +1,18 @@ --TEST-- -RowsDecoder::rows decodes a batch identically to per-body row() and the pure-PHP decoder +RustFloeEncoderNative + RowHydrator decode a batch identically to the pure-PHP pipeline --SKIPIF-- --FILE-- row( int_entry('id', $i), @@ -34,21 +36,17 @@ foreach ($frames as $frame) { var_dump(count($rowBodies)); -$batchDecoder = new RowsDecoder(); -$batchDecoder->schema($schemaBody); -$batched = $batchDecoder->rows($rowBodies); +$decoder = new RustFloeEncoderNative(); +$hydrator = new PhpRowHydrator(); +$schema = schema_from_json($schemaBody); +$decodedValues = $decoder->decode($rowBodies, $schemaBody); +var_dump($decodedValues[0] instanceof RawRowValues); + +$batched = $hydrator->hydrate($decodedValues, $schema); var_dump($batched instanceof Rows); var_dump($batched->count()); -$singleDecoder = new RowsDecoder(); -$singleDecoder->schema($schemaBody); -$perBody = []; - -foreach ($rowBodies as $body) { - $perBody[] = $singleDecoder->row($body); -} - $php = php_decode_frames($frames); $batchedRows = $batched->all(); @@ -59,34 +57,19 @@ foreach ($php as $i => $expected) { $identical = false; echo "FAIL: batched row {$i} differs\n"; } - - if (serialize($expected) !== serialize($perBody[$i])) { - $identical = false; - echo "FAIL: per-body row {$i} differs\n"; - } } var_dump($identical); -$emptyDecoder = new RowsDecoder(); -$emptyDecoder->schema($schemaBody); -$empty = $emptyDecoder->rows([]); +$empty = $hydrator->hydrate($decoder->decode([], $schemaBody), $schema); var_dump($empty instanceof Rows); var_dump($empty->count()); - -$fresh = new RowsDecoder(); -try { - $fresh->rows($rowBodies); - echo "FAIL: no exception\n"; -} catch (Flow\Floe\Exception\ExtensionException $e) { - echo $e->getMessage(), "\n"; -} ?> --EXPECT-- int(500) bool(true) +bool(true) int(500) bool(true) bool(true) int(0) -flow_php found a row frame before any schema frame diff --git a/src/extension/flow-php-ext/tests/phpt/022_row_encoder_round_trip.phpt b/src/extension/flow-php-ext/tests/phpt/022_row_encoder_round_trip.phpt index fbb428f3e6..08f1bca5ae 100644 --- a/src/extension/flow-php-ext/tests/phpt/022_row_encoder_round_trip.phpt +++ b/src/extension/flow-php-ext/tests/phpt/022_row_encoder_round_trip.phpt @@ -1,18 +1,17 @@ --TEST-- -RowsEncoder frame bodies round-trip through RowsDecoder::rows +RustFloeEncoderNative frame bodies round-trip through the RawRowValues pipeline --SKIPIF-- --FILE-- schemaBody; +$schemaBody = json_encode($sourceRows[0]->schema()->normalize(), JSON_THROW_ON_ERROR); +$hydrator = new PhpRowHydrator(); -$encoder = new RowsEncoder(); -$encoder->schema($schemaBody); -$bodies = array_map(fn($row) => $encoder->row($row), $sourceRows); +$encoder = new RustFloeEncoderNative(); +$bodies = $encoder->encode($hydrator->dehydrate(new Rows(...$sourceRows)), $schemaBody); -$decoder = new RowsDecoder(); -$decoder->schema($schemaBody); -$decoded = $decoder->rows($bodies); +$decoded = $hydrator->hydrate((new RustFloeEncoderNative())->decode($bodies, $schemaBody), schema_from_json($schemaBody)); var_dump($decoded instanceof Rows); var_dump($decoded->count()); -$reEncoder = new RowsEncoder(); -$reEncoder->schema($schemaBody); -$reBodies = array_map(fn($row) => $reEncoder->row($row), $decoded->all()); +$reEncoder = new RustFloeEncoderNative(); +$reBodies = $reEncoder->encode($hydrator->dehydrate($decoded), $schemaBody); var_dump($bodies === $reBodies); $frames = array_merge( diff --git a/src/extension/flow-php-ext/tests/phpt/023_encoder_datetime_subclass.phpt b/src/extension/flow-php-ext/tests/phpt/023_encoder_datetime_subclass.phpt index 8b36d435a4..0517356a42 100644 --- a/src/extension/flow-php-ext/tests/phpt/023_encoder_datetime_subclass.phpt +++ b/src/extension/flow-php-ext/tests/phpt/023_encoder_datetime_subclass.phpt @@ -1,5 +1,5 @@ --TEST-- -RowsEncoder rejects DateTime subclasses with the Floe parity error +RustFloeEncoderNative rejects DateTime subclasses with the Floe parity error --SKIPIF-- --FILE-- @@ -7,8 +7,9 @@ RowsEncoder rejects DateTime subclasses with the Floe parity error require __DIR__ . '/bootstrap.php'; use Flow\ETL\Row\Entry\DateTimeEntry; -use Flow\Floe\FloeWriter; -use Flow\Floe\RowsEncoder; +use Flow\ETL\Row\PhpRowHydrator; +use Flow\ETL\Rows; +use Flow\Floe\RustFloeEncoderNative; use function Flow\ETL\DSL\row; @@ -17,11 +18,11 @@ class PhptCustomDateTime extends DateTimeImmutable } $badRow = row(new DateTimeEntry('custom', new PhptCustomDateTime('2020-05-05 10:20:30.000042', new DateTimeZone('Europe/Warsaw')))); +$typed = (new PhpRowHydrator())->dehydrate(new Rows($badRow)); -$encoder = new RowsEncoder(); -$encoder->schema(FloeWriter::growSectionPlan(null, $badRow)->schemaBody); +$encoder = new RustFloeEncoderNative(); -expect_exception(fn() => $encoder->row($badRow)); +expect_exception(fn() => $encoder->encode($typed, json_encode($badRow->schema()->normalize(), JSON_THROW_ON_ERROR))); ?> --EXPECT-- Flow\Floe\Exception\ExtensionException: Floe supports only DateTime and DateTimeImmutable, got PhptCustomDateTime - convert custom datetime instances before writing diff --git a/src/extension/flow-php-ext/tests/phpt/024_row_hydrator_parity.phpt b/src/extension/flow-php-ext/tests/phpt/024_row_hydrator_parity.phpt new file mode 100644 index 0000000000..fbd7b88c0f --- /dev/null +++ b/src/extension/flow-php-ext/tests/phpt/024_row_hydrator_parity.phpt @@ -0,0 +1,111 @@ +--TEST-- +NativeRowHydrator hydrate/dehydrate are serialize-identical to PhpRowHydrator +--SKIPIF-- + +--FILE-- + [ + schema(int_schema('id'), str_schema('name', nullable: true), float_schema('p'), bool_schema('a')), + [ + new RawRowValues(['id' => 1, 'name' => 'x', 'p' => 1.5, 'a' => true]), + new RawRowValues(['id' => 2, 'name' => null, 'p' => -0.25, 'a' => false]), + ], + ], + 'null_nonnullable' => [ + schema(int_schema('id'), str_schema('name')), + [new RawRowValues(['id' => 1, 'name' => null]), new RawRowValues(['id' => 2, 'name' => null])], + ], + 'absent' => [ + schema(int_schema('id'), str_schema('name', nullable: true)), + [new RawRowValues(['id' => 1]), new RawRowValues(['id' => 2, 'name' => 'y'])], + ], + 'metadata' => [ + schema(int_schema('id')), + [ + new RawRowValues(['id' => 1], ['id' => Metadata::fromArray(['k' => 'v1'])]), + new RawRowValues(['id' => 2], ['id' => Metadata::fromArray(['k' => 'v2'])]), + ], + ], + 'temporal' => [ + schema(datetime_schema('at'), date_schema('d'), time_schema('t'), uuid_schema('u')), + [new RawRowValues([ + 'at' => new DateTimeImmutable('2025-01-01 12:00:00.123456', new DateTimeZone('Europe/Warsaw')), + 'd' => new DateTimeImmutable('2025-03-01'), + 't' => new DateInterval('PT2H30M5S'), + 'u' => new Flow\Types\Value\Uuid('01234567-89ab-4def-8123-456789abcdef'), + ])], + ], + 'containers' => [ + schema( + list_schema('l', type_list(type_integer())), + map_schema('m', type_map(type_string(), type_integer())), + structure_schema('st', type_structure(['a' => type_integer()], ['b' => type_string()], true)), + list_schema('opt', type_list(type_optional(type_integer()))), + json_schema('j'), + ), + [new RawRowValues([ + 'l' => [1, 2, 3], + 'm' => ['a' => 1], + 'st' => ['a' => 1, 'extra' => 'kept'], + 'opt' => [1, null], + 'j' => Flow\Types\Value\Json::fromArray(['x' => 1]), + ])], + ], + 'enum_and_null' => [ + schema(enum_schema('s', PhptSuit::class), null_schema('n')), + [new RawRowValues(['s' => PhptSuit::Hearts, 'n' => null]), new RawRowValues(['s' => null, 'n' => null])], + ], + 'empty' => [schema(int_schema('id')), []], +]; + +$php = new PhpRowHydrator(); +$native = new NativeRowHydrator(); + +foreach ($datasets as $label => [$s, $batch]) { + $hydrateOk = serialize($php->hydrate($batch, $s)) === serialize($native->hydrate($batch, $s)); + $rows = $php->hydrate($batch, $s); + $dehydrateOk = serialize($php->dehydrate($rows)) === serialize($native->dehydrate($rows)); + printf("%-16s hydrate:%s dehydrate:%s\n", $label, $hydrateOk ? 'yes' : 'NO', $dehydrateOk ? 'yes' : 'NO'); +} + +$mutated = schema(int_schema('id')); +$php->hydrate([new RawRowValues(['id' => 1])], $mutated); +$native->hydrate([new RawRowValues(['id' => 1])], $mutated); +$mutated->add(str_schema('name', nullable: true))->makeNullable(); +$batch = [new RawRowValues(['id' => null, 'name' => 'x'])]; +printf( + "%-16s hydrate:%s\n", + 'schema_mutation', + serialize($php->hydrate($batch, $mutated)) === serialize($native->hydrate($batch, $mutated)) ? 'yes' : 'NO', +); + +printf("native class registered:%s\n", class_exists(RustRowHydratorNative::class, false) ? 'yes' : 'NO'); +?> +--EXPECT-- +scalars hydrate:yes dehydrate:yes +null_nonnullable hydrate:yes dehydrate:yes +absent hydrate:yes dehydrate:yes +metadata hydrate:yes dehydrate:yes +temporal hydrate:yes dehydrate:yes +containers hydrate:yes dehydrate:yes +enum_and_null hydrate:yes dehydrate:yes +empty hydrate:yes dehydrate:yes +schema_mutation hydrate:yes +native class registered:yes diff --git a/src/extension/flow-php-ext/tests/phpt/025_hydrator_no_leaks.phpt b/src/extension/flow-php-ext/tests/phpt/025_hydrator_no_leaks.phpt new file mode 100644 index 0000000000..8ab45f4872 --- /dev/null +++ b/src/extension/flow-php-ext/tests/phpt/025_hydrator_no_leaks.phpt @@ -0,0 +1,75 @@ +--TEST-- +repeated native hydrate and dehydrate do not leak memory +--SKIPIF-- + +--FILE-- + type_integer(), 'tags' => type_list(type_string())])), + json_schema('json'), +); + +$batch = []; + +for ($i = 1; $i <= 100; $i++) { + $batch[] = new RawRowValues( + [ + 'id' => $i, + 'name' => $i % 10 === 0 ? null : 'user_' . $i, // exercises the makeNullable path + 'price' => $i / 100, + 'active' => $i % 3 === 0, + 'created_at' => new DateTimeImmutable('2025-01-01 00:00:00.123456', new DateTimeZone('Europe/Warsaw')), + 'duration' => new DateInterval('PT1H2M3S'), + 'uuid' => new Flow\Types\Value\Uuid('01234567-89ab-4def-8123-456789abcdef'), + 'mixed' => [$i, 'x', null, ['k' => 1.5]], + 'metrics' => ['cpu' => 0.5, 'mem' => 0.25], + 'nested' => ['a' => $i, 'tags' => ['x']], + 'json' => Flow\Types\Value\Json::fromArray([$i, ['a' => true]]), + ], + $i % 5 === 0 ? ['id' => Metadata::fromArray(['batch' => $i])] : [], // exercises the clone + setMetadata path + ); +} + +$phpRows = (new PhpRowHydrator())->hydrate($batch, $schema); + +$cycle = static function () use ($batch, $schema, $phpRows): void { + $native = new RustRowHydratorNative(); + $rows = $native->hydrate($batch, $schema); + $native->dehydrate($rows); + $native->dehydrate($phpRows); +}; + +for ($i = 0; $i < 10; $i++) { + $cycle(); +} +gc_collect_cycles(); +$baseline = memory_get_usage(false); + +for ($i = 0; $i < 100; $i++) { + $cycle(); +} +gc_collect_cycles(); + +var_dump(memory_get_usage(false) <= $baseline); +?> +--EXPECT-- +bool(true) diff --git a/src/extension/flow-php-ext/tests/phpt/026_row_hydrator_cast_parity.phpt b/src/extension/flow-php-ext/tests/phpt/026_row_hydrator_cast_parity.phpt new file mode 100644 index 0000000000..f829b4df3f --- /dev/null +++ b/src/extension/flow-php-ext/tests/phpt/026_row_hydrator_cast_parity.phpt @@ -0,0 +1,141 @@ +--TEST-- +NativeRowHydrator cast is serialize-identical to PhpRowHydrator +--SKIPIF-- + +--FILE-- + [ + schema(int_schema('id'), float_schema('p'), bool_schema('a'), str_schema('n')), + [ + new RawRowValues(['id' => '42', 'p' => '3.14', 'a' => 'yes', 'n' => 7]), + new RawRowValues(['id' => ' 7', 'p' => '1e3', 'a' => 'OFF', 'n' => 1.5]), + new RawRowValues(['id' => 'abc', 'p' => '0x1A', 'a' => 'weird', 'n' => true]), + new RawRowValues(['id' => '9223372036854775808', 'p' => true, 'a' => 3.5, 'n' => null]), + new RawRowValues(['id' => 5, 'p' => 2.5, 'a' => true, 'n' => 'text']), + ], + ], + 'nested_families' => [ + schema( + list_schema('counts', type_list(type_positive_integer())), + structure_schema('labels', type_structure(['label' => type_non_empty_string()])), + structure_schema('codes', type_structure(['code' => type_numeric_string()])), + ), + [ + new RawRowValues(['counts' => [5, 7], 'labels' => ['label' => 'x'], 'codes' => ['code' => '42']]), + new RawRowValues(['counts' => ['5', 8], 'labels' => ['label' => 9], 'codes' => ['code' => 42]]), + ], + ], + 'temporal' => [ + schema(datetime_schema('at'), datetime_schema('at2'), date_schema('d')), + [ + new RawRowValues(['at' => $shared, 'at2' => $shared, 'd' => $shared]), + new RawRowValues(['at' => $shared, 'at2' => '2024-03-01 10:20:30', 'd' => new DateTimeImmutable('2025-03-01')]), + new RawRowValues(['at' => 1700000000, 'at2' => 1700000000.5, 'd' => '2024-03-05 08:30:00']), + ], + ], + 'uuid_json' => [ + schema(uuid_schema('u'), json_schema('j')), + [ + new RawRowValues(['u' => '01234567-89ab-4def-8123-456789abcdef', 'j' => '["a","b"]']), + new RawRowValues(['u' => new Flow\Types\Value\Uuid('01234567-89ab-4def-8123-456789abcdef'), 'j' => '{"a":1}']), + new RawRowValues(['u' => null, 'j' => ['a' => 1]]), + new RawRowValues(['u' => '11234567-89ab-4def-8123-456789abcdef', 'j' => Flow\Types\Value\Json::fromArray(['x' => 1])]), + ], + ], + 'containers' => [ + schema( + list_schema('l', type_list(type_integer())), + map_schema('m', type_map(type_string(), type_integer())), + map_schema('mi', type_map(type_integer(), type_string())), + list_schema('lo', type_list(type_optional(type_integer()))), + structure_schema('st', type_structure(['a' => type_integer()], ['b' => type_string()], true)), + ), + [ + new RawRowValues([ + 'l' => ['1', 2, '3'], + 'm' => ['a' => '1', 'b' => 2], + 'mi' => [0 => 'x', 5 => 7], + 'lo' => ['1', null, 3], + 'st' => ['a' => '5', 'extra' => 'dropped'], + ]), + new RawRowValues(['l' => [], 'm' => [], 'mi' => [], 'lo' => [], 'st' => ['a' => 1, 'b' => 'kept']]), + ], + ], + 'exotic_fallback' => [ + schema(enum_schema('s', CastSuit::class), xml_schema('x'), time_schema('t')), + [ + new RawRowValues(['s' => CastSuit::Hearts, 'x' => 'v', 't' => new DateInterval('PT2H30M5S')]), + new RawRowValues(['s' => 'h', 'x' => '', 't' => 'PT2H']), + ], + ], + 'fill_and_metadata' => [ + schema(int_schema('id'), str_schema('name', nullable: true), bool_schema('flag')), + [ + new RawRowValues(['id' => '1'], ['id' => Metadata::fromArray(['k' => 'v1'])]), + new RawRowValues([]), + new RawRowValues(['id' => 2, 'name' => null, 'unknown' => 'dropped', 'flag' => 'on']), + new RawRowValues(['id' => null], ['id' => Metadata::fromArray(['k' => 'v2'])]), + ], + ], + 'empty' => [schema(int_schema('id')), []], +]; + +$php = new PhpRowHydrator(); +$native = new NativeRowHydrator(); + +foreach ($datasets as $label => [$s, $batch]) { + $castOk = serialize($php->cast($batch, $s)) === serialize($native->cast($batch, $s)); + printf("%-16s cast:%s\n", $label, $castOk ? 'yes' : 'NO'); +} + +$mutated = schema(int_schema('id')); +$php->cast([new RawRowValues(['id' => '1'])], $mutated); +$native->cast([new RawRowValues(['id' => '1'])], $mutated); +$mutated->add(str_schema('name', nullable: true))->makeNullable(); +$batch = [new RawRowValues(['id' => null, 'name' => 7])]; +printf( + "%-16s cast:%s\n", + 'schema_mutation', + serialize($php->cast($batch, $mutated)) === serialize($native->cast($batch, $mutated)) ? 'yes' : 'NO', +); + +$inferBatch = [new RawRowValues(['id' => 1, 'name' => null])]; +printf( + "%-16s cast:%s\n", + 'null_schema', + serialize($php->cast($inferBatch)) === serialize($native->cast($inferBatch)) ? 'yes' : 'NO', +); + +printf("native class registered:%s\n", class_exists(RustRowHydratorNative::class, false) ? 'yes' : 'NO'); +?> +--EXPECT-- +scalars cast:yes +nested_families cast:yes +temporal cast:yes +uuid_json cast:yes +containers cast:yes +exotic_fallback cast:yes +fill_and_metadata cast:yes +empty cast:yes +schema_mutation cast:yes +null_schema cast:yes +native class registered:yes diff --git a/src/extension/flow-php-ext/tests/phpt/027_cast_fallback_exceptions.phpt b/src/extension/flow-php-ext/tests/phpt/027_cast_fallback_exceptions.phpt new file mode 100644 index 0000000000..957f9f0b39 --- /dev/null +++ b/src/extension/flow-php-ext/tests/phpt/027_cast_fallback_exceptions.phpt @@ -0,0 +1,89 @@ +--TEST-- +native cast propagates the exact PHP cast exceptions and aborts the batch +--SKIPIF-- + +--FILE-- + [schema(uuid_schema('u')), [new RawRowValues(['u' => 'not-a-uuid'])]], + 'uuid uppercase' => [schema(uuid_schema('u')), [new RawRowValues(['u' => '01234567-89AB-4DEF-8123-456789ABCDEF'])]], + 'json scalar' => [schema(json_schema('j')), [new RawRowValues(['j' => 5])]], + 'json invalid string' => [schema(json_schema('j')), [new RawRowValues(['j' => '{oops'])]], + 'json plain string' => [schema(json_schema('j')), [new RawRowValues(['j' => 'plain'])]], + 'datetime garbage' => [schema(datetime_schema('at')), [new RawRowValues(['at' => 'not-a-date'])]], + 'datetime array' => [schema(datetime_schema('at')), [new RawRowValues(['at' => ['nope']])]], + 'date garbage' => [schema(date_schema('d')), [new RawRowValues(['d' => 'not-a-date'])]], + 'string map int keys' => [ + schema(map_schema('m', type_map(type_string(), type_integer()))), + [new RawRowValues(['m' => [5 => 1]])], + ], + 'list bad keys' => [ + schema(list_schema('l', type_list(type_integer()))), + [new RawRowValues(['l' => [1 => 'x']])], + ], + 'positive int list string' => [ + schema(list_schema('l', type_list(type_positive_integer()))), + [new RawRowValues(['l' => ['abc']])], + ], + 'positive int list negative' => [ + schema(list_schema('l', type_list(type_positive_integer()))), + [new RawRowValues(['l' => [-3]])], + ], + 'all-optional structure' => [ + schema(structure_schema('st', type_structure([], ['b' => type_string()]))), + [new RawRowValues(['st' => ['other' => 1]])], + ], +]; + +$php = new PhpRowHydrator(); +$native = new NativeRowHydrator(); + +foreach ($throwing as $label => [$s, $batch]) { + $phpException = null; + + try { + $php->cast($batch, $s); + } catch (Throwable $e) { + $phpException = $e::class . '|' . $e->getMessage(); + } + + $nativeException = null; + $nativeResult = null; + + try { + $nativeResult = $native->cast($batch, $s); + } catch (Throwable $e) { + $nativeException = $e::class . '|' . $e->getMessage(); + } + + printf( + "%-27s exception:%s aborted:%s\n", + $label, + $phpException !== null && $phpException === $nativeException ? 'match' : "MISMATCH php[{$phpException}] native[{$nativeException}]", + $nativeResult === null ? 'yes' : 'NO', + ); +} +?> +--EXPECT-- +uuid invalid exception:match aborted:yes +uuid uppercase exception:match aborted:yes +json scalar exception:match aborted:yes +json invalid string exception:match aborted:yes +json plain string exception:match aborted:yes +datetime garbage exception:match aborted:yes +datetime array exception:match aborted:yes +date garbage exception:match aborted:yes +string map int keys exception:match aborted:yes +list bad keys exception:match aborted:yes +positive int list string exception:match aborted:yes +positive int list negative exception:match aborted:yes +all-optional structure exception:match aborted:yes diff --git a/src/extension/flow-php-ext/tests/phpt/027_rows_encoder_segments.phpt b/src/extension/flow-php-ext/tests/phpt/027_rows_encoder_segments.phpt deleted file mode 100644 index f76a2fcafb..0000000000 --- a/src/extension/flow-php-ext/tests/phpt/027_rows_encoder_segments.phpt +++ /dev/null @@ -1,84 +0,0 @@ ---TEST-- -RowsEncoder::rows produces section segments identical to Flow\Floe\PhpRowFrameEncoder ---SKIPIF-- - ---FILE-- - rows( - row(int_entry('id', 1), str_entry('name', null), float_entry('p', -1.5), bool_entry('a', true)), - row(int_entry('id', 2), str_entry('name', 'x'), float_entry('p', 0.25), bool_entry('a', false)), - ), - 'heterogeneous' => rows( - row(int_entry('id', 1)), - row(int_entry('id', 2), str_entry('n', 'x')), - row(str_entry('n', 'y'), int_entry('id', 3)), - row(int_entry('id', 4)), - ), - 'parametric' => rows( - row(int_entry('id', 1), list_entry('l', [1, 2], type_list(type_integer()))), - row(int_entry('id', 2), map_entry('m', ['cpu' => 1.5], type_map(type_string(), type_float()))), - row(int_entry('id', 3), structure_entry('st', ['a' => 1], type_structure(['a' => type_integer()]))), - ), - 'numeric_string_names' => rows( - row(int_entry('0', 1), str_entry('1', 'a')), - row(int_entry('0', 2), str_entry('1', 'b')), - ), - 'empty' => rows(), -]; - -function segment_dump(array $segments): array -{ - $dump = []; - - foreach ($segments as $segment) { - if (!$segment instanceof \Flow\Floe\FrameSegment) { - throw new RuntimeException('expected a FrameSegment, got ' . get_debug_type($segment)); - } - - $dump[] = [$segment->schemaBody, bin2hex($segment->frames), $segment->rowCount]; - } - - return $dump; -} - -foreach ($datasets as $name => $dataset) { - $php = segment_dump((new PhpRowFrameEncoder())->encode($dataset)); - $ext = segment_dump((new RowsEncoder())->rows($dataset)); - - echo $name . ': ' . ($php === $ext ? 'identical' : 'MISMATCH') . ' (' . count($ext) . " segments)\n"; -} - -// state continuation: the second call continues the section left open by the first -$phpEncoder = new PhpRowFrameEncoder(); -$extEncoder = new RowsEncoder(); - -$first = rows(row(int_entry('id', 1))); -$second = rows(row(int_entry('id', 2))); - -$phpFirst = segment_dump($phpEncoder->encode($first)); -$extFirst = segment_dump($extEncoder->rows($first)); -$phpSecond = segment_dump($phpEncoder->encode($second)); -$extSecond = segment_dump($extEncoder->rows($second)); - -echo 'continuation first: ' . ($phpFirst === $extFirst ? 'identical' : 'MISMATCH') . "\n"; -echo 'continuation second: ' . ($phpSecond === $extSecond ? 'identical' : 'MISMATCH') . "\n"; -echo 'continuation second schemaBody is null: ' . ($extSecond[0][0] === null ? 'yes' : 'no') . "\n"; -?> ---EXPECT-- -homogeneous: identical (1 segments) -heterogeneous: identical (2 segments) -parametric: identical (3 segments) -numeric_string_names: identical (1 segments) -empty: identical (0 segments) -continuation first: identical -continuation second: identical -continuation second schemaBody is null: yes diff --git a/src/extension/flow-php-ext/tests/phpt/028_cast_no_leaks.phpt b/src/extension/flow-php-ext/tests/phpt/028_cast_no_leaks.phpt new file mode 100644 index 0000000000..3377bb72e1 --- /dev/null +++ b/src/extension/flow-php-ext/tests/phpt/028_cast_no_leaks.phpt @@ -0,0 +1,85 @@ +--TEST-- +repeated native cast does not leak memory, including the throwing fallback path +--SKIPIF-- + +--FILE-- + type_integer()], ['b' => type_string()])), + json_schema('json'), + enum_schema('suit', LeakSuit::class), // exotic - per-value PHP fallback +); + +$batch = []; + +for ($i = 1; $i <= 100; $i++) { + $batch[] = new RawRowValues( + [ + 'id' => (string) $i, + 'name' => $i % 10 === 0 ? null : 'user_' . $i, // exercises the makeNullable path + 'price' => \sprintf('%d.%02d', $i, $i % 100), + 'active' => $i % 2 === 0 ? 'yes' : 'off', + 'created_at' => \sprintf('2024-03-%02d 10:20:%02d', 1 + $i % 28, $i % 60), + 'day' => \sprintf('2024-03-%02d', 1 + $i % 28), + 'uuid' => \sprintf('550e8400-e29b-41d4-a716-%012d', $i), + 'ints' => [(string) $i, null, $i], + 'metrics' => ['cpu' => (string) $i, 'mem' => $i], + 'nested' => ['a' => (string) $i, 'b' => $i], + 'json' => '["a","b"]', + 'suit' => 'h', + ], + $i % 5 === 0 ? ['id' => Metadata::fromArray(['batch' => $i])] : [], // exercises the clone + setMetadata path + ); +} + +$throwingBatch = [new RawRowValues(['id' => 1]), new RawRowValues(['uuid' => 'not-a-uuid', 'id' => 2])]; + +$cycle = static function () use ($batch, $throwingBatch, $schema): void { + $native = new RustRowHydratorNative(); + $native->cast($batch, $schema); + + try { + $native->cast($throwingBatch, $schema); + } catch (Throwable) { + // the aborted batch must not leak its partially built rows + } +}; + +for ($i = 0; $i < 10; $i++) { + $cycle(); +} +gc_collect_cycles(); +$baseline = memory_get_usage(false); + +for ($i = 0; $i < 100; $i++) { + $cycle(); +} +gc_collect_cycles(); + +var_dump(memory_get_usage(false) <= $baseline); +?> +--EXPECT-- +bool(true) diff --git a/src/extension/flow-php-ext/tests/phpt/bootstrap.php b/src/extension/flow-php-ext/tests/phpt/bootstrap.php index fadcc561e2..375b63b393 100644 --- a/src/extension/flow-php-ext/tests/phpt/bootstrap.php +++ b/src/extension/flow-php-ext/tests/phpt/bootstrap.php @@ -5,46 +5,68 @@ require __DIR__ . '/../../../../../vendor/autoload.php'; use Flow\ETL\Row; -use Flow\ETL\Row\Entry\Instantiators; +use Flow\ETL\Row\NativeRowHydrator; +use Flow\ETL\Row\PhpRowHydrator; use Flow\ETL\Rows; -use Flow\Floe\FloeWriter; use Flow\Floe\Format; -use Flow\Floe\RowEncoder; -use Flow\Floe\RowHydrator; -use Flow\Floe\RowsDecoder; -use Flow\Floe\SchemaDecoder; -use Flow\Floe\SchemaTracker; -use Flow\Floe\ValueDecoder; +use Flow\Floe\NativeFloeEncoder; +use Flow\Floe\PhpFloeEncoder; /** - * Pure-PHP reference framing built from the Floe encoder primitives: turns Rows - * into the ordered list of bare SCHEMA/ROW frame bodies the extension decodes. - * A new SCHEMA frame is emitted whenever the row no longer matches the plan. + * Pure-PHP reference framing built from the Floe encoder primitives: a write + * session carries one schema, so the whole Rows is framed as a single SCHEMA + * frame (its union) followed by one ROW frame per row. * * @return array */ function php_frames(Rows $rows): array { - $rowEncoder = new RowEncoder(); - $tracker = new SchemaTracker(); - $plan = null; - $frames = []; + if ($rows->count() === 0) { + return []; + } + + $hydrator = new PhpRowHydrator(); + $schemaBody = json_encode($rows->schema()->normalize(), JSON_THROW_ON_ERROR); + $encoder = new PhpFloeEncoder(Flow\ETL\DSL\schema_from_json($schemaBody)); + + $frames = [['type' => Format::FRAME_SCHEMA, 'body' => $schemaBody]]; foreach ($rows->all() as $row) { - if ($plan === null || !$tracker->fits($plan, $row)) { - $plan = FloeWriter::growSectionPlan(null, $row); - $frames[] = ['type' => Format::FRAME_SCHEMA, 'body' => $plan->schemaBody]; - } + $frames[] = ['type' => Format::FRAME_ROW, 'body' => $encoder->encode($hydrator->dehydrate(new Rows($row)))[0]]; + } - $frames[] = ['type' => Format::FRAME_ROW, 'body' => $rowEncoder->encode($plan, $row)]; + return $frames; +} + +/** + * Native counterpart of php_frames(): identical single-schema framing (PHP owns + * it), ROW bodies produced by NativeFloeEncoder. Compared against php_frames() + * to prove the native encode is byte-identical to the pure-PHP encode. + * + * @return array + */ +function ext_frames(Rows $rows): array +{ + if ($rows->count() === 0) { + return []; + } + + $hydrator = new NativeRowHydrator(); + $schemaBody = json_encode($rows->schema()->normalize(), JSON_THROW_ON_ERROR); + $encoder = new NativeFloeEncoder(Flow\ETL\DSL\schema_from_json($schemaBody)); + + $frames = [['type' => Format::FRAME_SCHEMA, 'body' => $schemaBody]]; + + foreach ($rows->all() as $row) { + $frames[] = ['type' => Format::FRAME_ROW, 'body' => $encoder->encode($hydrator->dehydrate(new Rows($row)))[0]]; } return $frames; } /** - * Pure-PHP reference decode of frame bodies via the Floe schema decoder and the - * row hydrator - the byte-for-byte oracle the extension is compared against. + * Pure-PHP reference decode of frame bodies via the Floe encoder and the row + * hydrator - the byte-for-byte oracle the extension is compared against. * * @param array $frames * @@ -52,19 +74,21 @@ function php_frames(Rows $rows): array */ function php_decode_frames(array $frames): array { - $schemaDecoder = new SchemaDecoder(new ValueDecoder(), new Instantiators()); - $rowHydrator = new RowHydrator(); - $plan = null; + $hydrator = new PhpRowHydrator(); + $encoder = null; + $schema = null; $rows = []; foreach ($frames as $frame) { if ($frame['type'] === Format::FRAME_SCHEMA) { - $plan = $schemaDecoder->decode($frame['body']); - } elseif ($plan === null) { + $schema = Flow\ETL\DSL\schema_from_json($frame['body']); + $encoder = new PhpFloeEncoder($schema); + } elseif ($schema === null || $encoder === null) { throw new RuntimeException('row frame before any schema frame'); } else { - $position = 0; - $rows[] = $rowHydrator->hydrate($plan, $frame['body'], $position); + foreach ($hydrator->hydrate($encoder->decode([$frame['body']]), $schema)->all() as $row) { + $rows[] = $row; + } } } @@ -72,22 +96,30 @@ function php_decode_frames(array $frames): array } /** - * Drives a RowsDecoder over frame bodies, priming schemas and decoding rows in - * order (mirrors what FloeReader does on the hot path). + * Drives the native two-layer pipeline over frame bodies, rebinding the schema + * per SCHEMA frame (mirrors what FloeStreamReader does on the hot path). * * @param array $frames * * @return array */ -function decoder_decode_frames(RowsDecoder $decoder, array $frames): array +function ext_decode_frames(array $frames): array { + $hydrator = new NativeRowHydrator(); + $encoder = null; + $schema = null; $rows = []; foreach ($frames as $frame) { if ($frame['type'] === Format::FRAME_SCHEMA) { - $decoder->schema($frame['body']); + $schema = Flow\ETL\DSL\schema_from_json($frame['body']); + $encoder = new NativeFloeEncoder($schema); + } elseif ($schema === null || $encoder === null) { + throw new RuntimeException('row frame before any schema frame'); } else { - $rows[] = $decoder->row($frame['body']); + foreach ($hydrator->hydrate($encoder->decode([$frame['body']]), $schema)->all() as $row) { + $rows[] = $row; + } } } diff --git a/src/lib/filesystem/src/Flow/Filesystem/Stream/StringDestinationStream.php b/src/lib/filesystem/src/Flow/Filesystem/Stream/StringDestinationStream.php new file mode 100644 index 0000000000..ccf300a0ab --- /dev/null +++ b/src/lib/filesystem/src/Flow/Filesystem/Stream/StringDestinationStream.php @@ -0,0 +1,50 @@ +buffer .= $data; + + return $this; + } + + public function content(): string + { + return $this->buffer; + } + + public function fromResource($resource): DestinationStream + { + $this->buffer .= (string) stream_get_contents($resource); + + return $this; + } + + public function close(): void {} + + public function isOpen(): bool + { + return true; + } + + public function path(): Path + { + return $this->path; + } +} diff --git a/src/lib/filesystem/src/Flow/Filesystem/Stream/StringSourceStream.php b/src/lib/filesystem/src/Flow/Filesystem/Stream/StringSourceStream.php new file mode 100644 index 0000000000..d5c08f5edf --- /dev/null +++ b/src/lib/filesystem/src/Flow/Filesystem/Stream/StringSourceStream.php @@ -0,0 +1,65 @@ +content; + } + + public function isOpen(): bool + { + return true; + } + + public function iterate(int $length = 1): Generator + { + foreach (str_split($this->content, $length) as $chunk) { + yield $chunk; + } + } + + public function path(): Path + { + return $this->path; + } + + public function read(int $length, int $offset): string + { + return substr($this->content, $offset, $length); + } + + public function readLines(string $separator = "\n", ?int $length = null): Generator + { + foreach (explode($separator, $this->content) as $line) { + if (strlen($line)) { + yield $line; + } + } + } + + public function size(): int + { + return strlen($this->content); + } +} diff --git a/src/lib/filesystem/tests/Flow/Filesystem/Tests/Unit/Stream/StringDestinationStreamTest.php b/src/lib/filesystem/tests/Flow/Filesystem/Tests/Unit/Stream/StringDestinationStreamTest.php new file mode 100644 index 0000000000..f835439613 --- /dev/null +++ b/src/lib/filesystem/tests/Flow/Filesystem/Tests/Unit/Stream/StringDestinationStreamTest.php @@ -0,0 +1,64 @@ +append('foo')->append('bar'); + + static::assertSame('foobar', $stream->content()); + } + + public function test_content_of_empty_stream_is_empty_string(): void + { + static::assertSame('', (new StringDestinationStream(path('memory://empty.bin')))->content()); + } + + public function test_from_resource_appends_resource_contents(): void + { + $resource = fopen('php://memory', 'r+b'); + fwrite($resource, 'from-resource'); + rewind($resource); + + $stream = new StringDestinationStream(path('memory://res.bin')); + $stream->append('head-')->fromResource($resource); + + static::assertSame('head-from-resource', $stream->content()); + } + + public function test_is_open_is_always_true(): void + { + static::assertTrue((new StringDestinationStream(path('memory://open.bin')))->isOpen()); + } + + public function test_close_is_a_noop_and_keeps_content_readable(): void + { + $stream = new StringDestinationStream(path('memory://close.bin')); + $stream->append('kept'); + $stream->close(); + + static::assertSame('kept', $stream->content()); + } + + public function test_path_returns_the_construction_path(): void + { + static::assertSame( + 'memory://value.bin', + (new StringDestinationStream(path('memory://value.bin')))->path()->uri(), + ); + } +} diff --git a/src/lib/filesystem/tests/Flow/Filesystem/Tests/Unit/Stream/StringSourceStreamTest.php b/src/lib/filesystem/tests/Flow/Filesystem/Tests/Unit/Stream/StringSourceStreamTest.php new file mode 100644 index 0000000000..a96a8b114f --- /dev/null +++ b/src/lib/filesystem/tests/Flow/Filesystem/Tests/Unit/Stream/StringSourceStreamTest.php @@ -0,0 +1,76 @@ +content()); + } + + public function test_empty_content_is_allowed(): void + { + $stream = new StringSourceStream(path('memory://empty.bin'), ''); + + static::assertSame('', $stream->content()); + static::assertSame(0, $stream->size()); + static::assertSame([], iterator_to_array($stream->iterate(4))); + } + + public function test_size_is_the_byte_length(): void + { + static::assertSame(6, (new StringSourceStream(path('memory://size.bin'), 'foobar'))->size()); + } + + public function test_read_returns_a_byte_range(): void + { + $stream = new StringSourceStream(path('memory://read.bin'), 'foobar'); + + static::assertSame('foo', $stream->read(3, 0)); + static::assertSame('bar', $stream->read(3, 3)); + } + + public function test_iterate_yields_fixed_size_chunks(): void + { + $stream = new StringSourceStream(path('memory://iterate.bin'), 'foobar'); + + static::assertSame(['foo', 'bar'], iterator_to_array($stream->iterate(3))); + } + + public function test_read_lines_splits_on_the_separator_and_skips_empty_lines(): void + { + $stream = new StringSourceStream(path('memory://lines.bin'), "a\nb\n\nc"); + + static::assertSame(['a', 'b', 'c'], iterator_to_array($stream->readLines())); + } + + public function test_is_open_is_always_true(): void + { + static::assertTrue((new StringSourceStream(path('memory://open.bin'), 'x'))->isOpen()); + } + + public function test_close_is_a_noop_and_keeps_content_readable(): void + { + $stream = new StringSourceStream(path('memory://close.bin'), 'kept'); + $stream->close(); + + static::assertSame('kept', $stream->content()); + } + + public function test_path_returns_the_construction_path(): void + { + static::assertSame( + 'memory://value.bin', + (new StringSourceStream(path('memory://value.bin'), 'x'))->path()->uri(), + ); + } +} diff --git a/web/landing/assets/codemirror/completions/dsl.js b/web/landing/assets/codemirror/completions/dsl.js index 3942b978c1..9f25130a46 100644 --- a/web/landing/assets/codemirror/completions/dsl.js +++ b/web/landing/assets/codemirror/completions/dsl.js @@ -1,7 +1,7 @@ /** * CodeMirror Completer for Flow PHP DSL Functions * - * Total functions: 793 + * Total functions: 798 * * This completer provides autocompletion for all Flow PHP DSL functions: * - Extractors (flow-extractors) @@ -700,7 +700,7 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `

- array_to_row(array $data, EntryFactory $entryFactory, Partitions|array $partitions = [], Schema $schema = null) : Row + array_to_row(array $data, Hydrator $hydrator = Flow\\ETL\\Row\\AdaptiveRowHydrator::..., Partitions|array $partitions = [], Schema $schema = null) : Row
@param array>|array $data
@param array|Partitions $partitions
@param null|Schema $schema @@ -708,7 +708,7 @@ const dslFunctions = [ ` return div }, - apply: snippet("\\Flow\\ETL\\DSL\\array_to_row(" + "$" + "{" + "1:data" + "}" + ", " + "$" + "{" + "2:entryFactory" + "}" + ", " + "$" + "{" + "3:partitions" + "}" + ", " + "$" + "{" + "4:schema" + "}" + ")"), + apply: snippet("\\Flow\\ETL\\DSL\\array_to_row(" + "$" + "{" + "1:data" + "}" + ", " + "$" + "{" + "2:hydrator" + "}" + ", " + "$" + "{" + "3:partitions" + "}" + ", " + "$" + "{" + "4:schema" + "}" + ")"), boost: 10 }, { label: "array_to_rows", @@ -718,7 +718,7 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- array_to_rows(array $data, EntryFactory $entryFactory, Partitions|array $partitions = [], Schema $schema = null) : Rows + array_to_rows(array $data, Hydrator $hydrator = Flow\\ETL\\Row\\AdaptiveRowHydrator::..., Partitions|array $partitions = [], Schema $schema = null) : Rows
@param array>|array $data
@param array|Partitions $partitions
@param null|Schema $schema @@ -726,7 +726,7 @@ const dslFunctions = [ ` return div }, - apply: snippet("\\Flow\\ETL\\DSL\\array_to_rows(" + "$" + "{" + "1:data" + "}" + ", " + "$" + "{" + "2:entryFactory" + "}" + ", " + "$" + "{" + "3:partitions" + "}" + ", " + "$" + "{" + "4:schema" + "}" + ")"), + apply: snippet("\\Flow\\ETL\\DSL\\array_to_rows(" + "$" + "{" + "1:data" + "}" + ", " + "$" + "{" + "2:hydrator" + "}" + ", " + "$" + "{" + "3:partitions" + "}" + ", " + "$" + "{" + "4:schema" + "}" + ")"), boost: 10 }, { label: "array_unpack", @@ -4033,12 +4033,12 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- filesystem_cache(Path|string|null $cache_dir = null, Filesystem $filesystem = Flow\\Filesystem\\Local\\NativeLocalFilesystem::..., SerializerMode $serializer_mode = null) : FilesystemCache + filesystem_cache(Path|string|null $cache_dir = null, Filesystem $filesystem = Flow\\Filesystem\\Local\\NativeLocalFilesystem::..., Serializer $serializer = Flow\\Floe\\FloeSerializer::...) : FilesystemCache
` return div }, - apply: snippet("\\Flow\\ETL\\DSL\\filesystem_cache(" + "$" + "{" + "1:cache_dir" + "}" + ", " + "$" + "{" + "2:filesystem" + "}" + ", " + "$" + "{" + "3:serializer_mode" + "}" + ")"), + apply: snippet("\\Flow\\ETL\\DSL\\filesystem_cache(" + "$" + "{" + "1:cache_dir" + "}" + ", " + "$" + "{" + "2:filesystem" + "}" + ", " + "$" + "{" + "3:serializer" + "}" + ")"), boost: 10 }, { label: "filesystem_telemetry_config", @@ -4897,7 +4897,7 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- generate_random_int(int $start = -9223372036854775808, int $end = 9223372036854775807, NativePHPRandomValueGenerator $generator = Flow\\ETL\\NativePHPRandomValueGenerator::...) : int + generate_random_int(int $start = -9223372036854775808, int $end = 9223372036854775807, RandomValueGenerator $generator = Flow\\ETL\\NativePHPRandomValueGenerator::...) : int
` return div @@ -4912,7 +4912,7 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- generate_random_string(int $length = 32, NativePHPRandomValueGenerator $generator = Flow\\ETL\\NativePHPRandomValueGenerator::...) : string + generate_random_string(int $length = 32, RandomValueGenerator $generator = Flow\\ETL\\NativePHPRandomValueGenerator::...) : string
` return div @@ -6724,7 +6724,7 @@ const dslFunctions = [ null_entry(string $name, Metadata $metadata = null) : Entry
- This functions is an alias for creating string entry from null.
The main difference between using this function an simply str_entry with second argument null
is that this function will also keep a note in the metadata that type might not be final.
For example when we need to guess column type from rows because schema was not provided,
and given column in the first row is null, it might still change once we get to the second row.
That metadata is used to determine if string_entry was created from null or not.
By design flow assumes when guessing column type that null would be a string (the most flexible type).
@return Entry + Creates an entry of the null type. Used when a column value is null and its final type is not yet known.
When guessing a schema from rows, a null column stays a NullDefinition until a later row reveals a real type,
at which point the schema merge turns it into that type made nullable.
@return Entry
` return div @@ -6757,7 +6757,7 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- null_schema(string $name, Metadata $metadata = null) : StringDefinition + null_schema(string $name, Metadata $metadata = null) : NullDefinition
` return div @@ -9065,6 +9065,24 @@ const dslFunctions = [ }, apply: snippet("\\Flow\\ETL\\DSL\\schema_from_json(" + "$" + "{" + "1:schema" + "}" + ")"), boost: 10 + }, { + label: "schema_from_json_schema", + type: "function", + detail: "flow\u002Ddsl\u002Dhelpers", + info: () => { + const div = document.createElement("div") + div.innerHTML = ` +
+ schema_from_json_schema(Path|array|string $json_schema, ClientInterface $client = null, RequestFactoryInterface $request_factory = null) : Schema +
+
+ Convert a JSON Schema (https://json-schema.org) document into a Flow Schema.
@param array|Path|string $json_schema - decoded document, raw JSON document or a path to a schema file
@param null|ClientInterface $client - PSR-18 http client, required to resolve remote http(s) references
@param null|RequestFactoryInterface $request_factory - PSR-17 request factory, required to resolve remote http(s) references +
+ ` + return div + }, + apply: snippet("\\Flow\\ETL\\Adapter\\JSON\\schema_from_json_schema(" + "$" + "{" + "1:json_schema" + "}" + ", " + "$" + "{" + "2:client" + "}" + ", " + "$" + "{" + "3:request_factory" + "}" + ")"), + boost: 10 }, { label: "schema_from_parquet", type: "function", @@ -9371,6 +9389,24 @@ const dslFunctions = [ }, apply: snippet("\\Flow\\ETL\\DSL\\schema_to_json(" + "$" + "{" + "1:schema" + "}" + ", " + "$" + "{" + "2:pretty" + "}" + ")"), boost: 10 + }, { + label: "schema_to_json_schema", + type: "function", + detail: "flow\u002Ddsl\u002Dhelpers", + info: () => { + const div = document.createElement("div") + div.innerHTML = ` +
+ schema_to_json_schema(Schema $schema) : array +
+
+ Convert a Flow Schema into a JSON Schema (https://json-schema.org, draft 2020-12) document.
@return array +
+ ` + return div + }, + apply: snippet("\\Flow\\ETL\\Adapter\\JSON\\schema_to_json_schema(" + "$" + "{" + "1:schema" + "}" + ")"), + boost: 10 }, { label: "schema_to_parquet", type: "function", @@ -9521,6 +9557,21 @@ const dslFunctions = [ }, apply: snippet("\\Flow\\PostgreSql\\DSL\\select(" + "$" + "{" + "1:expressions" + "}" + ")"), boost: 10 + }, { + label: "serialize_to_string", + type: "function", + detail: "flow\u002Ddsl\u002Dhelpers", + info: () => { + const div = document.createElement("div") + div.innerHTML = ` +
+ serialize_to_string(Serializer $serializer, Rows $rows) : string +
+ ` + return div + }, + apply: snippet("\\Flow\\Serializer\\DSL\\serialize_to_string(" + "$" + "{" + "1:serializer" + "}" + ", " + "$" + "{" + "2:rows" + "}" + ")"), + boost: 10 }, { label: "set_role", type: "function", @@ -10492,12 +10543,12 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- sum(EntryReference|string $ref) : Sum + sum(EntryReference|string $ref, ScalarFunction|bool $exact = false) : Sum
` return div }, - apply: snippet("\\Flow\\ETL\\DSL\\sum(" + "$" + "{" + "1:ref" + "}" + ")"), + apply: snippet("\\Flow\\ETL\\DSL\\sum(" + "$" + "{" + "1:ref" + "}" + ", " + "$" + "{" + "2:exact" + "}" + ")"), boost: 10 }, { label: "superglobal_carrier", @@ -10996,7 +11047,7 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- to_entry(string $name, mixed $data, EntryFactory $entryFactory) : Entry + to_entry(string $name, mixed $data, EntryFactory $entryFactory = Flow\\ETL\\Row\\EntryFactory::...) : Entry
@param array $data
@return Entry @@ -12172,7 +12223,7 @@ const dslFunctions = [ type_xml() : Type
- @return Type<\\DOMDocument> + @return Type<\\DOMDocument|XMLDocument>
` return div @@ -12190,7 +12241,7 @@ const dslFunctions = [ type_xml_element() : Type
- @return Type<\\DOMElement> + @return Type<\\DOMElement|Element>
` return div @@ -12230,6 +12281,24 @@ const dslFunctions = [ }, apply: snippet("\\Flow\\ETL\\DSL\\ulid(" + "$" + "{" + "1:value" + "}" + ")"), boost: 10 + }, { + label: "union_schema", + type: "function", + detail: "flow\u002Ddsl\u002Dschema", + info: () => { + const div = document.createElement("div") + div.innerHTML = ` +
+ union_schema(string $name, UnionType|Type $type, bool $nullable = false, Metadata $metadata = null) : UnionDefinition +
+
+ @param Type|UnionType $type +
+ ` + return div + }, + apply: snippet("\\Flow\\ETL\\DSL\\union_schema(" + "$" + "{" + "1:name" + "}" + ", " + "$" + "{" + "2:type" + "}" + ", " + "$" + "{" + "3:nullable" + "}" + ", " + "$" + "{" + "4:metadata" + "}" + ")"), + boost: 10 }, { label: "unique_constraint", type: "function", @@ -12266,6 +12335,21 @@ const dslFunctions = [ }, apply: snippet("\\Flow\\PostgreSql\\DSL\\unlisten(" + "$" + "{" + "1:channel" + "}" + ")"), boost: 10 + }, { + label: "unserialize_from_string", + type: "function", + detail: "flow\u002Ddsl\u002Dhelpers", + info: () => { + const div = document.createElement("div") + div.innerHTML = ` +
+ unserialize_from_string(Serializer $serializer, string $payload) : Rows +
+ ` + return div + }, + apply: snippet("\\Flow\\Serializer\\DSL\\unserialize_from_string(" + "$" + "{" + "1:serializer" + "}" + ", " + "$" + "{" + "2:payload" + "}" + ")"), + boost: 10 }, { label: "update", type: "function", @@ -13402,10 +13486,10 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- xml_element_entry(string $name, DOMElement|string|null $value, Metadata $metadata = null) : Entry + xml_element_entry(string $name, DOMElement|Dom\\Element|string|null $value, Metadata $metadata = null) : Entry
- @throws InvalidArgumentException
@return ($value is null ? Entry : Entry<\\DOMElement>) + @throws InvalidArgumentException
@return ($value is null ? Entry : Entry<\\DOMElement|Element>)
` return div @@ -13435,10 +13519,10 @@ const dslFunctions = [ const div = document.createElement("div") div.innerHTML = `
- xml_entry(string $name, DOMDocument|string|null $value, Metadata $metadata = null) : Entry + xml_entry(string $name, DOMDocument|Dom\\XMLDocument|string|null $value, Metadata $metadata = null) : Entry
- @throws InvalidArgumentException
@return ($value is null ? Entry : Entry<\\DOMDocument>) + @throws InvalidArgumentException
@return ($value is null ? Entry : Entry<\\DOMDocument|XMLDocument>)
` return div diff --git a/web/landing/assets/codemirror/completions/scalarfunctionchain.js b/web/landing/assets/codemirror/completions/scalarfunctionchain.js index d54ae22f60..462f28b1c5 100644 --- a/web/landing/assets/codemirror/completions/scalarfunctionchain.js +++ b/web/landing/assets/codemirror/completions/scalarfunctionchain.js @@ -1,7 +1,7 @@ /** * CodeMirror Completer for Flow PHP ScalarFunctionChain Methods * - * ScalarFunctionChain methods: 123 + * ScalarFunctionChain methods: 124 * ScalarFunctionChain-returning functions: 53 * * This completer triggers after ScalarFunctionChain-returning DSL functions @@ -537,6 +537,21 @@ const scalarFunctionChainMethods = [ }, apply: snippet("domElementAttributeValue(" + "$" + "{" + "1:attribute" + "}" + ")"), boost: 10 + }, { + label: "domElementNamespace", + type: "method", + detail: "Flow\\\\ETL\\\\Function\\\\ScalarFunctionChain", + info: () => { + const div = document.createElement("div") + div.innerHTML = ` +
+ domElementNamespace(ScalarFunction|string|null $attribute = null) : DOMElementNamespaceValue +
+ ` + return div + }, + apply: snippet("domElementNamespace(" + "$" + "{" + "1:attribute" + "}" + ")"), + boost: 10 }, { label: "domElementNextSibling", type: "method", diff --git a/web/landing/resources/dsl.json b/web/landing/resources/dsl.json index 977fc3d708..dce37049d4 100644 --- a/web/landing/resources/dsl.json +++ b/web/landing/resources/dsl.json @@ -1 +1 @@ -[{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":310,"slug":"df","name":"df","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false},{"name":"ConfigBuilder","namespace":"Flow\\ETL\\Config","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Flow","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"overwrite"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBkYXRhX2ZyYW1lKCkgOiBGbG93LgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":318,"slug":"data-frame","name":"data_frame","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false},{"name":"ConfigBuilder","namespace":"Flow\\ETL\\Config","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Flow","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"overwrite"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":324,"slug":"telemetry-options","name":"telemetry_options","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"trace_loading","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"trace_transformations","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"trace_cache","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"collect_metrics","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"filesystem","type":[{"name":"FilesystemTelemetryOptions","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TelemetryOptions","namespace":"Flow\\ETL\\Config\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":343,"slug":"from-rows","name":"from_rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"rows","type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"RowsExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"overwrite"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":350,"slug":"from-path-partitions","name":"from_path_partitions","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PathPartitionsExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"partitioning","example":"path_partitions"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":362,"slug":"from-array","name":"from_array","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"iterable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ArrayExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"array"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpdGVyYWJsZTxhcnJheTxtaXhlZD4+ICRhcnJheQogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYSAtIEBkZXByZWNhdGVkIHVzZSB3aXRoU2NoZW1hKCkgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":379,"slug":"from-cache","name":"from_cache","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"id","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"fallback_extractor","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"clear","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CacheExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBzdHJpbmcgJGlkIC0gY2FjaGUgaWQgZnJvbSB3aGljaCBkYXRhIHdpbGwgYmUgZXh0cmFjdGVkCiAqIEBwYXJhbSBudWxsfEV4dHJhY3RvciAkZmFsbGJhY2tfZXh0cmFjdG9yIC0gZXh0cmFjdG9yIHRoYXQgd2lsbCBiZSB1c2VkIHdoZW4gY2FjaGUgaXMgZW1wdHkgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aEZhbGxiYWNrRXh0cmFjdG9yKCkgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIGJvb2wgJGNsZWFyIC0gY2xlYXIgY2FjaGUgYWZ0ZXIgZXh0cmFjdGlvbiAtIEBkZXByZWNhdGVkIHVzZSB3aXRoQ2xlYXJPbkZpbmlzaCgpIG1ldGhvZCBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":395,"slug":"from-all","name":"from_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"extractors","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ChainExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":401,"slug":"from-memory","name":"from_memory","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"memory","type":[{"name":"Memory","namespace":"Flow\\ETL\\Memory","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"MemoryExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":407,"slug":"files","name":"files","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"directory","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FilesExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":416,"slug":"filesystem-cache","name":"filesystem_cache","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"cache_dir","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"filesystem","type":[{"name":"Filesystem","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Filesystem\\Local\\NativeLocalFilesystem::..."},{"name":"serializer_batch_size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"}],"return_type":[{"name":"FilesystemCache","namespace":"Flow\\ETL\\Cache\\Implementation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpbnQ8MSwgbWF4PiAkc2VyaWFsaXplcl9iYXRjaF9zaXplCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":432,"slug":"batched-by","name":"batched_by","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"extractor","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"column","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"min_size","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"BatchByExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGludDwxLCBtYXg+ICRtaW5fc2l6ZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":446,"slug":"batches","name":"batches","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"extractor","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BatchExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpbnQ8MSwgbWF4PiAkc2l6ZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":452,"slug":"from-pipeline","name":"from_pipeline","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pipeline","type":[{"name":"Pipeline","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PipelineExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":458,"slug":"from-data-frame","name":"from_data_frame","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"data_frame","type":[{"name":"DataFrame","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DataFrameExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":464,"slug":"from-sequence-date-period","name":"from_sequence_date_period","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"SequenceExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":478,"slug":"from-sequence-date-period-recurrences","name":"from_sequence_date_period_recurrences","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"recurrences","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"SequenceExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":492,"slug":"from-sequence-number","name":"from_sequence_number","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"step","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"}],"return_type":[{"name":"SequenceExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":502,"slug":"to-callable","name":"to_callable","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"callable","type":[{"name":"callable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CallbackLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":508,"slug":"to-memory","name":"to_memory","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"memory","type":[{"name":"Memory","namespace":"Flow\\ETL\\Memory","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"MemoryLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":522,"slug":"to-array","name":"to_array","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"array"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgcm93cyB0byBhbiBhcnJheSBhbmQgc3RvcmUgdGhlbSBpbiBwYXNzZWQgYXJyYXkgdmFyaWFibGUuCiAqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPiAkYXJyYXkKICoKICogQHBhcmFtLW91dCBhcnJheTxhcnJheTxtaXhlZD4+ICRhcnJheQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":530,"slug":"to-output","name":"to_output","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":540,"slug":"to-stderr","name":"to_stderr","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":550,"slug":"to-stdout","name":"to_stdout","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":560,"slug":"to-stream","name":"to_stream","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"uri","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"mode","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'w'"},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":580,"slug":"to-transformation","name":"to_transformation","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"transformer","type":[{"name":"Transformer","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false},{"name":"Transformation","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"loader","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TransformerLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":586,"slug":"to-branch","name":"to_branch","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"condition","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"loader","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BranchingLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":592,"slug":"rename-style","name":"rename_style","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"style","type":[{"name":"StringStyles","namespace":"Flow\\ETL\\String","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RenameCaseEntryStrategy","namespace":"Flow\\ETL\\Transformer\\Rename","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":602,"slug":"rename-replace","name":"rename_replace","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"search","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"replace","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RenameReplaceEntryStrategy","namespace":"Flow\\ETL\\Transformer\\Rename","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+fHN0cmluZyAkc2VhcmNoCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+fHN0cmluZyAkcmVwbGFjZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":611,"slug":"rename-map","name":"rename_map","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"renames","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RenameMapEntryStrategy","namespace":"Flow\\ETL\\Transformer\\Rename","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJHJlbmFtZXMgTWFwIG9mIG9sZF9uYW1lID0+IG5ld19uYW1lCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":620,"slug":"bool-entry","name":"bool_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxib29sPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":629,"slug":"boolean-entry","name":"boolean_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxib29sPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":640,"slug":"datetime-entry","name":"datetime_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRGF0ZVRpbWVJbnRlcmZhY2U+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":670,"slug":"time-entry","name":"time_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRGF0ZUludGVydmFsPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":709,"slug":"date-entry","name":"date_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRGF0ZVRpbWVJbnRlcmZhY2U+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":737,"slug":"int-entry","name":"int_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxpbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":746,"slug":"integer-entry","name":"integer_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxpbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":755,"slug":"enum-entry","name":"enum_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"enum","type":[{"name":"UnitEnum","namespace":"","is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCRlbnVtIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PFxVbml0RW51bT4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":764,"slug":"float-entry","name":"float_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxmbG9hdD4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":781,"slug":"json-entry","name":"json_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"data","type":[{"name":"Json","namespace":"Flow\\Types\\Value","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+fEpzb258c3RyaW5nICRkYXRhCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCRkYXRhIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PEpzb24+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":810,"slug":"json-object-entry","name":"json_object_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"data","type":[{"name":"Json","namespace":"Flow\\Types\\Value","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+fEpzb258c3RyaW5nICRkYXRhCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCRkYXRhIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PEpzb24+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":834,"slug":"str-entry","name":"str_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxzdHJpbmc+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":852,"slug":"null-entry","name":"null_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRoaXMgZnVuY3Rpb25zIGlzIGFuIGFsaWFzIGZvciBjcmVhdGluZyBzdHJpbmcgZW50cnkgZnJvbSBudWxsLgogKiBUaGUgbWFpbiBkaWZmZXJlbmNlIGJldHdlZW4gdXNpbmcgdGhpcyBmdW5jdGlvbiBhbiBzaW1wbHkgc3RyX2VudHJ5IHdpdGggc2Vjb25kIGFyZ3VtZW50IG51bGwKICogaXMgdGhhdCB0aGlzIGZ1bmN0aW9uIHdpbGwgYWxzbyBrZWVwIGEgbm90ZSBpbiB0aGUgbWV0YWRhdGEgdGhhdCB0eXBlIG1pZ2h0IG5vdCBiZSBmaW5hbC4KICogRm9yIGV4YW1wbGUgd2hlbiB3ZSBuZWVkIHRvIGd1ZXNzIGNvbHVtbiB0eXBlIGZyb20gcm93cyBiZWNhdXNlIHNjaGVtYSB3YXMgbm90IHByb3ZpZGVkLAogKiBhbmQgZ2l2ZW4gY29sdW1uIGluIHRoZSBmaXJzdCByb3cgaXMgbnVsbCwgaXQgbWlnaHQgc3RpbGwgY2hhbmdlIG9uY2Ugd2UgZ2V0IHRvIHRoZSBzZWNvbmQgcm93LgogKiBUaGF0IG1ldGFkYXRhIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHN0cmluZ19lbnRyeSB3YXMgY3JlYXRlZCBmcm9tIG51bGwgb3Igbm90LgogKgogKiBCeSBkZXNpZ24gZmxvdyBhc3N1bWVzIHdoZW4gZ3Vlc3NpbmcgY29sdW1uIHR5cGUgdGhhdCBudWxsIHdvdWxkIGJlIGEgc3RyaW5nICh0aGUgbW9zdCBmbGV4aWJsZSB0eXBlKS4KICoKICogQHJldHVybiBFbnRyeTw\/c3RyaW5nPgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":861,"slug":"string-entry","name":"string_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxzdHJpbmc+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":870,"slug":"uuid-entry","name":"uuid_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"Uuid","namespace":"Flow\\Types\\Value","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRmxvd1xUeXBlc1xWYWx1ZVxVdWlkPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":889,"slug":"xml-entry","name":"xml_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DOMDocument","namespace":"","is_nullable":false,"is_variadic":false},{"name":"Dom\\XMLDocument","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRE9NRG9jdW1lbnR8WE1MRG9jdW1lbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":914,"slug":"xml-element-entry","name":"xml_element_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DOMElement","namespace":"","is_nullable":false,"is_variadic":false},{"name":"Dom\\Element","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRE9NRWxlbWVudHxFbGVtZW50PikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":943,"slug":"html-entry","name":"html_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"Dom\\HTMLDocument","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxIVE1MRG9jdW1lbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":960,"slug":"html-element-entry","name":"html_element_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"Dom\\HTMLElement","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxIVE1MRWxlbWVudD4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":977,"slug":"entries","name":"entries","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Entries","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBFbnRyeTxtaXhlZD4gLi4uJGVudHJpZXMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":991,"slug":"struct-entry","name":"struct_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUU2hhcGUgb2YgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD4KICoKICogQHBhcmFtID9UU2hhcGUgJHZhbHVlCiAqIEBwYXJhbSBTdHJ1Y3R1cmVUeXBlPG1peGVkPnxUeXBlPFRTaGFwZT4gJHR5cGUKICoKICogQHJldHVybiAoJHZhbHVlIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PFRTaGFwZT4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1014,"slug":"structure-entry","name":"structure_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUU2hhcGUgb2YgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD4KICoKICogQHBhcmFtID9UU2hhcGUgJHZhbHVlCiAqIEBwYXJhbSBTdHJ1Y3R1cmVUeXBlPG1peGVkPnxUeXBlPFRTaGFwZT4gJHR5cGUKICoKICogQHJldHVybiAoJHZhbHVlIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PFRTaGFwZT4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1035,"slug":"list-entry","name":"list_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGxpc3Q8bWl4ZWQ+ICR2YWx1ZQogKiBAcGFyYW0gVHlwZTxtaXhlZD4gJHR5cGUKICoKICogQHJldHVybiAoJHZhbHVlIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PGxpc3Q8bWl4ZWQ+PikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1056,"slug":"map-entry","name":"map_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"mapType","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSA\/YXJyYXk8YXJyYXkta2V5LCBtaXhlZD4gJHZhbHVlCiAqIEBwYXJhbSBUeXBlPG1peGVkPiAkbWFwVHlwZQogKgogKiBAcmV0dXJuICgkdmFsdWUgaXMgbnVsbCA\/IEVudHJ5PG51bGw+IDogRW50cnk8YXJyYXk8YXJyYXkta2V5LCBtaXhlZD4+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1074,"slug":"row","name":"row","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Row","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBFbnRyeTxtaXhlZD4gLi4uJGVudHJ5CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1080,"slug":"rows","name":"rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"row","type":[{"name":"Row","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1090,"slug":"rows-partitioned","name":"rows_partitioned","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"rows","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"partitions","type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxSb3c+ICRyb3dzCiAqIEBwYXJhbSBhcnJheTxQYXJ0aXRpb258c3RyaW5nPnxQYXJ0aXRpb25zICRwYXJ0aXRpb25zCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1099,"slug":"col","name":"col","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEFuIGFsaWFzIGZvciBgcmVmYC4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1109,"slug":"entry","name":"entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"columns","option":"create"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEFuIGFsaWFzIGZvciBgcmVmYC4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1116,"slug":"ref","name":"ref","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"columns","option":"create"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1122,"slug":"structure-ref","name":"structure_ref","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"StructureFunctions","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1128,"slug":"list-ref","name":"list_ref","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ListFunctions","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1134,"slug":"refs","name":"refs","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1140,"slug":"select","name":"select","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Select","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1146,"slug":"drop","name":"drop","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Drop","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1152,"slug":"add-row-index","name":"add_row_index","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'index'"},{"name":"startFrom","type":[{"name":"StartFrom","namespace":"Flow\\ETL\\Transformation\\AddRowIndex","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformation\\AddRowIndex\\StartFrom::..."}],"return_type":[{"name":"AddRowIndex","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1161,"slug":"batch-size","name":"batch_size","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BatchSize","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpbnQ8MSwgbWF4PiAkc2l6ZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1167,"slug":"limit","name":"limit","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Limit","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1176,"slug":"mask-columns","name":"mask_columns","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"mask","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'******'"}],"return_type":[{"name":"MaskColumns","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxpbnQsIHN0cmluZz4gJGNvbHVtbnMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1182,"slug":"optional","name":"optional","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Optional","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1189,"slug":"lit","name":"lit","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Literal","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"columns","option":"create"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1195,"slug":"exists","name":"exists","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Exists","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1201,"slug":"when","name":"when","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"condition","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"then","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"else","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"When","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1207,"slug":"array-get","name":"array_get","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayGet","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1216,"slug":"array-get-collection","name":"array_get_collection","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayGetCollection","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAka2V5cwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1222,"slug":"array-get-collection-first","name":"array_get_collection_first","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ArrayGetCollection","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1231,"slug":"array-exists","name":"array_exists","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayPathExists","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkcmVmCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1241,"slug":"array-merge","name":"array_merge","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"left","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayMerge","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkbGVmdAogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58U2NhbGFyRnVuY3Rpb24gJHJpZ2h0CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1250,"slug":"array-merge-collection","name":"array_merge_collection","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayMergeCollection","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkYXJyYXkKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1256,"slug":"array-key-rename","name":"array_key_rename","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"newName","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayKeyRename","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1265,"slug":"array-keys-style-convert","name":"array_keys_style_convert","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"style","type":[{"name":"StringStyles","namespace":"Flow\\ETL\\String","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\String\\StringStyles::..."}],"return_type":[{"name":"ArrayKeysStyleConvert","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1273,"slug":"array-sort","name":"array_sort","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sort_function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"Sort","namespace":"Flow\\ETL\\Function\\ArraySort","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"recursive","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"ArraySort","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1290,"slug":"array-reverse","name":"array_reverse","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"preserveKeys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"ArrayReverse","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkZnVuY3Rpb24KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1296,"slug":"now","name":"now","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"time_zone","type":[{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false},{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"DateTimeZone::..."}],"return_type":[{"name":"Now","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1302,"slug":"between","name":"between","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"lower_bound","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"upper_bound","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"boundary","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"Boundary","namespace":"Flow\\ETL\\Function\\Between","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Function\\Between\\Boundary::..."}],"return_type":[{"name":"Between","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1312,"slug":"to-date-time","name":"to_date_time","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"format","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d H:i:s'"},{"name":"timeZone","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"DateTimeZone::..."}],"return_type":[{"name":"ToDateTime","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1321,"slug":"to-date","name":"to_date","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"format","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d'"},{"name":"timeZone","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"DateTimeZone::..."}],"return_type":[{"name":"ToDate","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1330,"slug":"date-time-format","name":"date_time_format","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DateTimeFormat","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1336,"slug":"split","name":"split","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"9223372036854775807"}],"return_type":[{"name":"Split","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1349,"slug":"combine","name":"combine","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"keys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"values","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Combine","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAka2V5cwogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58U2NhbGFyRnVuY3Rpb24gJHZhbHVlcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1358,"slug":"concat","name":"concat","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"functions","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Concat","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIENvbmNhdCBhbGwgdmFsdWVzLiBJZiB5b3Ugd2FudCB0byBjb25jYXRlbmF0ZSB2YWx1ZXMgd2l0aCBzZXBhcmF0b3IgdXNlIGNvbmNhdF93cyBmdW5jdGlvbi4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1367,"slug":"concat-ws","name":"concat_ws","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"functions","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ConcatWithSeparator","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIENvbmNhdCBhbGwgdmFsdWVzIHdpdGggc2VwYXJhdG9yLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1373,"slug":"hash","name":"hash","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"algorithm","type":[{"name":"Algorithm","namespace":"Flow\\ETL\\Hash","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Hash\\NativePHPHash::..."}],"return_type":[{"name":"Hash","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1382,"slug":"cast","name":"cast","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Cast","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBcRmxvd1xUeXBlc1xUeXBlPG1peGVkPnxzdHJpbmcgJHR5cGUKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1388,"slug":"coalesce","name":"coalesce","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Coalesce","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1394,"slug":"count","name":"count","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Count","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1407,"slug":"call","name":"call","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"callable","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"callable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"return_type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CallUserFunc","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIENhbGxzIGEgdXNlci1kZWZpbmVkIGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIHBhcmFtZXRlcnMuCiAqCiAqIEBwYXJhbSBjYWxsYWJsZXxTY2FsYXJGdW5jdGlvbiAkY2FsbGFibGUKICogQHBhcmFtIGFycmF5PG1peGVkPiAkcGFyYW1ldGVycwogKiBAcGFyYW0gbnVsbHxUeXBlPG1peGVkPiAkcmV0dXJuX3R5cGUKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1436,"slug":"array-unpack","name":"array_unpack","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"skip_keys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"entry_prefix","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ArrayUnpack","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkYXJyYXkKICogQHBhcmFtIGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+fFNjYWxhckZ1bmN0aW9uICRza2lwX2tleXMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1465,"slug":"array-expand","name":"array_expand","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"expand","type":[{"name":"ArrayExpand","namespace":"Flow\\ETL\\Function\\ArrayExpand","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Function\\ArrayExpand\\ArrayExpand::..."}],"return_type":[{"name":"ArrayExpand","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEV4cGFuZHMgZWFjaCB2YWx1ZSBpbnRvIGVudHJ5LCBpZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZSB2YWx1ZSwgbXVsdGlwbGUgcm93cyB3aWxsIGJlIGNyZWF0ZWQuCiAqIEFycmF5IGtleXMgYXJlIGlnbm9yZWQsIG9ubHkgdmFsdWVzIGFyZSB1c2VkIHRvIGNyZWF0ZSBuZXcgcm93cy4KICoKICogQmVmb3JlOgogKiAgICstLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgIHxpZHwgICAgICAgICAgICAgIGFycmF5fAogKiAgICstLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgIHwgMXx7ImEiOjEsImIiOjIsImMiOjN9fAogKiAgICstLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKgogKiBBZnRlcjoKICogICArLS0rLS0tLS0tLS0rCiAqICAgfGlkfGV4cGFuZGVkfAogKiAgICstLSstLS0tLS0tLSsKICogICB8IDF8ICAgICAgIDF8CiAqICAgfCAxfCAgICAgICAyfAogKiAgIHwgMXwgICAgICAgM3wKICogICArLS0rLS0tLS0tLS0rCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1471,"slug":"size","name":"size","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Size","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1477,"slug":"uuid-v4","name":"uuid_v4","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Uuid","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1483,"slug":"uuid-v7","name":"uuid_v7","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Uuid","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1489,"slug":"ulid","name":"ulid","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Ulid","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1495,"slug":"lower","name":"lower","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ToLower","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1501,"slug":"capitalize","name":"capitalize","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Capitalize","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1507,"slug":"upper","name":"upper","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ToUpper","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1513,"slug":"all","name":"all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"functions","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1519,"slug":"any","name":"any","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1525,"slug":"not","name":"not","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Not","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1531,"slug":"to-timezone","name":"to_timezone","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"timeZone","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ToTimeZone","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1537,"slug":"ignore-error-handler","name":"ignore_error_handler","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"IgnoreError","namespace":"Flow\\ETL\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1543,"slug":"skip-rows-handler","name":"skip_rows_handler","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SkipRows","namespace":"Flow\\ETL\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1549,"slug":"throw-error-handler","name":"throw_error_handler","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ThrowError","namespace":"Flow\\ETL\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1555,"slug":"regex-replace","name":"regex_replace","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"replacement","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"RegexReplace","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1565,"slug":"regex-match-all","name":"regex_match_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"RegexMatchAll","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1575,"slug":"regex-match","name":"regex_match","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"RegexMatch","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1585,"slug":"regex","name":"regex","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"Regex","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1595,"slug":"regex-all","name":"regex_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"RegexAll","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1605,"slug":"sprintf","name":"sprintf","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"format","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Sprintf","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1611,"slug":"sanitize","name":"sanitize","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"placeholder","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'*'"},{"name":"skipCharacters","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Sanitize","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1620,"slug":"round","name":"round","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"mode","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"}],"return_type":[{"name":"Round","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1629,"slug":"number-format","name":"number_format","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"decimals","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"decimal_separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'.'"},{"name":"thousands_separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"','"}],"return_type":[{"name":"NumberFormat","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1644,"slug":"to-entry","name":"to_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"data","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"entryFactory","type":[{"name":"EntryFactory","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxtaXhlZD4gJGRhdGEKICoKICogQHJldHVybiBFbnRyeTxtaXhlZD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1655,"slug":"array-to-row","name":"array_to_row","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"entryFactory","type":[{"name":"EntryFactory","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"partitions","type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Row","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheTxtaXhlZD4+fGFycmF5PG1peGVkfHN0cmluZz4gJGRhdGEKICogQHBhcmFtIGFycmF5PFBhcnRpdGlvbj58UGFydGl0aW9ucyAkcGFydGl0aW9ucwogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1705,"slug":"array-to-rows","name":"array_to_rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"entryFactory","type":[{"name":"EntryFactory","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"partitions","type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheTxtaXhlZD4+fGFycmF5PG1peGVkfHN0cmluZz4gJGRhdGEKICogQHBhcmFtIGFycmF5PFBhcnRpdGlvbj58UGFydGl0aW9ucyAkcGFydGl0aW9ucwogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1740,"slug":"rank","name":"rank","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Rank","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"WINDOW_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1746,"slug":"dens-rank","name":"dens_rank","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"DenseRank","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"WINDOW_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1752,"slug":"dense-rank","name":"dense_rank","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"DenseRank","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"WINDOW_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1758,"slug":"average","name":"average","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"rounding","type":[{"name":"Rounding","namespace":"Flow\\Calculator","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Calculator\\Rounding::..."}],"return_type":[{"name":"Average","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1764,"slug":"greatest","name":"greatest","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Greatest","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1770,"slug":"least","name":"least","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Least","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1776,"slug":"collect","name":"collect","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Collect","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1782,"slug":"string-agg","name":"string_agg","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"', '"},{"name":"sort","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StringAggregate","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1788,"slug":"collect-unique","name":"collect_unique","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CollectUnique","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1794,"slug":"window","name":"window","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Window","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1800,"slug":"sum","name":"sum","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"exact","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Sum","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1806,"slug":"first","name":"first","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"First","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1812,"slug":"last","name":"last","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Last","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1818,"slug":"max","name":"max","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Max","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1824,"slug":"min","name":"min","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Min","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1830,"slug":"row-number","name":"row_number","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"RowNumber","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1841,"slug":"schema","name":"schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"definitions","type":[{"name":"Definition","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBEZWZpbml0aW9uPG1peGVkPiAuLi4kZGVmaW5pdGlvbnMKICoKICogQHJldHVybiBTY2hlbWEKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1850,"slug":"schema-to-json","name":"schema_to_json","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pretty","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1859,"slug":"schema-to-php","name":"schema_to_php","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"valueFormatter","type":[{"name":"ValueFormatter","namespace":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter\\ValueFormatter::..."},{"name":"typeFormatter","type":[{"name":"TypeFormatter","namespace":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter\\TypeFormatter::..."}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1871,"slug":"schema-to-ascii","name":"schema_to_ascii","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"formatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1881,"slug":"schema-validate","name":"schema_validate","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"expected","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"given","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"validator","type":[{"name":"SchemaValidator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Schema\\Validator\\StrictValidator::..."}],"return_type":[{"name":"ValidationContext","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJGV4cGVjdGVkCiAqIEBwYXJhbSBTY2hlbWEgJGdpdmVuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1890,"slug":"schema-evolving-validator","name":"schema_evolving_validator","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"EvolvingValidator","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1896,"slug":"schema-strict-validator","name":"schema_strict_validator","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"StrictValidator","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1902,"slug":"schema-selective-validator","name":"schema_selective_validator","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SelectiveValidator","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1911,"slug":"schema-from-json","name":"schema_from_json","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gU2NoZW1hCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1924,"slug":"schema-metadata","name":"schema_metadata","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"metadata","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGFycmF5PGJvb2x8ZmxvYXR8aW50fHN0cmluZz58Ym9vbHxmbG9hdHxpbnR8c3RyaW5nPiAkbWV0YWRhdGEKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1933,"slug":"int-schema","name":"int_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"IntegerDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBgaW50ZWdlcl9zY2hlbWFgLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1939,"slug":"integer-schema","name":"integer_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"IntegerDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1948,"slug":"str-schema","name":"str_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StringDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBgc3RyaW5nX3NjaGVtYWAuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1954,"slug":"string-schema","name":"string_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StringDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1960,"slug":"bool-schema","name":"bool_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"BooleanDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1966,"slug":"float-schema","name":"float_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FloatDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1980,"slug":"map-schema","name":"map_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"MapType","namespace":"Flow\\Types\\Type\\Logical","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MapDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUS2V5IG9mIGFycmF5LWtleQogKiBAdGVtcGxhdGUgVFZhbHVlCiAqCiAqIEBwYXJhbSBNYXBUeXBlPFRLZXksIFRWYWx1ZT58VHlwZTxhcnJheTxUS2V5LCBUVmFsdWU+PiAkdHlwZQogKgogKiBAcmV0dXJuIE1hcERlZmluaXRpb248VEtleSwgVFZhbHVlPgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1994,"slug":"list-schema","name":"list_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ListType","namespace":"Flow\\Types\\Type\\Logical","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ListDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBMaXN0VHlwZTxUPnxUeXBlPGxpc3Q8VD4+ICR0eXBlCiAqCiAqIEByZXR1cm4gTGlzdERlZmluaXRpb248VD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2012,"slug":"enum-schema","name":"enum_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"EnumDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIFxVbml0RW51bQogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICR0eXBlCiAqCiAqIEByZXR1cm4gRW51bURlZmluaXRpb248VD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2018,"slug":"null-schema","name":"null_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StringDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2028,"slug":"datetime-schema","name":"datetime_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DateTimeDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2034,"slug":"time-schema","name":"time_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TimeDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2040,"slug":"date-schema","name":"date_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DateDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2046,"slug":"json-schema","name":"json_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"JsonDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2052,"slug":"html-schema","name":"html_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"HTMLDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2058,"slug":"html-element-schema","name":"html_element_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"HTMLElementDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2064,"slug":"xml-schema","name":"xml_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"XMLDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2070,"slug":"xml-element-schema","name":"xml_element_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"XMLElementDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2083,"slug":"structure-schema","name":"structure_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"StructureType","namespace":"Flow\\Types\\Type\\Logical","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StructureDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBTdHJ1Y3R1cmVUeXBlPFQ+fFR5cGU8YXJyYXk8c3RyaW5nLCBUPj4gJHR5cGUKICoKICogQHJldHVybiBTdHJ1Y3R1cmVEZWZpbml0aW9uPFQ+CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2097,"slug":"union-schema","name":"union_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"UnionType","namespace":"Flow\\Types\\Type\\Native","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"UnionDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBUeXBlPG1peGVkPnxVbmlvblR5cGU8bWl4ZWQsIG1peGVkPiAkdHlwZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2108,"slug":"uuid-schema","name":"uuid_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"UuidDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2121,"slug":"definition-from-array","name":"definition_from_array","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"definition","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Definition","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERlZmluaXRpb24gZnJvbSBhbiBhcnJheSByZXByZXNlbnRhdGlvbi4KICoKICogQHBhcmFtIGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+ICRkZWZpbml0aW9uCiAqCiAqIEByZXR1cm4gRGVmaW5pdGlvbjxtaXhlZD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2154,"slug":"definition-from-type","name":"definition_from_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Definition","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERlZmluaXRpb24gZnJvbSBhIFR5cGUuCiAqCiAqIEBwYXJhbSBUeXBlPG1peGVkPiAkdHlwZQogKgogKiBAcmV0dXJuIERlZmluaXRpb248bWl4ZWQ+CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2186,"slug":"execution-context","name":"execution_context","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FlowContext","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2192,"slug":"flow-context","name":"flow_context","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FlowContext","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2198,"slug":"config","name":"config","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2204,"slug":"config-builder","name":"config_builder","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ConfigBuilder","namespace":"Flow\\ETL\\Config","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2213,"slug":"overwrite","name":"overwrite","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfb3ZlcndyaXRlKCkuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2219,"slug":"save-mode-overwrite","name":"save_mode_overwrite","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2228,"slug":"ignore","name":"ignore","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfaWdub3JlKCkuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2234,"slug":"save-mode-ignore","name":"save_mode_ignore","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2243,"slug":"exception-if-exists","name":"exception_if_exists","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfZXhjZXB0aW9uX2lmX2V4aXN0cygpLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2249,"slug":"save-mode-exception-if-exists","name":"save_mode_exception_if_exists","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2258,"slug":"append","name":"append","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfYXBwZW5kKCkuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2264,"slug":"save-mode-append","name":"save_mode_append","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2274,"slug":"execution-strict","name":"execution_strict","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ExecutionMode","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEluIHRoaXMgbW9kZSwgZnVuY3Rpb25zIHRocm93cyBleGNlcHRpb25zIGlmIHRoZSBnaXZlbiBlbnRyeSBpcyBub3QgZm91bmQKICogb3IgcGFzc2VkIHBhcmFtZXRlcnMgYXJlIGludmFsaWQuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2283,"slug":"execution-lenient","name":"execution_lenient","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ExecutionMode","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEluIHRoaXMgbW9kZSwgZnVuY3Rpb25zIHJldHVybnMgbnVsbHMgaW5zdGVhZCBvZiB0aHJvd2luZyBleGNlcHRpb25zLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2289,"slug":"print-rows","name":"print_rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"rows","type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2295,"slug":"identical","name":"identical","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"left","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Identical","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2301,"slug":"equal","name":"equal","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"left","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Equal","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2307,"slug":"compare-all","name":"compare_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"comparison","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"comparisons","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2313,"slug":"compare-any","name":"compare_any","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"comparison","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"comparisons","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2324,"slug":"join-on","name":"join_on","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"comparisons","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"join_prefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"''"}],"return_type":[{"name":"Expression","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"join","example":"join"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"join","example":"join_each"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxDb21wYXJpc29ufHN0cmluZz58Q29tcGFyaXNvbiAkY29tcGFyaXNvbnMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2330,"slug":"compare-entries-by-name","name":"compare_entries_by_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"order","type":[{"name":"Order","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformer\\OrderEntries\\Order::..."}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2336,"slug":"compare-entries-by-name-desc","name":"compare_entries_by_name_desc","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2345,"slug":"compare-entries-by-type","name":"compare_entries_by_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"Order","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformer\\OrderEntries\\Order::..."}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8RW50cnk8bWl4ZWQ+PiwgaW50PiAkcHJpb3JpdGllcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2354,"slug":"compare-entries-by-type-desc","name":"compare_entries_by_type_desc","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8RW50cnk8bWl4ZWQ+PiwgaW50PiAkcHJpb3JpdGllcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2363,"slug":"compare-entries-by-type-and-name","name":"compare_entries_by_type_and_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"Order","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformer\\OrderEntries\\Order::..."}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8RW50cnk8bWl4ZWQ+PiwgaW50PiAkcHJpb3JpdGllcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2374,"slug":"schema-sort-by-name","name":"schema_sort_by_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2383,"slug":"schema-sort-by-type","name":"schema_sort_by_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+LCBpbnQ+ICRwcmlvcml0aWVzCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2394,"slug":"schema-sort-by-type-and-name","name":"schema_sort_by_type_and_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+LCBpbnQ+ICRwcmlvcml0aWVzCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2405,"slug":"schema-sort-by-metadata","name":"schema_sort_by_metadata","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"key","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2415,"slug":"is-type","name":"is_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmd8VHlwZTxtaXhlZD4+fFR5cGU8bWl4ZWQ+ICR0eXBlCiAqIEBwYXJhbSBtaXhlZCAkdmFsdWUKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2449,"slug":"generate-random-string","name":"generate_random_string","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"32"},{"name":"generator","type":[{"name":"RandomValueGenerator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\NativePHPRandomValueGenerator::..."}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2457,"slug":"generate-random-int","name":"generate_random_int","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"start","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"-9223372036854775808"},{"name":"end","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"9223372036854775807"},{"name":"generator","type":[{"name":"RandomValueGenerator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\NativePHPRandomValueGenerator::..."}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2466,"slug":"random-string","name":"random_string","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"length","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"generator","type":[{"name":"RandomValueGenerator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\NativePHPRandomValueGenerator::..."}],"return_type":[{"name":"RandomString","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2474,"slug":"date-interval-to-milliseconds","name":"date_interval_to_milliseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2491,"slug":"date-interval-to-seconds","name":"date_interval_to_seconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2508,"slug":"date-interval-to-microseconds","name":"date_interval_to_microseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2525,"slug":"with-entry","name":"with_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"WithEntry","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2531,"slug":"constraint-unique","name":"constraint_unique","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"reference","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"references","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"UniqueConstraint","namespace":"Flow\\ETL\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2537,"slug":"constraint-sorted-by","name":"constraint_sorted_by","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"column","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"SortedByConstraint","namespace":"Flow\\ETL\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2545,"slug":"analyze","name":"analyze","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Analyze","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2554,"slug":"match-cases","name":"match_cases","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"cases","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"default","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MatchCases","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxNYXRjaENvbmRpdGlvbj4gJGNhc2VzCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2560,"slug":"match-condition","name":"match_condition","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"condition","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"then","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"MatchCondition","namespace":"Flow\\ETL\\Function\\MatchCases","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2566,"slug":"retry-any-throwable","name":"retry_any_throwable","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AnyThrowable","namespace":"Flow\\ETL\\Retry\\RetryStrategy","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2575,"slug":"retry-on-exception-types","name":"retry_on_exception_types","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"exception_types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OnExceptionTypes","namespace":"Flow\\ETL\\Retry\\RetryStrategy","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8XFRocm93YWJsZT4+ICRleGNlcHRpb25fdHlwZXMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2581,"slug":"delay-linear","name":"delay_linear","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"delay","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"increment","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Linear","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2587,"slug":"delay-exponential","name":"delay_exponential","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"base","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"multiplier","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"max_delay","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Exponential","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2596,"slug":"delay-jitter","name":"delay_jitter","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"delay","type":[{"name":"DelayFactory","namespace":"Flow\\ETL\\Retry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"jitter_factor","type":[{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Jitter","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBmbG9hdCAkaml0dGVyX2ZhY3RvciBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMSByZXByZXNlbnRpbmcgdGhlIG1heGltdW0gcGVyY2VudGFnZSBvZiBqaXR0ZXIgdG8gYXBwbHkKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2602,"slug":"delay-fixed","name":"delay_fixed","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"delay","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Fixed","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2608,"slug":"duration-seconds","name":"duration_seconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"seconds","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2614,"slug":"duration-milliseconds","name":"duration_milliseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"milliseconds","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2620,"slug":"duration-microseconds","name":"duration_microseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"microseconds","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2626,"slug":"duration-minutes","name":"duration_minutes","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"minutes","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2632,"slug":"write-with-retries","name":"write_with_retries","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"loader","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"retry_strategy","type":[{"name":"RetryStrategy","namespace":"Flow\\ETL\\Retry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Retry\\RetryStrategy\\AnyThrowable::..."},{"name":"delay_factory","type":[{"name":"DelayFactory","namespace":"Flow\\ETL\\Retry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Retry\\DelayFactory\\Fixed\\FixedMilliseconds::..."},{"name":"sleep","type":[{"name":"Sleep","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Time\\SystemSleep::..."}],"return_type":[{"name":"RetryLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2642,"slug":"clock","name":"clock","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"time_zone","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'UTC'"}],"return_type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/Floe\/DSL\/functions.php","start_line_in_file":28,"slug":"from-floe","name":"from_floe","namespace":"Flow\\Floe\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"codec","type":[{"name":"Codec","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Floe\\Codec\\NoopCodec::..."},{"name":"chunk_size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"65536"}],"return_type":[{"name":"FloeExtractor","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FLOE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/Floe\/DSL\/functions.php","start_line_in_file":37,"slug":"to-floe","name":"to_floe","namespace":"Flow\\Floe\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"codec","type":[{"name":"Codec","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Floe\\Codec\\NoopCodec::..."}],"return_type":[{"name":"FloeLoader","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FLOE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/Floe\/DSL\/functions.php","start_line_in_file":50,"slug":"merge-floe","name":"merge_floe","namespace":"Flow\\Floe\\DSL","parameters":[{"name":"sources","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"dest","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"compact","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"void","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FLOE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE1lcmdlcyBzZXZlcmFsIEZsb2UgZmlsZXMgKHNhbWUgb3IgYXBwZW5kLWNvbXBhdGlibGUgZXZvbHZpbmcgc2NoZW1hKSBpbnRvIG9uZSwgb24gdGhlIGxvY2FsCiAqIGZpbGVzeXN0ZW0uIEJ5dGUtc3BsaWNlcyBmcmFtZSByZWdpb25zIGJ5IGRlZmF1bHQgKE8oYnl0ZXMpLCBubyByZS1lbmNvZGUpOyBjb21wYWN0IHJlLWVuY29kZXMKICogYWxsIHJvd3MgaW50byBmZXdlciBzZWN0aW9ucy4gRm9yIG5vbi1sb2NhbCBmaWxlc3lzdGVtcyB1c2UgRmxvZU1lcmdlciBkaXJlY3RseS4KICoKICogQHBhcmFtIGFycmF5PGludCwgUGF0aHxzdHJpbmc+ICRzb3VyY2VzCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-avro\/src\/Flow\/ETL\/Adapter\/Avro\/functions.php","start_line_in_file":19,"slug":"from-avro","name":"from_avro","namespace":"Flow\\ETL\\DSL\\Adapter\\Avro","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AvroExtractor","namespace":"Flow\\ETL\\Adapter\\Avro\\FlixTech","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AVRO","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-avro\/src\/Flow\/ETL\/Adapter\/Avro\/functions.php","start_line_in_file":25,"slug":"to-avro","name":"to_avro","namespace":"Flow\\ETL\\DSL\\Adapter\\Avro","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"AvroLoader","namespace":"Flow\\ETL\\Adapter\\Avro\\FlixTech","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AVRO","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":21,"slug":"bar-chart","name":"bar_chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"label","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"datasets","type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BarChart","namespace":"Flow\\ETL\\Adapter\\ChartJS\\Chart","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":27,"slug":"line-chart","name":"line_chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"label","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"datasets","type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"LineChart","namespace":"Flow\\ETL\\Adapter\\ChartJS\\Chart","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":33,"slug":"pie-chart","name":"pie_chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"label","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"datasets","type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PieChart","namespace":"Flow\\ETL\\Adapter\\ChartJS\\Chart","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":39,"slug":"to-chartjs","name":"to_chartjs","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"type","type":[{"name":"Chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ChartJSLoader","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":50,"slug":"to-chartjs-file","name":"to_chartjs_file","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"type","type":[{"name":"Chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"output","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"template","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ChartJSLoader","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDaGFydCAkdHlwZQogKiBAcGFyYW0gbnVsbHxQYXRofHN0cmluZyAkb3V0cHV0IC0gQGRlcHJlY2F0ZWQgdXNlICRsb2FkZXItPndpdGhPdXRwdXRQYXRoKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxQYXRofHN0cmluZyAkdGVtcGxhdGUgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aFRlbXBsYXRlKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":78,"slug":"to-chartjs-var","name":"to_chartjs_var","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"type","type":[{"name":"Chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"output","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ChartJSLoader","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDaGFydCAkdHlwZQogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBtaXhlZD4gJG91dHB1dCAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoT3V0cHV0VmFyKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-csv\/src\/Flow\/ETL\/Adapter\/CSV\/functions.php","start_line_in_file":33,"slug":"from-csv","name":"from_csv","namespace":"Flow\\ETL\\Adapter\\CSV","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"empty_to_null","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"separator","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"enclosure","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"escape","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"characters_read_in_line","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"10485760"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CSVExtractor","namespace":"Flow\\ETL\\Adapter\\CSV","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CSV","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"csv"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gYm9vbCAkZW1wdHlfdG9fbnVsbCAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRW1wdHlUb051bGwoKSBpbnN0ZWFkCiAqIEBwYXJhbSBib29sICR3aXRoX2hlYWRlciAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoSGVhZGVyKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNlcGFyYXRvciAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoU2VwYXJhdG9yKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGVuY2xvc3VyZSAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRW5jbG9zdXJlKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGVzY2FwZSAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRXNjYXBlKCkgaW5zdGVhZAogKiBAcGFyYW0gaW50PDEsIG1heD4gJGNoYXJhY3RlcnNfcmVhZF9pbl9saW5lIC0gQGRlcHJlY2F0ZWQgdXNlICRsb2FkZXItPndpdGhDaGFyYWN0ZXJzUmVhZEluTGluZSgpIGluc3RlYWQKICogQHBhcmFtIG51bGx8U2NoZW1hICRzY2hlbWEgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aFNjaGVtYSgpIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-csv\/src\/Flow\/ETL\/Adapter\/CSV\/functions.php","start_line_in_file":77,"slug":"to-csv","name":"to_csv","namespace":"Flow\\ETL\\Adapter\\CSV","parameters":[{"name":"uri","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"','"},{"name":"enclosure","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\\"'"},{"name":"escape","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\\\'"},{"name":"new_line_separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\n'"},{"name":"datetime_format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d\\\\TH:i:sP'"}],"return_type":[{"name":"CSVLoader","namespace":"Flow\\ETL\\Adapter\\CSV","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CSV","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkdXJpCiAqIEBwYXJhbSBib29sICR3aXRoX2hlYWRlciAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoSGVhZGVyKCkgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRzZXBhcmF0b3IgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aFNlcGFyYXRvcigpIGluc3RlYWQKICogQHBhcmFtIHN0cmluZyAkZW5jbG9zdXJlIC0gQGRlcHJlY2F0ZWQgdXNlICRsb2FkZXItPndpdGhFbmNsb3N1cmUoKSBpbnN0ZWFkCiAqIEBwYXJhbSBzdHJpbmcgJGVzY2FwZSAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRXNjYXBlKCkgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRuZXdfbGluZV9zZXBhcmF0b3IgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aE5ld0xpbmVTZXBhcmF0b3IoKSBpbnN0ZWFkCiAqIEBwYXJhbSBzdHJpbmcgJGRhdGV0aW1lX2Zvcm1hdCAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRGF0ZVRpbWVGb3JtYXQoKSBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-csv\/src\/Flow\/ETL\/Adapter\/CSV\/functions.php","start_line_in_file":102,"slug":"csv-detect-separator","name":"csv_detect_separator","namespace":"Flow\\ETL\\Adapter\\CSV","parameters":[{"name":"stream","type":[{"name":"SourceStream","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"lines","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"5"},{"name":"fallback","type":[{"name":"Option","namespace":"Flow\\ETL\\Adapter\\CSV\\Detector","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"Flow\\ETL\\Adapter\\CSV\\Detector\\Option::..."},{"name":"options","type":[{"name":"Options","namespace":"Flow\\ETL\\Adapter\\CSV\\Detector","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Option","namespace":"Flow\\ETL\\Adapter\\CSV\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CSV","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTb3VyY2VTdHJlYW0gJHN0cmVhbSAtIHZhbGlkIHJlc291cmNlIHRvIENTViBmaWxlCiAqIEBwYXJhbSBpbnQ8MSwgbWF4PiAkbGluZXMgLSBudW1iZXIgb2YgbGluZXMgdG8gcmVhZCBmcm9tIENTViBmaWxlLCBkZWZhdWx0IDUsIG1vcmUgbGluZXMgbWVhbnMgbW9yZSBhY2N1cmF0ZSBkZXRlY3Rpb24gYnV0IHNsb3dlciBkZXRlY3Rpb24KICogQHBhcmFtIG51bGx8T3B0aW9uICRmYWxsYmFjayAtIGZhbGxiYWNrIG9wdGlvbiB0byB1c2Ugd2hlbiBubyBiZXN0IG9wdGlvbiBjYW4gYmUgZGV0ZWN0ZWQsIGRlZmF1bHQgaXMgT3B0aW9uKCcsJywgJyInLCAnXFwnKQogKiBAcGFyYW0gbnVsbHxPcHRpb25zICRvcHRpb25zIC0gb3B0aW9ucyB0byB1c2UgZm9yIGRldGVjdGlvbiwgZGVmYXVsdCBpcyBPcHRpb25zOjphbGwoKQogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":39,"slug":"dbal-dataframe-factory","name":"dbal_dataframe_factory","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"QueryParameter","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"DbalDataFrameFactory","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPnxDb25uZWN0aW9uICRjb25uZWN0aW9uCiAqIEBwYXJhbSBzdHJpbmcgJHF1ZXJ5CiAqIEBwYXJhbSBRdWVyeVBhcmFtZXRlciAuLi4kcGFyYW1ldGVycwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":59,"slug":"from-dbal-limit-offset","name":"from_dbal_limit_offset","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"Table","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"order_by","type":[{"name":"OrderBy","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"page_size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"maximum","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DbalLimitOffsetExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDb25uZWN0aW9uICRjb25uZWN0aW9uCiAqIEBwYXJhbSBzdHJpbmd8VGFibGUgJHRhYmxlCiAqIEBwYXJhbSBhcnJheTxPcmRlckJ5PnxPcmRlckJ5ICRvcmRlcl9ieQogKiBAcGFyYW0gaW50ICRwYWdlX3NpemUKICogQHBhcmFtIG51bGx8aW50ICRtYXhpbXVtCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":86,"slug":"from-dbal-limit-offset-qb","name":"from_dbal_limit_offset_qb","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"queryBuilder","type":[{"name":"QueryBuilder","namespace":"Doctrine\\DBAL\\Query","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"page_size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"maximum","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"offset","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"DbalLimitOffsetExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDb25uZWN0aW9uICRjb25uZWN0aW9uCiAqIEBwYXJhbSBpbnQgJHBhZ2Vfc2l6ZQogKiBAcGFyYW0gbnVsbHxpbnQgJG1heGltdW0gLSBtYXhpbXVtIGNhbiBhbHNvIGJlIHRha2VuIGZyb20gYSBxdWVyeSBidWlsZGVyLCAkbWF4aW11bSBob3dldmVyIGlzIHVzZWQgcmVnYXJkbGVzcyBvZiB0aGUgcXVlcnkgYnVpbGRlciBpZiBpdCdzIHNldAogKiBAcGFyYW0gaW50ICRvZmZzZXQgLSBvZmZzZXQgY2FuIGFsc28gYmUgdGFrZW4gZnJvbSBhIHF1ZXJ5IGJ1aWxkZXIsICRvZmZzZXQgaG93ZXZlciBpcyB1c2VkIHJlZ2FyZGxlc3Mgb2YgdGhlIHF1ZXJ5IGJ1aWxkZXIgaWYgaXQncyBzZXQgdG8gbm9uIDAgdmFsdWUKICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":105,"slug":"from-dbal-key-set-qb","name":"from_dbal_key_set_qb","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"queryBuilder","type":[{"name":"QueryBuilder","namespace":"Doctrine\\DBAL\\Query","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key_set","type":[{"name":"KeySet","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DbalKeySetExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":115,"slug":"from-dbal-queries","name":"from_dbal_queries","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters_set","type":[{"name":"ParametersSet","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfFBhcmFtZXRlcnNTZXQgJHBhcmFtZXRlcnNfc2V0IC0gZWFjaCBvbmUgcGFyYW1ldGVycyBhcnJheSB3aWxsIGJlIGV2YWx1YXRlZCBhcyBuZXcgcXVlcnkKICogQHBhcmFtIGFycmF5PGludDwwLCBtYXg+fHN0cmluZywgRGJhbEFycmF5VHlwZXxEYmFsUGFyYW1ldGVyVHlwZXxEYmFsVHlwZXxzdHJpbmc+ICR0eXBlcwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":141,"slug":"dbal-from-queries","name":"dbal_from_queries","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters_set","type":[{"name":"ParametersSet","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBkZXByZWNhdGVkIHVzZSBmcm9tX2RiYWxfcXVlcmllcygpIGluc3RlYWQKICoKICogQHBhcmFtIG51bGx8UGFyYW1ldGVyc1NldCAkcGFyYW1ldGVyc19zZXQgLSBlYWNoIG9uZSBwYXJhbWV0ZXJzIGFycmF5IHdpbGwgYmUgZXZhbHVhdGVkIGFzIG5ldyBxdWVyeQogKiBAcGFyYW0gYXJyYXk8aW50PDAsIG1heD58c3RyaW5nLCBEYmFsQXJyYXlUeXBlfERiYWxQYXJhbWV0ZXJUeXBlfERiYWxUeXBlfHN0cmluZz4gJHR5cGVzCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":155,"slug":"from-dbal-query","name":"from_dbal_query","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPnxsaXN0PG1peGVkPiAkcGFyYW1ldGVycyAtIEBkZXByZWNhdGVkIHVzZSBEYmFsUXVlcnlFeHRyYWN0b3I6OndpdGhQYXJhbWV0ZXJzKCkgaW5zdGVhZAogKiBAcGFyYW0gYXJyYXk8aW50PDAsIG1heD58c3RyaW5nLCBEYmFsQXJyYXlUeXBlfERiYWxQYXJhbWV0ZXJUeXBlfERiYWxUeXBlfHN0cmluZz4gJHR5cGVzIC0gQGRlcHJlY2F0ZWQgdXNlIERiYWxRdWVyeUV4dHJhY3Rvcjo6d2l0aFR5cGVzKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":171,"slug":"dbal-from-query","name":"dbal_from_query","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBkZXByZWNhdGVkIHVzZSBmcm9tX2RiYWxfcXVlcnkoKSBpbnN0ZWFkCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPnxsaXN0PG1peGVkPiAkcGFyYW1ldGVycyAtIEBkZXByZWNhdGVkIHVzZSBEYmFsUXVlcnlFeHRyYWN0b3I6OndpdGhQYXJhbWV0ZXJzKCkgaW5zdGVhZAogKiBAcGFyYW0gYXJyYXk8aW50PDAsIG1heD58c3RyaW5nLCBEYmFsQXJyYXlUeXBlfERiYWxQYXJhbWV0ZXJUeXBlfERiYWxUeXBlfHN0cmluZz4gJHR5cGVzIC0gQGRlcHJlY2F0ZWQgdXNlIERiYWxRdWVyeUV4dHJhY3Rvcjo6d2l0aFR5cGVzKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":197,"slug":"to-dbal-table-insert","name":"to_dbal_table_insert","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"InsertOptions","namespace":"Flow\\Doctrine\\Bulk","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"database_upsert"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEluc2VydCBuZXcgcm93cyBpbnRvIGEgZGF0YWJhc2UgdGFibGUuCiAqIEluc2VydCBjYW4gYWxzbyBiZSB1c2VkIGFzIGFuIHVwc2VydCB3aXRoIHRoZSBoZWxwIG9mIEluc2VydE9wdGlvbnMuCiAqIEluc2VydE9wdGlvbnMgYXJlIHBsYXRmb3JtIHNwZWNpZmljLCBzbyBwbGVhc2UgY2hvb3NlIHRoZSByaWdodCBvbmUgZm9yIHlvdXIgZGF0YWJhc2UuCiAqCiAqICAtIE15U1FMSW5zZXJ0T3B0aW9ucwogKiAgLSBQb3N0Z3JlU1FMSW5zZXJ0T3B0aW9ucwogKiAgLSBTcWxpdGVJbnNlcnRPcHRpb25zCiAqCiAqIEluIG9yZGVyIHRvIGNvbnRyb2wgdGhlIHNpemUgb2YgdGhlIHNpbmdsZSBpbnNlcnQsIHVzZSBEYXRhRnJhbWU6OmNodW5rU2l6ZSgpIG1ldGhvZCBqdXN0IGJlZm9yZSBjYWxsaW5nIERhdGFGcmFtZTo6bG9hZCgpLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD58Q29ubmVjdGlvbiAkY29ubmVjdGlvbgogKgogKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":214,"slug":"to-dbal-table-update","name":"to_dbal_table_update","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"UpdateOptions","namespace":"Flow\\Doctrine\\Bulk","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqICBVcGRhdGUgZXhpc3Rpbmcgcm93cyBpbiBkYXRhYmFzZS4KICoKICogIEluIG9yZGVyIHRvIGNvbnRyb2wgdGhlIHNpemUgb2YgdGhlIHNpbmdsZSByZXF1ZXN0LCB1c2UgRGF0YUZyYW1lOjpjaHVua1NpemUoKSBtZXRob2QganVzdCBiZWZvcmUgY2FsbGluZyBEYXRhRnJhbWU6OmxvYWQoKS4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fENvbm5lY3Rpb24gJGNvbm5lY3Rpb24KICoKICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":233,"slug":"to-dbal-table-delete","name":"to_dbal_table_delete","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIERlbGV0ZSByb3dzIGZyb20gZGF0YWJhc2UgdGFibGUgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGRhdGEuCiAqCiAqIEluIG9yZGVyIHRvIGNvbnRyb2wgdGhlIHNpemUgb2YgdGhlIHNpbmdsZSByZXF1ZXN0LCB1c2UgRGF0YUZyYW1lOjpjaHVua1NpemUoKSBtZXRob2QganVzdCBiZWZvcmUgY2FsbGluZyBEYXRhRnJhbWU6OmxvYWQoKS4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fENvbm5lY3Rpb24gJGNvbm5lY3Rpb24KICoKICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":248,"slug":"to-dbal-schema-table","name":"to_dbal_schema_table","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table_options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"types_map","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Table","namespace":"Doctrine\\DBAL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnRzIGEgRmxvd1xFVExcU2NoZW1hIHRvIGEgRG9jdHJpbmVcREJBTFxTY2hlbWFcVGFibGUuCiAqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHRhYmxlX29wdGlvbnMKICogQHBhcmFtIGFycmF5PGNsYXNzLXN0cmluZzxcRmxvd1xUeXBlc1xUeXBlPG1peGVkPj4sIGNsYXNzLXN0cmluZzxcRG9jdHJpbmVcREJBTFxUeXBlc1xUeXBlPj4gJHR5cGVzX21hcAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":265,"slug":"table-schema-to-flow-schema","name":"table_schema_to_flow_schema","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"table","type":[{"name":"Table","namespace":"Doctrine\\DBAL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"types_map","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnRzIGEgRG9jdHJpbmVcREJBTFxTY2hlbWFcVGFibGUgdG8gYSBGbG93XEVUTFxTY2hlbWEuCiAqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8XEZsb3dcVHlwZXNcVHlwZTxtaXhlZD4+LCBjbGFzcy1zdHJpbmc8XERvY3RyaW5lXERCQUxcVHlwZXNcVHlwZT4+ICR0eXBlc19tYXAKICoKICogQHJldHVybiBTY2hlbWEKICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":276,"slug":"postgresql-insert-options","name":"postgresql_insert_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"skip_conflicts","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"constraint","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"conflict_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"PostgreSQLInsertOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"database_upsert"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICRjb25mbGljdF9jb2x1bW5zCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":289,"slug":"mysql-insert-options","name":"mysql_insert_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"skip_conflicts","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"upsert","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"MySQLInsertOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":302,"slug":"sqlite-insert-options","name":"sqlite_insert_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"skip_conflicts","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"conflict_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"SqliteInsertOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICRjb25mbGljdF9jb2x1bW5zCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":315,"slug":"postgresql-update-options","name":"postgresql_update_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"primary_key_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"PostgreSQLUpdateOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICRwcmltYXJ5X2tleV9jb2x1bW5zCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":331,"slug":"to-dbal-transaction","name":"to_dbal_transaction","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"loaders","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"TransactionalDbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4ZWN1dGUgbXVsdGlwbGUgbG9hZGVycyB3aXRoaW4gYSBkYXRhYmFzZSB0cmFuc2FjdGlvbi4KICogRWFjaCBiYXRjaCBvZiByb3dzIHdpbGwgYmUgcHJvY2Vzc2VkIGluIGl0cyBvd24gdHJhbnNhY3Rpb24uCiAqIElmIGFueSBsb2FkZXIgZmFpbHMsIHRoZSBlbnRpcmUgYmF0Y2ggd2lsbCBiZSByb2xsZWQgYmFjay4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fENvbm5lY3Rpb24gJGNvbm5lY3Rpb24KICogQHBhcmFtIExvYWRlciAuLi4kbG9hZGVycyAtIExvYWRlcnMgdG8gZXhlY3V0ZSB3aXRoaW4gdGhlIHRyYW5zYWN0aW9uCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":339,"slug":"pagination-key-asc","name":"pagination_key_asc","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ParameterType","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Doctrine\\DBAL\\Types","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Doctrine\\DBAL\\ParameterType::..."}],"return_type":[{"name":"Key","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":345,"slug":"pagination-key-desc","name":"pagination_key_desc","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ParameterType","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Doctrine\\DBAL\\Types","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Doctrine\\DBAL\\ParameterType::..."}],"return_type":[{"name":"Key","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":351,"slug":"pagination-key-set","name":"pagination_key_set","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"keys","type":[{"name":"Key","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"KeySet","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-excel\/src\/Flow\/ETL\/Adapter\/Excel\/DSL\/functions.php","start_line_in_file":20,"slug":"from-excel","name":"from_excel","namespace":"Flow\\ETL\\Adapter\\Excel\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExcelExtractor","namespace":"Flow\\ETL\\Adapter\\Excel","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"EXCEL","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-excel\/src\/Flow\/ETL\/Adapter\/Excel\/DSL\/functions.php","start_line_in_file":26,"slug":"to-excel","name":"to_excel","namespace":"Flow\\ETL\\Adapter\\Excel\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExcelLoader","namespace":"Flow\\ETL\\Adapter\\Excel","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"EXCEL","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-excel\/src\/Flow\/ETL\/Adapter\/Excel\/DSL\/functions.php","start_line_in_file":32,"slug":"is-valid-excel-sheet-name","name":"is_valid_excel_sheet_name","namespace":"Flow\\ETL\\Adapter\\Excel\\DSL","parameters":[{"name":"sheet_name","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"IsValidExcelSheetName","namespace":"Flow\\ETL\\Adapter\\Excel\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"EXCEL","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-google-sheet\/src\/Flow\/ETL\/Adapter\/GoogleSheet\/functions.php","start_line_in_file":22,"slug":"from-google-sheet","name":"from_google_sheet","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","parameters":[{"name":"auth_config","type":[{"name":"Sheets","namespace":"Google\\Service","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"spreadsheet_id","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sheet_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"rows_per_page","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"GoogleSheetExtractor","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"GOOGLE_SHEET","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheXt0eXBlOiBzdHJpbmcsIHByb2plY3RfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXlfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXk6IHN0cmluZywgY2xpZW50X2VtYWlsOiBzdHJpbmcsIGNsaWVudF9pZDogc3RyaW5nLCBhdXRoX3VyaTogc3RyaW5nLCB0b2tlbl91cmk6IHN0cmluZywgYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsOiBzdHJpbmcsIGNsaWVudF94NTA5X2NlcnRfdXJsOiBzdHJpbmd9fFNoZWV0cyAkYXV0aF9jb25maWcKICogQHBhcmFtIHN0cmluZyAkc3ByZWFkc2hlZXRfaWQKICogQHBhcmFtIHN0cmluZyAkc2hlZXRfbmFtZQogKiBAcGFyYW0gYm9vbCAkd2l0aF9oZWFkZXIgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aEhlYWRlciBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gaW50ICRyb3dzX3Blcl9wYWdlIC0gaG93IG1hbnkgcm93cyBwZXIgcGFnZSB0byBmZXRjaCBmcm9tIEdvb2dsZSBTaGVldHMgQVBJIC0gQGRlcHJlY2F0ZWQgdXNlIHdpdGhSb3dzUGVyUGFnZSBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gYXJyYXl7ZGF0ZVRpbWVSZW5kZXJPcHRpb24\/OiBzdHJpbmcsIG1ham9yRGltZW5zaW9uPzogc3RyaW5nLCB2YWx1ZVJlbmRlck9wdGlvbj86IHN0cmluZ30gJG9wdGlvbnMgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aE9wdGlvbnMgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-google-sheet\/src\/Flow\/ETL\/Adapter\/GoogleSheet\/functions.php","start_line_in_file":56,"slug":"from-google-sheet-columns","name":"from_google_sheet_columns","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","parameters":[{"name":"auth_config","type":[{"name":"Sheets","namespace":"Google\\Service","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"spreadsheet_id","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sheet_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start_range_column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end_range_column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"rows_per_page","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"GoogleSheetExtractor","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"GOOGLE_SHEET","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheXt0eXBlOiBzdHJpbmcsIHByb2plY3RfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXlfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXk6IHN0cmluZywgY2xpZW50X2VtYWlsOiBzdHJpbmcsIGNsaWVudF9pZDogc3RyaW5nLCBhdXRoX3VyaTogc3RyaW5nLCB0b2tlbl91cmk6IHN0cmluZywgYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsOiBzdHJpbmcsIGNsaWVudF94NTA5X2NlcnRfdXJsOiBzdHJpbmd9fFNoZWV0cyAkYXV0aF9jb25maWcKICogQHBhcmFtIHN0cmluZyAkc3ByZWFkc2hlZXRfaWQKICogQHBhcmFtIHN0cmluZyAkc2hlZXRfbmFtZQogKiBAcGFyYW0gc3RyaW5nICRzdGFydF9yYW5nZV9jb2x1bW4KICogQHBhcmFtIHN0cmluZyAkZW5kX3JhbmdlX2NvbHVtbgogKiBAcGFyYW0gYm9vbCAkd2l0aF9oZWFkZXIgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aEhlYWRlciBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gaW50ICRyb3dzX3Blcl9wYWdlIC0gaG93IG1hbnkgcm93cyBwZXIgcGFnZSB0byBmZXRjaCBmcm9tIEdvb2dsZSBTaGVldHMgQVBJLCBkZWZhdWx0IDEwMDAgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aFJvd3NQZXJQYWdlIG1ldGhvZCBpbnN0ZWFkCiAqIEBwYXJhbSBhcnJheXtkYXRlVGltZVJlbmRlck9wdGlvbj86IHN0cmluZywgbWFqb3JEaW1lbnNpb24\/OiBzdHJpbmcsIHZhbHVlUmVuZGVyT3B0aW9uPzogc3RyaW5nfSAkb3B0aW9ucyAtIEBkZXByZWNhdGVkIHVzZSB3aXRoT3B0aW9ucyBtZXRob2QgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-http\/src\/Flow\/ETL\/Adapter\/Http\/DSL\/functions.php","start_line_in_file":15,"slug":"from-dynamic-http-requests","name":"from_dynamic_http_requests","namespace":"Flow\\ETL\\Adapter\\Http","parameters":[{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"requestFactory","type":[{"name":"NextRequestFactory","namespace":"Flow\\ETL\\Adapter\\Http\\DynamicExtractor","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PsrHttpClientDynamicExtractor","namespace":"Flow\\ETL\\Adapter\\Http","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"HTTP","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-http\/src\/Flow\/ETL\/Adapter\/Http\/DSL\/functions.php","start_line_in_file":26,"slug":"from-static-http-requests","name":"from_static_http_requests","namespace":"Flow\\ETL\\Adapter\\Http","parameters":[{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"requests","type":[{"name":"iterable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PsrHttpClientStaticExtractor","namespace":"Flow\\ETL\\Adapter\\Http","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"HTTP","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpdGVyYWJsZTxSZXF1ZXN0SW50ZXJmYWNlPiAkcmVxdWVzdHMKICov"},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":30,"slug":"from-json","name":"from_json","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pointer","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"JsonExtractor","namespace":"Flow\\ETL\\Adapter\\JSON\\JSONMachine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"json"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aCAtIHN0cmluZyBpcyBpbnRlcm5hbGx5IHR1cm5lZCBpbnRvIHN0cmVhbQogKiBAcGFyYW0gP3N0cmluZyAkcG9pbnRlciAtIGlmIHlvdSB3YW50IHRvIGl0ZXJhdGUgb25seSByZXN1bHRzIG9mIGEgc3VidHJlZSwgdXNlIGEgcG9pbnRlciwgcmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9oYWxheGEvanNvbi1tYWNoaW5lI3BhcnNpbmctYS1zdWJ0cmVlIC0gQGRlcHJlY2F0ZSB1c2Ugd2l0aFBvaW50ZXIgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIG51bGx8U2NoZW1hICRzY2hlbWEgLSBlbmZvcmNlIHNjaGVtYSBvbiB0aGUgZXh0cmFjdGVkIGRhdGEgLSBAZGVwcmVjYXRlIHVzZSB3aXRoU2NoZW1hIG1ldGhvZCBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":52,"slug":"from-json-lines","name":"from_json_lines","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"JsonLinesExtractor","namespace":"Flow\\ETL\\Adapter\\JSON\\JSONMachine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"jsonl"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFVzZWQgdG8gcmVhZCBmcm9tIGEgSlNPTiBsaW5lcyBodHRwczovL2pzb25saW5lcy5vcmcvIGZvcm1hdHRlZCBmaWxlLgogKgogKiBAcGFyYW0gUGF0aHxzdHJpbmcgJHBhdGggLSBzdHJpbmcgaXMgaW50ZXJuYWxseSB0dXJuZWQgaW50byBzdHJlYW0KICov"},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":66,"slug":"to-json","name":"to_json","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"4194304"},{"name":"date_time_format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d\\\\TH:i:sP'"},{"name":"put_rows_in_new_lines","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"JsonLoader","namespace":"Flow\\ETL\\Adapter\\JSON","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gaW50ICRmbGFncyAtIFBIUCBKU09OIEZsYWdzIC0gQGRlcHJlY2F0ZSB1c2Ugd2l0aEZsYWdzIG1ldGhvZCBpbnN0ZWFkCiAqIEBwYXJhbSBzdHJpbmcgJGRhdGVfdGltZV9mb3JtYXQgLSBmb3JtYXQgZm9yIERhdGVUaW1lSW50ZXJmYWNlOjpmb3JtYXQoKSAtIEBkZXByZWNhdGUgdXNlIHdpdGhEYXRlVGltZUZvcm1hdCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gYm9vbCAkcHV0X3Jvd3NfaW5fbmV3X2xpbmVzIC0gaWYgeW91IHdhbnQgdG8gcHV0IGVhY2ggcm93IGluIGEgbmV3IGxpbmUgLSBAZGVwcmVjYXRlIHVzZSB3aXRoUm93c0luTmV3TGluZXMgbWV0aG9kIGluc3RlYWQKICoKICogQHJldHVybiBKc29uTG9hZGVyCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":86,"slug":"to-json-lines","name":"to_json_lines","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"JsonLinesLoader","namespace":"Flow\\ETL\\Adapter\\JSON","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFVzZWQgdG8gd3JpdGUgdG8gYSBKU09OIGxpbmVzIGh0dHBzOi8vanNvbmxpbmVzLm9yZy8gZm9ybWF0dGVkIGZpbGUuCiAqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKgogKiBAcmV0dXJuIEpzb25MaW5lc0xvYWRlcgogKi8="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":99,"slug":"schema-from-json-schema","name":"schema_from_json_schema","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"json_schema","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"request_factory","type":[{"name":"RequestFactoryInterface","namespace":"Psr\\Http\\Message","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgYSBKU09OIFNjaGVtYSAoaHR0cHM6Ly9qc29uLXNjaGVtYS5vcmcpIGRvY3VtZW50IGludG8gYSBGbG93IFNjaGVtYS4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fFBhdGh8c3RyaW5nICRqc29uX3NjaGVtYSAtIGRlY29kZWQgZG9jdW1lbnQsIHJhdyBKU09OIGRvY3VtZW50IG9yIGEgcGF0aCB0byBhIHNjaGVtYSBmaWxlCiAqIEBwYXJhbSBudWxsfENsaWVudEludGVyZmFjZSAkY2xpZW50IC0gUFNSLTE4IGh0dHAgY2xpZW50LCByZXF1aXJlZCB0byByZXNvbHZlIHJlbW90ZSBodHRwKHMpIHJlZmVyZW5jZXMKICogQHBhcmFtIG51bGx8UmVxdWVzdEZhY3RvcnlJbnRlcmZhY2UgJHJlcXVlc3RfZmFjdG9yeSAtIFBTUi0xNyByZXF1ZXN0IGZhY3RvcnksIHJlcXVpcmVkIHRvIHJlc29sdmUgcmVtb3RlIGh0dHAocykgcmVmZXJlbmNlcwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":113,"slug":"schema-to-json-schema","name":"schema_to_json_schema","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgYSBGbG93IFNjaGVtYSBpbnRvIGEgSlNPTiBTY2hlbWEgKGh0dHBzOi8vanNvbi1zY2hlbWEub3JnLCBkcmFmdCAyMDIwLTEyKSBkb2N1bWVudC4KICoKICogQHJldHVybiBhcnJheTxzdHJpbmcsIG1peGVkPgogKi8="},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":32,"slug":"from-parquet","name":"from_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Parquet","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Parquet\\Options::..."},{"name":"byte_order","type":[{"name":"ByteOrder","namespace":"Flow\\Parquet\\Binary","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Parquet\\Binary\\ByteOrder::..."},{"name":"offset","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ParquetExtractor","namespace":"Flow\\ETL\\Adapter\\Parquet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"parquet"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gYXJyYXk8c3RyaW5nPiAkY29sdW1ucyAtIGxpc3Qgb2YgY29sdW1ucyB0byByZWFkIGZyb20gcGFycXVldCBmaWxlIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoQ29sdW1uc2AgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIE9wdGlvbnMgJG9wdGlvbnMgLSBAZGVwcmVjYXRlZCB1c2UgYHdpdGhPcHRpb25zYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gQnl0ZU9yZGVyICRieXRlX29yZGVyIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoQnl0ZU9yZGVyYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxpbnQgJG9mZnNldCAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aE9mZnNldGAgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":62,"slug":"to-parquet","name":"to_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Parquet","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"compressions","type":[{"name":"Compressions","namespace":"Flow\\Parquet\\ParquetFile","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Parquet\\ParquetFile\\Compressions::..."},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ParquetLoader","namespace":"Flow\\ETL\\Adapter\\Parquet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"LOADER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"parquet"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gbnVsbHxPcHRpb25zICRvcHRpb25zIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoT3B0aW9uc2AgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIENvbXByZXNzaW9ucyAkY29tcHJlc3Npb25zIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoQ29tcHJlc3Npb25zYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYSAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aFNjaGVtYWAgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":89,"slug":"array-to-generator","name":"array_to_generator","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Generator","namespace":"","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBhcnJheTxUPiAkZGF0YQogKgogKiBAcmV0dXJuIFxHZW5lcmF0b3I8VD4KICov"},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":97,"slug":"empty-generator","name":"empty_generator","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[],"return_type":[{"name":"Generator","namespace":"","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":103,"slug":"schema-to-parquet","name":"schema_to_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\Parquet\\ParquetFile","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":109,"slug":"schema-from-parquet","name":"schema_from_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\Parquet\\ParquetFile","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":15,"slug":"to-seal-upsert","name":"to_seal_upsert","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"engine","type":[{"name":"EngineInterface","namespace":"CmsIg\\Seal","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"index","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SealLoader","namespace":"Flow\\ETL\\Adapter\\Seal","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":21,"slug":"to-seal-delete","name":"to_seal_delete","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"engine","type":[{"name":"EngineInterface","namespace":"CmsIg\\Seal","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"index","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SealLoader","namespace":"Flow\\ETL\\Adapter\\Seal","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":27,"slug":"to-seal-schema","name":"to_seal_schema","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"index_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"identifier","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Schema","namespace":"CmsIg\\Seal\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":33,"slug":"seal-schema-to-flow","name":"seal_schema_to_flow","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"CmsIg\\Seal\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-text\/src\/Flow\/ETL\/Adapter\/Text\/functions.php","start_line_in_file":20,"slug":"from-text","name":"from_text","namespace":"Flow\\ETL\\Adapter\\Text","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TextExtractor","namespace":"Flow\\ETL\\Adapter\\Text","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TEXT","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-text\/src\/Flow\/ETL\/Adapter\/Text\/functions.php","start_line_in_file":32,"slug":"to-text","name":"to_text","namespace":"Flow\\ETL\\Adapter\\Text","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"new_line_separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\n'"}],"return_type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TEXT","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gc3RyaW5nICRuZXdfbGluZV9zZXBhcmF0b3IgLSBkZWZhdWx0IFBIUF9FT0wgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aE5ld0xpbmVTZXBhcmF0b3IgbWV0aG9kIGluc3RlYWQKICoKICogQHJldHVybiBMb2FkZXIKICov"},{"repository_path":"src\/adapter\/etl-adapter-xml\/src\/Flow\/ETL\/Adapter\/XML\/functions.php","start_line_in_file":36,"slug":"from-xml","name":"from_xml","namespace":"Flow\\ETL\\Adapter\\XML","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"xml_node_path","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"''"}],"return_type":[{"name":"XMLParserExtractor","namespace":"Flow\\ETL\\Adapter\\XML","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"XML","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"xml"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqICBJbiBvcmRlciB0byBpdGVyYXRlIG9ubHkgb3ZlciA8ZWxlbWVudD4gbm9kZXMgdXNlIGBmcm9tX3htbCgkZmlsZSktPndpdGhYTUxOb2RlUGF0aCgncm9vdC9lbGVtZW50cy9lbGVtZW50JylgLgogKgogKiAgPHJvb3Q+CiAqICAgIDxlbGVtZW50cz4KICogICAgICA8ZWxlbWVudD48L2VsZW1lbnQ+CiAqICAgICAgPGVsZW1lbnQ+PC9lbGVtZW50PgogKiAgICA8ZWxlbWVudHM+CiAqICA8L3Jvb3Q+CiAqCiAqICBYTUwgTm9kZSBQYXRoIGRvZXMgbm90IHN1cHBvcnQgYXR0cmlidXRlcyBhbmQgaXQncyBub3QgeHBhdGgsIGl0IGlzIGp1c3QgYSBzZXF1ZW5jZQogKiAgb2Ygbm9kZSBuYW1lcyBzZXBhcmF0ZWQgd2l0aCBzbGFzaC4KICoKICogQHBhcmFtIFBhdGh8c3RyaW5nICRwYXRoCiAqIEBwYXJhbSBzdHJpbmcgJHhtbF9ub2RlX3BhdGggLSBAZGVwcmVjYXRlZCB1c2UgYGZyb21feG1sKCRmaWxlKS0+d2l0aFhNTE5vZGVQYXRoKCR4bWxOb2RlUGF0aClgIG1ldGhvZCBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-xml\/src\/Flow\/ETL\/Adapter\/XML\/functions.php","start_line_in_file":50,"slug":"to-xml","name":"to_xml","namespace":"Flow\\ETL\\Adapter\\XML","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"root_element_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'rows'"},{"name":"row_element_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'row'"},{"name":"attribute_prefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'_'"},{"name":"date_time_format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d\\\\TH:i:s.uP'"},{"name":"xml_writer","type":[{"name":"XMLWriter","namespace":"Flow\\ETL\\Adapter\\XML","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Adapter\\XML\\XMLWriter\\DOMDocumentWriter::..."}],"return_type":[{"name":"XMLLoader","namespace":"Flow\\ETL\\Adapter\\XML\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"XML","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gc3RyaW5nICRyb290X2VsZW1lbnRfbmFtZSAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aFJvb3RFbGVtZW50TmFtZSgpYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRyb3dfZWxlbWVudF9uYW1lIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoUm93RWxlbWVudE5hbWUoKWAgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIHN0cmluZyAkYXR0cmlidXRlX3ByZWZpeCAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aEF0dHJpYnV0ZVByZWZpeCgpYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRkYXRlX3RpbWVfZm9ybWF0IC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoRGF0ZVRpbWVGb3JtYXQoKWAgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIFhNTFdyaXRlciAkeG1sX3dyaXRlcgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":32,"slug":"mount","name":"mount","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Mount","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":38,"slug":"partition","name":"partition","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Partition","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":44,"slug":"partitions","name":"partitions","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"partition","type":[{"name":"Partition","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":63,"slug":"path","name":"path","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"path","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Filesystem\\Path","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhdGggc3VwcG9ydHMgZ2xvYiBwYXR0ZXJucy4KICogRXhhbXBsZXM6CiAqICAtIHBhdGgoJyouY3N2JykgLSBhbnkgY3N2IGZpbGUgaW4gY3VycmVudCBkaXJlY3RvcnkKICogIC0gcGF0aCgnLyoqIC8gKi5jc3YnKSAtIGFueSBjc3YgZmlsZSBpbiBhbnkgc3ViZGlyZWN0b3J5IChyZW1vdmUgZW1wdHkgc3BhY2VzKQogKiAgLSBwYXRoKCcvZGlyL3BhcnRpdGlvbj0qIC8qLnBhcnF1ZXQnKSAtIGFueSBwYXJxdWV0IGZpbGUgaW4gZ2l2ZW4gcGFydGl0aW9uIGRpcmVjdG9yeS4KICoKICogR2xvYiBwYXR0ZXJuIGlzIGFsc28gc3VwcG9ydGVkIGJ5IHJlbW90ZSBmaWxlc3lzdGVtcyBsaWtlIEF6dXJlCiAqCiAqICAtIHBhdGgoJ2F6dXJlLWJsb2I6Ly9kaXJlY3RvcnkvKi5jc3YnKSAtIGFueSBjc3YgZmlsZSBpbiBnaXZlbiBkaXJlY3RvcnkKICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbnVsbHxib29sfGZsb2F0fGludHxzdHJpbmd8XFVuaXRFbnVtPnxQYXRoXE9wdGlvbnMgJG9wdGlvbnMKICov"},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":74,"slug":"path-real","name":"path_real","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"path","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFJlc29sdmUgcmVhbCBwYXRoIGZyb20gZ2l2ZW4gcGF0aC4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbnVsbHxib29sfGZsb2F0fGludHxzdHJpbmd8XFVuaXRFbnVtPiAkb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":80,"slug":"native-local-filesystem","name":"native_local_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'file'"}],"return_type":[{"name":"NativeLocalFilesystem","namespace":"Flow\\Filesystem\\Local","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":90,"slug":"stdout-filesystem","name":"stdout_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'stdout'"}],"return_type":[{"name":"StdOutFilesystem","namespace":"Flow\\Filesystem\\Local","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyaXRlLW9ubHkgZmlsZXN5c3RlbSB1c2VmdWwgd2hlbiB3ZSBqdXN0IHdhbnQgdG8gd3JpdGUgdGhlIG91dHB1dCB0byBzdGRvdXQuCiAqIFRoZSBtYWluIHVzZSBjYXNlIGlzIGZvciBzdHJlYW1pbmcgZGF0YXNldHMgb3ZlciBodHRwLgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":99,"slug":"memory-filesystem","name":"memory_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'memory'"}],"return_type":[{"name":"MemoryFilesystem","namespace":"Flow\\Filesystem\\Local","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBtZW1vcnkgZmlsZXN5c3RlbSBhbmQgd3JpdGVzIGRhdGEgdG8gaXQgaW4gbWVtb3J5LgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":110,"slug":"fstab","name":"fstab","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"filesystems","type":[{"name":"Filesystem","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"FilesystemTable","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBmaWxlc3lzdGVtIHRhYmxlIHdpdGggZ2l2ZW4gZmlsZXN5c3RlbXMuCiAqIEZpbGVzeXN0ZW1zIGNhbiBiZSBhbHNvIG1vdW50ZWQgbGF0ZXIuCiAqIElmIG5vIGZpbGVzeXN0ZW1zIGFyZSBwcm92aWRlZCwgbG9jYWwgZmlsZXN5c3RlbSBpcyBtb3VudGVkLgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":126,"slug":"traceable-filesystem","name":"traceable_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"filesystem","type":[{"name":"Filesystem","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"telemetryConfig","type":[{"name":"FilesystemTelemetryConfig","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TraceableFilesystem","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYSBmaWxlc3lzdGVtIHdpdGggdGVsZW1ldHJ5IHRyYWNpbmcgc3VwcG9ydC4KICogQWxsIGZpbGVzeXN0ZW0gYW5kIHN0cmVhbSBvcGVyYXRpb25zIHdpbGwgYmUgdHJhY2VkIGFjY29yZGluZyB0byB0aGUgY29uZmlndXJhdGlvbi4KICov"},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":135,"slug":"filesystem-telemetry-config","name":"filesystem_telemetry_config","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"telemetry","type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"FilesystemTelemetryOptions","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FilesystemTelemetryConfig","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRlbGVtZXRyeSBjb25maWd1cmF0aW9uIGZvciB0aGUgZmlsZXN5c3RlbS4KICov"},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":150,"slug":"filesystem-telemetry-options","name":"filesystem_telemetry_options","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"trace_streams","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"collect_metrics","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"FilesystemTelemetryOptions","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBvcHRpb25zIGZvciBmaWxlc3lzdGVtIHRlbGVtZXRyeS4KICoKICogQHBhcmFtIGJvb2wgJHRyYWNlX3N0cmVhbXMgQ3JlYXRlIGEgc2luZ2xlIHNwYW4gcGVyIHN0cmVhbSBsaWZlY3ljbGUgKGRlZmF1bHQ6IE9OKQogKiBAcGFyYW0gYm9vbCAkY29sbGVjdF9tZXRyaWNzIENvbGxlY3QgbWV0cmljcyBmb3IgYnl0ZXMvb3BlcmF0aW9uIGNvdW50cyAoZGVmYXVsdDogT04pCiAqLw=="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":163,"slug":"file-copy","name":"file_copy","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"table","type":[{"name":"FilesystemTable","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"OperationOptions","namespace":"Flow\\Filesystem\\Operations","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Copy","namespace":"Flow\\Filesystem\\Operations","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvcHkgYSBmaWxlIGZyb20gb25lIHBhdGggdG8gYW5vdGhlciwgYWNyb3NzIGFueSBmaWxlc3lzdGVtcyBtb3VudGVkIGluIHRoZSB0YWJsZS4KICogQWx3YXlzIHN0cmVhbXMgYnl0ZXM7IHNhbWUtZmlsZXN5c3RlbSBjb3BpZXMgZG8gbm90IHVzZSBzZXJ2ZXItc2lkZSBvcHRpbWl6YXRpb25zCiAqIGJlY2F1c2UgYEZpbGVzeXN0ZW06Om12YCBpcyBhIG1vdmUsIG5vdCBhIGNvcHkuCiAqLw=="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":174,"slug":"file-move","name":"file_move","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"table","type":[{"name":"FilesystemTable","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"OperationOptions","namespace":"Flow\\Filesystem\\Operations","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Move","namespace":"Flow\\Filesystem\\Operations","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE1vdmUgYSBmaWxlIGZyb20gb25lIHBhdGggdG8gYW5vdGhlciwgYWNyb3NzIGFueSBmaWxlc3lzdGVtcyBtb3VudGVkIGluIHRoZSB0YWJsZS4KICogSW50cmEtZmlsZXN5c3RlbSBtb3ZlcyBkZWxlZ2F0ZSB0byBgRmlsZXN5c3RlbTo6bXZgIGZvciBzZXJ2ZXItc2lkZSBvcHRpbWl6YXRpb25zOwogKiBjcm9zcy1maWxlc3lzdGVtIG1vdmVzIHN0cmVhbS1jb3B5IHRoZW4gcmVtb3ZlIHRoZSBzb3VyY2UgKG5vbi1hdG9taWMpLgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":185,"slug":"operation-options","name":"operation_options","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"chunkSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"8192"}],"return_type":[{"name":"OperationOptions","namespace":"Flow\\Filesystem\\Operations","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE9wdGlvbnMgc2hhcmVkIGJ5IGZpbGVzeXN0ZW0gb3BlcmF0aW9ucy4KICoKICogQHBhcmFtIGludCAkY2h1bmtTaXplIE51bWJlciBvZiBieXRlcyByZWFkL3dyaXR0ZW4gcGVyIGl0ZXJhdGlvbiB3aGVuIHN0cmVhbWluZyBhY3Jvc3MgZmlsZXN5c3RlbXMgKGRlZmF1bHQ6IDgxOTIpCiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":68,"slug":"type-structure","name":"type_structure","namespace":"Flow\\Types\\DSL","parameters":[{"name":"elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"optional_elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"allow_extra","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIFR5cGU8VD4+ICRlbGVtZW50cwogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBUeXBlPFQ+PiAkb3B0aW9uYWxfZWxlbWVudHMKICoKICogQHJldHVybiBTdHJ1Y3R1cmVUeXBlPFQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":83,"slug":"type-union","name":"type_union","namespace":"Flow\\Types\\DSL","parameters":[{"name":"first","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"second","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"types","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICRmaXJzdAogKiBAcGFyYW0gVHlwZTxUPiAkc2Vjb25kCiAqIEBwYXJhbSBUeXBlPFQ+IC4uLiR0eXBlcwogKgogKiBAcmV0dXJuIFR5cGU8VD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":104,"slug":"type-intersection","name":"type_intersection","namespace":"Flow\\Types\\DSL","parameters":[{"name":"first","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"second","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"types","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICRmaXJzdAogKiBAcGFyYW0gVHlwZTxUPiAkc2Vjb25kCiAqIEBwYXJhbSBUeXBlPFQ+IC4uLiR0eXBlcwogKgogKiBAcmV0dXJuIFR5cGU8VD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":119,"slug":"type-numeric-string","name":"type_numeric_string","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxudW1lcmljLXN0cmluZz4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":132,"slug":"type-optional","name":"type_optional","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqCiAqIEByZXR1cm4gVHlwZTxUPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":143,"slug":"type-from-array","name":"type_from_array","namespace":"Flow\\Types\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPiAkZGF0YQogKgogKiBAcmV0dXJuIFR5cGU8bWl4ZWQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":154,"slug":"type-is-nullable","name":"type_is_nullable","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":176,"slug":"type-equals","name":"type_equals","namespace":"Flow\\Types\\DSL","parameters":[{"name":"left","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBUeXBlPG1peGVkPiAkbGVmdAogKiBAcGFyYW0gVHlwZTxtaXhlZD4gJHJpZ2h0CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":189,"slug":"types","name":"types","namespace":"Flow\\Types\\DSL","parameters":[{"name":"types","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Types","namespace":"Flow\\Types\\Type","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+IC4uLiR0eXBlcwogKgogKiBAcmV0dXJuIFR5cGVzPFQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":202,"slug":"type-list","name":"type_list","namespace":"Flow\\Types\\DSL","parameters":[{"name":"element","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICRlbGVtZW50CiAqCiAqIEByZXR1cm4gVHlwZTxsaXN0PFQ+PgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":217,"slug":"type-map","name":"type_map","namespace":"Flow\\Types\\DSL","parameters":[{"name":"key_type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value_type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUS2V5IG9mIGFycmF5LWtleQogKiBAdGVtcGxhdGUgVFZhbHVlCiAqCiAqIEBwYXJhbSBUeXBlPFRLZXk+ICRrZXlfdHlwZQogKiBAcGFyYW0gVHlwZTxUVmFsdWU+ICR2YWx1ZV90eXBlCiAqCiAqIEByZXR1cm4gVHlwZTxhcnJheTxUS2V5LCBUVmFsdWU+PgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":226,"slug":"type-json","name":"type_json","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxKc29uPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":235,"slug":"type-datetime","name":"type_datetime","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZVRpbWVJbnRlcmZhY2U+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":244,"slug":"type-date","name":"type_date","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZVRpbWVJbnRlcmZhY2U+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":253,"slug":"type-time","name":"type_time","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZUludGVydmFsPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":262,"slug":"type-time-zone","name":"type_time_zone","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZVRpbWVab25lPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":271,"slug":"type-xml","name":"type_xml","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRE9NRG9jdW1lbnR8WE1MRG9jdW1lbnQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":280,"slug":"type-xml-element","name":"type_xml_element","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRE9NRWxlbWVudHxFbGVtZW50PgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":289,"slug":"type-uuid","name":"type_uuid","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxVdWlkPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":298,"slug":"type-integer","name":"type_integer","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxpbnQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":307,"slug":"type-string","name":"type_string","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxzdHJpbmc+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":316,"slug":"type-float","name":"type_float","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxmbG9hdD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":325,"slug":"type-boolean","name":"type_boolean","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxib29sPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":338,"slug":"type-instance-of","name":"type_instance_of","namespace":"Flow\\Types\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICRjbGFzcwogKgogKiBAcmV0dXJuIFR5cGU8VD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":347,"slug":"type-object","name":"type_object","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxvYmplY3Q+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":356,"slug":"type-scalar","name":"type_scalar","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxib29sfGZsb2F0fGludHxzdHJpbmc+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":365,"slug":"type-resource","name":"type_resource","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxyZXNvdXJjZT4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":374,"slug":"type-array","name":"type_array","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxhcnJheTxtaXhlZD4+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":383,"slug":"type-callable","name":"type_callable","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxjYWxsYWJsZT4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":392,"slug":"type-null","name":"type_null","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxudWxsPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":401,"slug":"type-mixed","name":"type_mixed","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxtaXhlZD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":410,"slug":"type-positive-integer","name":"type_positive_integer","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxpbnQ8MCwgbWF4Pj4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":419,"slug":"type-non-empty-string","name":"type_non_empty_string","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxub24tZW1wdHktc3RyaW5nPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":432,"slug":"type-enum","name":"type_enum","namespace":"Flow\\Types\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIFVuaXRFbnVtCiAqCiAqIEBwYXJhbSBjbGFzcy1zdHJpbmc8VD4gJGNsYXNzCiAqCiAqIEByZXR1cm4gVHlwZTxUPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":445,"slug":"type-literal","name":"type_literal","namespace":"Flow\\Types\\DSL","parameters":[{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIGJvb2x8ZmxvYXR8aW50fHN0cmluZwogKgogKiBAcGFyYW0gVCAkdmFsdWUKICoKICogQHJldHVybiBUeXBlPFQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":454,"slug":"type-html","name":"type_html","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxIVE1MRG9jdW1lbnQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":463,"slug":"type-html-element","name":"type_html_element","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxIVE1MRWxlbWVudD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":475,"slug":"type-is","name":"type_is","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"typeClass","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqIEBwYXJhbSBjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+ICR0eXBlQ2xhc3MKICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":488,"slug":"type-is-any","name":"type_is_any","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"typeClass","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"typeClasses","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqIEBwYXJhbSBjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+ICR0eXBlQ2xhc3MKICogQHBhcmFtIGNsYXNzLXN0cmluZzxUeXBlPG1peGVkPj4gLi4uJHR5cGVDbGFzc2VzCiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":497,"slug":"get-type","name":"get_type","namespace":"Flow\\Types\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxtaXhlZD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":510,"slug":"type-class-string","name":"type_class_string","namespace":"Flow\\Types\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gbnVsbHxjbGFzcy1zdHJpbmc8VD4gJGNsYXNzCiAqCiAqIEByZXR1cm4gKCRjbGFzcyBpcyBudWxsID8gVHlwZTxjbGFzcy1zdHJpbmc+IDogVHlwZTxjbGFzcy1zdHJpbmc8VD4+KQogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":516,"slug":"dom-element-to-string","name":"dom_element_to_string","namespace":"Flow\\Types\\DSL","parameters":[{"name":"element","type":[{"name":"DOMElement","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"format_output","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"preserver_white_space","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"false","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":134,"slug":"column","name":"column","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnDefinition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbHVtbiBkZWZpbml0aW9uIGZvciBDUkVBVEUgVEFCTEUuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgQ29sdW1uIG5hbWUKICogQHBhcmFtIENvbHVtblR5cGUgJHR5cGUgQ29sdW1uIGRhdGEgdHlwZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":143,"slug":"catalog","name":"catalog","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"schemas","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Catalog","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYT4gJHNjaGVtYXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":154,"slug":"primary-key","name":"primary_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"PrimaryKeyConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBSSU1BUlkgS0VZIGNvbnN0cmFpbnQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgLi4uJGNvbHVtbnMgQ29sdW1ucyB0aGF0IGZvcm0gdGhlIHByaW1hcnkga2V5CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":165,"slug":"unique-constraint","name":"unique_constraint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"UniqueConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFVOSVFVRSBjb25zdHJhaW50LgogKgogKiBAcGFyYW0gc3RyaW5nIC4uLiRjb2x1bW5zIENvbHVtbnMgdGhhdCBtdXN0IGJlIHVuaXF1ZSB0b2dldGhlcgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":178,"slug":"foreign-key","name":"foreign_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceTable","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ForeignKeyConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEZPUkVJR04gS0VZIGNvbnN0cmFpbnQuCiAqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGNvbHVtbnMgTG9jYWwgY29sdW1ucwogKiBAcGFyYW0gc3RyaW5nICRyZWZlcmVuY2VUYWJsZSBSZWZlcmVuY2VkIHRhYmxlCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHJlZmVyZW5jZUNvbHVtbnMgUmVmZXJlbmNlZCBjb2x1bW5zIChkZWZhdWx0cyB0byBzYW1lIGFzICRjb2x1bW5zIGlmIGVtcHR5KQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":187,"slug":"check-constraint","name":"check_constraint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"condition","type":[{"name":"Condition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CheckConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENIRUNLIGNvbnN0cmFpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":218,"slug":"create","name":"create","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"CreateFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZhY3RvcnkgZm9yIGJ1aWxkaW5nIENSRUFURSBzdGF0ZW1lbnRzLgogKgogKiBQcm92aWRlcyBhIHVuaWZpZWQgZW50cnkgcG9pbnQgZm9yIGFsbCBDUkVBVEUgb3BlcmF0aW9uczoKICogLSBjcmVhdGUoKS0+dGFibGUoKSAtIENSRUFURSBUQUJMRQogKiAtIGNyZWF0ZSgpLT50YWJsZUFzKCkgLSBDUkVBVEUgVEFCTEUgQVMKICogLSBjcmVhdGUoKS0+aW5kZXgoKSAtIENSRUFURSBJTkRFWAogKiAtIGNyZWF0ZSgpLT52aWV3KCkgLSBDUkVBVEUgVklFVwogKiAtIGNyZWF0ZSgpLT5tYXRlcmlhbGl6ZWRWaWV3KCkgLSBDUkVBVEUgTUFURVJJQUxJWkVEIFZJRVcKICogLSBjcmVhdGUoKS0+c2VxdWVuY2UoKSAtIENSRUFURSBTRVFVRU5DRQogKiAtIGNyZWF0ZSgpLT5zY2hlbWEoKSAtIENSRUFURSBTQ0hFTUEKICogLSBjcmVhdGUoKS0+cm9sZSgpIC0gQ1JFQVRFIFJPTEUKICogLSBjcmVhdGUoKS0+ZnVuY3Rpb24oKSAtIENSRUFURSBGVU5DVElPTgogKiAtIGNyZWF0ZSgpLT5wcm9jZWR1cmUoKSAtIENSRUFURSBQUk9DRURVUkUKICogLSBjcmVhdGUoKS0+dHJpZ2dlcigpIC0gQ1JFQVRFIFRSSUdHRVIKICogLSBjcmVhdGUoKS0+cnVsZSgpIC0gQ1JFQVRFIFJVTEUKICogLSBjcmVhdGUoKS0+ZXh0ZW5zaW9uKCkgLSBDUkVBVEUgRVhURU5TSU9OCiAqIC0gY3JlYXRlKCktPmNvbXBvc2l0ZVR5cGUoKSAtIENSRUFURSBUWVBFIChjb21wb3NpdGUpCiAqIC0gY3JlYXRlKCktPmVudW1UeXBlKCkgLSBDUkVBVEUgVFlQRSAoZW51bSkKICogLSBjcmVhdGUoKS0+cmFuZ2VUeXBlKCkgLSBDUkVBVEUgVFlQRSAocmFuZ2UpCiAqIC0gY3JlYXRlKCktPmRvbWFpbigpIC0gQ1JFQVRFIERPTUFJTgogKgogKiBFeGFtcGxlOiBjcmVhdGUoKS0+dGFibGUoJ3VzZXJzJyktPmNvbHVtbnMoY29sX2RlZignaWQnLCBjb2x1bW5fdHlwZV9zZXJpYWwoKSkpCiAqIEV4YW1wbGU6IGNyZWF0ZSgpLT5pbmRleCgnaWR4X2VtYWlsJyktPm9uKCd1c2VycycpLT5jb2x1bW5zKCdlbWFpbCcpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":247,"slug":"drop","name":"drop","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"DropFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZhY3RvcnkgZm9yIGJ1aWxkaW5nIERST1Agc3RhdGVtZW50cy4KICoKICogUHJvdmlkZXMgYSB1bmlmaWVkIGVudHJ5IHBvaW50IGZvciBhbGwgRFJPUCBvcGVyYXRpb25zOgogKiAtIGRyb3AoKS0+dGFibGUoKSAtIERST1AgVEFCTEUKICogLSBkcm9wKCktPmluZGV4KCkgLSBEUk9QIElOREVYCiAqIC0gZHJvcCgpLT52aWV3KCkgLSBEUk9QIFZJRVcKICogLSBkcm9wKCktPm1hdGVyaWFsaXplZFZpZXcoKSAtIERST1AgTUFURVJJQUxJWkVEIFZJRVcKICogLSBkcm9wKCktPnNlcXVlbmNlKCkgLSBEUk9QIFNFUVVFTkNFCiAqIC0gZHJvcCgpLT5zY2hlbWEoKSAtIERST1AgU0NIRU1BCiAqIC0gZHJvcCgpLT5yb2xlKCkgLSBEUk9QIFJPTEUKICogLSBkcm9wKCktPmZ1bmN0aW9uKCkgLSBEUk9QIEZVTkNUSU9OCiAqIC0gZHJvcCgpLT5wcm9jZWR1cmUoKSAtIERST1AgUFJPQ0VEVVJFCiAqIC0gZHJvcCgpLT50cmlnZ2VyKCkgLSBEUk9QIFRSSUdHRVIKICogLSBkcm9wKCktPnJ1bGUoKSAtIERST1AgUlVMRQogKiAtIGRyb3AoKS0+ZXh0ZW5zaW9uKCkgLSBEUk9QIEVYVEVOU0lPTgogKiAtIGRyb3AoKS0+dHlwZSgpIC0gRFJPUCBUWVBFCiAqIC0gZHJvcCgpLT5kb21haW4oKSAtIERST1AgRE9NQUlOCiAqIC0gZHJvcCgpLT5vd25lZCgpIC0gRFJPUCBPV05FRAogKgogKiBFeGFtcGxlOiBkcm9wKCktPnRhYmxlKCd1c2VycycsICdvcmRlcnMnKS0+aWZFeGlzdHMoKS0+Y2FzY2FkZSgpCiAqIEV4YW1wbGU6IGRyb3AoKS0+aW5kZXgoJ2lkeF9lbWFpbCcpLT5pZkV4aXN0cygpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":281,"slug":"alter","name":"alter","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AlterFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZhY3RvcnkgZm9yIGJ1aWxkaW5nIEFMVEVSIHN0YXRlbWVudHMuCiAqCiAqIFByb3ZpZGVzIGEgdW5pZmllZCBlbnRyeSBwb2ludCBmb3IgYWxsIEFMVEVSIG9wZXJhdGlvbnM6CiAqIC0gYWx0ZXIoKS0+dGFibGUoKSAtIEFMVEVSIFRBQkxFCiAqIC0gYWx0ZXIoKS0+aW5kZXgoKSAtIEFMVEVSIElOREVYCiAqIC0gYWx0ZXIoKS0+dmlldygpIC0gQUxURVIgVklFVwogKiAtIGFsdGVyKCktPm1hdGVyaWFsaXplZFZpZXcoKSAtIEFMVEVSIE1BVEVSSUFMSVpFRCBWSUVXCiAqIC0gYWx0ZXIoKS0+c2VxdWVuY2UoKSAtIEFMVEVSIFNFUVVFTkNFCiAqIC0gYWx0ZXIoKS0+c2NoZW1hKCkgLSBBTFRFUiBTQ0hFTUEKICogLSBhbHRlcigpLT5yb2xlKCkgLSBBTFRFUiBST0xFCiAqIC0gYWx0ZXIoKS0+ZnVuY3Rpb24oKSAtIEFMVEVSIEZVTkNUSU9OCiAqIC0gYWx0ZXIoKS0+cHJvY2VkdXJlKCkgLSBBTFRFUiBQUk9DRURVUkUKICogLSBhbHRlcigpLT50cmlnZ2VyKCkgLSBBTFRFUiBUUklHR0VSCiAqIC0gYWx0ZXIoKS0+ZXh0ZW5zaW9uKCkgLSBBTFRFUiBFWFRFTlNJT04KICogLSBhbHRlcigpLT5lbnVtVHlwZSgpIC0gQUxURVIgVFlQRSAoZW51bSkKICogLSBhbHRlcigpLT5kb21haW4oKSAtIEFMVEVSIERPTUFJTgogKgogKiBSZW5hbWUgb3BlcmF0aW9ucyBhcmUgYWxzbyB1bmRlciBhbHRlcigpOgogKiAtIGFsdGVyKCktPmluZGV4KCdvbGQnKS0+cmVuYW1lVG8oJ25ldycpCiAqIC0gYWx0ZXIoKS0+dmlldygnb2xkJyktPnJlbmFtZVRvKCduZXcnKQogKiAtIGFsdGVyKCktPnNjaGVtYSgnb2xkJyktPnJlbmFtZVRvKCduZXcnKQogKiAtIGFsdGVyKCktPnJvbGUoJ29sZCcpLT5yZW5hbWVUbygnbmV3JykKICogLSBhbHRlcigpLT50cmlnZ2VyKCdvbGQnKS0+b24oJ3RhYmxlJyktPnJlbmFtZVRvKCduZXcnKQogKgogKiBFeGFtcGxlOiBhbHRlcigpLT50YWJsZSgndXNlcnMnKS0+YWRkQ29sdW1uKGNvbF9kZWYoJ2VtYWlsJywgY29sdW1uX3R5cGVfdGV4dCgpKSkKICogRXhhbXBsZTogYWx0ZXIoKS0+c2VxdWVuY2UoJ3VzZXJfaWRfc2VxJyktPnJlc3RhcnQoMTAwMCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":292,"slug":"truncate-table","name":"truncate_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"TruncateFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Truncate","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRSVU5DQVRFIFRBQkxFIGJ1aWxkZXIuCiAqCiAqIEBwYXJhbSBzdHJpbmcgLi4uJHRhYmxlcyBUYWJsZSBuYW1lcyB0byB0cnVuY2F0ZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":310,"slug":"refresh-materialized-view","name":"refresh_materialized_view","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"RefreshMatViewOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\View\\RefreshMaterializedView","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFRlJFU0ggTUFURVJJQUxJWkVEIFZJRVcgYnVpbGRlci4KICoKICogRXhhbXBsZTogcmVmcmVzaF9tYXRlcmlhbGl6ZWRfdmlldygndXNlcl9zdGF0cycpCiAqIFByb2R1Y2VzOiBSRUZSRVNIIE1BVEVSSUFMSVpFRCBWSUVXIHVzZXJfc3RhdHMKICoKICogRXhhbXBsZTogcmVmcmVzaF9tYXRlcmlhbGl6ZWRfdmlldygndXNlcl9zdGF0cycpLT5jb25jdXJyZW50bHkoKS0+d2l0aERhdGEoKQogKiBQcm9kdWNlczogUkVGUkVTSCBNQVRFUklBTElaRUQgVklFVyBDT05DVVJSRU5UTFkgdXNlcl9zdGF0cyBXSVRIIERBVEEKICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBWaWV3IG5hbWUgKG1heSBpbmNsdWRlIHNjaGVtYSBhcyAic2NoZW1hLnZpZXciKQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNjaGVtYSBTY2hlbWEgbmFtZSAob3B0aW9uYWwsIG92ZXJyaWRlcyBwYXJzZWQgc2NoZW1hKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":319,"slug":"ref-action-cascade","name":"ref_action_cascade","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIENBU0NBREUgcmVmZXJlbnRpYWwgYWN0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":328,"slug":"ref-action-restrict","name":"ref_action_restrict","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIFJFU1RSSUNUIHJlZmVyZW50aWFsIGFjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":337,"slug":"ref-action-set-null","name":"ref_action_set_null","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIFNFVCBOVUxMIHJlZmVyZW50aWFsIGFjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":346,"slug":"ref-action-set-default","name":"ref_action_set_default","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIFNFVCBERUZBVUxUIHJlZmVyZW50aWFsIGFjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":355,"slug":"ref-action-no-action","name":"ref_action_no_action","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIE5PIEFDVElPTiByZWZlcmVudGlhbCBhY3Rpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":370,"slug":"reindex-index","name":"reindex_index","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBJTkRFWCBzdGF0ZW1lbnQuCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5jb25jdXJyZW50bHkoKSwgLT52ZXJib3NlKCksIC0+dGFibGVzcGFjZSgpCiAqCiAqIEV4YW1wbGU6IHJlaW5kZXhfaW5kZXgoJ2lkeF91c2Vyc19lbWFpbCcpLT5jb25jdXJyZW50bHkoKQogKgogKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBpbmRleCBuYW1lIChtYXkgaW5jbHVkZSBzY2hlbWE6IHNjaGVtYS5pbmRleCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":385,"slug":"reindex-table","name":"reindex_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBUQUJMRSBzdGF0ZW1lbnQuCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5jb25jdXJyZW50bHkoKSwgLT52ZXJib3NlKCksIC0+dGFibGVzcGFjZSgpCiAqCiAqIEV4YW1wbGU6IHJlaW5kZXhfdGFibGUoJ3VzZXJzJyktPmNvbmN1cnJlbnRseSgpCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHRhYmxlIG5hbWUgKG1heSBpbmNsdWRlIHNjaGVtYTogc2NoZW1hLnRhYmxlKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":400,"slug":"reindex-schema","name":"reindex_schema","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBTQ0hFTUEgc3RhdGVtZW50LgogKgogKiBVc2UgY2hhaW5hYmxlIG1ldGhvZHM6IC0+Y29uY3VycmVudGx5KCksIC0+dmVyYm9zZSgpLCAtPnRhYmxlc3BhY2UoKQogKgogKiBFeGFtcGxlOiByZWluZGV4X3NjaGVtYSgncHVibGljJyktPmNvbmN1cnJlbnRseSgpCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHNjaGVtYSBuYW1lCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":415,"slug":"reindex-database","name":"reindex_database","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBEQVRBQkFTRSBzdGF0ZW1lbnQuCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5jb25jdXJyZW50bHkoKSwgLT52ZXJib3NlKCksIC0+dGFibGVzcGFjZSgpCiAqCiAqIEV4YW1wbGU6IHJlaW5kZXhfZGF0YWJhc2UoJ215ZGInKS0+Y29uY3VycmVudGx5KCkKICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgZGF0YWJhc2UgbmFtZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":430,"slug":"index-col","name":"index_col","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"IndexColumn","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbmRleCBjb2x1bW4gc3BlY2lmaWNhdGlvbi4KICoKICogVXNlIGNoYWluYWJsZSBtZXRob2RzOiAtPmFzYygpLCAtPmRlc2MoKSwgLT5udWxsc0ZpcnN0KCksIC0+bnVsbHNMYXN0KCksIC0+b3BjbGFzcygpLCAtPmNvbGxhdGUoKQogKgogKiBFeGFtcGxlOiBpbmRleF9jb2woJ2VtYWlsJyktPmRlc2MoKS0+bnVsbHNMYXN0KCkKICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgY29sdW1uIG5hbWUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":445,"slug":"index-expr","name":"index_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expression","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"IndexColumn","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbmRleCBjb2x1bW4gc3BlY2lmaWNhdGlvbiBmcm9tIGFuIGV4cHJlc3Npb24uCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5hc2MoKSwgLT5kZXNjKCksIC0+bnVsbHNGaXJzdCgpLCAtPm51bGxzTGFzdCgpLCAtPm9wY2xhc3MoKSwgLT5jb2xsYXRlKCkKICoKICogRXhhbXBsZTogaW5kZXhfZXhwcihmbl9jYWxsKCdsb3dlcicsIGNvbCgnZW1haWwnKSkpLT5kZXNjKCkKICoKICogQHBhcmFtIEV4cHJlc3Npb24gJGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gaW5kZXgKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":454,"slug":"index-method-btree","name":"index_method_btree","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgQlRSRUUgaW5kZXggbWV0aG9kLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":463,"slug":"index-method-hash","name":"index_method_hash","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgSEFTSCBpbmRleCBtZXRob2QuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":472,"slug":"index-method-gist","name":"index_method_gist","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgR0lTVCBpbmRleCBtZXRob2QuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":481,"slug":"index-method-spgist","name":"index_method_spgist","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgU1BHSVNUIGluZGV4IG1ldGhvZC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":490,"slug":"index-method-gin","name":"index_method_gin","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgR0lOIGluZGV4IG1ldGhvZC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":499,"slug":"index-method-brin","name":"index_method_brin","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgQlJJTiBpbmRleCBtZXRob2QuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":511,"slug":"vacuum","name":"vacuum","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"VacuumFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZBQ1VVTSBidWlsZGVyLgogKgogKiBFeGFtcGxlOiB2YWN1dW0oKS0+dGFibGUoJ3VzZXJzJykKICogUHJvZHVjZXM6IFZBQ1VVTSB1c2VycwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":523,"slug":"analyze","name":"analyze","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AnalyzeFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBTkFMWVpFIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IGFuYWx5emUoKS0+dGFibGUoJ3VzZXJzJykKICogUHJvZHVjZXM6IEFOQUxZWkUgdXNlcnMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":537,"slug":"explain","name":"explain","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false},{"name":"InsertBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Insert","is_nullable":false,"is_variadic":false},{"name":"UpdateBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Update","is_nullable":false,"is_variadic":false},{"name":"DeleteBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Delete","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExplainFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFWFBMQUlOIGJ1aWxkZXIgZm9yIGEgcXVlcnkuCiAqCiAqIEV4YW1wbGU6IGV4cGxhaW4oc2VsZWN0KCktPmZyb20oJ3VzZXJzJykpCiAqIFByb2R1Y2VzOiBFWFBMQUlOIFNFTEVDVCAqIEZST00gdXNlcnMKICoKICogQHBhcmFtIERlbGV0ZUJ1aWxkZXJ8SW5zZXJ0QnVpbGRlcnxTZWxlY3RGaW5hbFN0ZXB8VXBkYXRlQnVpbGRlciAkcXVlcnkgUXVlcnkgdG8gZXhwbGFpbgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":549,"slug":"lock-table","name":"lock_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"LockFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExPQ0sgVEFCTEUgYnVpbGRlci4KICoKICogRXhhbXBsZTogbG9ja190YWJsZSgndXNlcnMnLCAnb3JkZXJzJyktPmFjY2Vzc0V4Y2x1c2l2ZSgpCiAqIFByb2R1Y2VzOiBMT0NLIFRBQkxFIHVzZXJzLCBvcmRlcnMgSU4gQUNDRVNTIEVYQ0xVU0lWRSBNT0RFCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":564,"slug":"comment","name":"comment","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"target","type":[{"name":"CommentTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CommentFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPTU1FTlQgT04gYnVpbGRlci4KICoKICogRXhhbXBsZTogY29tbWVudChDb21tZW50VGFyZ2V0OjpUQUJMRSwgJ3VzZXJzJyktPmlzKCdVc2VyIGFjY291bnRzIHRhYmxlJykKICogUHJvZHVjZXM6IENPTU1FTlQgT04gVEFCTEUgdXNlcnMgSVMgJ1VzZXIgYWNjb3VudHMgdGFibGUnCiAqCiAqIEBwYXJhbSBDb21tZW50VGFyZ2V0ICR0YXJnZXQgVGFyZ2V0IHR5cGUgKFRBQkxFLCBDT0xVTU4sIElOREVYLCBldGMuKQogKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRhcmdldCBuYW1lICh1c2UgJ3RhYmxlLmNvbHVtbicgZm9yIENPTFVNTiB0YXJnZXRzKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":576,"slug":"cluster","name":"cluster","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ClusterFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENMVVNURVIgYnVpbGRlci4KICoKICogRXhhbXBsZTogY2x1c3RlcigpLT50YWJsZSgndXNlcnMnKS0+dXNpbmcoJ2lkeF91c2Vyc19wa2V5JykKICogUHJvZHVjZXM6IENMVVNURVIgdXNlcnMgVVNJTkcgaWR4X3VzZXJzX3BrZXkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":590,"slug":"discard","name":"discard","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"type","type":[{"name":"DiscardType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DiscardFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERJU0NBUkQgYnVpbGRlci4KICoKICogRXhhbXBsZTogZGlzY2FyZChEaXNjYXJkVHlwZTo6QUxMKQogKiBQcm9kdWNlczogRElTQ0FSRCBBTEwKICoKICogQHBhcmFtIERpc2NhcmRUeXBlICR0eXBlIFR5cGUgb2YgcmVzb3VyY2VzIHRvIGRpc2NhcmQgKEFMTCwgUExBTlMsIFNFUVVFTkNFUywgVEVNUCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":609,"slug":"grant","name":"grant","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"privileges","type":[{"name":"TablePrivilege","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"GrantOnStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdSQU5UIHByaXZpbGVnZXMgYnVpbGRlci4KICoKICogRXhhbXBsZTogZ3JhbnQoVGFibGVQcml2aWxlZ2U6OlNFTEVDVCktPm9uVGFibGUoJ3VzZXJzJyktPnRvKCdhcHBfdXNlcicpCiAqIFByb2R1Y2VzOiBHUkFOVCBTRUxFQ1QgT04gdXNlcnMgVE8gYXBwX3VzZXIKICoKICogRXhhbXBsZTogZ3JhbnQoVGFibGVQcml2aWxlZ2U6OkFMTCktPm9uQWxsVGFibGVzSW5TY2hlbWEoJ3B1YmxpYycpLT50bygnYWRtaW4nKQogKiBQcm9kdWNlczogR1JBTlQgQUxMIE9OIEFMTCBUQUJMRVMgSU4gU0NIRU1BIHB1YmxpYyBUTyBhZG1pbgogKgogKiBAcGFyYW0gc3RyaW5nfFRhYmxlUHJpdmlsZWdlIC4uLiRwcml2aWxlZ2VzIFRoZSBwcml2aWxlZ2VzIHRvIGdyYW50CiAqCiAqIEByZXR1cm4gR3JhbnRPblN0ZXAgQnVpbGRlciBmb3IgZ3JhbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":628,"slug":"grant-role","name":"grant_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"GrantRoleToStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdSQU5UIHJvbGUgYnVpbGRlci4KICoKICogRXhhbXBsZTogZ3JhbnRfcm9sZSgnYWRtaW4nKS0+dG8oJ3VzZXIxJykKICogUHJvZHVjZXM6IEdSQU5UIGFkbWluIFRPIHVzZXIxCiAqCiAqIEV4YW1wbGU6IGdyYW50X3JvbGUoJ2FkbWluJywgJ2RldmVsb3BlcicpLT50bygndXNlcjEnKS0+d2l0aEFkbWluT3B0aW9uKCkKICogUHJvZHVjZXM6IEdSQU5UIGFkbWluLCBkZXZlbG9wZXIgVE8gdXNlcjEgV0lUSCBBRE1JTiBPUFRJT04KICoKICogQHBhcmFtIHN0cmluZyAuLi4kcm9sZXMgVGhlIHJvbGVzIHRvIGdyYW50CiAqCiAqIEByZXR1cm4gR3JhbnRSb2xlVG9TdGVwIEJ1aWxkZXIgZm9yIGdyYW50IHJvbGUgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":647,"slug":"revoke","name":"revoke","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"privileges","type":[{"name":"TablePrivilege","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"RevokeOnStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVk9LRSBwcml2aWxlZ2VzIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJldm9rZShUYWJsZVByaXZpbGVnZTo6U0VMRUNUKS0+b25UYWJsZSgndXNlcnMnKS0+ZnJvbSgnYXBwX3VzZXInKQogKiBQcm9kdWNlczogUkVWT0tFIFNFTEVDVCBPTiB1c2VycyBGUk9NIGFwcF91c2VyCiAqCiAqIEV4YW1wbGU6IHJldm9rZShUYWJsZVByaXZpbGVnZTo6QUxMKS0+b25UYWJsZSgndXNlcnMnKS0+ZnJvbSgnYXBwX3VzZXInKS0+Y2FzY2FkZSgpCiAqIFByb2R1Y2VzOiBSRVZPS0UgQUxMIE9OIHVzZXJzIEZST00gYXBwX3VzZXIgQ0FTQ0FERQogKgogKiBAcGFyYW0gc3RyaW5nfFRhYmxlUHJpdmlsZWdlIC4uLiRwcml2aWxlZ2VzIFRoZSBwcml2aWxlZ2VzIHRvIHJldm9rZQogKgogKiBAcmV0dXJuIFJldm9rZU9uU3RlcCBCdWlsZGVyIGZvciByZXZva2Ugb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":666,"slug":"revoke-role","name":"revoke_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"RevokeRoleFromStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVk9LRSByb2xlIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJldm9rZV9yb2xlKCdhZG1pbicpLT5mcm9tKCd1c2VyMScpCiAqIFByb2R1Y2VzOiBSRVZPS0UgYWRtaW4gRlJPTSB1c2VyMQogKgogKiBFeGFtcGxlOiByZXZva2Vfcm9sZSgnYWRtaW4nKS0+ZnJvbSgndXNlcjEnKS0+Y2FzY2FkZSgpCiAqIFByb2R1Y2VzOiBSRVZPS0UgYWRtaW4gRlJPTSB1c2VyMSBDQVNDQURFCiAqCiAqIEBwYXJhbSBzdHJpbmcgLi4uJHJvbGVzIFRoZSByb2xlcyB0byByZXZva2UKICoKICogQHJldHVybiBSZXZva2VSb2xlRnJvbVN0ZXAgQnVpbGRlciBmb3IgcmV2b2tlIHJvbGUgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":682,"slug":"set-role","name":"set_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"role","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SetRoleFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Session","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBST0xFIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHNldF9yb2xlKCdhZG1pbicpCiAqIFByb2R1Y2VzOiBTRVQgUk9MRSBhZG1pbgogKgogKiBAcGFyYW0gc3RyaW5nICRyb2xlIFRoZSByb2xlIHRvIHNldAogKgogKiBAcmV0dXJuIFNldFJvbGVGaW5hbFN0ZXAgQnVpbGRlciBmb3Igc2V0IHJvbGUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":696,"slug":"reset-role","name":"reset_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ResetRoleFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Session","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFU0VUIFJPTEUgYnVpbGRlci4KICoKICogRXhhbXBsZTogcmVzZXRfcm9sZSgpCiAqIFByb2R1Y2VzOiBSRVNFVCBST0xFCiAqCiAqIEByZXR1cm4gUmVzZXRSb2xlRmluYWxTdGVwIEJ1aWxkZXIgZm9yIHJlc2V0IHJvbGUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":712,"slug":"reassign-owned","name":"reassign_owned","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ReassignOwnedToStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Ownership","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFQVNTSUdOIE9XTkVEIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJlYXNzaWduX293bmVkKCdvbGRfcm9sZScpLT50bygnbmV3X3JvbGUnKQogKiBQcm9kdWNlczogUkVBU1NJR04gT1dORUQgQlkgb2xkX3JvbGUgVE8gbmV3X3JvbGUKICoKICogQHBhcmFtIHN0cmluZyAuLi4kcm9sZXMgVGhlIHJvbGVzIHdob3NlIG93bmVkIG9iamVjdHMgc2hvdWxkIGJlIHJlYXNzaWduZWQKICoKICogQHJldHVybiBSZWFzc2lnbk93bmVkVG9TdGVwIEJ1aWxkZXIgZm9yIHJlYXNzaWduIG93bmVkIG9wdGlvbnMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":731,"slug":"drop-owned","name":"drop_owned","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"DropOwnedFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Ownership","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERST1AgT1dORUQgYnVpbGRlci4KICoKICogRXhhbXBsZTogZHJvcF9vd25lZCgncm9sZTEnKQogKiBQcm9kdWNlczogRFJPUCBPV05FRCBCWSByb2xlMQogKgogKiBFeGFtcGxlOiBkcm9wX293bmVkKCdyb2xlMScsICdyb2xlMicpLT5jYXNjYWRlKCkKICogUHJvZHVjZXM6IERST1AgT1dORUQgQlkgcm9sZTEsIHJvbGUyIENBU0NBREUKICoKICogQHBhcmFtIHN0cmluZyAuLi4kcm9sZXMgVGhlIHJvbGVzIHdob3NlIG93bmVkIG9iamVjdHMgc2hvdWxkIGJlIGRyb3BwZWQKICoKICogQHJldHVybiBEcm9wT3duZWRGaW5hbFN0ZXAgQnVpbGRlciBmb3IgZHJvcCBvd25lZCBvcHRpb25zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":749,"slug":"func-arg","name":"func_arg","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FunctionArgument","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSBuZXcgZnVuY3Rpb24gYXJndW1lbnQgZm9yIHVzZSBpbiBmdW5jdGlvbi9wcm9jZWR1cmUgZGVmaW5pdGlvbnMuCiAqCiAqIEV4YW1wbGU6IGZ1bmNfYXJnKGNvbHVtbl90eXBlX2ludGVnZXIoKSkKICogRXhhbXBsZTogZnVuY19hcmcoY29sdW1uX3R5cGVfdGV4dCgpKS0+bmFtZWQoJ3VzZXJuYW1lJykKICogRXhhbXBsZTogZnVuY19hcmcoY29sdW1uX3R5cGVfaW50ZWdlcigpKS0+bmFtZWQoJ2NvdW50JyktPmRlZmF1bHQoJzAnKQogKiBFeGFtcGxlOiBmdW5jX2FyZyhjb2x1bW5fdHlwZV90ZXh0KCkpLT5vdXQoKQogKgogKiBAcGFyYW0gQ29sdW1uVHlwZSAkdHlwZSBUaGUgUG9zdGdyZVNRTCBkYXRhIHR5cGUgZm9yIHRoZSBhcmd1bWVudAogKgogKiBAcmV0dXJuIEZ1bmN0aW9uQXJndW1lbnQgQnVpbGRlciBmb3IgZnVuY3Rpb24gYXJndW1lbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":768,"slug":"call","name":"call","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"procedure","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CallFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSBDQUxMIHN0YXRlbWVudCBidWlsZGVyIGZvciBpbnZva2luZyBhIHByb2NlZHVyZS4KICoKICogRXhhbXBsZTogY2FsbCgndXBkYXRlX3N0YXRzJyktPndpdGgoMTIzKQogKiBQcm9kdWNlczogQ0FMTCB1cGRhdGVfc3RhdHMoMTIzKQogKgogKiBFeGFtcGxlOiBjYWxsKCdwcm9jZXNzX2RhdGEnKS0+d2l0aCgndGVzdCcsIDQyLCB0cnVlKQogKiBQcm9kdWNlczogQ0FMTCBwcm9jZXNzX2RhdGEoJ3Rlc3QnLCA0MiwgdHJ1ZSkKICoKICogQHBhcmFtIHN0cmluZyAkcHJvY2VkdXJlIFRoZSBuYW1lIG9mIHRoZSBwcm9jZWR1cmUgdG8gY2FsbAogKgogKiBAcmV0dXJuIENhbGxGaW5hbFN0ZXAgQnVpbGRlciBmb3IgY2FsbCBzdGF0ZW1lbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":787,"slug":"do-block","name":"do_block","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"code","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DoFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSBETyBzdGF0ZW1lbnQgYnVpbGRlciBmb3IgZXhlY3V0aW5nIGFuIGFub255bW91cyBjb2RlIGJsb2NrLgogKgogKiBFeGFtcGxlOiBkb19ibG9jaygnQkVHSU4gUkFJU0UgTk9USUNFICQkSGVsbG8gV29ybGQkJDsgRU5EOycpCiAqIFByb2R1Y2VzOiBETyAkJCBCRUdJTiBSQUlTRSBOT1RJQ0UgJCRIZWxsbyBXb3JsZCQkOyBFTkQ7ICQkIExBTkdVQUdFIHBscGdzcWwKICoKICogRXhhbXBsZTogZG9fYmxvY2soJ1NFTEVDVCAxJyktPmxhbmd1YWdlKCdzcWwnKQogKiBQcm9kdWNlczogRE8gJCQgU0VMRUNUIDEgJCQgTEFOR1VBR0Ugc3FsCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNvZGUgVGhlIGFub255bW91cyBjb2RlIGJsb2NrIHRvIGV4ZWN1dGUKICoKICogQHJldHVybiBEb0ZpbmFsU3RlcCBCdWlsZGVyIGZvciBETyBzdGF0ZW1lbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":807,"slug":"type-attr","name":"type_attr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TypeAttribute","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Type","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSB0eXBlIGF0dHJpYnV0ZSBmb3IgY29tcG9zaXRlIHR5cGVzLgogKgogKiBFeGFtcGxlOiB0eXBlX2F0dHIoJ25hbWUnLCBjb2x1bW5fdHlwZV90ZXh0KCkpCiAqIFByb2R1Y2VzOiBuYW1lIHRleHQKICoKICogRXhhbXBsZTogdHlwZV9hdHRyKCdkZXNjcmlwdGlvbicsIGNvbHVtbl90eXBlX3RleHQoKSktPmNvbGxhdGUoJ2VuX1VTJykKICogUHJvZHVjZXM6IGRlc2NyaXB0aW9uIHRleHQgQ09MTEFURSAiZW5fVVMiCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lCiAqIEBwYXJhbSBDb2x1bW5UeXBlICR0eXBlIFRoZSBhdHRyaWJ1dGUgdHlwZQogKgogKiBAcmV0dXJuIFR5cGVBdHRyaWJ1dGUgVHlwZSBhdHRyaWJ1dGUgdmFsdWUgb2JqZWN0CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":816,"slug":"column-type-integer","name":"column_type_integer","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbnRlZ2VyIGRhdGEgdHlwZSAoUG9zdGdyZVNRTCBpbnQ0KS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":825,"slug":"column-type-smallint","name":"column_type_smallint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNtYWxsaW50IGRhdGEgdHlwZSAoUG9zdGdyZVNRTCBpbnQyKS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":834,"slug":"column-type-bigint","name":"column_type_bigint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJpZ2ludCBkYXRhIHR5cGUgKFBvc3RncmVTUUwgaW50OCkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":843,"slug":"column-type-boolean","name":"column_type_boolean","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJvb2xlYW4gZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":852,"slug":"column-type-text","name":"column_type_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRleHQgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":861,"slug":"column-type-varchar","name":"column_type_varchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHZhcmNoYXIgZGF0YSB0eXBlIHdpdGggbGVuZ3RoIGNvbnN0cmFpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":870,"slug":"column-type-char","name":"column_type_char","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNoYXIgZGF0YSB0eXBlIHdpdGggbGVuZ3RoIGNvbnN0cmFpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":879,"slug":"column-type-numeric","name":"column_type_numeric","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG51bWVyaWMgZGF0YSB0eXBlIHdpdGggb3B0aW9uYWwgcHJlY2lzaW9uIGFuZCBzY2FsZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":888,"slug":"column-type-decimal","name":"column_type_decimal","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRlY2ltYWwgZGF0YSB0eXBlIHdpdGggb3B0aW9uYWwgcHJlY2lzaW9uIGFuZCBzY2FsZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":897,"slug":"column-type-real","name":"column_type_real","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJlYWwgZGF0YSB0eXBlIChQb3N0Z3JlU1FMIGZsb2F0NCkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":906,"slug":"column-type-double-precision","name":"column_type_double_precision","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRvdWJsZSBwcmVjaXNpb24gZGF0YSB0eXBlIChQb3N0Z3JlU1FMIGZsb2F0OCkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":915,"slug":"column-type-date","name":"column_type_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRhdGUgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":924,"slug":"column-type-time","name":"column_type_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRpbWUgZGF0YSB0eXBlIHdpdGggb3B0aW9uYWwgcHJlY2lzaW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":933,"slug":"column-type-timestamp","name":"column_type_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRpbWVzdGFtcCBkYXRhIHR5cGUgd2l0aCBvcHRpb25hbCBwcmVjaXNpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":942,"slug":"column-type-timestamptz","name":"column_type_timestamptz","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRpbWVzdGFtcCB3aXRoIHRpbWUgem9uZSBkYXRhIHR5cGUgd2l0aCBvcHRpb25hbCBwcmVjaXNpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":951,"slug":"column-type-interval","name":"column_type_interval","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbnRlcnZhbCBkYXRhIHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":960,"slug":"column-type-uuid","name":"column_type_uuid","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFVVSUQgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":969,"slug":"column-type-json","name":"column_type_json","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":978,"slug":"column-type-jsonb","name":"column_type_jsonb","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":987,"slug":"column-type-bytea","name":"column_type_bytea","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJ5dGVhIGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":996,"slug":"column-type-xml","name":"column_type_xml","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBYTUwgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1005,"slug":"column-type-inet","name":"column_type_inet","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbmV0IGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1014,"slug":"column-type-cidr","name":"column_type_cidr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNpZHIgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1023,"slug":"column-type-macaddr","name":"column_type_macaddr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG1hY2FkZHIgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1032,"slug":"column-type-serial","name":"column_type_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNlcmlhbCBkYXRhIHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1041,"slug":"column-type-smallserial","name":"column_type_smallserial","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNtYWxsc2VyaWFsIGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1050,"slug":"column-type-bigserial","name":"column_type_bigserial","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJpZ3NlcmlhbCBkYXRhIHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1059,"slug":"column-type-array","name":"column_type_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"elementType","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBkYXRhIHR5cGUgZnJvbSBhbiBlbGVtZW50IHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1071,"slug":"column-type-custom","name":"column_type_custom","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"typeName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGN1c3RvbSBkYXRhIHR5cGUuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHR5cGVOYW1lIFR5cGUgbmFtZQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNjaGVtYSBPcHRpb25hbCBzY2hlbWEgbmFtZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1084,"slug":"column-type-from-string","name":"column_type_from_string","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"typeName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhcnNlIGEgUG9zdGdyZVNRTCB0eXBlIHN0cmluZyBpbnRvIGEgQ29sdW1uVHlwZS4KICoKICogSGFuZGxlcyBhbGwgUG9zdGdyZVNRTCB0eXBlIHN5bnRheCBpbmNsdWRpbmcgcHJlY2lzaW9uLCBhcnJheXMsIGFuZCBzY2hlbWEtcXVhbGlmaWVkIHR5cGVzLgogKgogKiBAcGFyYW0gc3RyaW5nICR0eXBlTmFtZSBQb3N0Z3JlU1FMIHR5cGUgc3RyaW5nIChlLmcuLCAnaW50ZWdlcicsICdjaGFyYWN0ZXIgdmFyeWluZygyNTUpJywgJ3RleHRbXScpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1092,"slug":"value-type-text","name":"value_type_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1098,"slug":"value-type-varchar","name":"value_type_varchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1104,"slug":"value-type-char","name":"value_type_char","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1110,"slug":"value-type-bpchar","name":"value_type_bpchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1116,"slug":"value-type-int2","name":"value_type_int2","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1122,"slug":"value-type-smallint","name":"value_type_smallint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1128,"slug":"value-type-int4","name":"value_type_int4","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1134,"slug":"value-type-integer","name":"value_type_integer","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1140,"slug":"value-type-int8","name":"value_type_int8","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1146,"slug":"value-type-bigint","name":"value_type_bigint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1152,"slug":"value-type-float4","name":"value_type_float4","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1158,"slug":"value-type-real","name":"value_type_real","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1164,"slug":"value-type-float8","name":"value_type_float8","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1170,"slug":"value-type-double","name":"value_type_double","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1176,"slug":"value-type-numeric","name":"value_type_numeric","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1182,"slug":"value-type-money","name":"value_type_money","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1188,"slug":"value-type-bool","name":"value_type_bool","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1194,"slug":"value-type-boolean","name":"value_type_boolean","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1200,"slug":"value-type-bytea","name":"value_type_bytea","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1206,"slug":"value-type-bit","name":"value_type_bit","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1212,"slug":"value-type-varbit","name":"value_type_varbit","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1218,"slug":"value-type-date","name":"value_type_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1224,"slug":"value-type-time","name":"value_type_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1230,"slug":"value-type-timetz","name":"value_type_timetz","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1236,"slug":"value-type-timestamp","name":"value_type_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1242,"slug":"value-type-timestamptz","name":"value_type_timestamptz","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1248,"slug":"value-type-interval","name":"value_type_interval","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1254,"slug":"value-type-json","name":"value_type_json","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1260,"slug":"value-type-jsonb","name":"value_type_jsonb","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1266,"slug":"value-type-uuid","name":"value_type_uuid","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1272,"slug":"value-type-inet","name":"value_type_inet","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1278,"slug":"value-type-cidr","name":"value_type_cidr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1284,"slug":"value-type-macaddr","name":"value_type_macaddr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1290,"slug":"value-type-macaddr8","name":"value_type_macaddr8","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1296,"slug":"value-type-xml","name":"value_type_xml","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1302,"slug":"value-type-oid","name":"value_type_oid","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1308,"slug":"value-type-text-array","name":"value_type_text_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1314,"slug":"value-type-varchar-array","name":"value_type_varchar_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1320,"slug":"value-type-int2-array","name":"value_type_int2_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1326,"slug":"value-type-int4-array","name":"value_type_int4_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1332,"slug":"value-type-int8-array","name":"value_type_int8_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1338,"slug":"value-type-float4-array","name":"value_type_float4_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1344,"slug":"value-type-float8-array","name":"value_type_float8_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1350,"slug":"value-type-bool-array","name":"value_type_bool_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1356,"slug":"value-type-uuid-array","name":"value_type_uuid_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1362,"slug":"value-type-json-array","name":"value_type_json_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1368,"slug":"value-type-jsonb-array","name":"value_type_jsonb_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1384,"slug":"schema","name":"schema","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"sequences","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"views","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"materializedViews","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"functions","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"procedures","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"domains","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"extensions","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Schema","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVRhYmxlPiAkdGFibGVzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVNlcXVlbmNlPiAkc2VxdWVuY2VzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVZpZXc+ICR2aWV3cwogKiBAcGFyYW0gbGlzdDxTY2hlbWFNYXRlcmlhbGl6ZWRWaWV3PiAkbWF0ZXJpYWxpemVkVmlld3MKICogQHBhcmFtIGxpc3Q8U2NoZW1hRnVuY3Rpb24+ICRmdW5jdGlvbnMKICogQHBhcmFtIGxpc3Q8U2NoZW1hUHJvY2VkdXJlPiAkcHJvY2VkdXJlcwogKiBAcGFyYW0gbGlzdDxTY2hlbWFEb21haW4+ICRkb21haW5zCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUV4dGVuc2lvbj4gJGV4dGVuc2lvbnMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1420,"slug":"schema-table","name":"schema_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"primaryKey","type":[{"name":"PrimaryKey","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"indexes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"foreignKeys","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"uniqueConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"checkConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"excludeConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"triggers","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'public'"},{"name":"unlogged","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"partitionStrategy","type":[{"name":"PartitionStrategy","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"partitionColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"inherits","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"tablespace","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Table","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxTY2hlbWFDb2x1bW4+ICRjb2x1bW5zCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUluZGV4PiAkaW5kZXhlcwogKiBAcGFyYW0gbGlzdDxTY2hlbWFGb3JlaWduS2V5PiAkZm9yZWlnbktleXMKICogQHBhcmFtIGxpc3Q8U2NoZW1hVW5pcXVlQ29uc3RyYWludD4gJHVuaXF1ZUNvbnN0cmFpbnRzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUNoZWNrQ29uc3RyYWludD4gJGNoZWNrQ29uc3RyYWludHMKICogQHBhcmFtIGxpc3Q8U2NoZW1hRXhjbHVkZUNvbnN0cmFpbnQ+ICRleGNsdWRlQ29uc3RyYWludHMKICogQHBhcmFtIGxpc3Q8U2NoZW1hVHJpZ2dlcj4gJHRyaWdnZXJzCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHBhcnRpdGlvbkNvbHVtbnMKICogQHBhcmFtIGxpc3Q8c3RyaW5nPiAkaW5oZXJpdHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1465,"slug":"schema-table-options","name":"schema_table_options","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"foreignKeys","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"checkConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"excludeConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"triggers","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"unlogged","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"partitionStrategy","type":[{"name":"PartitionStrategy","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"partitionColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"inherits","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"tablespace","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TableOptions","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUZvcmVpZ25LZXk+ICRmb3JlaWduS2V5cwogKiBAcGFyYW0gbGlzdDxTY2hlbWFDaGVja0NvbnN0cmFpbnQ+ICRjaGVja0NvbnN0cmFpbnRzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUV4Y2x1ZGVDb25zdHJhaW50PiAkZXhjbHVkZUNvbnN0cmFpbnRzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVRyaWdnZXI+ICR0cmlnZ2VycwogKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRwYXJ0aXRpb25Db2x1bW5zCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGluaGVyaXRzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1490,"slug":"schema-column","name":"schema_column","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"isIdentity","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"identityGeneration","type":[{"name":"IdentityGeneration","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"isGenerated","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"generationExpression","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"ordinalPosition","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1515,"slug":"schema-column-integer","name":"schema_column_integer","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1524,"slug":"schema-column-smallint","name":"schema_column_smallint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1533,"slug":"schema-column-bigint","name":"schema_column_bigint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1542,"slug":"schema-column-serial","name":"schema_column_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1548,"slug":"schema-column-small-serial","name":"schema_column_small_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1554,"slug":"schema-column-big-serial","name":"schema_column_big_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1560,"slug":"schema-column-boolean","name":"schema_column_boolean","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1569,"slug":"schema-column-text","name":"schema_column_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1578,"slug":"schema-column-varchar","name":"schema_column_varchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1588,"slug":"schema-column-char","name":"schema_column_char","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1598,"slug":"schema-column-numeric","name":"schema_column_numeric","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1609,"slug":"schema-column-real","name":"schema_column_real","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1618,"slug":"schema-column-double-precision","name":"schema_column_double_precision","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1627,"slug":"schema-column-date","name":"schema_column_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1636,"slug":"schema-column-time","name":"schema_column_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1646,"slug":"schema-column-timestamp","name":"schema_column_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1656,"slug":"schema-column-timestamp-tz","name":"schema_column_timestamp_tz","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1666,"slug":"schema-column-interval","name":"schema_column_interval","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1675,"slug":"schema-column-uuid","name":"schema_column_uuid","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1684,"slug":"schema-column-json","name":"schema_column_json","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1693,"slug":"schema-column-jsonb","name":"schema_column_jsonb","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1702,"slug":"schema-column-bytea","name":"schema_column_bytea","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1711,"slug":"schema-column-inet","name":"schema_column_inet","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1720,"slug":"schema-column-cidr","name":"schema_column_cidr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1729,"slug":"schema-column-macaddr","name":"schema_column_macaddr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1741,"slug":"schema-primary-key","name":"schema_primary_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"PrimaryKey","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1751,"slug":"schema-foreign-key","name":"schema_foreign_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceTable","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"referenceSchema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'public'"},{"name":"onUpdate","type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Schema\\ReferentialAction::..."},{"name":"onDelete","type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Schema\\ReferentialAction::..."},{"name":"deferrable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"initiallyDeferred","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"ForeignKey","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRyZWZlcmVuY2VDb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1779,"slug":"schema-unique","name":"schema_unique","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullsNotDistinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"UniqueConstraint","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1785,"slug":"schema-check","name":"schema_check","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expression","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"noInherit","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CheckConstraint","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1791,"slug":"schema-exclude","name":"schema_exclude","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ExcludeConstraint","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1800,"slug":"schema-index","name":"schema_index","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"unique","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"method","type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\Schema\\IndexMethod::..."},{"name":"primary","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"predicate","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Index","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1812,"slug":"schema-sequence","name":"schema_sequence","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"dataType","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'bigint'"},{"name":"startValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"minValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"maxValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"incrementBy","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"cycle","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"cacheValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"ownedByTable","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"ownedByColumn","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Sequence","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1839,"slug":"schema-view","name":"schema_view","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"isUpdatable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"View","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1848,"slug":"schema-materialized-view","name":"schema_materialized_view","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"indexes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"MaterializedView","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUluZGV4PiAkaW5kZXhlcwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1857,"slug":"schema-function","name":"schema_function","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"returnType","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"argumentTypes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"language","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'sql'"},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"isStrict","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"volatility","type":[{"name":"FunctionVolatility","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Func","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGFyZ3VtZW50VHlwZXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1873,"slug":"schema-procedure","name":"schema_procedure","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"argumentTypes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"language","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'sql'"},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Procedure","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGFyZ3VtZW50VHlwZXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1886,"slug":"schema-trigger","name":"schema_trigger","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tableName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"timing","type":[{"name":"TriggerTiming","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"events","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"functionName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"forEachRow","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"whenCondition","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Trigger","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxUcmlnZ2VyRXZlbnQ+ICRldmVudHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1902,"slug":"schema-domain","name":"schema_domain","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"baseType","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"checkConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Domain","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUNoZWNrQ29uc3RyYWludD4gJGNoZWNrQ29uc3RyYWludHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1913,"slug":"schema-extension","name":"schema_extension","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"version","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Extension","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1922,"slug":"client-catalog-provider","name":"client_catalog_provider","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"client","type":[{"name":"Client","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schemaNames","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"exclusionPolicy","type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSA\/bGlzdDxzdHJpbmc+ICRzY2hlbWFOYW1lcwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1931,"slug":"exclude-any","name":"exclude_any","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"policies","type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1937,"slug":"exclude-exact","name":"exclude_exact","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1943,"slug":"exclude-starts-with","name":"exclude_starts_with","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"prefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1949,"slug":"exclude-ends-with","name":"exclude_ends_with","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"suffix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1955,"slug":"exclude-pattern","name":"exclude_pattern","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"pattern","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1961,"slug":"exclude-schema","name":"exclude_schema","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1967,"slug":"exclude-scoped","name":"exclude_scoped","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"policy","type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"SchemaObjectType","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1976,"slug":"manual-catalog-provider","name":"manual_catalog_provider","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"catalog","type":[{"name":"Catalog","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1982,"slug":"chain-catalog-provider","name":"chain_catalog_provider","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"providers","type":[{"name":"CatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ChainCatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1991,"slug":"catalog-comparator","name":"catalog_comparator","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"renameStrategy","type":[{"name":"RenameStrategy","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"viewDependencyResolver","type":[{"name":"ViewDependencyResolver","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"tableOrderStrategy","type":[{"name":"ExecutionOrderStrategy","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"dropIfExists","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CatalogComparator","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfEV4ZWN1dGlvbk9yZGVyU3RyYXRlZ3k8XEZsb3dcUG9zdGdyZVNxbFxTY2hlbWFcVGFibGU+ICR0YWJsZU9yZGVyU3RyYXRlZ3kKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2006,"slug":"ast-view-dependency-resolver","name":"ast_view_dependency_resolver","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AstViewDependencyResolver","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2012,"slug":"noop-view-dependency-resolver","name":"noop_view_dependency_resolver","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"NoopViewDependencyResolver","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2018,"slug":"foreign-key-dependency-order","name":"foreign_key_dependency_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ForeignKeyDependencyOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2027,"slug":"no-execution-order","name":"no_execution_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"NoExecutionOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gTm9FeGVjdXRpb25PcmRlcjxtaXhlZD4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2033,"slug":"view-dependency-order","name":"view_dependency_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ViewDependencyOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2039,"slug":"materialized-view-dependency-order","name":"materialized_view_dependency_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"MaterializedViewDependencyOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":115,"slug":"select","name":"select","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"SelectBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBTRUxFQ1QgcXVlcnkgYnVpbGRlci4KICoKICogQHBhcmFtIEV4cHJlc3Npb258c3RyaW5nIC4uLiRleHByZXNzaW9ucyBDb2x1bW5zIHRvIHNlbGVjdC4gSWYgZW1wdHksIHJldHVybnMgU2VsZWN0U2VsZWN0U3RlcC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":132,"slug":"parsed-select","name":"parsed_select","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ParsedSelect","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNlbGVjdEZpbmFsU3RlcCBmcm9tIGEgcmF3IFNRTCBTRUxFQ1Qgc3RyaW5nLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":144,"slug":"with","name":"with","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"ctes","type":[{"name":"CTE","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"WithBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\With","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFdJVEggY2xhdXNlIGJ1aWxkZXIgZm9yIENURXMuCiAqCiAqIEV4YW1wbGU6IHdpdGgoY3RlKCd1c2VycycsICRzdWJxdWVyeSkpLT5zZWxlY3Qoc3RhcigpKS0+ZnJvbSh0YWJsZSgndXNlcnMnKSkKICogRXhhbXBsZTogd2l0aChjdGUoJ2EnLCAkcTEpLCBjdGUoJ2InLCAkcTIpKS0+cmVjdXJzaXZlKCktPnNlbGVjdCguLi4pLT5mcm9tKHRhYmxlKCdhJykpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":157,"slug":"insert","name":"insert","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"InsertIntoStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Insert","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBJTlNFUlQgcXVlcnkgYnVpbGRlci4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":173,"slug":"bulk-insert","name":"bulk_insert","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"rowCount","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BulkInsert","namespace":"Flow\\PostgreSql\\QueryBuilder\\Insert","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBvcHRpbWl6ZWQgYnVsayBJTlNFUlQgcXVlcnkgZm9yIGhpZ2gtcGVyZm9ybWFuY2UgbXVsdGktcm93IGluc2VydHMuCiAqCiAqIFVubGlrZSBpbnNlcnQoKSB3aGljaCB1c2VzIGltbXV0YWJsZSBidWlsZGVyIHBhdHRlcm5zIChPKG7CsikgZm9yIG4gcm93cyksCiAqIHRoaXMgZnVuY3Rpb24gZ2VuZXJhdGVzIFNRTCBkaXJlY3RseSB1c2luZyBzdHJpbmcgb3BlcmF0aW9ucyAoTyhuKSBjb21wbGV4aXR5KS4KICoKICogQHBhcmFtIHN0cmluZyAkdGFibGUgVGFibGUgbmFtZQogKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRjb2x1bW5zIENvbHVtbiBuYW1lcwogKiBAcGFyYW0gaW50ICRyb3dDb3VudCBOdW1iZXIgb2Ygcm93cyB0byBpbnNlcnQKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":182,"slug":"update","name":"update","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"UpdateTableStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Update","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBVUERBVEUgcXVlcnkgYnVpbGRlci4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":191,"slug":"delete","name":"delete","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"DeleteFromStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Delete","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBERUxFVEUgcXVlcnkgYnVpbGRlci4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":203,"slug":"merge","name":"merge","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"alias","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MergeUsingStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Merge","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBNRVJHRSBxdWVyeSBidWlsZGVyLgogKgogKiBAcGFyYW0gc3RyaW5nICR0YWJsZSBUYXJnZXQgdGFibGUgbmFtZQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGFsaWFzIE9wdGlvbmFsIHRhYmxlIGFsaWFzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":217,"slug":"copy","name":"copy","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"CopyFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBDT1BZIHF1ZXJ5IGJ1aWxkZXIgZm9yIGRhdGEgaW1wb3J0L2V4cG9ydC4KICoKICogVXNhZ2U6CiAqICAgY29weSgpLT5mcm9tKCd1c2VycycpLT5maWxlKCcvdG1wL3VzZXJzLmNzdicpLT5mb3JtYXQoQ29weUZvcm1hdDo6Q1NWKQogKiAgIGNvcHkoKS0+dG8oJ3VzZXJzJyktPmZpbGUoJy90bXAvdXNlcnMuY3N2JyktPmZvcm1hdChDb3B5Rm9ybWF0OjpDU1YpCiAqICAgY29weSgpLT50b1F1ZXJ5KHNlbGVjdCguLi4pKS0+ZmlsZSgnL3RtcC9kYXRhLmNzdicpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":229,"slug":"listen","name":"listen","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"channel","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ListenFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Listen","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExJU1RFTiBzdGF0ZW1lbnQgdG8gc3Vic2NyaWJlIHRoZSBjdXJyZW50IHNlc3Npb24gdG8gYSBub3RpZmljYXRpb24gY2hhbm5lbC4KICoKICogVXNhZ2U6CiAqICAgbGlzdGVuKCdteV9jaGFubmVsJyktPnRvU3FsKCkgIC8vIExJU1RFTiBteV9jaGFubmVsCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":241,"slug":"unlisten","name":"unlisten","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"channel","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"UnlistenFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Unlisten","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBVTkxJU1RFTiBzdGF0ZW1lbnQgdG8gdW5zdWJzY3JpYmUgdGhlIGN1cnJlbnQgc2Vzc2lvbiBmcm9tIGEgbm90aWZpY2F0aW9uIGNoYW5uZWwuCiAqCiAqIFVzYWdlOgogKiAgIHVubGlzdGVuKCdteV9jaGFubmVsJyktPnRvU3FsKCkgIC8vIFVOTElTVEVOIG15X2NoYW5uZWwKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":254,"slug":"notify","name":"notify","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"channel","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"NotifyFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Notify","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE5PVElGWSBzdGF0ZW1lbnQgdG8gc2VuZCBhIG5vdGlmaWNhdGlvbiBvbiBhIGNoYW5uZWwsIG9wdGlvbmFsbHkgd2l0aCBhIHBheWxvYWQuCiAqCiAqIFVzYWdlOgogKiAgIG5vdGlmeSgnbXlfY2hhbm5lbCcpLT50b1NxbCgpICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9USUZZIG15X2NoYW5uZWwKICogICBub3RpZnkoJ215X2NoYW5uZWwnKS0+d2l0aFBheWxvYWQoJ2hlbGxvJyktPnRvU3FsKCkgICAgIC8vIE5PVElGWSBteV9jaGFubmVsLCAnaGVsbG8nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":275,"slug":"col","name":"col","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbHVtbiByZWZlcmVuY2UgZXhwcmVzc2lvbi4KICoKICogQ2FuIGJlIHVzZWQgaW4gdHdvIG1vZGVzOgogKiAtIFBhcnNlIG1vZGU6IGNvbCgndXNlcnMuaWQnKSBvciBjb2woJ3NjaGVtYS50YWJsZS5jb2x1bW4nKSAtIHBhcnNlcyBkb3Qtc2VwYXJhdGVkIHN0cmluZwogKiAtIEV4cGxpY2l0IG1vZGU6IGNvbCgnaWQnLCAndXNlcnMnKSBvciBjb2woJ2lkJywgJ3VzZXJzJywgJ3NjaGVtYScpIC0gc2VwYXJhdGUgYXJndW1lbnRzCiAqCiAqIFdoZW4gJHRhYmxlIG9yICRzY2hlbWEgaXMgcHJvdmlkZWQsICRjb2x1bW4gbXVzdCBiZSBhIHBsYWluIGNvbHVtbiBuYW1lIChubyBkb3RzKS4KICoKICogQHBhcmFtIHN0cmluZyAkY29sdW1uIENvbHVtbiBuYW1lLCBvciBkb3Qtc2VwYXJhdGVkIHBhdGggbGlrZSAidGFibGUuY29sdW1uIiBvciAic2NoZW1hLnRhYmxlLmNvbHVtbiIKICogQHBhcmFtIG51bGx8c3RyaW5nICR0YWJsZSBUYWJsZSBuYW1lIChvcHRpb25hbCwgdHJpZ2dlcnMgZXhwbGljaXQgbW9kZSkKICogQHBhcmFtIG51bGx8c3RyaW5nICRzY2hlbWEgU2NoZW1hIG5hbWUgKG9wdGlvbmFsLCByZXF1aXJlcyAkdGFibGUpCiAqCiAqIEB0aHJvd3MgSW52YWxpZEV4cHJlc3Npb25FeGNlcHRpb24gd2hlbiAkc2NoZW1hIGlzIHByb3ZpZGVkIHdpdGhvdXQgJHRhYmxlLCBvciB3aGVuICRjb2x1bW4gY29udGFpbnMgZG90cyBpbiBleHBsaWNpdCBtb2RlCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":302,"slug":"star","name":"star","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Star","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFTEVDVCAqIGV4cHJlc3Npb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":318,"slug":"literal","name":"literal","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Literal","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxpdGVyYWwgdmFsdWUgZm9yIHVzZSBpbiBxdWVyaWVzLgogKgogKiBBdXRvbWF0aWNhbGx5IGRldGVjdHMgdGhlIHR5cGUgYW5kIGNyZWF0ZXMgdGhlIGFwcHJvcHJpYXRlIGxpdGVyYWw6CiAqIC0gbGl0ZXJhbCgnaGVsbG8nKSBjcmVhdGVzIGEgc3RyaW5nIGxpdGVyYWwKICogLSBsaXRlcmFsKDQyKSBjcmVhdGVzIGFuIGludGVnZXIgbGl0ZXJhbAogKiAtIGxpdGVyYWwoMy4xNCkgY3JlYXRlcyBhIGZsb2F0IGxpdGVyYWwKICogLSBsaXRlcmFsKHRydWUpIGNyZWF0ZXMgYSBib29sZWFuIGxpdGVyYWwKICogLSBsaXRlcmFsKG51bGwpIGNyZWF0ZXMgYSBOVUxMIGxpdGVyYWwKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":333,"slug":"param","name":"param","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"position","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Parameter","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHBvc2l0aW9uYWwgcGFyYW1ldGVyICgkMSwgJDIsIGV0Yy4pLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":342,"slug":"parameters","name":"parameters","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"count","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"startAt","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"}],"return_type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gbGlzdDxQYXJhbWV0ZXI+CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":368,"slug":"func","name":"func","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"FunctionCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZ1bmN0aW9uIGNhbGwgZXhwcmVzc2lvbi4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBGdW5jdGlvbiBuYW1lIChjYW4gaW5jbHVkZSBzY2hlbWEgbGlrZSAicGdfY2F0YWxvZy5ub3ciKQogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGFyZ3MgRnVuY3Rpb24gYXJndW1lbnRzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":402,"slug":"agg","name":"agg","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhZ2dyZWdhdGUgZnVuY3Rpb24gY2FsbCAoQ09VTlQsIFNVTSwgQVZHLCBldGMuKS4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBBZ2dyZWdhdGUgZnVuY3Rpb24gbmFtZQogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGFyZ3MgRnVuY3Rpb24gYXJndW1lbnRzCiAqIEBwYXJhbSBib29sICRkaXN0aW5jdCBVc2UgRElTVElOQ1QgbW9kaWZpZXIKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":416,"slug":"agg-count","name":"agg_count","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDT1VOVCgqKSBhZ2dyZWdhdGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":429,"slug":"count-all","name":"count_all","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDT1VOVCgqKSBhZ2dyZWdhdGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":438,"slug":"agg-sum","name":"agg_sum","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBTVU0gYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":447,"slug":"agg-avg","name":"agg_avg","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBBVkcgYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":456,"slug":"agg-min","name":"agg_min","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBNSU4gYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":465,"slug":"agg-max","name":"agg_max","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBNQVggYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":476,"slug":"coalesce","name":"coalesce","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Coalesce","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPQUxFU0NFIGV4cHJlc3Npb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gY29hbGVzY2UKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":487,"slug":"nullif","name":"nullif","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr1","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"expr2","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"NullIf","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE5VTExJRiBleHByZXNzaW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":501,"slug":"greatest","name":"greatest","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Greatest","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdSRUFURVNUIGV4cHJlc3Npb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gY29tcGFyZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":514,"slug":"least","name":"least","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Least","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExFQVNUIGV4cHJlc3Npb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gY29tcGFyZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":528,"slug":"cast","name":"cast","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"dataType","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TypeCast","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHR5cGUgY2FzdCBleHByZXNzaW9uLgogKgogKiBAcGFyYW0gRXhwcmVzc2lvbnxzdHJpbmcgJGV4cHIgRXhwcmVzc2lvbiB0byBjYXN0CiAqIEBwYXJhbSBDb2x1bW5UeXBlICRkYXRhVHlwZSBUYXJnZXQgZGF0YSB0eXBlICh1c2UgY29sdW1uX3R5cGVfKiBmdW5jdGlvbnMpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":543,"slug":"current-timestamp","name":"current_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SQLValueFunctionExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNRTCBzdGFuZGFyZCBDVVJSRU5UX1RJTUVTVEFNUCBmdW5jdGlvbi4KICoKICogUmV0dXJucyB0aGUgY3VycmVudCBkYXRlIGFuZCB0aW1lIChhdCB0aGUgc3RhcnQgb2YgdGhlIHRyYW5zYWN0aW9uKS4KICogVXNlZnVsIGFzIGEgY29sdW1uIGRlZmF1bHQgdmFsdWUgb3IgaW4gU0VMRUNUIHF1ZXJpZXMuCiAqCiAqIEV4YW1wbGU6IGNvbHVtbignY3JlYXRlZF9hdCcsIGNvbHVtbl90eXBlX3RpbWVzdGFtcCgpKS0+ZGVmYXVsdChjdXJyZW50X3RpbWVzdGFtcCgpKQogKiBFeGFtcGxlOiBzZWxlY3QoKS0+c2VsZWN0KGN1cnJlbnRfdGltZXN0YW1wKCktPmFzKCdub3cnKSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":558,"slug":"current-date","name":"current_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SQLValueFunctionExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNRTCBzdGFuZGFyZCBDVVJSRU5UX0RBVEUgZnVuY3Rpb24uCiAqCiAqIFJldHVybnMgdGhlIGN1cnJlbnQgZGF0ZSAoYXQgdGhlIHN0YXJ0IG9mIHRoZSB0cmFuc2FjdGlvbikuCiAqIFVzZWZ1bCBhcyBhIGNvbHVtbiBkZWZhdWx0IHZhbHVlIG9yIGluIFNFTEVDVCBxdWVyaWVzLgogKgogKiBFeGFtcGxlOiBjb2x1bW4oJ2JpcnRoX2RhdGUnLCBjb2x1bW5fdHlwZV9kYXRlKCkpLT5kZWZhdWx0KGN1cnJlbnRfZGF0ZSgpKQogKiBFeGFtcGxlOiBzZWxlY3QoKS0+c2VsZWN0KGN1cnJlbnRfZGF0ZSgpLT5hcygndG9kYXknKSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":573,"slug":"current-time","name":"current_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SQLValueFunctionExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNRTCBzdGFuZGFyZCBDVVJSRU5UX1RJTUUgZnVuY3Rpb24uCiAqCiAqIFJldHVybnMgdGhlIGN1cnJlbnQgdGltZSAoYXQgdGhlIHN0YXJ0IG9mIHRoZSB0cmFuc2FjdGlvbikuCiAqIFVzZWZ1bCBhcyBhIGNvbHVtbiBkZWZhdWx0IHZhbHVlIG9yIGluIFNFTEVDVCBxdWVyaWVzLgogKgogKiBFeGFtcGxlOiBjb2x1bW4oJ3N0YXJ0X3RpbWUnLCBjb2x1bW5fdHlwZV90aW1lKCkpLT5kZWZhdWx0KGN1cnJlbnRfdGltZSgpKQogKiBFeGFtcGxlOiBzZWxlY3QoKS0+c2VsZWN0KGN1cnJlbnRfdGltZSgpLT5hcygnbm93X3RpbWUnKSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":586,"slug":"case-when","name":"case_when","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"whenClauses","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"elseResult","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"operand","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CaseExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENBU0UgZXhwcmVzc2lvbi4KICoKICogQHBhcmFtIG5vbi1lbXB0eS1saXN0PFdoZW5DbGF1c2U+ICR3aGVuQ2xhdXNlcyBXSEVOIGNsYXVzZXMKICogQHBhcmFtIG51bGx8RXhwcmVzc2lvbnxzdHJpbmcgJGVsc2VSZXN1bHQgRUxTRSByZXN1bHQgKG9wdGlvbmFsKQogKiBAcGFyYW0gbnVsbHxFeHByZXNzaW9ufHN0cmluZyAkb3BlcmFuZCBDQVNFIG9wZXJhbmQgZm9yIHNpbXBsZSBDQVNFIChvcHRpb25hbCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":602,"slug":"when","name":"when","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"condition","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"result","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"WhenClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFdIRU4gY2xhdXNlIGZvciBDQVNFIGV4cHJlc3Npb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":614,"slug":"sub-select","name":"sub_select","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Subquery","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHN1YnF1ZXJ5IGV4cHJlc3Npb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":628,"slug":"array-expr","name":"array_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBleHByZXNzaW9uLgogKgogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGVsZW1lbnRzIEFycmF5IGVsZW1lbnRzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":641,"slug":"row-expr","name":"row_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RowExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJvdyBleHByZXNzaW9uLgogKgogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGVsZW1lbnRzIFJvdyBlbGVtZW50cwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":652,"slug":"binary-expr","name":"binary_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"operator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJpbmFyeSBleHByZXNzaW9uIChsZWZ0IG9wIHJpZ2h0KS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":670,"slug":"window-func","name":"window_func","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"partitionBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"orderBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"WindowFunction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHdpbmRvdyBmdW5jdGlvbi4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBGdW5jdGlvbiBuYW1lCiAqIEBwYXJhbSBsaXN0PEV4cHJlc3Npb258c3RyaW5nPiAkYXJncyBGdW5jdGlvbiBhcmd1bWVudHMKICogQHBhcmFtIGxpc3Q8RXhwcmVzc2lvbnxzdHJpbmc+ICRwYXJ0aXRpb25CeSBQQVJUSVRJT04gQlkgZXhwcmVzc2lvbnMKICogQHBhcmFtIGxpc3Q8T3JkZXJCeT4gJG9yZGVyQnkgT1JERVIgQlkgaXRlbXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":691,"slug":"concat","name":"concat","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbmNhdGVuYXRlIGV4cHJlc3Npb25zIHdpdGggdGhlIHx8IG9wZXJhdG9yLgogKgogKiBFeGFtcGxlOiBjb25jYXQoY29sKCdzY2hlbWEnKSwgbGl0ZXJhbCgnLicpLCBjb2woJ3RhYmxlJykpCiAqIFByb2R1Y2VzOiBzY2hlbWEgfHwgJy4nIHx8IHRhYmxlCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgQXQgbGVhc3QgMiBleHByZXNzaW9ucyB0byBjb25jYXRlbmF0ZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":721,"slug":"table","name":"table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Table","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRhYmxlIHJlZmVyZW5jZS4KICoKICogU3VwcG9ydHMgZG90IG5vdGF0aW9uIGZvciBzY2hlbWEtcXVhbGlmaWVkIG5hbWVzOiAicHVibGljLnVzZXJzIiBvciBleHBsaWNpdCBzY2hlbWEgcGFyYW1ldGVyLgogKiBEb3VibGUtcXVvdGVkIGlkZW50aWZpZXJzIHByZXNlcnZlIGRvdHM6ICcibXkudGFibGUiJyBjcmVhdGVzIGEgc2luZ2xlIGlkZW50aWZpZXIuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGFibGUgbmFtZSAobWF5IGluY2x1ZGUgc2NoZW1hIGFzICJzY2hlbWEudGFibGUiKQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNjaGVtYSBTY2hlbWEgbmFtZSAob3B0aW9uYWwsIG92ZXJyaWRlcyBwYXJzZWQgc2NoZW1hKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":736,"slug":"derived","name":"derived","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"alias","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DerivedTable","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRlcml2ZWQgdGFibGUgKHN1YnF1ZXJ5IGluIEZST00gY2xhdXNlKS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":750,"slug":"lateral","name":"lateral","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"reference","type":[{"name":"TableReference","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Lateral","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExBVEVSQUwgc3VicXVlcnkuCiAqCiAqIEBwYXJhbSBUYWJsZVJlZmVyZW5jZSAkcmVmZXJlbmNlIFRoZSBzdWJxdWVyeSBvciB0YWJsZSBmdW5jdGlvbiByZWZlcmVuY2UKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":762,"slug":"table-func","name":"table_func","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"function","type":[{"name":"FunctionCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"withOrdinality","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"TableFunction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRhYmxlIGZ1bmN0aW9uIHJlZmVyZW5jZS4KICoKICogQHBhcmFtIEZ1bmN0aW9uQ2FsbCAkZnVuY3Rpb24gVGhlIHRhYmxlLXZhbHVlZCBmdW5jdGlvbgogKiBAcGFyYW0gYm9vbCAkd2l0aE9yZGluYWxpdHkgV2hldGhlciB0byBhZGQgV0lUSCBPUkRJTkFMSVRZCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":781,"slug":"values-table","name":"values_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"rows","type":[{"name":"RowExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ValuesTable","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZBTFVFUyBjbGF1c2UgYXMgYSB0YWJsZSByZWZlcmVuY2UuCiAqCiAqIFVzYWdlOgogKiAgIHNlbGVjdCgpLT5mcm9tKAogKiAgICAgICB2YWx1ZXNfdGFibGUoCiAqICAgICAgICAgICByb3dfZXhwcihbbGl0ZXJhbCgxKSwgbGl0ZXJhbCgnQWxpY2UnKV0pLAogKiAgICAgICAgICAgcm93X2V4cHIoW2xpdGVyYWwoMiksIGxpdGVyYWwoJ0JvYicpXSkKICogICAgICAgKS0+YXMoJ3QnLCBbJ2lkJywgJ25hbWUnXSkKICogICApCiAqCiAqIEdlbmVyYXRlczogU0VMRUNUICogRlJPTSAoVkFMVUVTICgxLCAnQWxpY2UnKSwgKDIsICdCb2InKSkgQVMgdChpZCwgbmFtZSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":790,"slug":"order-by","name":"order_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"direction","type":[{"name":"SortDirection","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\SortDirection::..."},{"name":"nulls","type":[{"name":"NullsPosition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\NullsPosition::..."}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPUkRFUiBCWSBpdGVtLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":802,"slug":"asc","name":"asc","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nulls","type":[{"name":"NullsPosition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\NullsPosition::..."}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPUkRFUiBCWSBpdGVtIHdpdGggQVNDIGRpcmVjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":811,"slug":"desc","name":"desc","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nulls","type":[{"name":"NullsPosition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\NullsPosition::..."}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPUkRFUiBCWSBpdGVtIHdpdGggREVTQyBkaXJlY3Rpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":825,"slug":"cte","name":"cte","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columnNames","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"materialization","type":[{"name":"CTEMaterialization","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\CTEMaterialization::..."},{"name":"recursive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CTE","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENURSAoQ29tbW9uIFRhYmxlIEV4cHJlc3Npb24pLgogKgogKiBAcGFyYW0gc3RyaW5nICRuYW1lIENURSBuYW1lCiAqIEBwYXJhbSBTZWxlY3RGaW5hbFN0ZXAgJHF1ZXJ5IENURSBxdWVyeQogKiBAcGFyYW0gYXJyYXk8c3RyaW5nPiAkY29sdW1uTmFtZXMgQ29sdW1uIGFsaWFzZXMgKG9wdGlvbmFsKQogKiBAcGFyYW0gQ1RFTWF0ZXJpYWxpemF0aW9uICRtYXRlcmlhbGl6YXRpb24gTWF0ZXJpYWxpemF0aW9uIGhpbnQKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":847,"slug":"window-def","name":"window_def","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"partitionBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"orderBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"frame","type":[{"name":"WindowFrame","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"WindowDefinition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHdpbmRvdyBkZWZpbml0aW9uIGZvciBXSU5ET1cgY2xhdXNlLgogKgogKiBAcGFyYW0gc3RyaW5nICRuYW1lIFdpbmRvdyBuYW1lCiAqIEBwYXJhbSBsaXN0PEV4cHJlc3Npb258c3RyaW5nPiAkcGFydGl0aW9uQnkgUEFSVElUSU9OIEJZIGV4cHJlc3Npb25zCiAqIEBwYXJhbSBsaXN0PE9yZGVyQnk+ICRvcmRlckJ5IE9SREVSIEJZIGl0ZW1zCiAqIEBwYXJhbSBudWxsfFdpbmRvd0ZyYW1lICRmcmFtZSBXaW5kb3cgZnJhbWUgc3BlY2lmaWNhdGlvbgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":867,"slug":"window-frame","name":"window_frame","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"mode","type":[{"name":"FrameMode","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end","type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"exclusion","type":[{"name":"FrameExclusion","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\FrameExclusion::..."}],"return_type":[{"name":"WindowFrame","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHdpbmRvdyBmcmFtZSBzcGVjaWZpY2F0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":880,"slug":"frame-current-row","name":"frame_current_row","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBDVVJSRU5UIFJPVy4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":889,"slug":"frame-unbounded-preceding","name":"frame_unbounded_preceding","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBVTkJPVU5ERUQgUFJFQ0VESU5HLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":898,"slug":"frame-unbounded-following","name":"frame_unbounded_following","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBVTkJPVU5ERUQgRk9MTE9XSU5HLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":907,"slug":"frame-preceding","name":"frame_preceding","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"offset","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBOIFBSRUNFRElORy4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":916,"slug":"frame-following","name":"frame_following","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"offset","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBOIEZPTExPV0lORy4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":929,"slug":"lock-for","name":"lock_for","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"strength","type":[{"name":"LockStrength","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"waitPolicy","type":[{"name":"LockWaitPolicy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\LockWaitPolicy::..."}],"return_type":[{"name":"LockingClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxvY2tpbmcgY2xhdXNlIChGT1IgVVBEQVRFLCBGT1IgU0hBUkUsIGV0Yy4pLgogKgogKiBAcGFyYW0gTG9ja1N0cmVuZ3RoICRzdHJlbmd0aCBMb2NrIHN0cmVuZ3RoCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHRhYmxlcyBUYWJsZXMgdG8gbG9jayAoZW1wdHkgZm9yIGFsbCkKICogQHBhcmFtIExvY2tXYWl0UG9saWN5ICR3YWl0UG9saWN5IFdhaXQgcG9saWN5CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":943,"slug":"for-update","name":"for_update","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"LockingClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEZPUiBVUERBVEUgbG9ja2luZyBjbGF1c2UuCiAqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHRhYmxlcyBUYWJsZXMgdG8gbG9jayAoZW1wdHkgZm9yIGFsbCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":954,"slug":"for-share","name":"for_share","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"LockingClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEZPUiBTSEFSRSBsb2NraW5nIGNsYXVzZS4KICoKICogQHBhcmFtIGxpc3Q8c3RyaW5nPiAkdGFibGVzIFRhYmxlcyB0byBsb2NrIChlbXB0eSBmb3IgYWxsKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":963,"slug":"on-conflict-nothing","name":"on_conflict_nothing","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"target","type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"OnConflictClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPTiBDT05GTElDVCBETyBOT1RISU5HIGNsYXVzZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":975,"slug":"on-conflict-update","name":"on_conflict_update","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"target","type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"updates","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OnConflictClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPTiBDT05GTElDVCBETyBVUERBVEUgY2xhdXNlLgogKgogKiBAcGFyYW0gQ29uZmxpY3RUYXJnZXQgJHRhcmdldCBDb25mbGljdCB0YXJnZXQgKGNvbHVtbnMgb3IgY29uc3RyYWludCkKICogQHBhcmFtIGFycmF5PHN0cmluZywgRXhwcmVzc2lvbnxzdHJpbmc+ICR1cGRhdGVzIENvbHVtbiB1cGRhdGVzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":989,"slug":"conflict-columns","name":"conflict_columns","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbmZsaWN0IHRhcmdldCBmb3IgT04gQ09ORkxJQ1QgKGNvbHVtbnMpLgogKgogKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRjb2x1bW5zIENvbHVtbnMgdGhhdCBkZWZpbmUgdW5pcXVlbmVzcwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":998,"slug":"conflict-constraint","name":"conflict_constraint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbmZsaWN0IHRhcmdldCBmb3IgT04gQ09ORkxJQ1QgT04gQ09OU1RSQUlOVC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1009,"slug":"returning","name":"returning","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ReturningClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVFVSTklORyBjbGF1c2UuCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gcmV0dXJuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1020,"slug":"returning-all","name":"returning_all","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReturningClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVFVSTklORyAqIGNsYXVzZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1032,"slug":"begin","name":"begin","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"BeginOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJFR0lOIHRyYW5zYWN0aW9uIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IGJlZ2luKCktPmlzb2xhdGlvbkxldmVsKElzb2xhdGlvbkxldmVsOjpTRVJJQUxJWkFCTEUpLT5yZWFkT25seSgpCiAqIFByb2R1Y2VzOiBCRUdJTiBJU09MQVRJT04gTEVWRUwgU0VSSUFMSVpBQkxFIFJFQUQgT05MWQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1044,"slug":"commit","name":"commit","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"CommitOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPTU1JVCB0cmFuc2FjdGlvbiBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBjb21taXQoKS0+YW5kQ2hhaW4oKQogKiBQcm9kdWNlczogQ09NTUlUIEFORCBDSEFJTgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1056,"slug":"rollback","name":"rollback","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"RollbackOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJPTExCQUNLIHRyYW5zYWN0aW9uIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJvbGxiYWNrKCktPnRvU2F2ZXBvaW50KCdteV9zYXZlcG9pbnQnKQogKiBQcm9kdWNlczogUk9MTEJBQ0sgVE8gU0FWRVBPSU5UIG15X3NhdmVwb2ludAogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1068,"slug":"savepoint","name":"savepoint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SavepointFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNBVkVQT0lOVC4KICoKICogRXhhbXBsZTogc2F2ZXBvaW50KCdteV9zYXZlcG9pbnQnKQogKiBQcm9kdWNlczogU0FWRVBPSU5UIG15X3NhdmVwb2ludAogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1080,"slug":"release-savepoint","name":"release_savepoint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SavepointFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFJlbGVhc2UgYSBTQVZFUE9JTlQuCiAqCiAqIEV4YW1wbGU6IHJlbGVhc2Vfc2F2ZXBvaW50KCdteV9zYXZlcG9pbnQnKQogKiBQcm9kdWNlczogUkVMRUFTRSBteV9zYXZlcG9pbnQKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1092,"slug":"set-transaction","name":"set_transaction","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SetTransactionOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBUUkFOU0FDVElPTiBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBzZXRfdHJhbnNhY3Rpb24oKS0+aXNvbGF0aW9uTGV2ZWwoSXNvbGF0aW9uTGV2ZWw6OlNFUklBTElaQUJMRSktPnJlYWRPbmx5KCkKICogUHJvZHVjZXM6IFNFVCBUUkFOU0FDVElPTiBJU09MQVRJT04gTEVWRUwgU0VSSUFMSVpBQkxFLCBSRUFEIE9OTFkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1104,"slug":"set-session-transaction","name":"set_session_transaction","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SetTransactionOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBTRVNTSU9OIENIQVJBQ1RFUklTVElDUyBBUyBUUkFOU0FDVElPTiBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBzZXRfc2Vzc2lvbl90cmFuc2FjdGlvbigpLT5pc29sYXRpb25MZXZlbChJc29sYXRpb25MZXZlbDo6U0VSSUFMSVpBQkxFKQogKiBQcm9kdWNlczogU0VUIFNFU1NJT04gQ0hBUkFDVEVSSVNUSUNTIEFTIFRSQU5TQUNUSU9OIElTT0xBVElPTiBMRVZFTCBTRVJJQUxJWkFCTEUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1116,"slug":"transaction-snapshot","name":"transaction_snapshot","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"snapshotId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SetTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBUUkFOU0FDVElPTiBTTkFQU0hPVCBidWlsZGVyLgogKgogKiBFeGFtcGxlOiB0cmFuc2FjdGlvbl9zbmFwc2hvdCgnMDAwMDAwMDMtMDAwMDAwMUEtMScpCiAqIFByb2R1Y2VzOiBTRVQgVFJBTlNBQ1RJT04gU05BUFNIT1QgJzAwMDAwMDAzLTAwMDAwMDFBLTEnCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1128,"slug":"prepare-transaction","name":"prepare_transaction","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"transactionId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PreparedTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBSRVBBUkUgVFJBTlNBQ1RJT04gYnVpbGRlci4KICoKICogRXhhbXBsZTogcHJlcGFyZV90cmFuc2FjdGlvbignbXlfdHJhbnNhY3Rpb24nKQogKiBQcm9kdWNlczogUFJFUEFSRSBUUkFOU0FDVElPTiAnbXlfdHJhbnNhY3Rpb24nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1140,"slug":"commit-prepared","name":"commit_prepared","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"transactionId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PreparedTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPTU1JVCBQUkVQQVJFRCBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBjb21taXRfcHJlcGFyZWQoJ215X3RyYW5zYWN0aW9uJykKICogUHJvZHVjZXM6IENPTU1JVCBQUkVQQVJFRCAnbXlfdHJhbnNhY3Rpb24nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1152,"slug":"rollback-prepared","name":"rollback_prepared","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"transactionId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PreparedTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJPTExCQUNLIFBSRVBBUkVEIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJvbGxiYWNrX3ByZXBhcmVkKCdteV90cmFuc2FjdGlvbicpCiAqIFByb2R1Y2VzOiBST0xMQkFDSyBQUkVQQVJFRCAnbXlfdHJhbnNhY3Rpb24nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1175,"slug":"declare-cursor","name":"declare_cursor","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"cursorName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false},{"name":"Sql","namespace":"Flow\\PostgreSql\\QueryBuilder","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DeclareCursorOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Cursor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIERlY2xhcmUgYSBzZXJ2ZXItc2lkZSBjdXJzb3IgZm9yIGEgcXVlcnkuCiAqCiAqIEN1cnNvcnMgbXVzdCBiZSBkZWNsYXJlZCB3aXRoaW4gYSB0cmFuc2FjdGlvbiBhbmQgcHJvdmlkZSBtZW1vcnktZWZmaWNpZW50CiAqIGl0ZXJhdGlvbiBvdmVyIGxhcmdlIHJlc3VsdCBzZXRzIHZpYSBGRVRDSCBjb21tYW5kcy4KICoKICogRXhhbXBsZSB3aXRoIHF1ZXJ5IGJ1aWxkZXI6CiAqICAgZGVjbGFyZV9jdXJzb3IoJ215X2N1cnNvcicsIHNlbGVjdChzdGFyKCkpLT5mcm9tKHRhYmxlKCd1c2VycycpKSktPm5vU2Nyb2xsKCkKICogICBQcm9kdWNlczogREVDTEFSRSBteV9jdXJzb3IgTk8gU0NST0xMIENVUlNPUiBGT1IgU0VMRUNUICogRlJPTSB1c2VycwogKgogKiBFeGFtcGxlIHdpdGggcmF3IFNRTDoKICogICBkZWNsYXJlX2N1cnNvcignbXlfY3Vyc29yJywgJ1NFTEVDVCAqIEZST00gdXNlcnMgV0hFUkUgYWN0aXZlID0gdHJ1ZScpLT53aXRoSG9sZCgpCiAqICAgUHJvZHVjZXM6IERFQ0xBUkUgbXlfY3Vyc29yIE5PIFNDUk9MTCBDVVJTT1IgV0lUSCBIT0xEIEZPUiBTRUxFQ1QgKiBGUk9NIHVzZXJzIFdIRVJFIGFjdGl2ZSA9IHRydWUKICoKICogQHBhcmFtIHN0cmluZyAkY3Vyc29yTmFtZSBVbmlxdWUgY3Vyc29yIG5hbWUKICogQHBhcmFtIFNlbGVjdEZpbmFsU3RlcHxTcWx8c3RyaW5nICRxdWVyeSBRdWVyeSB0byBpdGVyYXRlIG92ZXIKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1196,"slug":"fetch","name":"fetch","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"cursorName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FetchCursorBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Cursor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEZldGNoIHJvd3MgZnJvbSBhIGN1cnNvci4KICoKICogRXhhbXBsZTogZmV0Y2goJ215X2N1cnNvcicpLT5mb3J3YXJkKDEwMCkKICogUHJvZHVjZXM6IEZFVENIIEZPUldBUkQgMTAwIG15X2N1cnNvcgogKgogKiBFeGFtcGxlOiBmZXRjaCgnbXlfY3Vyc29yJyktPmFsbCgpCiAqIFByb2R1Y2VzOiBGRVRDSCBBTEwgbXlfY3Vyc29yCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGN1cnNvck5hbWUgQ3Vyc29yIHRvIGZldGNoIGZyb20KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1213,"slug":"close-cursor","name":"close_cursor","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"cursorName","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CloseCursorFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Cursor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENsb3NlIGEgY3Vyc29yLgogKgogKiBFeGFtcGxlOiBjbG9zZV9jdXJzb3IoJ215X2N1cnNvcicpCiAqIFByb2R1Y2VzOiBDTE9TRSBteV9jdXJzb3IKICoKICogRXhhbXBsZTogY2xvc2VfY3Vyc29yKCkgLSBjbG9zZXMgYWxsIGN1cnNvcnMKICogUHJvZHVjZXM6IENMT1NFIEFMTAogKgogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGN1cnNvck5hbWUgQ3Vyc29yIHRvIGNsb3NlLCBvciBudWxsIHRvIGNsb3NlIGFsbAogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":42,"slug":"eq","name":"eq","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBlcXVhbGl0eSBjb21wYXJpc29uIChjb2x1bW4gPSB2YWx1ZSkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":55,"slug":"ne","name":"ne","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5vdC1lcXVhbCBjb21wYXJpc29uIChjb2x1bW4gIT0gdmFsdWUpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":68,"slug":"lt","name":"lt","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxlc3MtdGhhbiBjb21wYXJpc29uIChjb2x1bW4gPCB2YWx1ZSkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":81,"slug":"le","name":"le","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxlc3MtdGhhbi1vci1lcXVhbCBjb21wYXJpc29uIChjb2x1bW4gPD0gdmFsdWUpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":94,"slug":"gt","name":"gt","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGdyZWF0ZXItdGhhbiBjb21wYXJpc29uIChjb2x1bW4gPiB2YWx1ZSkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":107,"slug":"ge","name":"ge","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGdyZWF0ZXItdGhhbi1vci1lcXVhbCBjb21wYXJpc29uIChjb2x1bW4gPj0gdmFsdWUpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":120,"slug":"between","name":"between","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"low","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"high","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"not","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Between","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJFVFdFRU4gY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":139,"slug":"in","name":"in_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"values","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"In","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJTiBjb25kaXRpb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAkZXhwciBFeHByZXNzaW9uIHRvIGNoZWNrCiAqIEBwYXJhbSBsaXN0PEV4cHJlc3Npb24+ICR2YWx1ZXMgTGlzdCBvZiB2YWx1ZXMgKG11c3QgYmUgbm9uLWVtcHR5KQogKgogKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gd2hlbiB2YWx1ZXMgYXJyYXkgaXMgZW1wdHkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":156,"slug":"is-null","name":"is_null","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"not","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"IsNull","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJUyBOVUxMIGNvbmRpdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":165,"slug":"like","name":"like","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"caseInsensitive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"negated","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Like","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExJS0UgY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":183,"slug":"similar-to","name":"similar_to","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SimilarTo","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNJTUlMQVIgVE8gY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":195,"slug":"distinct-from","name":"distinct_from","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"not","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"IsDistinctFrom","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJUyBESVNUSU5DVCBGUk9NIGNvbmRpdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":208,"slug":"exists","name":"exists","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"subquery","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Exists","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFWElTVFMgY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":223,"slug":"any","name":"any_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"operator","type":[{"name":"ComparisonOperator","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"arrayOrSubquery","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBTlkgY29uZGl0aW9uIHdpdGggYSBzdWJxdWVyeSBvciBhcnJheSBleHByZXNzaW9uLgogKgogKiBFeGFtcGxlOiBhbnlfKGNvbCgnaWQnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpFUSwgc2VsZWN0KGNvbCgndXNlcl9pZCcpKS0+ZnJvbSh0YWJsZSgnb3JkZXJzJykpKQogKiBFeGFtcGxlOiBhbnlfKGNvbCgnYXR0bnVtJywgJ2EnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpFUSwgY29sKCdjb25rZXknLCAnY29uJykpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":243,"slug":"all","name":"all_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"operator","type":[{"name":"ComparisonOperator","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"arrayOrSubquery","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBTEwgY29uZGl0aW9uIHdpdGggYSBzdWJxdWVyeSBvciBhcnJheSBleHByZXNzaW9uLgogKgogKiBFeGFtcGxlOiBhbGxfKGNvbCgnaWQnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpFUSwgc2VsZWN0KGNvbCgndXNlcl9pZCcpKS0+ZnJvbSh0YWJsZSgnb3JkZXJzJykpKQogKiBFeGFtcGxlOiBhbGxfKGNvbCgndmFsdWUnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpHVCwgY29sKCd0aHJlc2hvbGRzJykpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":262,"slug":"is-true","name":"is_true","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BooleanCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYW4gZXhwcmVzc2lvbiBhcyBhIGJvb2xlYW4gY29uZGl0aW9uIGZvciB1c2UgaW4gV0hFUkUvSEFWSU5HL0pPSU4gT04uCiAqCiAqIEV4YW1wbGU6IGlzX3RydWUoY29sKCdpc19hY3RpdmUnKSkg4oCUIHVzZXMgYSBib29sZWFuIGNvbHVtbiBpbiBXSEVSRSBjbGF1c2UuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":274,"slug":"not-like","name":"not_like","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"caseInsensitive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Like","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE5PVCBMSUtFIGNvbmRpdGlvbi4KICoKICogRXhhbXBsZTogbm90X2xpa2UoY29sKCduYW1lJyksIGxpdGVyYWwoJ3BnXyUnKSkKICogUHJvZHVjZXM6IG5hbWUgTk9UIExJS0UgJ3BnXyUnCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":302,"slug":"conditions","name":"conditions","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ConditionBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbmRpdGlvbiBidWlsZGVyIGZvciBmbHVlbnQgY29uZGl0aW9uIGNvbXBvc2l0aW9uLgogKgogKiBUaGlzIGJ1aWxkZXIgYWxsb3dzIGluY3JlbWVudGFsIGNvbmRpdGlvbiBidWlsZGluZyB3aXRoIGEgZmx1ZW50IEFQSToKICoKICogYGBgcGhwCiAqICRidWlsZGVyID0gY29uZGl0aW9ucygpOwogKgogKiBpZiAoJGhhc0ZpbHRlcikgewogKiAgICAgJGJ1aWxkZXIgPSAkYnVpbGRlci0+YW5kKGVxKGNvbCgnc3RhdHVzJyksIGxpdGVyYWwoJ2FjdGl2ZScpKSk7CiAqIH0KICoKICogaWYgKCEkYnVpbGRlci0+aXNFbXB0eSgpKSB7CiAqICAgICAkcXVlcnkgPSBzZWxlY3QoKS0+ZnJvbSh0YWJsZSgndXNlcnMnKSktPndoZXJlKCRidWlsZGVyKTsKICogfQogKiBgYGAKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":313,"slug":"and","name":"and_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"conditions","type":[{"name":"Condition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"AndCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgY29uZGl0aW9ucyB3aXRoIEFORC4KICoKICogQHBhcmFtIENvbmRpdGlvbiAuLi4kY29uZGl0aW9ucyBDb25kaXRpb25zIHRvIGNvbWJpbmUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":324,"slug":"or","name":"or_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"conditions","type":[{"name":"Condition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"OrCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgY29uZGl0aW9ucyB3aXRoIE9SLgogKgogKiBAcGFyYW0gQ29uZGl0aW9uIC4uLiRjb25kaXRpb25zIENvbmRpdGlvbnMgdG8gY29tYmluZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":336,"slug":"not","name":"not_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expression","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"NotCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5lZ2F0ZSBhIGNvbmRpdGlvbiBvciBleHByZXNzaW9uIHdpdGggTk9ULgogKgogKiBBY2NlcHRzIGJvdGggQ29uZGl0aW9uIGFuZCBFeHByZXNzaW9uIOKAlCBOT1QgYWx3YXlzIHByb2R1Y2VzIGEgYm9vbGVhbiByZXN1bHQuCiAqIENhbiBiZSB1c2VkIGluIFdIRVJFIGNsYXVzZXMgYW5kIFNFTEVDVCBsaXN0cyAodmlhIC0+YXMoJ2FsaWFzJykpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":348,"slug":"json-contains","name":"json_contains","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGNvbnRhaW5zIGNvbmRpdGlvbiAoQD4pLgogKgogKiBFeGFtcGxlOiBqc29uX2NvbnRhaW5zKGNvbCgnbWV0YWRhdGEnKSwgbGl0ZXJhbF9qc29uKCd7ImNhdGVnb3J5IjogImVsZWN0cm9uaWNzIn0nKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhIEA+ICd7ImNhdGVnb3J5IjogImVsZWN0cm9uaWNzIn0nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":364,"slug":"json-contained-by","name":"json_contained_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGlzIGNvbnRhaW5lZCBieSBjb25kaXRpb24gKDxAKS4KICoKICogRXhhbXBsZToganNvbl9jb250YWluZWRfYnkoY29sKCdtZXRhZGF0YScpLCBsaXRlcmFsX2pzb24oJ3siY2F0ZWdvcnkiOiAiZWxlY3Ryb25pY3MiLCAicHJpY2UiOiAxMDB9JykpCiAqIFByb2R1Y2VzOiBtZXRhZGF0YSA8QCAneyJjYXRlZ29yeSI6ICJlbGVjdHJvbmljcyIsICJwcmljZSI6IDEwMH0nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":381,"slug":"json-get","name":"json_get","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gZmllbGQgYWNjZXNzIGV4cHJlc3Npb24gKC0+KS4KICogUmV0dXJucyBKU09OLgogKgogKiBFeGFtcGxlOiBqc29uX2dldChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCdjYXRlZ29yeScpKQogKiBQcm9kdWNlczogbWV0YWRhdGEgLT4gJ2NhdGVnb3J5JwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":398,"slug":"json-get-text","name":"json_get_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gZmllbGQgYWNjZXNzIGV4cHJlc3Npb24gKC0+PikuCiAqIFJldHVybnMgdGV4dC4KICoKICogRXhhbXBsZToganNvbl9nZXRfdGV4dChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCduYW1lJykpCiAqIFByb2R1Y2VzOiBtZXRhZGF0YSAtPj4gJ25hbWUnCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":415,"slug":"json-path","name":"json_path","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gcGF0aCBhY2Nlc3MgZXhwcmVzc2lvbiAoIz4pLgogKiBSZXR1cm5zIEpTT04uCiAqCiAqIEV4YW1wbGU6IGpzb25fcGF0aChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCd7Y2F0ZWdvcnksbmFtZX0nKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhICM+ICd7Y2F0ZWdvcnksbmFtZX0nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":432,"slug":"json-path-text","name":"json_path_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gcGF0aCBhY2Nlc3MgZXhwcmVzc2lvbiAoIz4+KS4KICogUmV0dXJucyB0ZXh0LgogKgogKiBFeGFtcGxlOiBqc29uX3BhdGhfdGV4dChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCd7Y2F0ZWdvcnksbmFtZX0nKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhICM+PiAne2NhdGVnb3J5LG5hbWV9JwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":448,"slug":"json-exists","name":"json_exists","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGtleSBleGlzdHMgY29uZGl0aW9uICg\/KS4KICoKICogRXhhbXBsZToganNvbl9leGlzdHMoY29sKCdtZXRhZGF0YScpLCBsaXRlcmFsX3N0cmluZygnY2F0ZWdvcnknKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhID8gJ2NhdGVnb3J5JwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":464,"slug":"json-exists-any","name":"json_exists_any","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGFueSBrZXkgZXhpc3RzIGNvbmRpdGlvbiAoP3wpLgogKgogKiBFeGFtcGxlOiBqc29uX2V4aXN0c19hbnkoY29sKCdtZXRhZGF0YScpLCBhcnJheV9leHByKFtsaXRlcmFsKCdjYXRlZ29yeScpLCBsaXRlcmFsKCduYW1lJyldKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhID98IGFycmF5WydjYXRlZ29yeScsICduYW1lJ10KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":480,"slug":"json-exists-all","name":"json_exists_all","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGFsbCBrZXlzIGV4aXN0IGNvbmRpdGlvbiAoPyYpLgogKgogKiBFeGFtcGxlOiBqc29uX2V4aXN0c19hbGwoY29sKCdtZXRhZGF0YScpLCBhcnJheV9leHByKFtsaXRlcmFsKCdjYXRlZ29yeScpLCBsaXRlcmFsKCduYW1lJyldKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhID8mIGFycmF5WydjYXRlZ29yeScsICduYW1lJ10KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":496,"slug":"array-contains","name":"array_contains","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBjb250YWlucyBjb25kaXRpb24gKEA+KS4KICoKICogRXhhbXBsZTogYXJyYXlfY29udGFpbnMoY29sKCd0YWdzJyksIGFycmF5X2V4cHIoW2xpdGVyYWwoJ3NhbGUnKV0pKQogKiBQcm9kdWNlczogdGFncyBAPiBBUlJBWVsnc2FsZSddCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":512,"slug":"array-contained-by","name":"array_contained_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBpcyBjb250YWluZWQgYnkgY29uZGl0aW9uICg8QCkuCiAqCiAqIEV4YW1wbGU6IGFycmF5X2NvbnRhaW5lZF9ieShjb2woJ3RhZ3MnKSwgYXJyYXlfZXhwcihbbGl0ZXJhbCgnc2FsZScpLCBsaXRlcmFsKCdmZWF0dXJlZCcpLCBsaXRlcmFsKCduZXcnKV0pKQogKiBQcm9kdWNlczogdGFncyA8QCBBUlJBWVsnc2FsZScsICdmZWF0dXJlZCcsICduZXcnXQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":528,"slug":"array-overlap","name":"array_overlap","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBvdmVybGFwIGNvbmRpdGlvbiAoJiYpLgogKgogKiBFeGFtcGxlOiBhcnJheV9vdmVybGFwKGNvbCgndGFncycpLCBhcnJheV9leHByKFtsaXRlcmFsKCdzYWxlJyksIGxpdGVyYWwoJ2ZlYXR1cmVkJyldKSkKICogUHJvZHVjZXM6IHRhZ3MgJiYgQVJSQVlbJ3NhbGUnLCAnZmVhdHVyZWQnXQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":546,"slug":"regex-match","name":"regex_match","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG1hdGNoIGNvbmRpdGlvbiAofikuCiAqIENhc2Utc2Vuc2l0aXZlLgogKgogKiBFeGFtcGxlOiByZWdleF9tYXRjaChjb2woJ2VtYWlsJyksIGxpdGVyYWxfc3RyaW5nKCcuKkBnbWFpbFxcLmNvbScpKQogKgogKiBQcm9kdWNlczogZW1haWwgfiAnLipAZ21haWxcLmNvbScKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":564,"slug":"regex-imatch","name":"regex_imatch","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG1hdGNoIGNvbmRpdGlvbiAofiopLgogKiBDYXNlLWluc2Vuc2l0aXZlLgogKgogKiBFeGFtcGxlOiByZWdleF9pbWF0Y2goY29sKCdlbWFpbCcpLCBsaXRlcmFsX3N0cmluZygnLipAZ21haWxcXC5jb20nKSkKICoKICogUHJvZHVjZXM6IGVtYWlsIH4qICcuKkBnbWFpbFwuY29tJwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":582,"slug":"not-regex-match","name":"not_regex_match","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG5vdCBtYXRjaCBjb25kaXRpb24gKCF+KS4KICogQ2FzZS1zZW5zaXRpdmUuCiAqCiAqIEV4YW1wbGU6IG5vdF9yZWdleF9tYXRjaChjb2woJ2VtYWlsJyksIGxpdGVyYWxfc3RyaW5nKCcuKkBzcGFtXFwuY29tJykpCiAqCiAqIFByb2R1Y2VzOiBlbWFpbCAhfiAnLipAc3BhbVwuY29tJwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":600,"slug":"not-regex-imatch","name":"not_regex_imatch","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG5vdCBtYXRjaCBjb25kaXRpb24gKCF+KikuCiAqIENhc2UtaW5zZW5zaXRpdmUuCiAqCiAqIEV4YW1wbGU6IG5vdF9yZWdleF9pbWF0Y2goY29sKCdlbWFpbCcpLCBsaXRlcmFsX3N0cmluZygnLipAc3BhbVxcLmNvbScpKQogKgogKiBQcm9kdWNlczogZW1haWwgIX4qICcuKkBzcGFtXC5jb20nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":616,"slug":"text-search-match","name":"text_search_match","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"document","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZ1bGwtdGV4dCBzZWFyY2ggbWF0Y2ggY29uZGl0aW9uIChAQCkuCiAqCiAqIEV4YW1wbGU6IHRleHRfc2VhcmNoX21hdGNoKGNvbCgnZG9jdW1lbnQnKSwgZnVuYygndG9fdHNxdWVyeScsIFtsaXRlcmFsKCdlbmdsaXNoJyksIGxpdGVyYWwoJ2hlbGxvICYgd29ybGQnKV0pKQogKiBQcm9kdWNlczogZG9jdW1lbnQgQEAgdG9fdHNxdWVyeSgnZW5nbGlzaCcsICdoZWxsbyAmIHdvcmxkJykKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":33,"slug":"sql-parser","name":"sql_parser","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"Parser","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":39,"slug":"sql-parse","name":"sql_parse","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":49,"slug":"sql-fingerprint","name":"sql_fingerprint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFJldHVybnMgYSBmaW5nZXJwcmludCBvZiB0aGUgZ2l2ZW4gU1FMIHF1ZXJ5LgogKiBMaXRlcmFsIHZhbHVlcyBhcmUgbm9ybWFsaXplZCBzbyB0aGV5IHdvbid0IGFmZmVjdCB0aGUgZmluZ2VycHJpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":60,"slug":"sql-normalize","name":"sql_normalize","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5vcm1hbGl6ZSBTUUwgcXVlcnkgYnkgcmVwbGFjaW5nIGxpdGVyYWwgdmFsdWVzIGFuZCBuYW1lZCBwYXJhbWV0ZXJzIHdpdGggcG9zaXRpb25hbCBwYXJhbWV0ZXJzLgogKiBXSEVSRSBpZCA9IDppZCB3aWxsIGJlIGNoYW5nZWQgaW50byBXSEVSRSBpZCA9ICQxCiAqIFdIRVJFIGlkID0gMSB3aWxsIGJlIGNoYW5nZWQgaW50byBXSEVSRSBpZCA9ICQxLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":70,"slug":"sql-normalize-utility","name":"sql_normalize_utility","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5vcm1hbGl6ZSB1dGlsaXR5IFNRTCBzdGF0ZW1lbnRzIChEREwgbGlrZSBDUkVBVEUsIEFMVEVSLCBEUk9QKS4KICogVGhpcyBoYW5kbGVzIERETCBzdGF0ZW1lbnRzIGRpZmZlcmVudGx5IGZyb20gcGdfbm9ybWFsaXplKCkgd2hpY2ggaXMgb3B0aW1pemVkIGZvciBETUwuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":81,"slug":"sql-split","name":"sql_split","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNwbGl0IHN0cmluZyB3aXRoIG11bHRpcGxlIFNRTCBzdGF0ZW1lbnRzIGludG8gYXJyYXkgb2YgaW5kaXZpZHVhbCBzdGF0ZW1lbnRzLgogKgogKiBAcmV0dXJuIGFycmF5PHN0cmluZz4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":90,"slug":"sql-deparse-options","name":"sql_deparse_options","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"DeparseOptions","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBEZXBhcnNlT3B0aW9ucyBmb3IgY29uZmlndXJpbmcgU1FMIGZvcm1hdHRpbmcuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":104,"slug":"sql-deparse","name":"sql_deparse","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"DeparseOptions","namespace":"Flow\\PostgreSql","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgYSBQYXJzZWRRdWVyeSBBU1QgYmFjayB0byBTUUwgc3RyaW5nLgogKgogKiBXaGVuIGNhbGxlZCB3aXRob3V0IG9wdGlvbnMsIHJldHVybnMgdGhlIFNRTCBhcyBhIHNpbXBsZSBzdHJpbmcuCiAqIFdoZW4gY2FsbGVkIHdpdGggRGVwYXJzZU9wdGlvbnMsIGFwcGxpZXMgZm9ybWF0dGluZyAocHJldHR5LXByaW50aW5nLCBpbmRlbnRhdGlvbiwgZXRjLikuCiAqCiAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gaWYgZGVwYXJzaW5nIGZhaWxzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":120,"slug":"sql-format","name":"sql_format","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"DeparseOptions","namespace":"Flow\\PostgreSql","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhcnNlIGFuZCBmb3JtYXQgU1FMIHF1ZXJ5IHdpdGggcHJldHR5IHByaW50aW5nLgogKgogKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgZnVuY3Rpb24gdGhhdCBwYXJzZXMgU1FMIGFuZCByZXR1cm5zIGl0IGZvcm1hdHRlZC4KICoKICogQHBhcmFtIHN0cmluZyAkc3FsIFRoZSBTUUwgcXVlcnkgdG8gZm9ybWF0CiAqIEBwYXJhbSBudWxsfERlcGFyc2VPcHRpb25zICRvcHRpb25zIEZvcm1hdHRpbmcgb3B0aW9ucyAoZGVmYXVsdHMgdG8gcHJldHR5LXByaW50IGVuYWJsZWQpCiAqCiAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gaWYgcGFyc2luZyBvciBkZXBhcnNpbmcgZmFpbHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":132,"slug":"sql-summary","name":"sql_summary","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"truncateLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdlbmVyYXRlIGEgc3VtbWFyeSBvZiBwYXJzZWQgcXVlcmllcyBpbiBwcm90b2J1ZiBmb3JtYXQuCiAqIFVzZWZ1bCBmb3IgcXVlcnkgbW9uaXRvcmluZyBhbmQgbG9nZ2luZyB3aXRob3V0IGZ1bGwgQVNUIG92ZXJoZWFkLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":147,"slug":"sql-to-paginated-query","name":"sql_to_paginated_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"offset","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGEgcGFnaW5hdGVkIHF1ZXJ5IHdpdGggTElNSVQgYW5kIE9GRlNFVC4KICoKICogQHBhcmFtIHN0cmluZyAkc3FsIFRoZSBTUUwgcXVlcnkgdG8gcGFnaW5hdGUKICogQHBhcmFtIGludCAkbGltaXQgTWF4aW11bSBudW1iZXIgb2Ygcm93cyB0byByZXR1cm4KICogQHBhcmFtIGludCAkb2Zmc2V0IE51bWJlciBvZiByb3dzIHRvIHNraXAgKHJlcXVpcmVzIE9SREVSIEJZIGluIHF1ZXJ5KQogKgogKiBAcmV0dXJuIHN0cmluZyBUaGUgcGFnaW5hdGVkIFNRTCBxdWVyeQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":164,"slug":"sql-to-limited-query","name":"sql_to_limited_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSB0byBsaW1pdCByZXN1bHRzIHRvIGEgc3BlY2lmaWMgbnVtYmVyIG9mIHJvd3MuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHNxbCBUaGUgU1FMIHF1ZXJ5IHRvIGxpbWl0CiAqIEBwYXJhbSBpbnQgJGxpbWl0IE1heGltdW0gbnVtYmVyIG9mIHJvd3MgdG8gcmV0dXJuCiAqCiAqIEByZXR1cm4gc3RyaW5nIFRoZSBsaW1pdGVkIFNRTCBxdWVyeQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":183,"slug":"sql-to-count-query","name":"sql_to_count_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGEgQ09VTlQgcXVlcnkgZm9yIHBhZ2luYXRpb24uCiAqCiAqIFdyYXBzIHRoZSBxdWVyeSBpbjogU0VMRUNUIENPVU5UKCopIEZST00gKC4uLikgQVMgX2NvdW50X3N1YnEKICogUmVtb3ZlcyBPUkRFUiBCWSBhbmQgTElNSVQvT0ZGU0VUIGZyb20gdGhlIGlubmVyIHF1ZXJ5LgogKgogKiBAcGFyYW0gc3RyaW5nICRzcWwgVGhlIFNRTCBxdWVyeSB0byB0cmFuc2Zvcm0KICoKICogQHJldHVybiBzdHJpbmcgVGhlIENPVU5UIHF1ZXJ5CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":205,"slug":"sql-to-keyset-query","name":"sql_to_keyset_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"cursor","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGEga2V5c2V0IChjdXJzb3ItYmFzZWQpIHBhZ2luYXRlZCBxdWVyeS4KICoKICogTW9yZSBlZmZpY2llbnQgdGhhbiBPRkZTRVQgZm9yIGxhcmdlIGRhdGFzZXRzIC0gdXNlcyBpbmRleGVkIFdIRVJFIGNvbmRpdGlvbnMuCiAqIEF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBleGlzdGluZyBxdWVyeSBwYXJhbWV0ZXJzIGFuZCBhcHBlbmRzIGtleXNldCBwbGFjZWhvbGRlcnMgYXQgdGhlIGVuZC4KICoKICogQHBhcmFtIHN0cmluZyAkc3FsIFRoZSBTUUwgcXVlcnkgdG8gcGFnaW5hdGUgKG11c3QgaGF2ZSBPUkRFUiBCWSkKICogQHBhcmFtIGludCAkbGltaXQgTWF4aW11bSBudW1iZXIgb2Ygcm93cyB0byByZXR1cm4KICogQHBhcmFtIGxpc3Q8S2V5c2V0Q29sdW1uPiAkY29sdW1ucyBDb2x1bW5zIGZvciBrZXlzZXQgcGFnaW5hdGlvbiAobXVzdCBtYXRjaCBPUkRFUiBCWSkKICogQHBhcmFtIG51bGx8bGlzdDxudWxsfGJvb2x8ZmxvYXR8aW50fHN0cmluZz4gJGN1cnNvciBWYWx1ZXMgZnJvbSBsYXN0IHJvdyBvZiBwcmV2aW91cyBwYWdlIChudWxsIGZvciBmaXJzdCBwYWdlKQogKgogKiBAcmV0dXJuIHN0cmluZyBUaGUgcGFnaW5hdGVkIFNRTCBxdWVyeQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":220,"slug":"sql-keyset-column","name":"sql_keyset_column","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\AST\\Transformers\\SortOrder::..."}],"return_type":[{"name":"KeysetColumn","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEtleXNldENvbHVtbiBmb3Iga2V5c2V0IHBhZ2luYXRpb24uCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNvbHVtbiBDb2x1bW4gbmFtZSAoY2FuIGluY2x1ZGUgdGFibGUgYWxpYXMgbGlrZSAidS5pZCIpCiAqIEBwYXJhbSBTb3J0T3JkZXIgJG9yZGVyIFNvcnQgb3JkZXIgKEFTQyBvciBERVNDKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":229,"slug":"sql-query-columns","name":"sql_query_columns","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Columns","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgY29sdW1ucyBmcm9tIGEgcGFyc2VkIFNRTCBxdWVyeS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":238,"slug":"sql-query-tables","name":"sql_query_tables","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Tables","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgdGFibGVzIGZyb20gYSBwYXJzZWQgU1FMIHF1ZXJ5LgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":247,"slug":"sql-query-functions","name":"sql_query_functions","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Functions","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgZnVuY3Rpb25zIGZyb20gYSBwYXJzZWQgU1FMIHF1ZXJ5LgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":256,"slug":"sql-query-order-by","name":"sql_query_order_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgT1JERVIgQlkgY2xhdXNlcyBmcm9tIGEgcGFyc2VkIFNRTCBxdWVyeS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":270,"slug":"sql-query-depth","name":"sql_query_depth","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgbWF4aW11bSBuZXN0aW5nIGRlcHRoIG9mIGEgU1FMIHF1ZXJ5LgogKgogKiBFeGFtcGxlOgogKiAtICJTRUxFQ1QgKiBGUk9NIHQiID0+IDEKICogLSAiU0VMRUNUICogRlJPTSAoU0VMRUNUICogRlJPTSB0KSIgPT4gMgogKiAtICJTRUxFQ1QgKiBGUk9NIChTRUxFQ1QgKiBGUk9NIChTRUxFQ1QgKiBGUk9NIHQpKSIgPT4gMwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":287,"slug":"sql-to-explain","name":"sql_to_explain","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"config","type":[{"name":"ExplainConfig","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGFuIEVYUExBSU4gcXVlcnkuCiAqCiAqIFJldHVybnMgdGhlIG1vZGlmaWVkIFNRTCB3aXRoIEVYUExBSU4gd3JhcHBlZCBhcm91bmQgaXQuCiAqIERlZmF1bHRzIHRvIEVYUExBSU4gQU5BTFlaRSB3aXRoIEpTT04gZm9ybWF0IGZvciBlYXN5IHBhcnNpbmcuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHNxbCBUaGUgU1FMIHF1ZXJ5IHRvIGV4cGxhaW4KICogQHBhcmFtIG51bGx8RXhwbGFpbkNvbmZpZyAkY29uZmlnIEVYUExBSU4gY29uZmlndXJhdGlvbiAoZGVmYXVsdHMgdG8gZm9yQW5hbHlzaXMoKSkKICoKICogQHJldHVybiBzdHJpbmcgVGhlIEVYUExBSU4gcXVlcnkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":307,"slug":"sql-explain-config","name":"sql_explain_config","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"analyze","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"verbose","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"costs","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"buffers","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"timing","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"format","type":[{"name":"ExplainFormat","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Utility\\ExplainFormat::..."}],"return_type":[{"name":"ExplainConfig","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFeHBsYWluQ29uZmlnIGZvciBjdXN0b21pemluZyBFWFBMQUlOIG9wdGlvbnMuCiAqCiAqIEBwYXJhbSBib29sICRhbmFseXplIFdoZXRoZXIgdG8gYWN0dWFsbHkgZXhlY3V0ZSB0aGUgcXVlcnkgKEFOQUxZWkUpCiAqIEBwYXJhbSBib29sICR2ZXJib3NlIEluY2x1ZGUgdmVyYm9zZSBvdXRwdXQKICogQHBhcmFtIGJvb2wgJGNvc3RzIEluY2x1ZGUgY29zdCBlc3RpbWF0ZXMgKGRlZmF1bHQgdHJ1ZSkKICogQHBhcmFtIGJvb2wgJGJ1ZmZlcnMgSW5jbHVkZSBidWZmZXIgdXNhZ2Ugc3RhdGlzdGljcyAocmVxdWlyZXMgYW5hbHl6ZSkKICogQHBhcmFtIGJvb2wgJHRpbWluZyBJbmNsdWRlIHRpbWluZyBpbmZvcm1hdGlvbiAocmVxdWlyZXMgYW5hbHl6ZSkKICogQHBhcmFtIEV4cGxhaW5Gb3JtYXQgJGZvcm1hdCBPdXRwdXQgZm9ybWF0IChKU09OIHJlY29tbWVuZGVkIGZvciBwYXJzaW5nKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":329,"slug":"sql-explain-modifier","name":"sql_explain_modifier","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"config","type":[{"name":"ExplainConfig","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExplainModifier","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFeHBsYWluTW9kaWZpZXIgZm9yIHRyYW5zZm9ybWluZyBxdWVyaWVzIGludG8gRVhQTEFJTiBxdWVyaWVzLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":342,"slug":"sql-explain-parse","name":"sql_explain_parse","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"jsonOutput","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Plan","namespace":"Flow\\PostgreSql\\Explain\\Plan","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhcnNlIEVYUExBSU4gSlNPTiBvdXRwdXQgaW50byBhIFBsYW4gb2JqZWN0LgogKgogKiBAcGFyYW0gc3RyaW5nICRqc29uT3V0cHV0IFRoZSBKU09OIG91dHB1dCBmcm9tIEVYUExBSU4gKEZPUk1BVCBKU09OKQogKgogKiBAcmV0dXJuIFBsYW4gVGhlIHBhcnNlZCBleGVjdXRpb24gcGxhbgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":355,"slug":"sql-analyze","name":"sql_analyze","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"plan","type":[{"name":"Plan","namespace":"Flow\\PostgreSql\\Explain\\Plan","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PlanAnalyzer","namespace":"Flow\\PostgreSql\\Explain\\Analyzer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHBsYW4gYW5hbHl6ZXIgZm9yIGFuYWx5emluZyBFWFBMQUlOIHBsYW5zLgogKgogKiBAcGFyYW0gUGxhbiAkcGxhbiBUaGUgZXhlY3V0aW9uIHBsYW4gdG8gYW5hbHl6ZQogKgogKiBAcmV0dXJuIFBsYW5BbmFseXplciBUaGUgYW5hbHl6ZXIgZm9yIGV4dHJhY3RpbmcgaW5zaWdodHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":45,"slug":"pgsql-connection","name":"pgsql_connection","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"connectionString","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgZnJvbSBhIGNvbm5lY3Rpb24gc3RyaW5nLgogKgogKiBBY2NlcHRzIGxpYnBxLXN0eWxlIGNvbm5lY3Rpb24gc3RyaW5nczoKICogLSBLZXktdmFsdWUgZm9ybWF0OiAiaG9zdD1sb2NhbGhvc3QgcG9ydD01NDMyIGRibmFtZT1teWRiIHVzZXI9bXl1c2VyIHBhc3N3b3JkPXNlY3JldCIKICogLSBVUkkgZm9ybWF0OiAicG9zdGdyZXNxbDovL3VzZXI6cGFzc3dvcmRAbG9jYWxob3N0OjU0MzIvZGJuYW1lIgogKgogKiBAZXhhbXBsZQogKiAkcGFyYW1zID0gcGdzcWxfY29ubmVjdGlvbignaG9zdD1sb2NhbGhvc3QgZGJuYW1lPW15ZGInKTsKICogJHBhcmFtcyA9IHBnc3FsX2Nvbm5lY3Rpb24oJ3Bvc3RncmVzcWw6Ly91c2VyOnBhc3NAbG9jYWxob3N0L215ZGInKTsKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":67,"slug":"pgsql-connection-dsn","name":"pgsql_connection_dsn","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"dsn","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgZnJvbSBhIERTTiBzdHJpbmcuCiAqCiAqIFBhcnNlcyBzdGFuZGFyZCBQb3N0Z3JlU1FMIERTTiBmb3JtYXQgY29tbW9ubHkgdXNlZCBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZXMKICogKGUuZy4sIERBVEFCQVNFX1VSTCkuIFN1cHBvcnRzIHBvc3RncmVzOi8vLCBwb3N0Z3Jlc3FsOi8vLCBhbmQgcGdzcWw6Ly8gc2NoZW1lcy4KICoKICogQHBhcmFtIHN0cmluZyAkZHNuIERTTiBzdHJpbmcgaW4gZm9ybWF0OiBwb3N0Z3JlczovL3VzZXI6cGFzc3dvcmRAaG9zdDpwb3J0L2RhdGFiYXNlP29wdGlvbnMKICoKICogQHRocm93cyBDbGllbnRcRHNuUGFyc2VyRXhjZXB0aW9uIElmIHRoZSBEU04gY2Fubm90IGJlIHBhcnNlZAogKgogKiBAZXhhbXBsZQogKiAkcGFyYW1zID0gcGdzcWxfY29ubmVjdGlvbl9kc24oJ3Bvc3RncmVzOi8vbXl1c2VyOnNlY3JldEBsb2NhbGhvc3Q6NTQzMi9teWRiJyk7CiAqICRwYXJhbXMgPSBwZ3NxbF9jb25uZWN0aW9uX2RzbigncG9zdGdyZXNxbDovL3VzZXI6cGFzc0BkYi5leGFtcGxlLmNvbS9hcHA\/c3NsbW9kZT1yZXF1aXJlJyk7CiAqICRwYXJhbXMgPSBwZ3NxbF9jb25uZWN0aW9uX2RzbigncGdzcWw6Ly91c2VyOnBhc3NAbG9jYWxob3N0L215ZGInKTsgLy8gU3ltZm9ueS9Eb2N0cmluZSBmb3JtYXQKICogJHBhcmFtcyA9IHBnc3FsX2Nvbm5lY3Rpb25fZHNuKGdldGVudignREFUQUJBU0VfVVJMJykpOwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":94,"slug":"pgsql-connection-params","name":"pgsql_connection_params","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"database","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'localhost'"},{"name":"port","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"5432"},{"name":"user","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"password","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgZnJvbSBpbmRpdmlkdWFsIHZhbHVlcy4KICoKICogQWxsb3dzIHNwZWNpZnlpbmcgY29ubmVjdGlvbiBwYXJhbWV0ZXJzIGluZGl2aWR1YWxseSBmb3IgYmV0dGVyIHR5cGUgc2FmZXR5CiAqIGFuZCBJREUgc3VwcG9ydC4KICoKICogQHBhcmFtIHN0cmluZyAkZGF0YWJhc2UgRGF0YWJhc2UgbmFtZSAocmVxdWlyZWQpCiAqIEBwYXJhbSBzdHJpbmcgJGhvc3QgSG9zdG5hbWUgKGRlZmF1bHQ6IGxvY2FsaG9zdCkKICogQHBhcmFtIGludCAkcG9ydCBQb3J0IG51bWJlciAoZGVmYXVsdDogNTQzMikKICogQHBhcmFtIG51bGx8c3RyaW5nICR1c2VyIFVzZXJuYW1lIChvcHRpb25hbCkKICogQHBhcmFtIG51bGx8c3RyaW5nICRwYXNzd29yZCBQYXNzd29yZCAob3B0aW9uYWwpCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJG9wdGlvbnMgQWRkaXRpb25hbCBsaWJwcSBvcHRpb25zCiAqCiAqIEBleGFtcGxlCiAqICRwYXJhbXMgPSBwZ3NxbF9jb25uZWN0aW9uX3BhcmFtcygKICogICAgIGRhdGFiYXNlOiAnbXlkYicsCiAqICAgICBob3N0OiAnbG9jYWxob3N0JywKICogICAgIHVzZXI6ICdteXVzZXInLAogKiAgICAgcGFzc3dvcmQ6ICdzZWNyZXQnLAogKiApOwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":125,"slug":"pgsql-client","name":"pgsql_client","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"params","type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"valueConverters","type":[{"name":"ValueConverters","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"context","type":[{"name":"Context","namespace":"Flow\\PostgreSql\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Client","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBvc3RncmVTUUwgY2xpZW50IHVzaW5nIGV4dC1wZ3NxbC4KICoKICogVGhlIGNsaWVudCBjb25uZWN0cyBpbW1lZGlhdGVseSBhbmQgaXMgcmVhZHkgdG8gZXhlY3V0ZSBxdWVyaWVzLgogKgogKiBAcGFyYW0gQ2xpZW50XENvbm5lY3Rpb25QYXJhbWV0ZXJzICRwYXJhbXMgQ29ubmVjdGlvbiBwYXJhbWV0ZXJzCiAqIEBwYXJhbSBudWxsfFZhbHVlQ29udmVydGVycyAkdmFsdWVDb252ZXJ0ZXJzIEN1c3RvbSB0eXBlIGNvbnZlcnRlcnMgKG9wdGlvbmFsKQogKiBAcGFyYW0gbnVsbHxDb250ZXh0ICRjb250ZXh0IEJhc2UgbWFwcGVyIENvbnRleHQg4oCUIHRoZSBDbGllbnQgZW5yaWNoZXMgaXQgd2l0aCBzcWwvcGFyYW1ldGVycy9zZWxmIHBlciBxdWVyeSBiZWZvcmUgaGFuZGluZyBpdCB0byBSb3dNYXBwZXI6Om1hcCgpCiAqCiAqIEB0aHJvd3MgQ29ubmVjdGlvbkV4Y2VwdGlvbiBJZiBjb25uZWN0aW9uIGZhaWxzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":142,"slug":"postgresql-context","name":"postgresql_context","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"catalog","type":[{"name":"Catalog","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Context","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJvd01hcHBlciBDb250ZXh0IHNlZWRlZCB3aXRoIHVzZXItc3VwcGxpZWQga2V5L3ZhbHVlIGRhdGEgYW5kIGFuIG9wdGlvbmFsIENhdGFsb2cuCiAqCiAqIFRoZSBDb250ZXh0IGlzIGxhdGVyIGVucmljaGVkIHdpdGggYSBRdWVyeSAoc3FsICsgcGFyYW1ldGVycykgYW5kIHRoZSBleGVjdXRpbmcgQ2xpZW50IGJ5IHRoZQogKiBQb3N0Z3JlU1FMIENsaWVudCBiZWZvcmUgYmVpbmcgaGFuZGVkIHRvIFJvd01hcHBlcjo6bWFwKCkuCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPiAkZGF0YSBVc2VyLXN1cHBsaWVkIGtleS92YWx1ZSBwYWlycwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":175,"slug":"postgresql-telemetry-options","name":"postgresql_telemetry_options","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"traceQueries","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"transactionSpans","type":[{"name":"TransactionSpanMode","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\Client\\Telemetry\\TransactionSpanMode::..."},{"name":"collectMetrics","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"logQueries","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"maxQueryLength","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"1000"},{"name":"includeParameters","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"maxParameters","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"10"},{"name":"maxParameterLength","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"100"}],"return_type":[{"name":"PostgreSqlTelemetryOptions","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSB0ZWxlbWV0cnkgb3B0aW9ucyBmb3IgUG9zdGdyZVNRTCBjbGllbnQgaW5zdHJ1bWVudGF0aW9uLgogKgogKiBDb250cm9scyB3aGljaCB0ZWxlbWV0cnkgc2lnbmFscyAodHJhY2VzLCBtZXRyaWNzLCBsb2dzKSBhcmUgZW5hYmxlZAogKiBhbmQgaG93IHF1ZXJ5IGluZm9ybWF0aW9uIGlzIGNhcHR1cmVkLgogKgogKiBAcGFyYW0gYm9vbCAkdHJhY2VRdWVyaWVzIENyZWF0ZSBzcGFucyBmb3IgcXVlcnkgZXhlY3V0aW9uIChkZWZhdWx0OiB0cnVlKQogKiBAcGFyYW0gVHJhbnNhY3Rpb25TcGFuTW9kZSAkdHJhbnNhY3Rpb25TcGFucyBIb3cgdHJhbnNhY3Rpb25zIGFyZSB0cmFjZWQ6IEdST1VQRUQgKGRlZmF1bHQpLCBQRVJfT1BFUkFUSU9OIG9yIE9GRgogKiBAcGFyYW0gYm9vbCAkY29sbGVjdE1ldHJpY3MgQ29sbGVjdCBkdXJhdGlvbiBhbmQgcm93IGNvdW50IG1ldHJpY3MgKGRlZmF1bHQ6IHRydWUpCiAqIEBwYXJhbSBib29sICRsb2dRdWVyaWVzIExvZyBleGVjdXRlZCBxdWVyaWVzIChkZWZhdWx0OiBmYWxzZSkKICogQHBhcmFtIG51bGx8aW50ICRtYXhRdWVyeUxlbmd0aCBNYXhpbXVtIHF1ZXJ5IHRleHQgbGVuZ3RoIGluIHRlbGVtZXRyeSAoZGVmYXVsdDogMTAwMCwgbnVsbCA9IHVubGltaXRlZCkKICogQHBhcmFtIGJvb2wgJGluY2x1ZGVQYXJhbWV0ZXJzIEluY2x1ZGUgcXVlcnkgcGFyYW1ldGVycyBpbiB0ZWxlbWV0cnkgKGRlZmF1bHQ6IGZhbHNlLCBzZWN1cml0eSBjb25zaWRlcmF0aW9uKQogKgogKiBAZXhhbXBsZQogKiAvLyBEZWZhdWx0IG9wdGlvbnMgKHRyYWNlcyBhbmQgbWV0cmljcyBlbmFibGVkKQogKiAkb3B0aW9ucyA9IHBvc3RncmVzcWxfdGVsZW1ldHJ5X29wdGlvbnMoKTsKICoKICogLy8gRW5hYmxlIHF1ZXJ5IGxvZ2dpbmcKICogJG9wdGlvbnMgPSBwb3N0Z3Jlc3FsX3RlbGVtZXRyeV9vcHRpb25zKGxvZ1F1ZXJpZXM6IHRydWUpOwogKgogKiAvLyBNZXRyaWNzIG9ubHksIG5vIHNwYW5zCiAqICRvcHRpb25zID0gcG9zdGdyZXNxbF90ZWxlbWV0cnlfb3B0aW9ucygKICogICAgIHRyYWNlUXVlcmllczogZmFsc2UsCiAqICAgICB0cmFuc2FjdGlvblNwYW5zOiBUcmFuc2FjdGlvblNwYW5Nb2RlOjpPRkYsCiAqICAgICBjb2xsZWN0TWV0cmljczogdHJ1ZSwKICogKTsKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":213,"slug":"postgresql-telemetry-config","name":"postgresql_telemetry_config","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"telemetry","type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"PostgreSqlTelemetryOptions","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"PostgreSqlTelemetryConfig","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiBmb3IgUG9zdGdyZVNRTCBjbGllbnQuCiAqCiAqIEJ1bmRsZXMgdGVsZW1ldHJ5IGluc3RhbmNlLCBjbG9jaywgYW5kIG9wdGlvbnMgbmVlZGVkIHRvIGluc3RydW1lbnQgYSBQb3N0Z3JlU1FMIGNsaWVudC4KICoKICogQHBhcmFtIFRlbGVtZXRyeSAkdGVsZW1ldHJ5IFRoZSB0ZWxlbWV0cnkgaW5zdGFuY2UKICogQHBhcmFtIENsb2NrSW50ZXJmYWNlICRjbG9jayBDbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gbnVsbHxQb3N0Z3JlU3FsVGVsZW1ldHJ5T3B0aW9ucyAkb3B0aW9ucyBUZWxlbWV0cnkgb3B0aW9ucyAoZGVmYXVsdDogYWxsIGVuYWJsZWQpCiAqCiAqIEBleGFtcGxlCiAqICRjb25maWcgPSBwb3N0Z3Jlc3FsX3RlbGVtZXRyeV9jb25maWcoCiAqICAgICB0ZWxlbWV0cnkocmVzb3VyY2UoWydzZXJ2aWNlLm5hbWUnID0+ICdteS1hcHAnXSkpLAogKiAgICAgbmV3IFN5c3RlbUNsb2NrKCksCiAqICk7CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":259,"slug":"traceable-postgresql-client","name":"traceable_postgresql_client","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"client","type":[{"name":"Client","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"telemetryConfig","type":[{"name":"PostgreSqlTelemetryConfig","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TraceableClient","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYSBQb3N0Z3JlU1FMIGNsaWVudCB3aXRoIHRlbGVtZXRyeSBpbnN0cnVtZW50YXRpb24uCiAqCiAqIFJldHVybnMgYSBkZWNvcmF0b3IgdGhhdCBhZGRzIHNwYW5zLCBtZXRyaWNzLCBhbmQgbG9ncyB0byBhbGwKICogcXVlcnkgYW5kIHRyYW5zYWN0aW9uIG9wZXJhdGlvbnMgZm9sbG93aW5nIE9wZW5UZWxlbWV0cnkgY29udmVudGlvbnMuCiAqCiAqIEBwYXJhbSBDbGllbnRcQ2xpZW50ICRjbGllbnQgVGhlIFBvc3RncmVTUUwgY2xpZW50IHRvIGluc3RydW1lbnQKICogQHBhcmFtIFBvc3RncmVTcWxUZWxlbWV0cnlDb25maWcgJHRlbGVtZXRyeUNvbmZpZyBUZWxlbWV0cnkgY29uZmlndXJhdGlvbgogKgogKiBAZXhhbXBsZQogKiAkY2xpZW50ID0gcGdzcWxfY2xpZW50KHBnc3FsX2Nvbm5lY3Rpb24oJ2hvc3Q9bG9jYWxob3N0IGRibmFtZT1teWRiJykpOwogKgogKiAkdHJhY2VhYmxlQ2xpZW50ID0gdHJhY2VhYmxlX3Bvc3RncmVzcWxfY2xpZW50KAogKiAgICAgJGNsaWVudCwKICogICAgIHBvc3RncmVzcWxfdGVsZW1ldHJ5X2NvbmZpZygKICogICAgICAgICB0ZWxlbWV0cnkocmVzb3VyY2UoWydzZXJ2aWNlLm5hbWUnID0+ICdteS1hcHAnXSkpLAogKiAgICAgICAgIG5ldyBTeXN0ZW1DbG9jaygpLAogKiAgICAgICAgIHBvc3RncmVzcWxfdGVsZW1ldHJ5X29wdGlvbnMoCiAqICAgICAgICAgICAgIHRyYWNlUXVlcmllczogdHJ1ZSwKICogICAgICAgICAgICAgdHJhbnNhY3Rpb25TcGFuczogVHJhbnNhY3Rpb25TcGFuTW9kZTo6R1JPVVBFRCwKICogICAgICAgICAgICAgY29sbGVjdE1ldHJpY3M6IHRydWUsCiAqICAgICAgICAgICAgIGxvZ1F1ZXJpZXM6IHRydWUsCiAqICAgICAgICAgICAgIG1heFF1ZXJ5TGVuZ3RoOiA1MDAsCiAqICAgICAgICAgKSwKICogICAgICksCiAqICk7CiAqCiAqIC8vIEFsbCBvcGVyYXRpb25zIG5vdyB0cmFjZWQKICogJHRyYWNlYWJsZUNsaWVudC0+dHJhbnNhY3Rpb24oZnVuY3Rpb24gKENsaWVudCAkY2xpZW50KSB7CiAqICAgICAkdXNlciA9ICRjbGllbnQtPmZldGNoU2luZ2xlKCdTRUxFQ1QgKiBGUk9NIHVzZXJzIFdIRVJFIGlkID0gJDEnLCBbMTIzXSk7CiAqICAgICAkY2xpZW50LT5leGVjdXRlKCdVUERBVEUgdXNlcnMgU0VUIGxhc3RfbG9naW4gPSBOT1coKSBXSEVSRSBpZCA9ICQxJywgWzEyM10pOwogKiB9KTsKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":299,"slug":"constructor-mapper","name":"constructor_mapper","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConstructorMapper","namespace":"Flow\\PostgreSql\\Client\\RowMapper","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICRjbGFzcwogKgogKiBAcmV0dXJuIENvbnN0cnVjdG9yTWFwcGVyPFQ+CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":314,"slug":"type-mapper","name":"type_mapper","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"next","type":[{"name":"RowMapper","namespace":"Flow\\PostgreSql\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TypeMapper","namespace":"Flow\\PostgreSql\\Client\\RowMapper","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUVHlwZQogKiBAdGVtcGxhdGUgVE91dAogKgogKiBAcGFyYW0gRmxvd1R5cGU8VFR5cGU+ICR0eXBlCiAqIEBwYXJhbSBudWxsfFJvd01hcHBlcjxUT3V0PiAkbmV4dAogKgogKiBAcmV0dXJuICgkbmV4dCBpcyBudWxsID8gVHlwZU1hcHBlcjxUVHlwZSwgVFR5cGU+IDogVHlwZU1hcHBlcjxUVHlwZSwgVE91dD4pCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":342,"slug":"static-factory-mapper","name":"static_factory_mapper","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"method","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"StaticFactoryMapper","namespace":"Flow\\PostgreSql\\Client\\RowMapper","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJvdyBtYXBwZXIgYmFja2VkIGJ5IGEgcHVibGljIHN0YXRpYyBmYWN0b3J5IG1ldGhvZC4KICoKICogVGhlIGZhY3RvcnkgbWV0aG9kIG11c3QgYWNjZXB0IGEgc2luZ2xlIGFycmF5PHN0cmluZywgbWl4ZWQ+ICRyb3cgYW5kIHJldHVybgogKiBhbiBpbnN0YW5jZSBvZiB0aGUgdGFyZ2V0IGNsYXNzLiBJZiB5b3VyIGZhY3RvcnkgbmVlZHMgYWNjZXNzIHRvIHRoZSBtYXBwaW5nCiAqIENvbnRleHQgKHNxbC9wYXJhbWV0ZXJzL2NsaWVudC9jYXRhbG9nL3VzZXItZGF0YSksIGltcGxlbWVudCBSb3dNYXBwZXIgZGlyZWN0bHkuCiAqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICRjbGFzcwogKiBAcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkbWV0aG9kCiAqCiAqIEByZXR1cm4gU3RhdGljRmFjdG9yeU1hcHBlcjxUPgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":371,"slug":"typed","name":"typed","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"targetType","type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TypedValue","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYSB2YWx1ZSB3aXRoIGV4cGxpY2l0IFBvc3RncmVTUUwgdHlwZSBpbmZvcm1hdGlvbiBmb3IgcGFyYW1ldGVyIGJpbmRpbmcuCiAqCiAqIFVzZSB3aGVuIGF1dG8tZGV0ZWN0aW9uIGlzbid0IHN1ZmZpY2llbnQgb3Igd2hlbiB5b3UgbmVlZCB0byBzcGVjaWZ5CiAqIHRoZSBleGFjdCBQb3N0Z3JlU1FMIHR5cGUgKHNpbmNlIG9uZSBQSFAgdHlwZSBjYW4gbWFwIHRvIG11bHRpcGxlIFBvc3RncmVTUUwgdHlwZXMpOgogKiAtIGludCBjb3VsZCBiZSBJTlQyLCBJTlQ0LCBvciBJTlQ4CiAqIC0gc3RyaW5nIGNvdWxkIGJlIFRFWFQsIFZBUkNIQVIsIG9yIENIQVIKICogLSBhcnJheSBtdXN0IGFsd2F5cyB1c2UgdHlwZWQoKSBzaW5jZSBhdXRvLWRldGVjdGlvbiBjYW5ub3QgZGV0ZXJtaW5lIGVsZW1lbnQgdHlwZQogKiAtIERhdGVUaW1lSW50ZXJmYWNlIGNvdWxkIGJlIFRJTUVTVEFNUCBvciBUSU1FU1RBTVBUWgogKiAtIEpzb24gY291bGQgYmUgSlNPTiBvciBKU09OQgogKgogKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFRoZSB2YWx1ZSB0byBiaW5kCiAqIEBwYXJhbSBWYWx1ZVR5cGUgJHRhcmdldFR5cGUgVGhlIFBvc3RncmVTUUwgdHlwZSB0byBjb252ZXJ0IHRoZSB2YWx1ZSB0bwogKgogKiBAZXhhbXBsZQogKiAkY2xpZW50LT5mZXRjaCgKICogICAgICdTRUxFQ1QgKiBGUk9NIHVzZXJzIFdIRVJFIGlkID0gJDEgQU5EIHRhZ3MgPSAkMicsCiAqICAgICBbCiAqICAgICAgICAgdHlwZWQoJzU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCcsIFZhbHVlVHlwZTo6VVVJRCksCiAqICAgICAgICAgdHlwZWQoWyd0YWcxJywgJ3RhZzInXSwgVmFsdWVUeXBlOjpURVhUX0FSUkFZKSwKICogICAgIF0KICogKTsKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":126,"slug":"trace-id","name":"trace_id","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"hex","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TraceId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlSWQuCiAqCiAqIElmIGEgaGV4IHN0cmluZyBpcyBwcm92aWRlZCwgY3JlYXRlcyBhIFRyYWNlSWQgZnJvbSBpdC4KICogT3RoZXJ3aXNlLCBnZW5lcmF0ZXMgYSBuZXcgcmFuZG9tIFRyYWNlSWQuCiAqCiAqIEBwYXJhbSBudWxsfHN0cmluZyAkaGV4IE9wdGlvbmFsIDMyLWNoYXJhY3RlciBoZXhhZGVjaW1hbCBzdHJpbmcKICoKICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBoZXggc3RyaW5nIGlzIGludmFsaWQKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":146,"slug":"span-id","name":"span_id","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"hex","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SpanId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5JZC4KICoKICogSWYgYSBoZXggc3RyaW5nIGlzIHByb3ZpZGVkLCBjcmVhdGVzIGEgU3BhbklkIGZyb20gaXQuCiAqIE90aGVyd2lzZSwgZ2VuZXJhdGVzIGEgbmV3IHJhbmRvbSBTcGFuSWQuCiAqCiAqIEBwYXJhbSBudWxsfHN0cmluZyAkaGV4IE9wdGlvbmFsIDE2LWNoYXJhY3RlciBoZXhhZGVjaW1hbCBzdHJpbmcKICoKICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBoZXggc3RyaW5nIGlzIGludmFsaWQKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":161,"slug":"baggage","name":"baggage","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"entries","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Baggage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhZ2dhZ2UuCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJGVudHJpZXMgSW5pdGlhbCBrZXktdmFsdWUgZW50cmllcwogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":175,"slug":"context","name":"context","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"baggage","type":[{"name":"Baggage","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Context","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJvb3QgQ29udGV4dCAobm8gYWN0aXZlIHNwYW4pLgogKgogKiBBIHNwYW4gY3JlYXRlZCBpbiB0aGlzIGNvbnRleHQgYmVjb21lcyBhIG5ldyB0cmFjZSByb290LiBBdHRhY2ggYW4gYWN0aXZlIHNwYW4gd2l0aAogKiBDb250ZXh0Ojp3aXRoQWN0aXZlU3BhbigpIHRvIG1ha2Ugc3Vic2VxdWVudCBzcGFucyBpdHMgY2hpbGRyZW4uCiAqCiAqIEBwYXJhbSBudWxsfEJhZ2dhZ2UgJGJhZ2dhZ2UgT3B0aW9uYWwgQmFnZ2FnZSB0byB1c2UKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":189,"slug":"memory-context-storage","name":"memory_context_storage","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"context","type":[{"name":"Context","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MemoryContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeUNvbnRleHRTdG9yYWdlLgogKgogKiBJbi1tZW1vcnkgY29udGV4dCBzdG9yYWdlIGZvciBzdG9yaW5nIGFuZCByZXRyaWV2aW5nIHRoZSBjdXJyZW50IGNvbnRleHQuCiAqIEEgc2luZ2xlIGluc3RhbmNlIHNob3VsZCBiZSBzaGFyZWQgYWNyb3NzIGFsbCBwcm92aWRlcnMgd2l0aGluIGEgcmVxdWVzdCBsaWZlY3ljbGUuCiAqCiAqIEBwYXJhbSBudWxsfENvbnRleHQgJGNvbnRleHQgT3B0aW9uYWwgaW5pdGlhbCBjb250ZXh0CiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":200,"slug":"resource","name":"resource","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Resource","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJlc291cmNlLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBhcnJheTxhcnJheS1rZXksIG1peGVkPnxib29sfFxEYXRlVGltZUludGVyZmFjZXxmbG9hdHxpbnR8c3RyaW5nfFxUaHJvd2FibGU+fEF0dHJpYnV0ZXMgJGF0dHJpYnV0ZXMgUmVzb3VyY2UgYXR0cmlidXRlcwogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":213,"slug":"span-context","name":"span_context","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"traceId","type":[{"name":"TraceId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"spanId","type":[{"name":"SpanId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parentSpanId","type":[{"name":"SpanId","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SpanContext","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5Db250ZXh0LgogKgogKiBAcGFyYW0gVHJhY2VJZCAkdHJhY2VJZCBUaGUgdHJhY2UgSUQKICogQHBhcmFtIFNwYW5JZCAkc3BhbklkIFRoZSBzcGFuIElECiAqIEBwYXJhbSBudWxsfFNwYW5JZCAkcGFyZW50U3BhbklkIE9wdGlvbmFsIHBhcmVudCBzcGFuIElECiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":226,"slug":"span-event","name":"span_event","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"timestamp","type":[{"name":"DateTimeImmutable","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"GenericEvent","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5FdmVudCAoR2VuZXJpY0V2ZW50KSB3aXRoIGFuIGV4cGxpY2l0IHRpbWVzdGFtcC4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBFdmVudCBuYW1lCiAqIEBwYXJhbSBcRGF0ZVRpbWVJbW11dGFibGUgJHRpbWVzdGFtcCBFdmVudCB0aW1lc3RhbXAKICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58Ym9vbHxcRGF0ZVRpbWVJbnRlcmZhY2V8ZmxvYXR8aW50fHN0cmluZ3xcVGhyb3dhYmxlPnxBdHRyaWJ1dGVzICRhdHRyaWJ1dGVzIEV2ZW50IGF0dHJpYnV0ZXMKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":238,"slug":"span-link","name":"span_link","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"context","type":[{"name":"SpanContext","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"SpanLink","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5MaW5rLgogKgogKiBAcGFyYW0gU3BhbkNvbnRleHQgJGNvbnRleHQgVGhlIGxpbmtlZCBzcGFuIGNvbnRleHQKICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58Ym9vbHxcRGF0ZVRpbWVJbnRlcmZhY2V8ZmxvYXR8aW50fHN0cmluZ3xcVGhyb3dhYmxlPnxBdHRyaWJ1dGVzICRhdHRyaWJ1dGVzIExpbmsgYXR0cmlidXRlcwogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":254,"slug":"span-limits","name":"span_limits","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributeCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"eventCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"linkCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributePerEventCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributePerLinkCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributeValueLengthLimit","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SpanLimits","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBTcGFuTGltaXRzIGNvbmZpZ3VyYXRpb24uCiAqCiAqIEBwYXJhbSBpbnQgJGF0dHJpYnV0ZUNvdW50TGltaXQgTWF4aW11bSBudW1iZXIgb2YgYXR0cmlidXRlcyBwZXIgc3BhbgogKiBAcGFyYW0gaW50ICRldmVudENvdW50TGltaXQgTWF4aW11bSBudW1iZXIgb2YgZXZlbnRzIHBlciBzcGFuCiAqIEBwYXJhbSBpbnQgJGxpbmtDb3VudExpbWl0IE1heGltdW0gbnVtYmVyIG9mIGxpbmtzIHBlciBzcGFuCiAqIEBwYXJhbSBpbnQgJGF0dHJpYnV0ZVBlckV2ZW50Q291bnRMaW1pdCBNYXhpbXVtIG51bWJlciBvZiBhdHRyaWJ1dGVzIHBlciBldmVudAogKiBAcGFyYW0gaW50ICRhdHRyaWJ1dGVQZXJMaW5rQ291bnRMaW1pdCBNYXhpbXVtIG51bWJlciBvZiBhdHRyaWJ1dGVzIHBlciBsaW5rCiAqIEBwYXJhbSBudWxsfGludCAkYXR0cmlidXRlVmFsdWVMZW5ndGhMaW1pdCBNYXhpbXVtIGxlbmd0aCBmb3Igc3RyaW5nIGF0dHJpYnV0ZSB2YWx1ZXMgKG51bGwgPSB1bmxpbWl0ZWQpCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":279,"slug":"log-record-limits","name":"log_record_limits","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributeCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributeValueLengthLimit","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"LogRecordLimits","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBMb2dSZWNvcmRMaW1pdHMgY29uZmlndXJhdGlvbi4KICoKICogQHBhcmFtIGludCAkYXR0cmlidXRlQ291bnRMaW1pdCBNYXhpbXVtIG51bWJlciBvZiBhdHRyaWJ1dGVzIHBlciBsb2cgcmVjb3JkCiAqIEBwYXJhbSBudWxsfGludCAkYXR0cmlidXRlVmFsdWVMZW5ndGhMaW1pdCBNYXhpbXVtIGxlbmd0aCBmb3Igc3RyaW5nIGF0dHJpYnV0ZSB2YWx1ZXMgKG51bGwgPSB1bmxpbWl0ZWQpCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":290,"slug":"metric-limits","name":"metric_limits","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"cardinalityLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2000"}],"return_type":[{"name":"MetricLimits","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBNZXRyaWNMaW1pdHMgY29uZmlndXJhdGlvbi4KICoKICogQHBhcmFtIGludCAkY2FyZGluYWxpdHlMaW1pdCBNYXhpbXVtIG51bWJlciBvZiB1bmlxdWUgYXR0cmlidXRlIGNvbWJpbmF0aW9ucyBwZXIgaW5zdHJ1bWVudAogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":301,"slug":"void-span-processor","name":"void_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidSpanProcessor","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRTcGFuUHJvY2Vzc29yLgogKgogKiBOby1vcCBzcGFuIHByb2Nlc3NvciB0aGF0IGRpc2NhcmRzIGFsbCBkYXRhLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":312,"slug":"void-metric-processor","name":"void_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidMetricProcessor","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRNZXRyaWNQcm9jZXNzb3IuCiAqCiAqIE5vLW9wIG1ldHJpYyBwcm9jZXNzb3IgdGhhdCBkaXNjYXJkcyBhbGwgZGF0YS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":323,"slug":"void-log-processor","name":"void_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidLogProcessor","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRMb2dQcm9jZXNzb3IuCiAqCiAqIE5vLW9wIGxvZyBwcm9jZXNzb3IgdGhhdCBkaXNjYXJkcyBhbGwgZGF0YS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":334,"slug":"void-exporter","name":"void_exporter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidExporter","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRFeHBvcnRlci4KICoKICogTm8tb3AgdW5pZmllZCBleHBvcnRlciB0aGF0IGRpc2NhcmRzIGxvZ3MsIG1ldHJpY3MsIGFuZCBzcGFucy4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":348,"slug":"memory-exporter","name":"memory_exporter","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"maxEntriesPerSignal","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MemoryExporter","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeUV4cG9ydGVyLgogKgogKiBVbmlmaWVkIGV4cG9ydGVyIHRoYXQgc3RvcmVzIGxvZ3MsIG1ldHJpY3MsIGFuZCBzcGFucyBpbiBtZW1vcnkgZm9yIGRpcmVjdCBhY2Nlc3MuCiAqIFVzZWZ1bCBmb3IgdGVzdGluZyBhbmQgaW5zcGVjdGlvbiB3aXRob3V0IHNlcmlhbGl6YXRpb24uCiAqCiAqIEBwYXJhbSBudWxsfGludCAkbWF4RW50cmllc1BlclNpZ25hbCBtYXhpbXVtIGVudHJpZXMgcmV0YWluZWQgcGVyIHNpZ25hbCB0eXBlOyBudWxsIGtlZXBzIGV2ZXJ5dGhpbmcKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":360,"slug":"memory-span-processor","name":"memory_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MemorySpanProcessor","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeVNwYW5Qcm9jZXNzb3IuCiAqCiAqIEBwYXJhbSBFeHBvcnRlciAkZXhwb3J0ZXIgVGhlIGV4cG9ydGVyIHRvIHNlbmQgc3BhbnMgdG8KICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBleHBvcnRlcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":374,"slug":"memory-metric-processor","name":"memory_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MemoryMetricProcessor","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeU1ldHJpY1Byb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBtZXRyaWNzIHRvCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":388,"slug":"memory-log-processor","name":"memory_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MemoryLogProcessor","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeUxvZ1Byb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBsb2dzIHRvCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":406,"slug":"tracer-provider","name":"tracer_provider","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"SpanProcessor","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sampler","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."},{"name":"limits","type":[{"name":"SpanLimits","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\SpanLimits::..."},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"TracerProvider","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlclByb3ZpZGVyLgogKgogKiBAcGFyYW0gU3BhblByb2Nlc3NvciAkcHJvY2Vzc29yIFRoZSBwcm9jZXNzb3IgZm9yIHNwYW5zCiAqIEBwYXJhbSBDbG9ja0ludGVyZmFjZSAkY2xvY2sgVGhlIGNsb2NrIGZvciB0aW1lc3RhbXBzCiAqIEBwYXJhbSBDb250ZXh0U3RvcmFnZSAkY29udGV4dFN0b3JhZ2UgU3RvcmFnZSBmb3IgY29udGV4dCBwcm9wYWdhdGlvbgogKiBAcGFyYW0gU2FtcGxlciAkc2FtcGxlciBTYW1wbGluZyBzdHJhdGVneSBmb3Igc3BhbnMKICogQHBhcmFtIFNwYW5MaW1pdHMgJGxpbWl0cyBMaW1pdHMgZm9yIHNwYW4gYXR0cmlidXRlcywgZXZlbnRzLCBhbmQgbGlua3MKICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIHJ1bnRpbWUgVGhyb3dhYmxlcyByYWlzZWQgYnkgdGhlIHByb2Nlc3NvcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":427,"slug":"logger-provider","name":"logger_provider","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"LogProcessor","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limits","type":[{"name":"LogRecordLimits","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Logger\\LogRecordLimits::..."},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"LoggerProvider","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExvZ2dlclByb3ZpZGVyLgogKgogKiBAcGFyYW0gTG9nUHJvY2Vzc29yICRwcm9jZXNzb3IgVGhlIHByb2Nlc3NvciBmb3IgbG9ncwogKiBAcGFyYW0gQ2xvY2tJbnRlcmZhY2UgJGNsb2NrIFRoZSBjbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gQ29udGV4dFN0b3JhZ2UgJGNvbnRleHRTdG9yYWdlIFN0b3JhZ2UgZm9yIHNwYW4gY29ycmVsYXRpb24KICogQHBhcmFtIExvZ1JlY29yZExpbWl0cyAkbGltaXRzIExpbWl0cyBmb3IgbG9nIHJlY29yZCBhdHRyaWJ1dGVzCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBydW50aW1lIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBwcm9jZXNzb3IKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":448,"slug":"meter-provider","name":"meter_provider","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"MetricProcessor","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"temporality","type":[{"name":"AggregationTemporality","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\AggregationTemporality::..."},{"name":"exemplarFilter","type":[{"name":"ExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\Exemplar\\TraceBasedExemplarFilter::..."},{"name":"limits","type":[{"name":"MetricLimits","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\MetricLimits::..."},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MeterProvider","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1ldGVyUHJvdmlkZXIuCiAqCiAqIEBwYXJhbSBNZXRyaWNQcm9jZXNzb3IgJHByb2Nlc3NvciBUaGUgcHJvY2Vzc29yIGZvciBtZXRyaWNzCiAqIEBwYXJhbSBDbG9ja0ludGVyZmFjZSAkY2xvY2sgVGhlIGNsb2NrIGZvciB0aW1lc3RhbXBzCiAqIEBwYXJhbSBBZ2dyZWdhdGlvblRlbXBvcmFsaXR5ICR0ZW1wb3JhbGl0eSBBZ2dyZWdhdGlvbiB0ZW1wb3JhbGl0eSBmb3IgbWV0cmljcwogKiBAcGFyYW0gRXhlbXBsYXJGaWx0ZXIgJGV4ZW1wbGFyRmlsdGVyIEZpbHRlciBmb3IgZXhlbXBsYXIgc2FtcGxpbmcgKGRlZmF1bHQ6IFRyYWNlQmFzZWRFeGVtcGxhckZpbHRlcikKICogQHBhcmFtIE1ldHJpY0xpbWl0cyAkbGltaXRzIENhcmRpbmFsaXR5IGxpbWl0cyBmb3IgbWV0cmljIGluc3RydW1lbnRzCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBydW50aW1lIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBwcm9jZXNzb3IKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":471,"slug":"telemetry","name":"telemetry","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"resource","type":[{"name":"Resource","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tracerProvider","type":[{"name":"TracerProvider","namespace":"Flow\\Telemetry\\Tracer","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"meterProvider","type":[{"name":"MeterProvider","namespace":"Flow\\Telemetry\\Meter","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"loggerProvider","type":[{"name":"LoggerProvider","namespace":"Flow\\Telemetry\\Logger","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBUZWxlbWV0cnkgaW5zdGFuY2Ugd2l0aCB0aGUgZ2l2ZW4gcHJvdmlkZXJzLgogKgogKiBJZiBwcm92aWRlcnMgYXJlIG5vdCBzcGVjaWZpZWQsIHZvaWQgcHJvdmlkZXJzIChuby1vcCkgYXJlIHVzZWQuCiAqCiAqIEBwYXJhbSBcRmxvd1xUZWxlbWV0cnlcUmVzb3VyY2UgJHJlc291cmNlIFRoZSByZXNvdXJjZSBkZXNjcmliaW5nIHRoZSBlbnRpdHkgcHJvZHVjaW5nIHRlbGVtZXRyeQogKiBAcGFyYW0gbnVsbHxUcmFjZXJQcm92aWRlciAkdHJhY2VyUHJvdmlkZXIgVGhlIHRyYWNlciBwcm92aWRlciAobnVsbCBmb3Igdm9pZC9kaXNhYmxlZCkKICogQHBhcmFtIG51bGx8TWV0ZXJQcm92aWRlciAkbWV0ZXJQcm92aWRlciBUaGUgbWV0ZXIgcHJvdmlkZXIgKG51bGwgZm9yIHZvaWQvZGlzYWJsZWQpCiAqIEBwYXJhbSBudWxsfExvZ2dlclByb3ZpZGVyICRsb2dnZXJQcm92aWRlciBUaGUgbG9nZ2VyIHByb3ZpZGVyIChudWxsIGZvciB2b2lkL2Rpc2FibGVkKQogKiBAcGFyYW0gRXJyb3JIYW5kbGVyICRlcnJvckhhbmRsZXIgSGFuZGxlciBwcm9wYWdhdGVkIHRvIGRlZmF1bHQgdm9pZCBwcm92aWRlcnMgd2hlbiBleHBsaWNpdCBvbmVzIGFyZSBub3Qgc3VwcGxpZWQKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":507,"slug":"instrumentation-scope","name":"instrumentation_scope","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"version","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'unknown'"},{"name":"schemaUrl","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Attributes::..."}],"return_type":[{"name":"InstrumentationScope","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJbnN0cnVtZW50YXRpb25TY29wZS4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgaW5zdHJ1bWVudGF0aW9uIHNjb3BlIG5hbWUKICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiBUaGUgaW5zdHJ1bWVudGF0aW9uIHNjb3BlIHZlcnNpb24KICogQHBhcmFtIG51bGx8c3RyaW5nICRzY2hlbWFVcmwgT3B0aW9uYWwgc2NoZW1hIFVSTAogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":524,"slug":"batching-span-processor","name":"batching_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"batchSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"512"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"BatchingSpanProcessor","namespace":"Flow\\Telemetry\\Tracer\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhdGNoaW5nU3BhblByb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBzcGFucyB0bwogKiBAcGFyYW0gaW50ICRiYXRjaFNpemUgTnVtYmVyIG9mIHNwYW5zIHRvIGNvbGxlY3QgYmVmb3JlIGV4cG9ydGluZyAoZGVmYXVsdCA1MTIpCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":539,"slug":"pass-through-span-processor","name":"pass_through_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"PassThroughSpanProcessor","namespace":"Flow\\Telemetry\\Tracer\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhc3NUaHJvdWdoU3BhblByb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBzcGFucyB0bwogKiBAcGFyYW0gRXJyb3JIYW5kbGVyICRlcnJvckhhbmRsZXIgSGFuZGxlciBmb3IgVGhyb3dhYmxlcyByYWlzZWQgYnkgdGhlIGV4cG9ydGVyCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":554,"slug":"batching-metric-processor","name":"batching_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"batchSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"512"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"BatchingMetricProcessor","namespace":"Flow\\Telemetry\\Meter\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhdGNoaW5nTWV0cmljUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIG1ldHJpY3MgdG8KICogQHBhcmFtIGludCAkYmF0Y2hTaXplIE51bWJlciBvZiBtZXRyaWNzIHRvIGNvbGxlY3QgYmVmb3JlIGV4cG9ydGluZyAoZGVmYXVsdCA1MTIpCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":569,"slug":"pass-through-metric-processor","name":"pass_through_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"PassThroughMetricProcessor","namespace":"Flow\\Telemetry\\Meter\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhc3NUaHJvdWdoTWV0cmljUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIG1ldHJpY3MgdG8KICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBleHBvcnRlcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":584,"slug":"batching-log-processor","name":"batching_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"batchSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"512"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"BatchingLogProcessor","namespace":"Flow\\Telemetry\\Logger\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhdGNoaW5nTG9nUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIGxvZ3MgdG8KICogQHBhcmFtIGludCAkYmF0Y2hTaXplIE51bWJlciBvZiBsb2dzIHRvIGNvbGxlY3QgYmVmb3JlIGV4cG9ydGluZyAoZGVmYXVsdCA1MTIpCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":599,"slug":"pass-through-log-processor","name":"pass_through_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"PassThroughLogProcessor","namespace":"Flow\\Telemetry\\Logger\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhc3NUaHJvdWdoTG9nUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIGxvZ3MgdG8KICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBleHBvcnRlcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":614,"slug":"pipeline-log-processor","name":"pipeline_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"middleware","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sink","type":[{"name":"LogSink","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PipelineLogProcessor","namespace":"Flow\\Telemetry\\Logger\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBpcGVsaW5lTG9nUHJvY2Vzc29yOiBydW4gZWFjaCBsb2cgZW50cnkgdGhyb3VnaCBhbiBvcmRlcmVkIGNoYWluIG9mCiAqIG1pZGRsZXdhcmUsIHRoZW4gZm9yd2FyZCB0aGUgc3Vydml2b3JzIHRvIGEgc2luZ2xlIHNpbmsuCiAqCiAqIEBwYXJhbSBsaXN0PExvZ01pZGRsZXdhcmU+ICRtaWRkbGV3YXJlIHJ1biBpbiBvcmRlcjsgdGhlIGZpcnN0IHRvIGRyb3AgYW4gZW50cnkgc2hvcnQtY2lyY3VpdHMgdGhlIHJlc3QKICogQHBhcmFtIExvZ1NpbmsgJHNpbmsgdGhlIHRlcm1pbmFsIHByb2Nlc3NvciB0aGF0IGV4cG9ydHMgc3Vydml2aW5nIGVudHJpZXMKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":626,"slug":"enriching-log-middleware","name":"enriching_log_middleware","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EnrichingLogMiddleware","namespace":"Flow\\Telemetry\\Logger\\Middleware","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFbnJpY2hpbmdMb2dNaWRkbGV3YXJlIHRoYXQgbWVyZ2VzIGRlZmF1bHQgYXR0cmlidXRlcyBpbnRvIGV2ZXJ5IGxvZwogKiBlbnRyeS4gQXR0cmlidXRlcyBzZXQgYXQgdGhlIGNhbGwgc2l0ZSB3aW4gb3ZlciB0aGVzZSBkZWZhdWx0cy4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58Ym9vbHxcRGF0ZVRpbWVJbnRlcmZhY2V8ZmxvYXR8aW50fHN0cmluZ3xcVGhyb3dhYmxlPnxBdHRyaWJ1dGVzICRhdHRyaWJ1dGVzCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":637,"slug":"attribute-filtering-log-middleware","name":"attribute_filtering_log_middleware","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AttributeFilteringLogMiddleware","namespace":"Flow\\Telemetry\\Logger\\Middleware","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXJpbmdMb2dNaWRkbGV3YXJlIHRoYXQgZHJvcHMgbG9nIGVudHJpZXMgbWF0Y2hpbmcgdGhlIGZpbHRlci4KICoKICogQHBhcmFtIEF0dHJpYnV0ZUZpbHRlciAkZmlsdGVyIFRoZSBhdHRyaWJ1dGUgZmlsdGVyIHRvIGFwcGx5CiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":648,"slug":"severity-filtering-log-middleware","name":"severity_filtering_log_middleware","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"minimumSeverity","type":[{"name":"Severity","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Logger\\Severity::..."}],"return_type":[{"name":"SeverityFilteringLogMiddleware","namespace":"Flow\\Telemetry\\Logger\\Middleware","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNldmVyaXR5RmlsdGVyaW5nTG9nTWlkZGxld2FyZSB0aGF0IGRyb3BzIGxvZyBlbnRyaWVzIGJlbG93IGEgbWluaW11bSBzZXZlcml0eS4KICoKICogQHBhcmFtIFNldmVyaXR5ICRtaW5pbXVtU2V2ZXJpdHkgTWluaW11bSBzZXZlcml0eSBsZXZlbCAoZGVmYXVsdDogSU5GTykKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":662,"slug":"attribute-rule","name":"attribute_rule","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"path","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"mode","type":[{"name":"MatchMode","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"expected","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"caseSensitive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"AttributeRule","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNpbmdsZSBhdHRyaWJ1dGUtbWF0Y2hpbmcgcnVsZSBmb3IgYW4gQXR0cmlidXRlRmlsdGVyLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nPnxzdHJpbmcgJHBhdGggYXR0cmlidXRlIHBhdGg6IGEgdG9wLWxldmVsIGtleSwgb3Igc2VnbWVudHMgZGVzY2VuZGluZyBpbnRvIG5lc3RlZCBhcnJheSB2YWx1ZXMKICogQHBhcmFtIE1hdGNoTW9kZSAkbW9kZSBjb21wYXJpc29uIGFwcGxpZWQgYmV0d2VlbiB0aGUgdmFsdWUgYXQgdGhlIHBhdGggYW5kIHRoZSBleHBlY3RlZCB2YWx1ZQogKiBAcGFyYW0gYm9vbHxEYXRlVGltZUludGVyZmFjZXxmbG9hdHxpbnR8c3RyaW5nICRleHBlY3RlZCBleHBlY3RlZCB2YWx1ZSAobXVzdCBiZSBhIHN0cmluZyBmb3IgdGhlIHBhdHRlcm4gbW9kZXMpCiAqIEBwYXJhbSBib29sICRjYXNlU2Vuc2l0aXZlIGFwcGxpZXMgdG8gdGhlIHN1YnN0cmluZyBtb2RlcyBvbmx5IChTVEFSVFNfV0lUSCwgRU5EU19XSVRILCBDT05UQUlOUykKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":675,"slug":"all","name":"all","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matchers","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgbWF0Y2hlcnMgc28gdGhhdCBldmVyeSBvbmUgbXVzdCBtYXRjaCAobG9naWNhbCBBTkQpLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":684,"slug":"any","name":"any","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matchers","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgbWF0Y2hlcnMgc28gdGhhdCBhdCBsZWFzdCBvbmUgbXVzdCBtYXRjaCAobG9naWNhbCBPUikuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":693,"slug":"not","name":"not","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matcher","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Not","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5lZ2F0ZSBhIG1hdGNoZXIgKGxvZ2ljYWwgTk9UKS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":712,"slug":"attribute-filter","name":"attribute_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matcher","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"exclude","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"sources","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"cacheDir","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"cacheDirPermissions","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"448"}],"return_type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXIgZnJvbSBhIG1hdGNoZXIuCiAqCiAqIEBwYXJhbSBNYXRjaGVyICRtYXRjaGVyIHRoZSBtYXRjaGVyIHRvIGV2YWx1YXRlIGFnYWluc3QgYSBzaWduYWwncyBhdHRyaWJ1dGVzIChjb21wb3NlIHdpdGggYWxsKCksIGFueSgpLCBub3QoKSkKICogQHBhcmFtIGJvb2wgJGV4Y2x1ZGUgd2hlbiB0cnVlIChkZWZhdWx0KSBhIG1hdGNoIGRyb3BzIHRoZSBzaWduYWw7IHdoZW4gZmFsc2Ugb25seSBtYXRjaGluZyBzaWduYWxzIGFyZSBrZXB0CiAqIEBwYXJhbSBsaXN0PEF0dHJpYnV0ZVNvdXJjZT4gJHNvdXJjZXMgd2hpY2ggYXR0cmlidXRlIHNldHMgdG8gaW5zcGVjdCAoc2lnbmFsLCByZXNvdXJjZSBhbmQvb3Igc2NvcGUpOyB0aGUgbWF0Y2hlciBpcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9SLWNvbWJpbmVkIGFjcm9zcyB0aGVtLCBkZWZhdWx0aW5nIHRvIHRoZSBzaWduYWwncyBvd24gYXR0cmlidXRlcwogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGNhY2hlRGlyIGRpcmVjdG9yeSBmb3IgdGhlIGdlbmVyYXRlZCBtYXRjaGVyIGZpbGUgKGRlZmF1bHRzIHRvIHRoZSBzeXN0ZW0gdGVtcCBkaXJlY3RvcnkpLiBJdCBpcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGByZXF1aXJlYGQsIHNvIGl0IE1VU1QgYmUgdHJ1c3RlZCAtIG5vdCB3cml0YWJsZSBieSB1bnRydXN0ZWQgdXNlcnMuIFByZWZlciBhbgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGxpY2F0aW9uLXByaXZhdGUgZGlyZWN0b3J5IG92ZXIgdGhlIHNoYXJlZCBzeXN0ZW0gdGVtcCBpbiBtdWx0aS10ZW5hbnQgZW52aXJvbm1lbnRzLgogKiBAcGFyYW0gaW50ICRjYWNoZURpclBlcm1pc3Npb25zIG1vZGUgYXBwbGllZCB3aGVuIHRoZSBjYWNoZSBkaXJlY3RvcnkgaXMgY3JlYXRlZCAob2N0YWwsIHN1YmplY3QgdG8gdW1hc2s7IGRlZmF1bHRzCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gMDcwMCAtIG93bmVyIG9ubHksIHNpbmNlIHRoZSBkaXJlY3RvcnkgaG9sZHMgYHJlcXVpcmVgZCBQSFApCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":729,"slug":"attribute-filtering-metric-processor","name":"attribute_filtering_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"MetricProcessor","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AttributeFilteringMetricProcessor","namespace":"Flow\\Telemetry\\Meter\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXJpbmdNZXRyaWNQcm9jZXNzb3IuCiAqCiAqIEBwYXJhbSBNZXRyaWNQcm9jZXNzb3IgJHByb2Nlc3NvciBUaGUgcHJvY2Vzc29yIHRvIHdyYXAKICogQHBhcmFtIEF0dHJpYnV0ZUZpbHRlciAkZmlsdGVyIFRoZSBhdHRyaWJ1dGUgZmlsdGVyIHRvIGFwcGx5CiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":743,"slug":"attribute-filtering-span-processor","name":"attribute_filtering_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"SpanProcessor","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AttributeFilteringSpanProcessor","namespace":"Flow\\Telemetry\\Tracer\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXJpbmdTcGFuUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gU3BhblByb2Nlc3NvciAkcHJvY2Vzc29yIFRoZSBwcm9jZXNzb3IgdG8gd3JhcAogKiBAcGFyYW0gQXR0cmlidXRlRmlsdGVyICRmaWx0ZXIgVGhlIGF0dHJpYnV0ZSBmaWx0ZXIgdG8gYXBwbHkKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":762,"slug":"console-exporter","name":"console_exporter","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"colors","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"maxLogBodyLength","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"100"},{"name":"logOptions","type":[{"name":"ConsoleLogOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Provider\\Console\\ConsoleLogOptions::..."},{"name":"metricOptions","type":[{"name":"ConsoleMetricOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Provider\\Console\\ConsoleMetricOptions::..."},{"name":"spanOptions","type":[{"name":"ConsoleSpanOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Provider\\Console\\ConsoleSpanOptions::..."}],"return_type":[{"name":"ConsoleExporter","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHVuaWZpZWQgQ29uc29sZUV4cG9ydGVyIGZvciBsb2dzLCBtZXRyaWNzLCBhbmQgc3BhbnMuCiAqCiAqIE91dHB1dHMgdGVsZW1ldHJ5IHRvIHRoZSBjb25zb2xlIHdpdGggQVNDSUkgdGFibGUgZm9ybWF0dGluZyBhbmQgb3B0aW9uYWwgQU5TSSBjb2xvcnMuCiAqCiAqIEBwYXJhbSBib29sICRjb2xvcnMgV2hldGhlciB0byB1c2UgQU5TSSBjb2xvcnMgKGRlZmF1bHQ6IHRydWUpCiAqIEBwYXJhbSBudWxsfGludCAkbWF4TG9nQm9keUxlbmd0aCBNYXhpbXVtIGxlbmd0aCBmb3IgbG9nIGJvZHkrYXR0cmlidXRlcyBjb2x1bW4gKG51bGwgPSBubyBsaW1pdCkKICogQHBhcmFtIENvbnNvbGVMb2dPcHRpb25zICRsb2dPcHRpb25zIERpc3BsYXkgb3B0aW9ucyBmb3IgbG9nIHJlY29yZHMKICogQHBhcmFtIENvbnNvbGVNZXRyaWNPcHRpb25zICRtZXRyaWNPcHRpb25zIERpc3BsYXkgb3B0aW9ucyBmb3IgbWV0cmljcwogKiBAcGFyYW0gQ29uc29sZVNwYW5PcHRpb25zICRzcGFuT3B0aW9ucyBEaXNwbGF5IG9wdGlvbnMgZm9yIHNwYW5zCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":776,"slug":"console-span-options","name":"console_span_options","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleSpanOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlU3Bhbk9wdGlvbnMgd2l0aCBhbGwgZGlzcGxheSBvcHRpb25zIGVuYWJsZWQgKGRlZmF1bHQgYmVoYXZpb3IpLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":785,"slug":"console-span-options-minimal","name":"console_span_options_minimal","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleSpanOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlU3Bhbk9wdGlvbnMgd2l0aCBtaW5pbWFsIGRpc3BsYXkgKGxlZ2FjeSBjb21wYWN0IGZvcm1hdCkuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":794,"slug":"console-log-options","name":"console_log_options","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleLogOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTG9nT3B0aW9ucyB3aXRoIGFsbCBkaXNwbGF5IG9wdGlvbnMgZW5hYmxlZCAoZGVmYXVsdCBiZWhhdmlvcikuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":803,"slug":"console-log-options-minimal","name":"console_log_options_minimal","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleLogOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTG9nT3B0aW9ucyB3aXRoIG1pbmltYWwgZGlzcGxheSAobGVnYWN5IGNvbXBhY3QgZm9ybWF0KS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":812,"slug":"console-metric-options","name":"console_metric_options","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleMetricOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTWV0cmljT3B0aW9ucyB3aXRoIGFsbCBkaXNwbGF5IG9wdGlvbnMgZW5hYmxlZCAoZGVmYXVsdCBiZWhhdmlvcikuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":821,"slug":"console-metric-options-minimal","name":"console_metric_options_minimal","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleMetricOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTWV0cmljT3B0aW9ucyB3aXRoIG1pbmltYWwgZGlzcGxheSAobGVnYWN5IGNvbXBhY3QgZm9ybWF0KS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":830,"slug":"always-on-exemplar-filter","name":"always_on_exemplar_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOnExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPbkV4ZW1wbGFyRmlsdGVyLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":839,"slug":"always-off-exemplar-filter","name":"always_off_exemplar_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOffExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPZmZFeGVtcGxhckZpbHRlci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":848,"slug":"trace-based-exemplar-filter","name":"trace_based_exemplar_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"TraceBasedExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlQmFzZWRFeGVtcGxhckZpbHRlci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":857,"slug":"always-on-sampler","name":"always_on_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOnSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPblNhbXBsZXIuIFJlY29yZHMgYW5kIHNhbXBsZXMgZXZlcnkgc3Bhbi4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":866,"slug":"always-off-sampler","name":"always_off_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOffSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPZmZTYW1wbGVyLiBEcm9wcyBldmVyeSBzcGFuLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":877,"slug":"trace-id-ratio-based-sampler","name":"trace_id_ratio_based_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"ratio","type":[{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TraceIdRatioBasedSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlSWRSYXRpb0Jhc2VkU2FtcGxlci4gU2FtcGxlcyBhIGRldGVybWluaXN0aWMgZnJhY3Rpb24gb2YgdHJhY2VzLgogKgogKiBAcGFyYW0gZmxvYXQgJHJhdGlvIFNhbXBsaW5nIHByb2JhYmlsaXR5IGJldHdlZW4gMC4wIGFuZCAxLjAKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":889,"slug":"parent-based-sampler","name":"parent_based_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"root","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."}],"return_type":[{"name":"ParentBasedSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhcmVudEJhc2VkU2FtcGxlci4gSG9ub3JzIHRoZSBwYXJlbnQgc3BhbidzIHNhbXBsaW5nIGRlY2lzaW9uLCBmYWxsaW5nCiAqIGJhY2sgdG8gdGhlIHJvb3Qgc2FtcGxlciBmb3Igc3BhbnMgd2l0aG91dCBhIHBhcmVudC4KICoKICogQHBhcmFtIFNhbXBsZXIgJHJvb3QgU2FtcGxlciB1c2VkIGZvciByb290IHNwYW5zIChubyBwYXJlbnQpCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":905,"slug":"attribute-matching-sampler","name":"attribute_matching_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"delegate","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."}],"return_type":[{"name":"AttributeMatchingSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVNYXRjaGluZ1NhbXBsZXIuIERyb3BzIHNwYW5zIHdob3NlIHN0YXJ0LXRpbWUgYXR0cmlidXRlcyBtYXRjaAogKiB0aGUgZmlsdGVyIChvciBrZWVwcyBPTkxZIG1hdGNoaW5nIHNwYW5zIHdoZW4gdGhlIGZpbHRlcidzIGV4Y2x1ZGUgaXMgZmFsc2UpLCBhbmQKICogZGVmZXJzIGFsbCBvdGhlciBzcGFucyB0byB0aGUgZGVsZWdhdGUgc2FtcGxlci4KICoKICogT25seSBhdHRyaWJ1dGVzIGF2YWlsYWJsZSBhdCBzcGFuIHN0YXJ0IGFyZSB2aXNpYmxlOyBhdHRyaWJ1dGVzIGFkZGVkIGxhdGVyIGFyZSBub3QuCiAqCiAqIEBwYXJhbSBBdHRyaWJ1dGVGaWx0ZXIgJGZpbHRlciBUaGUgYXR0cmlidXRlIGZpbHRlciBldmFsdWF0ZWQgYWdhaW5zdCB0aGUgc3BhbidzIHN0YXJ0IGF0dHJpYnV0ZXMKICogQHBhcmFtIFNhbXBsZXIgJGRlbGVnYXRlIFNhbXBsZXIgdGhhdCBkZWNpZGVzIHNwYW5zIHdoaWNoIGRvIG5vdCBtYXRjaCAoZGVmYXVsdDogQWx3YXlzT25TYW1wbGVyKQogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":919,"slug":"propagation-context","name":"propagation_context","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"spanContext","type":[{"name":"SpanContext","namespace":"Flow\\Telemetry\\Tracer","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"baggage","type":[{"name":"Baggage","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"PropagationContext","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFByb3BhZ2F0aW9uQ29udGV4dC4KICoKICogQHBhcmFtIG51bGx8U3BhbkNvbnRleHQgJHNwYW5Db250ZXh0IE9wdGlvbmFsIHNwYW4gY29udGV4dAogKiBAcGFyYW0gbnVsbHxCYWdnYWdlICRiYWdnYWdlIE9wdGlvbmFsIGJhZ2dhZ2UKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":930,"slug":"array-carrier","name":"array_carrier","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ArrayCarrier","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBcnJheUNhcnJpZXIuCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJGRhdGEgSW5pdGlhbCBjYXJyaWVyIGRhdGEKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":939,"slug":"superglobal-carrier","name":"superglobal_carrier","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"SuperglobalCarrier","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFN1cGVyZ2xvYmFsQ2Fycmllci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":948,"slug":"w3c-trace-context","name":"w3c_trace_context","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"W3CTraceContext","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFczQ1RyYWNlQ29udGV4dCBwcm9wYWdhdG9yLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":957,"slug":"w3c-baggage","name":"w3c_baggage","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"W3CBaggage","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFczQ0JhZ2dhZ2UgcHJvcGFnYXRvci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":968,"slug":"composite-propagator","name":"composite_propagator","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"propagators","type":[{"name":"Propagator","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"CompositePropagator","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENvbXBvc2l0ZVByb3BhZ2F0b3IuCiAqCiAqIEBwYXJhbSBQcm9wYWdhdG9yIC4uLiRwcm9wYWdhdG9ycyBUaGUgcHJvcGFnYXRvcnMgdG8gY29tYmluZQogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":979,"slug":"chain-detector","name":"chain_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"detectors","type":[{"name":"ResourceDetector","namespace":"Flow\\Telemetry\\Resource","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ChainDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENoYWluRGV0ZWN0b3IuCiAqCiAqIEBwYXJhbSBSZXNvdXJjZURldGVjdG9yIC4uLiRkZXRlY3RvcnMgVGhlIGRldGVjdG9ycyB0byBjaGFpbgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":988,"slug":"os-detector","name":"os_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"OsDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPc0RldGVjdG9yLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":997,"slug":"host-detector","name":"host_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"HostDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEhvc3REZXRlY3Rvci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1006,"slug":"process-detector","name":"process_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ProcessDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFByb2Nlc3NEZXRlY3Rvci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1015,"slug":"environment-detector","name":"environment_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"EnvironmentDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFbnZpcm9ubWVudERldGVjdG9yLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1024,"slug":"composer-detector","name":"composer_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ComposerDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENvbXBvc2VyRGV0ZWN0b3IuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1036,"slug":"git-detector","name":"git_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"workingDirectory","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"gitBinary","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'git'"}],"return_type":[{"name":"GitDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdpdERldGVjdG9yLgogKgogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHdvcmtpbmdEaXJlY3RvcnkgRGlyZWN0b3J5IHRvIHJ1biBnaXQgaW4gKGRlZmF1bHQ6IGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkpCiAqIEBwYXJhbSBzdHJpbmcgJGdpdEJpbmFyeSBQYXRoIHRvIHRoZSBnaXQgYmluYXJ5IChkZWZhdWx0OiAiZ2l0IiwgcmVzb2x2ZWQgZnJvbSAkUEFUSCkKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1047,"slug":"manual-detector","name":"manual_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ManualDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1hbnVhbERldGVjdG9yLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBhcnJheTxhcnJheS1rZXksIG1peGVkPnxib29sfFxEYXRlVGltZUludGVyZmFjZXxmbG9hdHxpbnR8c3RyaW5nfFxUaHJvd2FibGU+ICRhdHRyaWJ1dGVzIFJlc291cmNlIGF0dHJpYnV0ZXMKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1059,"slug":"caching-detector","name":"caching_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"detector","type":[{"name":"ResourceDetector","namespace":"Flow\\Telemetry\\Resource","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"cachePath","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CachingDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENhY2hpbmdEZXRlY3Rvci4KICoKICogQHBhcmFtIFJlc291cmNlRGV0ZWN0b3IgJGRldGVjdG9yIFRoZSBkZXRlY3RvciB0byB3cmFwCiAqIEBwYXJhbSBudWxsfHN0cmluZyAkY2FjaGVQYXRoIENhY2hlIGZpbGUgcGF0aCAoZGVmYXVsdDogc3lzX2dldF90ZW1wX2RpcigpL2Zsb3dfdGVsZW1ldHJ5X3Jlc291cmNlLmNhY2hlKQogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1070,"slug":"resource-detector","name":"resource_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"detectors","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ChainDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJlc291cmNlIGRldGVjdG9yIGNoYWluLgogKgogKiBAcGFyYW0gYXJyYXk8UmVzb3VyY2VEZXRlY3Rvcj4gJGRldGVjdG9ycyBPcHRpb25hbCBjdXN0b20gZGV0ZWN0b3JzIChlbXB0eSA9IHVzZSBkZWZhdWx0cykKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1089,"slug":"error-log-handler","name":"error_log_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"messageType","type":[{"name":"ErrorLogMessageType","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogMessageType::..."},{"name":"expandNewlines","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"messagePrefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'[flow-telemetry]'"}],"return_type":[{"name":"ErrorLogHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSB0aGUgZGVmYXVsdCBFcnJvckxvZ0hhbmRsZXIuIFdyaXRlcyB2aWEgUEhQJ3MgZXJyb3JfbG9nKCkuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1102,"slug":"stream-error-handler","name":"stream_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"destination","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filePermissions","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"420"},{"name":"createDirectories","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"messagePrefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'[flow-telemetry]'"}],"return_type":[{"name":"StreamHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFN0cmVhbUhhbmRsZXIuIEFwcGVuZHMgZm9ybWF0dGVkIFRocm93YWJsZXMgKG9uZSBwZXIgbGluZSkgdG8gYSBmaWxlCiAqIHBhdGggb3IgcGhwOi8vIHN0cmVhbSB3cmFwcGVyLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1115,"slug":"syslog-error-handler","name":"syslog_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"ident","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'flow-telemetry'"},{"name":"facility","type":[{"name":"SyslogFacility","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogFacility::..."},{"name":"logOpts","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"severity","type":[{"name":"SyslogSeverity","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogSeverity::..."}],"return_type":[{"name":"SyslogHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFN5c2xvZ0hhbmRsZXIuIFdyaXRlcyB2aWEgb3BlbmxvZy9zeXNsb2cvY2xvc2Vsb2cuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1128,"slug":"udp-syslog-error-handler","name":"udp_syslog_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"port","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"514"},{"name":"ident","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'flow-telemetry'"},{"name":"facility","type":[{"name":"SyslogFacility","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogFacility::..."},{"name":"severity","type":[{"name":"SyslogSeverity","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogSeverity::..."}],"return_type":[{"name":"UdpSyslogHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFVkcFN5c2xvZ0hhbmRsZXIuIFNlbmRzIFJGQyA1NDI0LXN0eWxlIHN5c2xvZyBmcmFtZXMgb3ZlciBVRFAuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1142,"slug":"composite-error-handler","name":"composite_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"handlers","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"CompositeErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEZhbiBlcnJvcnMgb3V0IHRvIG11bHRpcGxlIGhhbmRsZXJzLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1151,"slug":"null-error-handler","name":"null_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"NullErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIERpc2NhcmQgZXZlcnkgZXJyb3IuIFVzZSBvbmx5IGluIHRlc3RzIG9yIGZvciBleHBsaWNpdCBzaWxlbmNlLgogKi8="},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":29,"slug":"azurite-url-factory","name":"azurite_url_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'localhost'"},{"name":"port","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'10000'"},{"name":"secure","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AzuriteURLFactory","namespace":"Flow\\Azure\\SDK\\BlobService\\URLFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":38,"slug":"azure-shared-key-authorization-factory","name":"azure_shared_key_authorization_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"account","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SharedKeyFactory","namespace":"Flow\\Azure\\SDK\\AuthorizationFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":48,"slug":"azure-blob-service-config","name":"azure_blob_service_config","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"account","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"container","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Configuration","namespace":"Flow\\Azure\\SDK\\BlobService","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":54,"slug":"azure-url-factory","name":"azure_url_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'blob.core.windows.net'"}],"return_type":[{"name":"AzureURLFactory","namespace":"Flow\\Azure\\SDK\\BlobService\\URLFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":60,"slug":"azure-http-factory","name":"azure_http_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"request_factory","type":[{"name":"RequestFactoryInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"stream_factory","type":[{"name":"StreamFactoryInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"HttpFactory","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":68,"slug":"azure-blob-service","name":"azure_blob_service","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"configuration","type":[{"name":"Configuration","namespace":"Flow\\Azure\\SDK\\BlobService","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"azure_authorization_factory","type":[{"name":"AuthorizationFactory","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"azure_http_factory","type":[{"name":"HttpFactory","namespace":"Flow\\Azure\\SDK","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"azure_url_factory","type":[{"name":"URLFactory","namespace":"Flow\\Azure\\SDK","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"logger","type":[{"name":"LoggerInterface","namespace":"Psr\\Log","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"BlobServiceInterface","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/filesystem\/azure\/src\/Flow\/Filesystem\/Bridge\/Azure\/DSL\/functions.php","start_line_in_file":16,"slug":"azure-filesystem-options","name":"azure_filesystem_options","namespace":"Flow\\Filesystem\\Bridge\\Azure\\DSL","parameters":[],"return_type":[{"name":"Options","namespace":"Flow\\Filesystem\\Bridge\\Azure","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/filesystem\/azure\/src\/Flow\/Filesystem\/Bridge\/Azure\/DSL\/functions.php","start_line_in_file":22,"slug":"azure-filesystem","name":"azure_filesystem","namespace":"Flow\\Filesystem\\Bridge\\Azure\\DSL","parameters":[{"name":"blob_service","type":[{"name":"BlobServiceInterface","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Filesystem\\Bridge\\Azure","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Filesystem\\Bridge\\Azure\\Options::..."},{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'azure-blob'"}],"return_type":[{"name":"AzureBlobFilesystem","namespace":"Flow\\Filesystem\\Bridge\\Azure","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/filesystem\/async-aws\/src\/Flow\/Filesystem\/Bridge\/AsyncAWS\/DSL\/functions.php","start_line_in_file":20,"slug":"aws-s3-client","name":"aws_s3_client","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS\\DSL","parameters":[{"name":"configuration","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"S3Client","namespace":"AsyncAws\\S3","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"S3_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxDb25maWd1cmF0aW9uOjpPUFRJT05fKiwgbnVsbHxzdHJpbmc+ICRjb25maWd1cmF0aW9uIC0gZm9yIGRldGFpbHMgcGxlYXNlIHNlZSBodHRwczovL2FzeW5jLWF3cy5jb20vY2xpZW50cy9zMy5odG1sCiAqLw=="},{"repository_path":"src\/bridge\/filesystem\/async-aws\/src\/Flow\/Filesystem\/Bridge\/AsyncAWS\/DSL\/functions.php","start_line_in_file":26,"slug":"aws-s3-filesystem","name":"aws_s3_filesystem","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS\\DSL","parameters":[{"name":"bucket","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"s3Client","type":[{"name":"S3Client","namespace":"AsyncAws\\S3","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Filesystem\\Bridge\\AsyncAWS\\Options::..."},{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'aws-s3'"}],"return_type":[{"name":"AsyncAWSS3Filesystem","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"S3_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":40,"slug":"value-normalizer","name":"value_normalizer","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ValueNormalizer","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZhbHVlTm9ybWFsaXplciBmb3IgY29udmVydGluZyBhcmJpdHJhcnkgUEhQIHZhbHVlcyB0byBUZWxlbWV0cnkgYXR0cmlidXRlIHR5cGVzLgogKgogKiBUaGUgbm9ybWFsaXplciBoYW5kbGVzOgogKiAtIG51bGwg4oaSICdudWxsJyBzdHJpbmcKICogLSBzY2FsYXJzIChzdHJpbmcsIGludCwgZmxvYXQsIGJvb2wpIOKGkiB1bmNoYW5nZWQKICogLSBEYXRlVGltZUludGVyZmFjZSDihpIgdW5jaGFuZ2VkCiAqIC0gVGhyb3dhYmxlIOKGkiB1bmNoYW5nZWQKICogLSBhcnJheXMg4oaSIHJlY3Vyc2l2ZWx5IG5vcm1hbGl6ZWQKICogLSBvYmplY3RzIHdpdGggX190b1N0cmluZygpIOKGkiBzdHJpbmcgY2FzdAogKiAtIG9iamVjdHMgd2l0aG91dCBfX3RvU3RyaW5nKCkg4oaSIGNsYXNzIG5hbWUKICogLSBvdGhlciB0eXBlcyDihpIgZ2V0X2RlYnVnX3R5cGUoKSByZXN1bHQKICoKICogRXhhbXBsZSB1c2FnZToKICogYGBgcGhwCiAqICRub3JtYWxpemVyID0gdmFsdWVfbm9ybWFsaXplcigpOwogKiAkbm9ybWFsaXplZCA9ICRub3JtYWxpemVyLT5ub3JtYWxpemUoJHZhbHVlKTsKICogYGBgCiAqLw=="},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":73,"slug":"severity-mapper","name":"severity_mapper","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[{"name":"customMapping","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SeverityMapper","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNldmVyaXR5TWFwcGVyIGZvciBtYXBwaW5nIE1vbm9sb2cgbGV2ZWxzIHRvIFRlbGVtZXRyeSBzZXZlcml0aWVzLgogKgogKiBAcGFyYW0gbnVsbHxhcnJheTxpbnQsIFNldmVyaXR5PiAkY3VzdG9tTWFwcGluZyBPcHRpb25hbCBjdXN0b20gbWFwcGluZyAoTW9ub2xvZyBMZXZlbCB2YWx1ZSA9PiBUZWxlbWV0cnkgU2V2ZXJpdHkpCiAqCiAqIEV4YW1wbGUgd2l0aCBkZWZhdWx0IG1hcHBpbmc6CiAqIGBgYHBocAogKiAkbWFwcGVyID0gc2V2ZXJpdHlfbWFwcGVyKCk7CiAqIGBgYAogKgogKiBFeGFtcGxlIHdpdGggY3VzdG9tIG1hcHBpbmc6CiAqIGBgYHBocAogKiB1c2UgTW9ub2xvZ1xMZXZlbDsKICogdXNlIEZsb3dcVGVsZW1ldHJ5XExvZ2dlclxTZXZlcml0eTsKICoKICogJG1hcHBlciA9IHNldmVyaXR5X21hcHBlcihbCiAqICAgICBMZXZlbDo6RGVidWctPnZhbHVlID0+IFNldmVyaXR5OjpERUJVRywKICogICAgIExldmVsOjpJbmZvLT52YWx1ZSA9PiBTZXZlcml0eTo6SU5GTywKICogICAgIExldmVsOjpOb3RpY2UtPnZhbHVlID0+IFNldmVyaXR5OjpXQVJOLCAgLy8gQ3VzdG9tOiBOT1RJQ0Ug4oaSIFdBUk4gaW5zdGVhZCBvZiBJTkZPCiAqICAgICBMZXZlbDo6V2FybmluZy0+dmFsdWUgPT4gU2V2ZXJpdHk6OldBUk4sCiAqICAgICBMZXZlbDo6RXJyb3ItPnZhbHVlID0+IFNldmVyaXR5OjpFUlJPUiwKICogICAgIExldmVsOjpDcml0aWNhbC0+dmFsdWUgPT4gU2V2ZXJpdHk6OkZBVEFMLAogKiAgICAgTGV2ZWw6OkFsZXJ0LT52YWx1ZSA9PiBTZXZlcml0eTo6RkFUQUwsCiAqICAgICBMZXZlbDo6RW1lcmdlbmN5LT52YWx1ZSA9PiBTZXZlcml0eTo6RkFUQUwsCiAqIF0pOwogKiBgYGAKICov"},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":107,"slug":"log-record-converter","name":"log_record_converter","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[{"name":"severityMapper","type":[{"name":"SeverityMapper","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"valueNormalizer","type":[{"name":"ValueNormalizer","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"LogRecordConverter","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExvZ1JlY29yZENvbnZlcnRlciBmb3IgY29udmVydGluZyBNb25vbG9nIExvZ1JlY29yZCB0byBUZWxlbWV0cnkgTG9nUmVjb3JkLgogKgogKiBUaGUgY29udmVydGVyIGhhbmRsZXM6CiAqIC0gU2V2ZXJpdHkgbWFwcGluZyBmcm9tIE1vbm9sb2cgTGV2ZWwgdG8gVGVsZW1ldHJ5IFNldmVyaXR5CiAqIC0gTWVzc2FnZSBib2R5IGNvbnZlcnNpb24KICogLSBDaGFubmVsIGFuZCBsZXZlbCBuYW1lIGFzIG1vbm9sb2cuKiBhdHRyaWJ1dGVzCiAqIC0gQ29udGV4dCB2YWx1ZXMgYXMgY29udGV4dC4qIGF0dHJpYnV0ZXMgKFRocm93YWJsZXMgdXNlIHNldEV4Y2VwdGlvbigpKQogKiAtIEV4dHJhIHZhbHVlcyBhcyBleHRyYS4qIGF0dHJpYnV0ZXMKICoKICogQHBhcmFtIG51bGx8U2V2ZXJpdHlNYXBwZXIgJHNldmVyaXR5TWFwcGVyIEN1c3RvbSBzZXZlcml0eSBtYXBwZXIgKGRlZmF1bHRzIHRvIHN0YW5kYXJkIG1hcHBpbmcpCiAqIEBwYXJhbSBudWxsfFZhbHVlTm9ybWFsaXplciAkdmFsdWVOb3JtYWxpemVyIEN1c3RvbSB2YWx1ZSBub3JtYWxpemVyIChkZWZhdWx0cyB0byBzdGFuZGFyZCBub3JtYWxpemVyKQogKgogKiBFeGFtcGxlIHVzYWdlOgogKiBgYGBwaHAKICogJGNvbnZlcnRlciA9IGxvZ19yZWNvcmRfY29udmVydGVyKCk7CiAqICR0ZWxlbWV0cnlSZWNvcmQgPSAkY29udmVydGVyLT5jb252ZXJ0KCRtb25vbG9nUmVjb3JkKTsKICogYGBgCiAqCiAqIEV4YW1wbGUgd2l0aCBjdXN0b20gbWFwcGVyOgogKiBgYGBwaHAKICogJGNvbnZlcnRlciA9IGxvZ19yZWNvcmRfY29udmVydGVyKAogKiAgICAgc2V2ZXJpdHlNYXBwZXI6IHNldmVyaXR5X21hcHBlcihbCiAqICAgICAgICAgTGV2ZWw6OkRlYnVnLT52YWx1ZSA9PiBTZXZlcml0eTo6VFJBQ0UsCiAqICAgICBdKQogKiApOwogKiBgYGAKICov"},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":149,"slug":"telemetry-handler","name":"telemetry_handler","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[{"name":"logger","type":[{"name":"Logger","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"converter","type":[{"name":"LogRecordConverter","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Monolog\\Telemetry\\LogRecordConverter::..."},{"name":"level","type":[{"name":"Level","namespace":"Monolog","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Monolog\\Level::..."},{"name":"bubble","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"TelemetryHandler","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRlbGVtZXRyeUhhbmRsZXIgZm9yIGZvcndhcmRpbmcgTW9ub2xvZyBsb2dzIHRvIEZsb3cgVGVsZW1ldHJ5LgogKgogKiBAcGFyYW0gTG9nZ2VyICRsb2dnZXIgVGhlIEZsb3cgVGVsZW1ldHJ5IGxvZ2dlciB0byBmb3J3YXJkIGxvZ3MgdG8KICogQHBhcmFtIExvZ1JlY29yZENvbnZlcnRlciAkY29udmVydGVyIENvbnZlcnRlciB0byB0cmFuc2Zvcm0gTW9ub2xvZyBMb2dSZWNvcmQgdG8gVGVsZW1ldHJ5IExvZ1JlY29yZAogKiBAcGFyYW0gTGV2ZWwgJGxldmVsIFRoZSBtaW5pbXVtIGxvZ2dpbmcgbGV2ZWwgYXQgd2hpY2ggdGhpcyBoYW5kbGVyIHdpbGwgYmUgdHJpZ2dlcmVkCiAqIEBwYXJhbSBib29sICRidWJibGUgV2hldGhlciBtZXNzYWdlcyBoYW5kbGVkIGJ5IHRoaXMgaGFuZGxlciBzaG91bGQgYnViYmxlIHVwIHRvIG90aGVyIGhhbmRsZXJzCiAqCiAqIEV4YW1wbGUgdXNhZ2U6CiAqIGBgYHBocAogKiB1c2UgTW9ub2xvZ1xMb2dnZXIgYXMgTW9ub2xvZ0xvZ2dlcjsKICogdXNlIGZ1bmN0aW9uIEZsb3dcQnJpZGdlXE1vbm9sb2dcVGVsZW1ldHJ5XERTTFx0ZWxlbWV0cnlfaGFuZGxlcjsKICogdXNlIGZ1bmN0aW9uIEZsb3dcVGVsZW1ldHJ5XERTTFx0ZWxlbWV0cnk7CiAqCiAqICR0ZWxlbWV0cnkgPSB0ZWxlbWV0cnkoKTsKICogJGxvZ2dlciA9ICR0ZWxlbWV0cnktPmxvZ2dlcignbXktYXBwJyk7CiAqCiAqICRtb25vbG9nID0gbmV3IE1vbm9sb2dMb2dnZXIoJ2NoYW5uZWwnKTsKICogJG1vbm9sb2ctPnB1c2hIYW5kbGVyKHRlbGVtZXRyeV9oYW5kbGVyKCRsb2dnZXIpKTsKICoKICogJG1vbm9sb2ctPmluZm8oJ1VzZXIgbG9nZ2VkIGluJywgWyd1c2VyX2lkJyA9PiAxMjNdKTsKICogLy8g4oaSIEZvcndhcmRlZCB0byBGbG93IFRlbGVtZXRyeSB3aXRoIElORk8gc2V2ZXJpdHkKICogYGBgCiAqCiAqIEV4YW1wbGUgd2l0aCBjdXN0b20gY29udmVydGVyOgogKiBgYGBwaHAKICogJGNvbnZlcnRlciA9IGxvZ19yZWNvcmRfY29udmVydGVyKAogKiAgICAgc2V2ZXJpdHlNYXBwZXI6IHNldmVyaXR5X21hcHBlcihbCiAqICAgICAgICAgTGV2ZWw6OkRlYnVnLT52YWx1ZSA9PiBTZXZlcml0eTo6VFJBQ0UsCiAqICAgICBdKQogKiApOwogKiAkbW9ub2xvZy0+cHVzaEhhbmRsZXIodGVsZW1ldHJ5X2hhbmRsZXIoJGxvZ2dlciwgJGNvbnZlcnRlcikpOwogKiBgYGAKICov"},{"repository_path":"src\/bridge\/symfony\/http-foundation-telemetry\/src\/Flow\/Bridge\/Symfony\/HttpFoundationTelemetry\/DSL\/functions.php","start_line_in_file":16,"slug":"symfony-request-carrier","name":"symfony_request_carrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry\\DSL","parameters":[{"name":"request","type":[{"name":"Request","namespace":"Symfony\\Component\\HttpFoundation","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RequestCarrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SYMFONY_HTTP_FOUNDATION_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/symfony\/http-foundation-telemetry\/src\/Flow\/Bridge\/Symfony\/HttpFoundationTelemetry\/DSL\/functions.php","start_line_in_file":22,"slug":"symfony-response-carrier","name":"symfony_response_carrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry\\DSL","parameters":[{"name":"response","type":[{"name":"Response","namespace":"Symfony\\Component\\HttpFoundation","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ResponseCarrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SYMFONY_HTTP_FOUNDATION_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/psr7\/telemetry\/src\/Flow\/Bridge\/Psr7\/Telemetry\/DSL\/functions.php","start_line_in_file":16,"slug":"psr7-request-carrier","name":"psr7_request_carrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry\\DSL","parameters":[{"name":"request","type":[{"name":"ServerRequestInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RequestCarrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PSR7_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/psr7\/telemetry\/src\/Flow\/Bridge\/Psr7\/Telemetry\/DSL\/functions.php","start_line_in_file":22,"slug":"psr7-response-carrier","name":"psr7_response_carrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry\\DSL","parameters":[{"name":"response","type":[{"name":"ResponseInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ResponseCarrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PSR7_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/psr18\/telemetry\/src\/Flow\/Bridge\/Psr18\/Telemetry\/DSL\/functions.php","start_line_in_file":15,"slug":"psr18-traceable-client","name":"psr18_traceable_client","namespace":"Flow\\Bridge\\Psr18\\Telemetry\\DSL","parameters":[{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"telemetry","type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PSR18TraceableClient","namespace":"Flow\\Bridge\\Psr18\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PSR18_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":48,"slug":"otlp-json-serializer","name":"otlp_json_serializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"JsonSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gc2VyaWFsaXplciBmb3IgT1RMUC4KICoKICogUmV0dXJucyBhIEpzb25TZXJpYWxpemVyIHRoYXQgY29udmVydHMgdGVsZW1ldHJ5IGRhdGEgdG8gT1RMUCBKU09OIHdpcmUgZm9ybWF0LgogKiBVc2UgdGhpcyB3aXRoIEN1cmxUcmFuc3BvcnQgZm9yIEpTT04gb3ZlciBIVFRQLgogKgogKiBFeGFtcGxlIHVzYWdlOgogKiBgYGBwaHAKICogJHNlcmlhbGl6ZXIgPSBvdGxwX2pzb25fc2VyaWFsaXplcigpOwogKiAkdHJhbnNwb3J0ID0gb3RscF9jdXJsX3RyYW5zcG9ydCgkZW5kcG9pbnQsICRzZXJpYWxpemVyKTsKICogYGBgCiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":69,"slug":"otlp-protobuf-serializer","name":"otlp_protobuf_serializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"ProtobufSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFByb3RvYnVmIHNlcmlhbGl6ZXIgZm9yIE9UTFAuCiAqCiAqIFJldHVybnMgYSBQcm90b2J1ZlNlcmlhbGl6ZXIgdGhhdCBjb252ZXJ0cyB0ZWxlbWV0cnkgZGF0YSB0byBPVExQIFByb3RvYnVmIGJpbmFyeSBmb3JtYXQuCiAqIFVzZSB0aGlzIHdpdGggQ3VybFRyYW5zcG9ydCBmb3IgUHJvdG9idWYgb3ZlciBIVFRQLCBvciB3aXRoIEdycGNUcmFuc3BvcnQuCiAqCiAqIFJlcXVpcmVzOgogKiAtIGdvb2dsZS9wcm90b2J1ZiBwYWNrYWdlCiAqCiAqIEV4YW1wbGUgdXNhZ2U6CiAqIGBgYHBocAogKiAkc2VyaWFsaXplciA9IG90bHBfcHJvdG9idWZfc2VyaWFsaXplcigpOwogKiAkdHJhbnNwb3J0ID0gb3RscF9jdXJsX3RyYW5zcG9ydCgkZW5kcG9pbnQsICRzZXJpYWxpemVyKTsKICogYGBgCiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":93,"slug":"otlp-grpc-transport","name":"otlp_grpc_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"endpoint","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"headers","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"insecure","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"timeoutMs","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"250"},{"name":"shutdownTimeoutMs","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"5000"},{"name":"failover","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGdSUEMgdHJhbnNwb3J0IGZvciBPVExQIGVuZHBvaW50cy4KICoKICogQ3JlYXRlcyBhIEdycGNUcmFuc3BvcnQgY29uZmlndXJlZCB0byBzZW5kIHRlbGVtZXRyeSBkYXRhIHRvIGFuIE9UTFAtY29tcGF0aWJsZQogKiBlbmRwb2ludCB1c2luZyBnUlBDIHByb3RvY29sIHdpdGggUHJvdG9idWYgc2VyaWFsaXphdGlvbi4gT1RMUC9nUlBDIG1hbmRhdGVzCiAqIFByb3RvYnVmLCBzbyB0aGUgc2VyaWFsaXplciBpcyBidWlsdCBpbnRlcm5hbGx5IGFuZCBub3QgY29uZmlndXJhYmxlLgogKgogKiBSZXF1aXJlczoKICogLSBleHQtZ3JwYyBQSFAgZXh0ZW5zaW9uCiAqIC0gZ29vZ2xlL3Byb3RvYnVmIHBhY2thZ2UKICoKICogQHBhcmFtIHN0cmluZyAkZW5kcG9pbnQgZ1JQQyBlbmRwb2ludCAoZS5nLiwgJ2xvY2FsaG9zdDo0MzE3JykKICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkaGVhZGVycyBBZGRpdGlvbmFsIGhlYWRlcnMgKG1ldGFkYXRhKSB0byBpbmNsdWRlIGluIHJlcXVlc3RzCiAqIEBwYXJhbSBib29sICRpbnNlY3VyZSBXaGV0aGVyIHRvIHVzZSBpbnNlY3VyZSBjaGFubmVsIGNyZWRlbnRpYWxzIChkZWZhdWx0IHRydWUgZm9yIGxvY2FsIGRldikKICogQHBhcmFtIGludCAkdGltZW91dE1zIFBlci1jYWxsIGRlYWRsaW5lIGluIG1pbGxpc2Vjb25kcyAoY292ZXJzIGNvbm5lY3QgKyBzZW5kICsgcmVjZWl2ZSkKICogQHBhcmFtIGludCAkc2h1dGRvd25UaW1lb3V0TXMgV2FsbC1jbG9jayBidWRnZXQgZm9yIGRyYWluaW5nIHBlbmRpbmcgY2FsbHMgYXQgc2h1dGRvd24KICogQHBhcmFtID9UcmFuc3BvcnQgJGZhaWxvdmVyIE9wdGlvbmFsIGZhaWxvdmVyIHRyYW5zcG9ydCByZWNlaXZpbmcgcHJpb3IgYmF0Y2hlcyB3aGVuIHByaW1hcnkgZmFpbHMKICov"},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":108,"slug":"otlp-curl-options","name":"otlp_curl_options","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"CurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjdXJsIHRyYW5zcG9ydCBvcHRpb25zIGZvciBPVExQLgogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":129,"slug":"otlp-curl-transport","name":"otlp_curl_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"endpoint","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"serializer","type":[{"name":"JsonSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false},{"name":"ProtobufSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer\\JsonSerializer::..."},{"name":"options","type":[{"name":"CurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Transport\\CurlTransportOptions::..."},{"name":"failover","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHN5bmNocm9ub3VzIGN1cmwgdHJhbnNwb3J0IGZvciBPVExQIGVuZHBvaW50cy4KICoKICogQ3JlYXRlcyBhIEN1cmxUcmFuc3BvcnQgdGhhdCBkcml2ZXMgZWFjaCByZXF1ZXN0IHRvIGNvbXBsZXRpb24gYW5kIHJlcG9ydHMgdGhlCiAqIG91dGNvbWUgaW1tZWRpYXRlbHkgKHJldHVybnMgb24gc3VjY2VzcywgdGhyb3dzIG9uIGZhaWx1cmUpLiBPVExQL0hUVFAgYWxsb3dzCiAqIEpTT04gb3IgUHJvdG9idWYgZW5jb2Rpbmc7IGRlZmF1bHRzIHRvIEpTT04uIEtlZXBpbmcgZXhwb3J0IG9mZiB0aGUgYXBwbGljYXRpb24KICogaG90IHBhdGggaXMgdGhlIGpvYiBvZiB0aGUgYmF0Y2hpbmcgcHJvY2Vzc29yIGluIGZyb250IG9mIHRoZSBleHBvcnRlci4KICoKICogUmVxdWlyZXM6IGV4dC1jdXJsIFBIUCBleHRlbnNpb24KICoKICogQHBhcmFtIHN0cmluZyAkZW5kcG9pbnQgT1RMUCBlbmRwb2ludCBVUkwgKGUuZy4sICdodHRwOi8vbG9jYWxob3N0OjQzMTgnKQogKiBAcGFyYW0gSnNvblNlcmlhbGl6ZXJ8UHJvdG9idWZTZXJpYWxpemVyICRzZXJpYWxpemVyIFNlcmlhbGl6ZXIgZm9yIGVuY29kaW5nIHRlbGVtZXRyeSBkYXRhIChKU09OIG9yIFByb3RvYnVmKQogKiBAcGFyYW0gQ3VybFRyYW5zcG9ydE9wdGlvbnMgJG9wdGlvbnMgVHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24gb3B0aW9ucwogKiBAcGFyYW0gP1RyYW5zcG9ydCAkZmFpbG92ZXIgT3B0aW9uYWwgZmFpbG92ZXIgdHJhbnNwb3J0IHJlY2VpdmluZyB0aGUgYmF0Y2ggd2hlbiB0aGUgcHJpbWFyeSBmYWlscwogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":142,"slug":"otlp-async-curl-options","name":"otlp_async_curl_options","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"AsyncCurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhc3luYyBjdXJsIHRyYW5zcG9ydCBvcHRpb25zIGZvciBPVExQLgogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":157,"slug":"otlp-async-curl-transport","name":"otlp_async_curl_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"endpoint","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"serializer","type":[{"name":"JsonSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false},{"name":"ProtobufSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer\\JsonSerializer::..."},{"name":"options","type":[{"name":"AsyncCurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Transport\\AsyncCurlTransportOptions::..."},{"name":"failover","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"error_handler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhc3luY2hyb25vdXMgY3VybCB0cmFuc3BvcnQgZm9yIE9UTFAgZW5kcG9pbnRzLgogKgogKiBAcGFyYW0gc3RyaW5nICRlbmRwb2ludCBPVExQIGVuZHBvaW50IFVSTCAoZS5nLiwgJ2h0dHA6Ly9sb2NhbGhvc3Q6NDMxOCcpCiAqIEBwYXJhbSBKc29uU2VyaWFsaXplcnxQcm90b2J1ZlNlcmlhbGl6ZXIgJHNlcmlhbGl6ZXIgU2VyaWFsaXplciBmb3IgZW5jb2RpbmcgdGVsZW1ldHJ5IGRhdGEgKEpTT04gb3IgUHJvdG9idWYpCiAqIEBwYXJhbSBBc3luY0N1cmxUcmFuc3BvcnRPcHRpb25zICRvcHRpb25zIFRyYW5zcG9ydCBjb25maWd1cmF0aW9uIG9wdGlvbnMKICogQHBhcmFtID9UcmFuc3BvcnQgJGZhaWxvdmVyIE9wdGlvbmFsIGZhaWxvdmVyIHRyYW5zcG9ydCByZWNlaXZpbmcgcHJpb3IgYmF0Y2hlcyB3aGVuIHByaW1hcnkgZmFpbHMKICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JfaGFuZGxlciBIYW5kbGVyIGZvciBmYWlsdXJlcyByZWFwZWQgb24gc2VuZCgpL3RpY2soKS9zaHV0ZG93bigpIChubyBmYWlsb3ZlcikKICov"},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":179,"slug":"otlp-stream-transport","name":"otlp_stream_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"destination","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filePermissions","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"420"},{"name":"createDirectories","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHN0cmVhbSB0cmFuc3BvcnQgZm9yIE9UTFAgdGhhdCB3cml0ZXMgSlNPTkwgdG8gYSBzaW5nbGUgZGVzdGluYXRpb24uCiAqCiAqIEFjY2VwdHMgYW4gYWJzb2x1dGUgZmlsZSBwYXRoIG9yIGEgcGhwOi8vIHN0cmVhbSB3cmFwcGVyIHN1Y2ggYXMKICogJ3BocDovL3N0ZG91dCcsICdwaHA6Ly9zdGRlcnInLCAncGhwOi8vbWVtb3J5Jywgb3IgJ3BocDovL3RlbXAnLiBFYWNoCiAqIGV4cG9ydCgpIGNhbGwgYXBwZW5kcyBvbmUgSlNPTiBMaW5lIHVuZGVyIExPQ0tfRVggc28gY29uY3VycmVudCB3cml0ZXJzCiAqIGludGVybGVhdmUgYXQgbGluZSBib3VuZGFyaWVzLiBUaGUgJGZpbGVQZXJtaXNzaW9ucyBhbmQgJGNyZWF0ZURpcmVjdG9yaWVzCiAqIHBhcmFtZXRlcnMgYXBwbHkgb25seSB3aGVuIHRoZSBkZXN0aW5hdGlvbiBpcyBhIGZpbGUgcGF0aC4KICoKICogUGVyIHRoZSBPVExQIEZpbGUgRXhwb3J0ZXIgc3BlYyBvbmx5IEpTT04gZW5jb2RpbmcgaXMgc3VwcG9ydGVkLgogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":202,"slug":"otlp-exporter","name":"otlp_exporter","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"transport","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"OTLPExporter","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Exporter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPVExQIGV4cG9ydGVyIHRoYXQgZGlzcGF0Y2hlcyBsb2dzLCBtZXRyaWNzLCBhbmQgc3BhbnMgdGhyb3VnaCBhIHNpbmdsZSB0cmFuc3BvcnQuCiAqCiAqIEV4YW1wbGUgdXNhZ2U6CiAqIGBgYHBocAogKiAkZXhwb3J0ZXIgPSBvdGxwX2V4cG9ydGVyKCR0cmFuc3BvcnQpOwogKiAkc3BhblByb2Nlc3NvciA9IGJhdGNoaW5nX3NwYW5fcHJvY2Vzc29yKCRleHBvcnRlcik7CiAqICRtZXRyaWNQcm9jZXNzb3IgPSBiYXRjaGluZ19tZXRyaWNfcHJvY2Vzc29yKCRleHBvcnRlcik7CiAqICRsb2dQcm9jZXNzb3IgPSBiYXRjaGluZ19sb2dfcHJvY2Vzc29yKCRleHBvcnRlcik7CiAqIGBgYAogKgogKiBAcGFyYW0gVHJhbnNwb3J0ICR0cmFuc3BvcnQgVGhlIHRyYW5zcG9ydCBmb3Igc2VuZGluZyB0ZWxlbWV0cnkgZGF0YQogKiBAcGFyYW0gRXJyb3JIYW5kbGVyICRlcnJvckhhbmRsZXIgSGFuZGxlciBmb3IgVGhyb3dhYmxlcyByYWlzZWQgYnkgdGhlIHRyYW5zcG9ydAogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":216,"slug":"otlp-tracer-provider","name":"otlp_tracer_provider","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"processor","type":[{"name":"SpanProcessor","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sampler","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Context\\MemoryContextStorage::..."}],"return_type":[{"name":"TracerProvider","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRyYWNlciBwcm92aWRlciBjb25maWd1cmVkIGZvciBPVExQIGV4cG9ydC4KICoKICogQHBhcmFtIFNwYW5Qcm9jZXNzb3IgJHByb2Nlc3NvciBUaGUgcHJvY2Vzc29yIGZvciBoYW5kbGluZyBzcGFucwogKiBAcGFyYW0gQ2xvY2tJbnRlcmZhY2UgJGNsb2NrIFRoZSBjbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gU2FtcGxlciAkc2FtcGxlciBUaGUgc2FtcGxlciBmb3IgZGVjaWRpbmcgd2hldGhlciB0byByZWNvcmQgc3BhbnMKICogQHBhcmFtIENvbnRleHRTdG9yYWdlICRjb250ZXh0U3RvcmFnZSBUaGUgY29udGV4dCBzdG9yYWdlIGZvciBwcm9wYWdhdGluZyB0cmFjZSBjb250ZXh0CiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":233,"slug":"otlp-meter-provider","name":"otlp_meter_provider","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"processor","type":[{"name":"MetricProcessor","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"temporality","type":[{"name":"AggregationTemporality","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\AggregationTemporality::..."}],"return_type":[{"name":"MeterProvider","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG1ldGVyIHByb3ZpZGVyIGNvbmZpZ3VyZWQgZm9yIE9UTFAgZXhwb3J0LgogKgogKiBAcGFyYW0gTWV0cmljUHJvY2Vzc29yICRwcm9jZXNzb3IgVGhlIHByb2Nlc3NvciBmb3IgaGFuZGxpbmcgbWV0cmljcwogKiBAcGFyYW0gQ2xvY2tJbnRlcmZhY2UgJGNsb2NrIFRoZSBjbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gQWdncmVnYXRpb25UZW1wb3JhbGl0eSAkdGVtcG9yYWxpdHkgVGhlIGFnZ3JlZ2F0aW9uIHRlbXBvcmFsaXR5IGZvciBtZXRyaWNzCiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":249,"slug":"otlp-logger-provider","name":"otlp_logger_provider","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"processor","type":[{"name":"LogProcessor","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Context\\MemoryContextStorage::..."}],"return_type":[{"name":"LoggerProvider","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxvZ2dlciBwcm92aWRlciBjb25maWd1cmVkIGZvciBPVExQIGV4cG9ydC4KICoKICogQHBhcmFtIExvZ1Byb2Nlc3NvciAkcHJvY2Vzc29yIFRoZSBwcm9jZXNzb3IgZm9yIGhhbmRsaW5nIGxvZyByZWNvcmRzCiAqIEBwYXJhbSBDbG9ja0ludGVyZmFjZSAkY2xvY2sgVGhlIGNsb2NrIGZvciB0aW1lc3RhbXBzCiAqIEBwYXJhbSBDb250ZXh0U3RvcmFnZSAkY29udGV4dFN0b3JhZ2UgVGhlIGNvbnRleHQgc3RvcmFnZSBmb3IgcHJvcGFnYXRpbmcgY29udGV4dAogKi8="}] \ No newline at end of file +[{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":316,"slug":"df","name":"df","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false},{"name":"ConfigBuilder","namespace":"Flow\\ETL\\Config","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Flow","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"overwrite"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBkYXRhX2ZyYW1lKCkgOiBGbG93LgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":324,"slug":"data-frame","name":"data_frame","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false},{"name":"ConfigBuilder","namespace":"Flow\\ETL\\Config","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Flow","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"overwrite"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":330,"slug":"telemetry-options","name":"telemetry_options","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"trace_loading","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"trace_transformations","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"trace_cache","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"collect_metrics","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"filesystem","type":[{"name":"FilesystemTelemetryOptions","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TelemetryOptions","namespace":"Flow\\ETL\\Config\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":349,"slug":"from-rows","name":"from_rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"rows","type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"RowsExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"overwrite"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":356,"slug":"from-path-partitions","name":"from_path_partitions","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PathPartitionsExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"partitioning","example":"path_partitions"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":368,"slug":"from-array","name":"from_array","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"iterable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ArrayExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"array"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"data_frame"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpdGVyYWJsZTxhcnJheTxtaXhlZD4+ICRhcnJheQogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYSAtIEBkZXByZWNhdGVkIHVzZSB3aXRoU2NoZW1hKCkgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":385,"slug":"from-cache","name":"from_cache","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"id","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"fallback_extractor","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"clear","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CacheExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBzdHJpbmcgJGlkIC0gY2FjaGUgaWQgZnJvbSB3aGljaCBkYXRhIHdpbGwgYmUgZXh0cmFjdGVkCiAqIEBwYXJhbSBudWxsfEV4dHJhY3RvciAkZmFsbGJhY2tfZXh0cmFjdG9yIC0gZXh0cmFjdG9yIHRoYXQgd2lsbCBiZSB1c2VkIHdoZW4gY2FjaGUgaXMgZW1wdHkgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aEZhbGxiYWNrRXh0cmFjdG9yKCkgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIGJvb2wgJGNsZWFyIC0gY2xlYXIgY2FjaGUgYWZ0ZXIgZXh0cmFjdGlvbiAtIEBkZXByZWNhdGVkIHVzZSB3aXRoQ2xlYXJPbkZpbmlzaCgpIG1ldGhvZCBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":401,"slug":"from-all","name":"from_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"extractors","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ChainExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":407,"slug":"from-memory","name":"from_memory","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"memory","type":[{"name":"Memory","namespace":"Flow\\ETL\\Memory","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"MemoryExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":413,"slug":"files","name":"files","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"directory","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FilesExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":419,"slug":"filesystem-cache","name":"filesystem_cache","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"cache_dir","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"filesystem","type":[{"name":"Filesystem","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Filesystem\\Local\\NativeLocalFilesystem::..."},{"name":"serializer","type":[{"name":"Serializer","namespace":"Flow\\Serializer","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Floe\\FloeSerializer::..."}],"return_type":[{"name":"FilesystemCache","namespace":"Flow\\ETL\\Cache\\Implementation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":431,"slug":"batched-by","name":"batched_by","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"extractor","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"column","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"min_size","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"BatchByExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGludDwxLCBtYXg+ICRtaW5fc2l6ZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":445,"slug":"batches","name":"batches","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"extractor","type":[{"name":"Extractor","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BatchExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpbnQ8MSwgbWF4PiAkc2l6ZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":451,"slug":"from-pipeline","name":"from_pipeline","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pipeline","type":[{"name":"Pipeline","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PipelineExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":457,"slug":"from-data-frame","name":"from_data_frame","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"data_frame","type":[{"name":"DataFrame","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DataFrameExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":463,"slug":"from-sequence-date-period","name":"from_sequence_date_period","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"SequenceExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":477,"slug":"from-sequence-date-period-recurrences","name":"from_sequence_date_period_recurrences","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"recurrences","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"SequenceExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":491,"slug":"from-sequence-number","name":"from_sequence_number","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"step","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"}],"return_type":[{"name":"SequenceExtractor","namespace":"Flow\\ETL\\Extractor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":501,"slug":"to-callable","name":"to_callable","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"callable","type":[{"name":"callable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CallbackLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":507,"slug":"to-memory","name":"to_memory","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"memory","type":[{"name":"Memory","namespace":"Flow\\ETL\\Memory","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"MemoryLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":521,"slug":"to-array","name":"to_array","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"array"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgcm93cyB0byBhbiBhcnJheSBhbmQgc3RvcmUgdGhlbSBpbiBwYXNzZWQgYXJyYXkgdmFyaWFibGUuCiAqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPiAkYXJyYXkKICoKICogQHBhcmFtLW91dCBhcnJheTxhcnJheTxtaXhlZD4+ICRhcnJheQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":529,"slug":"to-output","name":"to_output","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":539,"slug":"to-stderr","name":"to_stderr","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":549,"slug":"to-stdout","name":"to_stdout","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":559,"slug":"to-stream","name":"to_stream","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"uri","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"20"},{"name":"output","type":[{"name":"Output","namespace":"Flow\\ETL\\Loader\\StreamLoader","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Loader\\StreamLoader\\Output::..."},{"name":"mode","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'w'"},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Formatter\\AsciiTableFormatter::..."},{"name":"schemaFormatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\Formatter\\ASCIISchemaFormatter::..."}],"return_type":[{"name":"StreamLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":579,"slug":"to-transformation","name":"to_transformation","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"transformer","type":[{"name":"Transformer","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false},{"name":"Transformation","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"loader","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TransformerLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":585,"slug":"to-branch","name":"to_branch","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"condition","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"loader","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BranchingLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":591,"slug":"rename-style","name":"rename_style","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"style","type":[{"name":"StringStyles","namespace":"Flow\\ETL\\String","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RenameCaseEntryStrategy","namespace":"Flow\\ETL\\Transformer\\Rename","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":601,"slug":"rename-replace","name":"rename_replace","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"search","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"replace","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RenameReplaceEntryStrategy","namespace":"Flow\\ETL\\Transformer\\Rename","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+fHN0cmluZyAkc2VhcmNoCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+fHN0cmluZyAkcmVwbGFjZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":610,"slug":"rename-map","name":"rename_map","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"renames","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RenameMapEntryStrategy","namespace":"Flow\\ETL\\Transformer\\Rename","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJHJlbmFtZXMgTWFwIG9mIG9sZF9uYW1lID0+IG5ld19uYW1lCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":619,"slug":"bool-entry","name":"bool_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxib29sPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":628,"slug":"boolean-entry","name":"boolean_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxib29sPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":639,"slug":"datetime-entry","name":"datetime_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRGF0ZVRpbWVJbnRlcmZhY2U+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":669,"slug":"time-entry","name":"time_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRGF0ZUludGVydmFsPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":708,"slug":"date-entry","name":"date_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRGF0ZVRpbWVJbnRlcmZhY2U+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":736,"slug":"int-entry","name":"int_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxpbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":745,"slug":"integer-entry","name":"integer_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxpbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":754,"slug":"enum-entry","name":"enum_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"enum","type":[{"name":"UnitEnum","namespace":"","is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCRlbnVtIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PFxVbml0RW51bT4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":763,"slug":"float-entry","name":"float_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxmbG9hdD4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":780,"slug":"json-entry","name":"json_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"data","type":[{"name":"Json","namespace":"Flow\\Types\\Value","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+fEpzb258c3RyaW5nICRkYXRhCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCRkYXRhIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PEpzb24+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":809,"slug":"json-object-entry","name":"json_object_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"data","type":[{"name":"Json","namespace":"Flow\\Types\\Value","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+fEpzb258c3RyaW5nICRkYXRhCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCRkYXRhIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PEpzb24+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":833,"slug":"str-entry","name":"str_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxzdHJpbmc+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":846,"slug":"null-entry","name":"null_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYW4gZW50cnkgb2YgdGhlIG51bGwgdHlwZS4gVXNlZCB3aGVuIGEgY29sdW1uIHZhbHVlIGlzIG51bGwgYW5kIGl0cyBmaW5hbCB0eXBlIGlzIG5vdCB5ZXQga25vd24uCiAqIFdoZW4gZ3Vlc3NpbmcgYSBzY2hlbWEgZnJvbSByb3dzLCBhIG51bGwgY29sdW1uIHN0YXlzIGEgTnVsbERlZmluaXRpb24gdW50aWwgYSBsYXRlciByb3cgcmV2ZWFscyBhIHJlYWwgdHlwZSwKICogYXQgd2hpY2ggcG9pbnQgdGhlIHNjaGVtYSBtZXJnZSB0dXJucyBpdCBpbnRvIHRoYXQgdHlwZSBtYWRlIG51bGxhYmxlLgogKgogKiBAcmV0dXJuIEVudHJ5PG51bGw+CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":855,"slug":"string-entry","name":"string_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxzdHJpbmc+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":864,"slug":"uuid-entry","name":"uuid_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"Uuid","namespace":"Flow\\Types\\Value","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRmxvd1xUeXBlc1xWYWx1ZVxVdWlkPikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":883,"slug":"xml-entry","name":"xml_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DOMDocument","namespace":"","is_nullable":false,"is_variadic":false},{"name":"Dom\\XMLDocument","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRE9NRG9jdW1lbnR8WE1MRG9jdW1lbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":908,"slug":"xml-element-entry","name":"xml_element_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"DOMElement","namespace":"","is_nullable":false,"is_variadic":false},{"name":"Dom\\Element","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxcRE9NRWxlbWVudHxFbGVtZW50PikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":937,"slug":"html-entry","name":"html_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"Dom\\HTMLDocument","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxIVE1MRG9jdW1lbnQ+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":954,"slug":"html-element-entry","name":"html_element_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"Dom\\HTMLElement","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gKCR2YWx1ZSBpcyBudWxsID8gRW50cnk8bnVsbD4gOiBFbnRyeTxIVE1MRWxlbWVudD4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":971,"slug":"entries","name":"entries","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Entries","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBFbnRyeTxtaXhlZD4gLi4uJGVudHJpZXMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":985,"slug":"struct-entry","name":"struct_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUU2hhcGUgb2YgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD4KICoKICogQHBhcmFtID9UU2hhcGUgJHZhbHVlCiAqIEBwYXJhbSBTdHJ1Y3R1cmVUeXBlPG1peGVkPnxUeXBlPFRTaGFwZT4gJHR5cGUKICoKICogQHJldHVybiAoJHZhbHVlIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PFRTaGFwZT4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1008,"slug":"structure-entry","name":"structure_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUU2hhcGUgb2YgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD4KICoKICogQHBhcmFtID9UU2hhcGUgJHZhbHVlCiAqIEBwYXJhbSBTdHJ1Y3R1cmVUeXBlPG1peGVkPnxUeXBlPFRTaGFwZT4gJHR5cGUKICoKICogQHJldHVybiAoJHZhbHVlIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PFRTaGFwZT4pCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1029,"slug":"list-entry","name":"list_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfGxpc3Q8bWl4ZWQ+ICR2YWx1ZQogKiBAcGFyYW0gVHlwZTxtaXhlZD4gJHR5cGUKICoKICogQHJldHVybiAoJHZhbHVlIGlzIG51bGwgPyBFbnRyeTxudWxsPiA6IEVudHJ5PGxpc3Q8bWl4ZWQ+PikKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1050,"slug":"map-entry","name":"map_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"mapType","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"ENTRY"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSA\/YXJyYXk8YXJyYXkta2V5LCBtaXhlZD4gJHZhbHVlCiAqIEBwYXJhbSBUeXBlPG1peGVkPiAkbWFwVHlwZQogKgogKiBAcmV0dXJuICgkdmFsdWUgaXMgbnVsbCA\/IEVudHJ5PG51bGw+IDogRW50cnk8YXJyYXk8YXJyYXkta2V5LCBtaXhlZD4+KQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1068,"slug":"row","name":"row","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Row","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBFbnRyeTxtaXhlZD4gLi4uJGVudHJ5CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1074,"slug":"rows","name":"rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"row","type":[{"name":"Row","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1084,"slug":"rows-partitioned","name":"rows_partitioned","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"rows","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"partitions","type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxSb3c+ICRyb3dzCiAqIEBwYXJhbSBhcnJheTxQYXJ0aXRpb258c3RyaW5nPnxQYXJ0aXRpb25zICRwYXJ0aXRpb25zCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1093,"slug":"col","name":"col","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEFuIGFsaWFzIGZvciBgcmVmYC4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1103,"slug":"entry","name":"entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"columns","option":"create"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEFuIGFsaWFzIGZvciBgcmVmYC4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1110,"slug":"ref","name":"ref","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"columns","option":"create"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1116,"slug":"structure-ref","name":"structure_ref","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"StructureFunctions","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1122,"slug":"list-ref","name":"list_ref","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entry","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ListFunctions","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1128,"slug":"refs","name":"refs","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1134,"slug":"select","name":"select","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Select","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1140,"slug":"drop","name":"drop","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"entries","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Drop","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1146,"slug":"add-row-index","name":"add_row_index","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'index'"},{"name":"startFrom","type":[{"name":"StartFrom","namespace":"Flow\\ETL\\Transformation\\AddRowIndex","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformation\\AddRowIndex\\StartFrom::..."}],"return_type":[{"name":"AddRowIndex","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1155,"slug":"batch-size","name":"batch_size","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BatchSize","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpbnQ8MSwgbWF4PiAkc2l6ZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1161,"slug":"limit","name":"limit","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Limit","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1170,"slug":"mask-columns","name":"mask_columns","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"mask","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'******'"}],"return_type":[{"name":"MaskColumns","namespace":"Flow\\ETL\\Transformation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"TRANSFORMER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxpbnQsIHN0cmluZz4gJGNvbHVtbnMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1176,"slug":"optional","name":"optional","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Optional","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1183,"slug":"lit","name":"lit","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Literal","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"columns","option":"create"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1189,"slug":"exists","name":"exists","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Exists","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1195,"slug":"when","name":"when","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"condition","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"then","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"else","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"When","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1201,"slug":"array-get","name":"array_get","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayGet","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1210,"slug":"array-get-collection","name":"array_get_collection","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayGetCollection","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAka2V5cwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1216,"slug":"array-get-collection-first","name":"array_get_collection_first","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ArrayGetCollection","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1225,"slug":"array-exists","name":"array_exists","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayPathExists","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkcmVmCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1235,"slug":"array-merge","name":"array_merge","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"left","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayMerge","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkbGVmdAogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58U2NhbGFyRnVuY3Rpb24gJHJpZ2h0CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1244,"slug":"array-merge-collection","name":"array_merge_collection","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayMergeCollection","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkYXJyYXkKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1250,"slug":"array-key-rename","name":"array_key_rename","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"newName","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayKeyRename","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1259,"slug":"array-keys-style-convert","name":"array_keys_style_convert","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"style","type":[{"name":"StringStyles","namespace":"Flow\\ETL\\String","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\String\\StringStyles::..."}],"return_type":[{"name":"ArrayKeysStyleConvert","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1267,"slug":"array-sort","name":"array_sort","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sort_function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"Sort","namespace":"Flow\\ETL\\Function\\ArraySort","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"recursive","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"ArraySort","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1284,"slug":"array-reverse","name":"array_reverse","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"preserveKeys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"ArrayReverse","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkZnVuY3Rpb24KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1290,"slug":"now","name":"now","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"time_zone","type":[{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false},{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"DateTimeZone::..."}],"return_type":[{"name":"Now","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1296,"slug":"between","name":"between","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"lower_bound","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"upper_bound","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"boundary","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"Boundary","namespace":"Flow\\ETL\\Function\\Between","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Function\\Between\\Boundary::..."}],"return_type":[{"name":"Between","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1306,"slug":"to-date-time","name":"to_date_time","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"format","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d H:i:s'"},{"name":"timeZone","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"DateTimeZone::..."}],"return_type":[{"name":"ToDateTime","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1315,"slug":"to-date","name":"to_date","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"format","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d'"},{"name":"timeZone","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"DateTimeZone::..."}],"return_type":[{"name":"ToDate","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1324,"slug":"date-time-format","name":"date_time_format","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DateTimeFormat","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1330,"slug":"split","name":"split","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"9223372036854775807"}],"return_type":[{"name":"Split","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1343,"slug":"combine","name":"combine","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"keys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"values","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Combine","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAka2V5cwogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58U2NhbGFyRnVuY3Rpb24gJHZhbHVlcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1352,"slug":"concat","name":"concat","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"functions","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Concat","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIENvbmNhdCBhbGwgdmFsdWVzLiBJZiB5b3Ugd2FudCB0byBjb25jYXRlbmF0ZSB2YWx1ZXMgd2l0aCBzZXBhcmF0b3IgdXNlIGNvbmNhdF93cyBmdW5jdGlvbi4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1361,"slug":"concat-ws","name":"concat_ws","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"functions","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ConcatWithSeparator","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIENvbmNhdCBhbGwgdmFsdWVzIHdpdGggc2VwYXJhdG9yLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1367,"slug":"hash","name":"hash","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"algorithm","type":[{"name":"Algorithm","namespace":"Flow\\ETL\\Hash","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Hash\\NativePHPHash::..."}],"return_type":[{"name":"Hash","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1376,"slug":"cast","name":"cast","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Cast","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBcRmxvd1xUeXBlc1xUeXBlPG1peGVkPnxzdHJpbmcgJHR5cGUKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1382,"slug":"coalesce","name":"coalesce","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Coalesce","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1388,"slug":"count","name":"count","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Count","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1401,"slug":"call","name":"call","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"callable","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"callable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"return_type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CallUserFunc","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIENhbGxzIGEgdXNlci1kZWZpbmVkIGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIHBhcmFtZXRlcnMuCiAqCiAqIEBwYXJhbSBjYWxsYWJsZXxTY2FsYXJGdW5jdGlvbiAkY2FsbGFibGUKICogQHBhcmFtIGFycmF5PG1peGVkPiAkcGFyYW1ldGVycwogKiBAcGFyYW0gbnVsbHxUeXBlPG1peGVkPiAkcmV0dXJuX3R5cGUKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1430,"slug":"array-unpack","name":"array_unpack","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"array","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"skip_keys","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"entry_prefix","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ArrayUnpack","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIG1peGVkPnxTY2FsYXJGdW5jdGlvbiAkYXJyYXkKICogQHBhcmFtIGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+fFNjYWxhckZ1bmN0aW9uICRza2lwX2tleXMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1459,"slug":"array-expand","name":"array_expand","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"expand","type":[{"name":"ArrayExpand","namespace":"Flow\\ETL\\Function\\ArrayExpand","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Function\\ArrayExpand\\ArrayExpand::..."}],"return_type":[{"name":"ArrayExpand","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEV4cGFuZHMgZWFjaCB2YWx1ZSBpbnRvIGVudHJ5LCBpZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZSB2YWx1ZSwgbXVsdGlwbGUgcm93cyB3aWxsIGJlIGNyZWF0ZWQuCiAqIEFycmF5IGtleXMgYXJlIGlnbm9yZWQsIG9ubHkgdmFsdWVzIGFyZSB1c2VkIHRvIGNyZWF0ZSBuZXcgcm93cy4KICoKICogQmVmb3JlOgogKiAgICstLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgIHxpZHwgICAgICAgICAgICAgIGFycmF5fAogKiAgICstLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKiAgIHwgMXx7ImEiOjEsImIiOjIsImMiOjN9fAogKiAgICstLSstLS0tLS0tLS0tLS0tLS0tLS0tKwogKgogKiBBZnRlcjoKICogICArLS0rLS0tLS0tLS0rCiAqICAgfGlkfGV4cGFuZGVkfAogKiAgICstLSstLS0tLS0tLSsKICogICB8IDF8ICAgICAgIDF8CiAqICAgfCAxfCAgICAgICAyfAogKiAgIHwgMXwgICAgICAgM3wKICogICArLS0rLS0tLS0tLS0rCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1465,"slug":"size","name":"size","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Size","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1471,"slug":"uuid-v4","name":"uuid_v4","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Uuid","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1477,"slug":"uuid-v7","name":"uuid_v7","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Uuid","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1483,"slug":"ulid","name":"ulid","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Ulid","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1489,"slug":"lower","name":"lower","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ToLower","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1495,"slug":"capitalize","name":"capitalize","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Capitalize","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1501,"slug":"upper","name":"upper","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ToUpper","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1507,"slug":"all","name":"all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"functions","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1513,"slug":"any","name":"any","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1519,"slug":"not","name":"not","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Not","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1525,"slug":"to-timezone","name":"to_timezone","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"timeZone","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"DateTimeZone","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ToTimeZone","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1531,"slug":"ignore-error-handler","name":"ignore_error_handler","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"IgnoreError","namespace":"Flow\\ETL\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1537,"slug":"skip-rows-handler","name":"skip_rows_handler","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SkipRows","namespace":"Flow\\ETL\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1543,"slug":"throw-error-handler","name":"throw_error_handler","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ThrowError","namespace":"Flow\\ETL\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1549,"slug":"regex-replace","name":"regex_replace","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"replacement","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"RegexReplace","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1559,"slug":"regex-match-all","name":"regex_match_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"RegexMatchAll","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1569,"slug":"regex-match","name":"regex_match","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"RegexMatch","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1579,"slug":"regex","name":"regex","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"Regex","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1589,"slug":"regex-all","name":"regex_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"pattern","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"subject","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"offset","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"RegexAll","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1599,"slug":"sprintf","name":"sprintf","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"format","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Sprintf","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1605,"slug":"sanitize","name":"sanitize","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"placeholder","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'*'"},{"name":"skipCharacters","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Sanitize","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1614,"slug":"round","name":"round","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"mode","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"}],"return_type":[{"name":"Round","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1623,"slug":"number-format","name":"number_format","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"value","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"decimals","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"decimal_separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'.'"},{"name":"thousands_separator","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"','"}],"return_type":[{"name":"NumberFormat","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1638,"slug":"to-entry","name":"to_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"data","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"entryFactory","type":[{"name":"EntryFactory","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\EntryFactory::..."}],"return_type":[{"name":"Entry","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxtaXhlZD4gJGRhdGEKICoKICogQHJldHVybiBFbnRyeTxtaXhlZD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1649,"slug":"array-to-row","name":"array_to_row","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"hydrator","type":[{"name":"Hydrator","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\AdaptiveRowHydrator::..."},{"name":"partitions","type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Row","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheTxtaXhlZD4+fGFycmF5PG1peGVkfHN0cmluZz4gJGRhdGEKICogQHBhcmFtIGFycmF5PFBhcnRpdGlvbj58UGFydGl0aW9ucyAkcGFydGl0aW9ucwogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1678,"slug":"array-to-rows","name":"array_to_rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"hydrator","type":[{"name":"Hydrator","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\AdaptiveRowHydrator::..."},{"name":"partitions","type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxhcnJheTxtaXhlZD4+fGFycmF5PG1peGVkfHN0cmluZz4gJGRhdGEKICogQHBhcmFtIGFycmF5PFBhcnRpdGlvbj58UGFydGl0aW9ucyAkcGFydGl0aW9ucwogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1724,"slug":"rank","name":"rank","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Rank","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"WINDOW_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1730,"slug":"dens-rank","name":"dens_rank","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"DenseRank","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"WINDOW_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1736,"slug":"dense-rank","name":"dense_rank","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"DenseRank","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"WINDOW_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1742,"slug":"average","name":"average","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"rounding","type":[{"name":"Rounding","namespace":"Flow\\Calculator","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Calculator\\Rounding::..."}],"return_type":[{"name":"Average","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1748,"slug":"greatest","name":"greatest","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Greatest","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1754,"slug":"least","name":"least","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"values","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Least","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1760,"slug":"collect","name":"collect","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Collect","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1766,"slug":"string-agg","name":"string_agg","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"', '"},{"name":"sort","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StringAggregate","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1772,"slug":"collect-unique","name":"collect_unique","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CollectUnique","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1778,"slug":"window","name":"window","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Window","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1784,"slug":"sum","name":"sum","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"exact","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Sum","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1790,"slug":"first","name":"first","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"First","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1796,"slug":"last","name":"last","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Last","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1802,"slug":"max","name":"max","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Max","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1808,"slug":"min","name":"min","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Min","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"AGGREGATING_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1814,"slug":"row-number","name":"row_number","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"RowNumber","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1825,"slug":"schema","name":"schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"definitions","type":[{"name":"Definition","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBEZWZpbml0aW9uPG1peGVkPiAuLi4kZGVmaW5pdGlvbnMKICoKICogQHJldHVybiBTY2hlbWEKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1834,"slug":"schema-to-json","name":"schema_to_json","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pretty","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1843,"slug":"schema-to-php","name":"schema_to_php","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"valueFormatter","type":[{"name":"ValueFormatter","namespace":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter\\ValueFormatter::..."},{"name":"typeFormatter","type":[{"name":"TypeFormatter","namespace":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Schema\\Formatter\\PHPFormatter\\TypeFormatter::..."}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1855,"slug":"schema-to-ascii","name":"schema_to_ascii","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"formatter","type":[{"name":"SchemaFormatter","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1865,"slug":"schema-validate","name":"schema_validate","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"expected","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"given","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"validator","type":[{"name":"SchemaValidator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Schema\\Validator\\StrictValidator::..."}],"return_type":[{"name":"ValidationContext","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTY2hlbWEgJGV4cGVjdGVkCiAqIEBwYXJhbSBTY2hlbWEgJGdpdmVuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1874,"slug":"schema-evolving-validator","name":"schema_evolving_validator","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"EvolvingValidator","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1880,"slug":"schema-strict-validator","name":"schema_strict_validator","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"StrictValidator","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1886,"slug":"schema-selective-validator","name":"schema_selective_validator","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SelectiveValidator","namespace":"Flow\\ETL\\Schema\\Validator","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1895,"slug":"schema-from-json","name":"schema_from_json","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gU2NoZW1hCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1908,"slug":"schema-metadata","name":"schema_metadata","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"metadata","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIGFycmF5PGJvb2x8ZmxvYXR8aW50fHN0cmluZz58Ym9vbHxmbG9hdHxpbnR8c3RyaW5nPiAkbWV0YWRhdGEKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1917,"slug":"int-schema","name":"int_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"IntegerDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBgaW50ZWdlcl9zY2hlbWFgLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1923,"slug":"integer-schema","name":"integer_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"IntegerDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1932,"slug":"str-schema","name":"str_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StringDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBgc3RyaW5nX3NjaGVtYWAuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1938,"slug":"string-schema","name":"string_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StringDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1944,"slug":"bool-schema","name":"bool_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"BooleanDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1950,"slug":"float-schema","name":"float_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FloatDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1964,"slug":"map-schema","name":"map_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"MapType","namespace":"Flow\\Types\\Type\\Logical","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MapDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUS2V5IG9mIGFycmF5LWtleQogKiBAdGVtcGxhdGUgVFZhbHVlCiAqCiAqIEBwYXJhbSBNYXBUeXBlPFRLZXksIFRWYWx1ZT58VHlwZTxhcnJheTxUS2V5LCBUVmFsdWU+PiAkdHlwZQogKgogKiBAcmV0dXJuIE1hcERlZmluaXRpb248VEtleSwgVFZhbHVlPgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1978,"slug":"list-schema","name":"list_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ListType","namespace":"Flow\\Types\\Type\\Logical","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ListDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBMaXN0VHlwZTxUPnxUeXBlPGxpc3Q8VD4+ICR0eXBlCiAqCiAqIEByZXR1cm4gTGlzdERlZmluaXRpb248VD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":1996,"slug":"enum-schema","name":"enum_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"EnumDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIFxVbml0RW51bQogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICR0eXBlCiAqCiAqIEByZXR1cm4gRW51bURlZmluaXRpb248VD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2002,"slug":"null-schema","name":"null_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"NullDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2008,"slug":"datetime-schema","name":"datetime_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DateTimeDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2014,"slug":"time-schema","name":"time_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TimeDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2020,"slug":"date-schema","name":"date_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DateDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2026,"slug":"json-schema","name":"json_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"JsonDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2032,"slug":"html-schema","name":"html_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"HTMLDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2038,"slug":"html-element-schema","name":"html_element_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"HTMLElementDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2044,"slug":"xml-schema","name":"xml_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"XMLDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2050,"slug":"xml-element-schema","name":"xml_element_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"XMLElementDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2063,"slug":"structure-schema","name":"structure_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"StructureType","namespace":"Flow\\Types\\Type\\Logical","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"StructureDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBTdHJ1Y3R1cmVUeXBlPFQ+fFR5cGU8YXJyYXk8c3RyaW5nLCBUPj4gJHR5cGUKICoKICogQHJldHVybiBTdHJ1Y3R1cmVEZWZpbml0aW9uPFQ+CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2077,"slug":"union-schema","name":"union_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"UnionType","namespace":"Flow\\Types\\Type\\Native","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"UnionDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBUeXBlPG1peGVkPnxVbmlvblR5cGU8bWl4ZWQsIG1peGVkPiAkdHlwZQogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2088,"slug":"uuid-schema","name":"uuid_schema","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"UuidDefinition","namespace":"Flow\\ETL\\Schema\\Definition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2101,"slug":"definition-from-array","name":"definition_from_array","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"definition","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Definition","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERlZmluaXRpb24gZnJvbSBhbiBhcnJheSByZXByZXNlbnRhdGlvbi4KICoKICogQHBhcmFtIGFycmF5PGFycmF5LWtleSwgbWl4ZWQ+ICRkZWZpbml0aW9uCiAqCiAqIEByZXR1cm4gRGVmaW5pdGlvbjxtaXhlZD4KICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2134,"slug":"definition-from-type","name":"definition_from_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"ref","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Definition","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERlZmluaXRpb24gZnJvbSBhIFR5cGUuCiAqCiAqIEBwYXJhbSBUeXBlPG1peGVkPiAkdHlwZQogKgogKiBAcmV0dXJuIERlZmluaXRpb248bWl4ZWQ+CiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2167,"slug":"execution-context","name":"execution_context","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FlowContext","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2173,"slug":"flow-context","name":"flow_context","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"config","type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FlowContext","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2179,"slug":"config","name":"config","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Config","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2185,"slug":"config-builder","name":"config_builder","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ConfigBuilder","namespace":"Flow\\ETL\\Config","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2194,"slug":"overwrite","name":"overwrite","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfb3ZlcndyaXRlKCkuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2200,"slug":"save-mode-overwrite","name":"save_mode_overwrite","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2209,"slug":"ignore","name":"ignore","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfaWdub3JlKCkuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2215,"slug":"save-mode-ignore","name":"save_mode_ignore","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2224,"slug":"exception-if-exists","name":"exception_if_exists","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfZXhjZXB0aW9uX2lmX2V4aXN0cygpLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2230,"slug":"save-mode-exception-if-exists","name":"save_mode_exception_if_exists","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2239,"slug":"append","name":"append","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEFsaWFzIGZvciBzYXZlX21vZGVfYXBwZW5kKCkuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2245,"slug":"save-mode-append","name":"save_mode_append","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"SaveMode","namespace":"Flow\\ETL\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2255,"slug":"execution-strict","name":"execution_strict","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ExecutionMode","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEluIHRoaXMgbW9kZSwgZnVuY3Rpb25zIHRocm93cyBleGNlcHRpb25zIGlmIHRoZSBnaXZlbiBlbnRyeSBpcyBub3QgZm91bmQKICogb3IgcGFzc2VkIHBhcmFtZXRlcnMgYXJlIGludmFsaWQuCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2264,"slug":"execution-lenient","name":"execution_lenient","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"ExecutionMode","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEluIHRoaXMgbW9kZSwgZnVuY3Rpb25zIHJldHVybnMgbnVsbHMgaW5zdGVhZCBvZiB0aHJvd2luZyBleGNlcHRpb25zLgogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2270,"slug":"print-rows","name":"print_rows","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"rows","type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"truncate","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"formatter","type":[{"name":"Formatter","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2276,"slug":"identical","name":"identical","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"left","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Identical","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2282,"slug":"equal","name":"equal","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"left","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Equal","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2288,"slug":"compare-all","name":"compare_all","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"comparison","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"comparisons","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2294,"slug":"compare-any","name":"compare_any","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"comparison","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"comparisons","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\ETL\\Join\\Comparison","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"COMPARISON"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2305,"slug":"join-on","name":"join_on","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"comparisons","type":[{"name":"Comparison","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"join_prefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"''"}],"return_type":[{"name":"Expression","namespace":"Flow\\ETL\\Join","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"join","example":"join"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"join","example":"join_each"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxDb21wYXJpc29ufHN0cmluZz58Q29tcGFyaXNvbiAkY29tcGFyaXNvbnMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2311,"slug":"compare-entries-by-name","name":"compare_entries_by_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"order","type":[{"name":"Order","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformer\\OrderEntries\\Order::..."}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2317,"slug":"compare-entries-by-name-desc","name":"compare_entries_by_name_desc","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2326,"slug":"compare-entries-by-type","name":"compare_entries_by_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"Order","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformer\\OrderEntries\\Order::..."}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8RW50cnk8bWl4ZWQ+PiwgaW50PiAkcHJpb3JpdGllcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2335,"slug":"compare-entries-by-type-desc","name":"compare_entries_by_type_desc","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8RW50cnk8bWl4ZWQ+PiwgaW50PiAkcHJpb3JpdGllcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2344,"slug":"compare-entries-by-type-and-name","name":"compare_entries_by_type_and_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"Order","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Transformer\\OrderEntries\\Order::..."}],"return_type":[{"name":"Comparator","namespace":"Flow\\ETL\\Transformer\\OrderEntries","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8RW50cnk8bWl4ZWQ+PiwgaW50PiAkcHJpb3JpdGllcwogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2355,"slug":"schema-sort-by-name","name":"schema_sort_by_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2364,"slug":"schema-sort-by-type","name":"schema_sort_by_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+LCBpbnQ+ICRwcmlvcml0aWVzCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2375,"slug":"schema-sort-by-type-and-name","name":"schema_sort_by_type_and_name","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"priorities","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+LCBpbnQ+ICRwcmlvcml0aWVzCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2386,"slug":"schema-sort-by-metadata","name":"schema_sort_by_metadata","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"key","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Row\\SortOrder::..."}],"return_type":[{"name":"SortingStrategy","namespace":"Flow\\ETL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2396,"slug":"is-type","name":"is_type","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmd8VHlwZTxtaXhlZD4+fFR5cGU8bWl4ZWQ+ICR0eXBlCiAqIEBwYXJhbSBtaXhlZCAkdmFsdWUKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2430,"slug":"generate-random-string","name":"generate_random_string","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"32"},{"name":"generator","type":[{"name":"RandomValueGenerator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\NativePHPRandomValueGenerator::..."}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2438,"slug":"generate-random-int","name":"generate_random_int","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"start","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"-9223372036854775808"},{"name":"end","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"9223372036854775807"},{"name":"generator","type":[{"name":"RandomValueGenerator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\NativePHPRandomValueGenerator::..."}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2447,"slug":"random-string","name":"random_string","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"length","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"generator","type":[{"name":"RandomValueGenerator","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\NativePHPRandomValueGenerator::..."}],"return_type":[{"name":"RandomString","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"DATA_FRAME"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2455,"slug":"date-interval-to-milliseconds","name":"date_interval_to_milliseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2472,"slug":"date-interval-to-seconds","name":"date_interval_to_seconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2489,"slug":"date-interval-to-microseconds","name":"date_interval_to_microseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"interval","type":[{"name":"DateInterval","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2506,"slug":"with-entry","name":"with_entry","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"function","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"WithEntry","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2512,"slug":"constraint-unique","name":"constraint_unique","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"reference","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"references","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"UniqueConstraint","namespace":"Flow\\ETL\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2518,"slug":"constraint-sorted-by","name":"constraint_sorted_by","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"column","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"Reference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"SortedByConstraint","namespace":"Flow\\ETL\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2526,"slug":"analyze","name":"analyze","namespace":"Flow\\ETL\\DSL","parameters":[],"return_type":[{"name":"Analyze","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2535,"slug":"match-cases","name":"match_cases","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"cases","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"default","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MatchCases","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":true,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxNYXRjaENvbmRpdGlvbj4gJGNhc2VzCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2541,"slug":"match-condition","name":"match_condition","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"condition","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"then","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"MatchCondition","namespace":"Flow\\ETL\\Function\\MatchCases","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"SCALAR_FUNCTION"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2547,"slug":"retry-any-throwable","name":"retry_any_throwable","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AnyThrowable","namespace":"Flow\\ETL\\Retry\\RetryStrategy","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2556,"slug":"retry-on-exception-types","name":"retry_on_exception_types","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"exception_types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OnExceptionTypes","namespace":"Flow\\ETL\\Retry\\RetryStrategy","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8XFRocm93YWJsZT4+ICRleGNlcHRpb25fdHlwZXMKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2562,"slug":"delay-linear","name":"delay_linear","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"delay","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"increment","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Linear","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2568,"slug":"delay-exponential","name":"delay_exponential","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"base","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"multiplier","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2"},{"name":"max_delay","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Exponential","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2577,"slug":"delay-jitter","name":"delay_jitter","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"delay","type":[{"name":"DelayFactory","namespace":"Flow\\ETL\\Retry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"jitter_factor","type":[{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Jitter","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBmbG9hdCAkaml0dGVyX2ZhY3RvciBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMSByZXByZXNlbnRpbmcgdGhlIG1heGltdW0gcGVyY2VudGFnZSBvZiBqaXR0ZXIgdG8gYXBwbHkKICov"},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2583,"slug":"delay-fixed","name":"delay_fixed","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"delay","type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Fixed","namespace":"Flow\\ETL\\Retry\\DelayFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2589,"slug":"duration-seconds","name":"duration_seconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"seconds","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2595,"slug":"duration-milliseconds","name":"duration_milliseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"milliseconds","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2601,"slug":"duration-microseconds","name":"duration_microseconds","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"microseconds","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2607,"slug":"duration-minutes","name":"duration_minutes","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"minutes","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Duration","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2613,"slug":"write-with-retries","name":"write_with_retries","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"loader","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"retry_strategy","type":[{"name":"RetryStrategy","namespace":"Flow\\ETL\\Retry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Retry\\RetryStrategy\\AnyThrowable::..."},{"name":"delay_factory","type":[{"name":"DelayFactory","namespace":"Flow\\ETL\\Retry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Retry\\DelayFactory\\Fixed\\FixedMilliseconds::..."},{"name":"sleep","type":[{"name":"Sleep","namespace":"Flow\\ETL\\Time","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Time\\SystemSleep::..."}],"return_type":[{"name":"RetryLoader","namespace":"Flow\\ETL\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/ETL\/DSL\/functions.php","start_line_in_file":2623,"slug":"clock","name":"clock","namespace":"Flow\\ETL\\DSL","parameters":[{"name":"time_zone","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'UTC'"}],"return_type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/Floe\/DSL\/functions.php","start_line_in_file":28,"slug":"from-floe","name":"from_floe","namespace":"Flow\\Floe\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"codec","type":[{"name":"Codec","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Floe\\Codec\\NoopCodec::..."},{"name":"chunk_size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"65536"}],"return_type":[{"name":"FloeExtractor","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FLOE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/Floe\/DSL\/functions.php","start_line_in_file":37,"slug":"to-floe","name":"to_floe","namespace":"Flow\\Floe\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"codec","type":[{"name":"Codec","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Floe\\Codec\\NoopCodec::..."}],"return_type":[{"name":"FloeLoader","namespace":"Flow\\Floe","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FLOE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKi8="},{"repository_path":"src\/core\/etl\/src\/Flow\/Floe\/DSL\/functions.php","start_line_in_file":50,"slug":"merge-floe","name":"merge_floe","namespace":"Flow\\Floe\\DSL","parameters":[{"name":"sources","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"dest","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"compact","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"metadata","type":[{"name":"Metadata","namespace":"Flow\\ETL\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"void","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FLOE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE1lcmdlcyBzZXZlcmFsIEZsb2UgZmlsZXMgKHNhbWUgb3IgYXBwZW5kLWNvbXBhdGlibGUgZXZvbHZpbmcgc2NoZW1hKSBpbnRvIG9uZSwgb24gdGhlIGxvY2FsCiAqIGZpbGVzeXN0ZW0uIEJ5dGUtc3BsaWNlcyBmcmFtZSByZWdpb25zIGJ5IGRlZmF1bHQgKE8oYnl0ZXMpLCBubyByZS1lbmNvZGUpOyBjb21wYWN0IHJlLWVuY29kZXMKICogYWxsIHJvd3MgaW50byBmZXdlciBzZWN0aW9ucy4gRm9yIG5vbi1sb2NhbCBmaWxlc3lzdGVtcyB1c2UgRmxvZU1lcmdlciBkaXJlY3RseS4KICoKICogQHBhcmFtIGFycmF5PGludCwgUGF0aHxzdHJpbmc+ICRzb3VyY2VzCiAqLw=="},{"repository_path":"src\/core\/etl\/src\/Flow\/Serializer\/DSL\/functions.php","start_line_in_file":18,"slug":"serialize-to-string","name":"serialize_to_string","namespace":"Flow\\Serializer\\DSL","parameters":[{"name":"serializer","type":[{"name":"Serializer","namespace":"Flow\\Serializer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"rows","type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/core\/etl\/src\/Flow\/Serializer\/DSL\/functions.php","start_line_in_file":27,"slug":"unserialize-from-string","name":"unserialize_from_string","namespace":"Flow\\Serializer\\DSL","parameters":[{"name":"serializer","type":[{"name":"Serializer","namespace":"Flow\\Serializer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"payload","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Rows","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CORE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-avro\/src\/Flow\/ETL\/Adapter\/Avro\/functions.php","start_line_in_file":19,"slug":"from-avro","name":"from_avro","namespace":"Flow\\ETL\\DSL\\Adapter\\Avro","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AvroExtractor","namespace":"Flow\\ETL\\Adapter\\Avro\\FlixTech","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AVRO","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-avro\/src\/Flow\/ETL\/Adapter\/Avro\/functions.php","start_line_in_file":25,"slug":"to-avro","name":"to_avro","namespace":"Flow\\ETL\\DSL\\Adapter\\Avro","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"AvroLoader","namespace":"Flow\\ETL\\Adapter\\Avro\\FlixTech","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AVRO","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":21,"slug":"bar-chart","name":"bar_chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"label","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"datasets","type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BarChart","namespace":"Flow\\ETL\\Adapter\\ChartJS\\Chart","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":27,"slug":"line-chart","name":"line_chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"label","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"datasets","type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"LineChart","namespace":"Flow\\ETL\\Adapter\\ChartJS\\Chart","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":33,"slug":"pie-chart","name":"pie_chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"label","type":[{"name":"EntryReference","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"datasets","type":[{"name":"References","namespace":"Flow\\ETL\\Row","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PieChart","namespace":"Flow\\ETL\\Adapter\\ChartJS\\Chart","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":39,"slug":"to-chartjs","name":"to_chartjs","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"type","type":[{"name":"Chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ChartJSLoader","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":50,"slug":"to-chartjs-file","name":"to_chartjs_file","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"type","type":[{"name":"Chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"output","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"template","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ChartJSLoader","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDaGFydCAkdHlwZQogKiBAcGFyYW0gbnVsbHxQYXRofHN0cmluZyAkb3V0cHV0IC0gQGRlcHJlY2F0ZWQgdXNlICRsb2FkZXItPndpdGhPdXRwdXRQYXRoKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxQYXRofHN0cmluZyAkdGVtcGxhdGUgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aFRlbXBsYXRlKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-chartjs\/src\/Flow\/ETL\/Adapter\/ChartJS\/functions.php","start_line_in_file":78,"slug":"to-chartjs-var","name":"to_chartjs_var","namespace":"Flow\\ETL\\Adapter\\ChartJS","parameters":[{"name":"type","type":[{"name":"Chart","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"output","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ChartJSLoader","namespace":"Flow\\ETL\\Adapter\\ChartJS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CHART_JS","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDaGFydCAkdHlwZQogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBtaXhlZD4gJG91dHB1dCAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoT3V0cHV0VmFyKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-csv\/src\/Flow\/ETL\/Adapter\/CSV\/functions.php","start_line_in_file":33,"slug":"from-csv","name":"from_csv","namespace":"Flow\\ETL\\Adapter\\CSV","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"empty_to_null","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"separator","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"enclosure","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"escape","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"characters_read_in_line","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"10485760"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CSVExtractor","namespace":"Flow\\ETL\\Adapter\\CSV","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CSV","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"csv"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gYm9vbCAkZW1wdHlfdG9fbnVsbCAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRW1wdHlUb051bGwoKSBpbnN0ZWFkCiAqIEBwYXJhbSBib29sICR3aXRoX2hlYWRlciAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoSGVhZGVyKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNlcGFyYXRvciAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoU2VwYXJhdG9yKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGVuY2xvc3VyZSAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRW5jbG9zdXJlKCkgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGVzY2FwZSAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRXNjYXBlKCkgaW5zdGVhZAogKiBAcGFyYW0gaW50PDEsIG1heD4gJGNoYXJhY3RlcnNfcmVhZF9pbl9saW5lIC0gQGRlcHJlY2F0ZWQgdXNlICRsb2FkZXItPndpdGhDaGFyYWN0ZXJzUmVhZEluTGluZSgpIGluc3RlYWQKICogQHBhcmFtIG51bGx8U2NoZW1hICRzY2hlbWEgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aFNjaGVtYSgpIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-csv\/src\/Flow\/ETL\/Adapter\/CSV\/functions.php","start_line_in_file":77,"slug":"to-csv","name":"to_csv","namespace":"Flow\\ETL\\Adapter\\CSV","parameters":[{"name":"uri","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"','"},{"name":"enclosure","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\\"'"},{"name":"escape","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\\\'"},{"name":"new_line_separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\n'"},{"name":"datetime_format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d\\\\TH:i:sP'"}],"return_type":[{"name":"CSVLoader","namespace":"Flow\\ETL\\Adapter\\CSV","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CSV","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkdXJpCiAqIEBwYXJhbSBib29sICR3aXRoX2hlYWRlciAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoSGVhZGVyKCkgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRzZXBhcmF0b3IgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aFNlcGFyYXRvcigpIGluc3RlYWQKICogQHBhcmFtIHN0cmluZyAkZW5jbG9zdXJlIC0gQGRlcHJlY2F0ZWQgdXNlICRsb2FkZXItPndpdGhFbmNsb3N1cmUoKSBpbnN0ZWFkCiAqIEBwYXJhbSBzdHJpbmcgJGVzY2FwZSAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRXNjYXBlKCkgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRuZXdfbGluZV9zZXBhcmF0b3IgLSBAZGVwcmVjYXRlZCB1c2UgJGxvYWRlci0+d2l0aE5ld0xpbmVTZXBhcmF0b3IoKSBpbnN0ZWFkCiAqIEBwYXJhbSBzdHJpbmcgJGRhdGV0aW1lX2Zvcm1hdCAtIEBkZXByZWNhdGVkIHVzZSAkbG9hZGVyLT53aXRoRGF0ZVRpbWVGb3JtYXQoKSBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-csv\/src\/Flow\/ETL\/Adapter\/CSV\/functions.php","start_line_in_file":102,"slug":"csv-detect-separator","name":"csv_detect_separator","namespace":"Flow\\ETL\\Adapter\\CSV","parameters":[{"name":"stream","type":[{"name":"SourceStream","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"lines","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"5"},{"name":"fallback","type":[{"name":"Option","namespace":"Flow\\ETL\\Adapter\\CSV\\Detector","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"Flow\\ETL\\Adapter\\CSV\\Detector\\Option::..."},{"name":"options","type":[{"name":"Options","namespace":"Flow\\ETL\\Adapter\\CSV\\Detector","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Option","namespace":"Flow\\ETL\\Adapter\\CSV\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"CSV","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBTb3VyY2VTdHJlYW0gJHN0cmVhbSAtIHZhbGlkIHJlc291cmNlIHRvIENTViBmaWxlCiAqIEBwYXJhbSBpbnQ8MSwgbWF4PiAkbGluZXMgLSBudW1iZXIgb2YgbGluZXMgdG8gcmVhZCBmcm9tIENTViBmaWxlLCBkZWZhdWx0IDUsIG1vcmUgbGluZXMgbWVhbnMgbW9yZSBhY2N1cmF0ZSBkZXRlY3Rpb24gYnV0IHNsb3dlciBkZXRlY3Rpb24KICogQHBhcmFtIG51bGx8T3B0aW9uICRmYWxsYmFjayAtIGZhbGxiYWNrIG9wdGlvbiB0byB1c2Ugd2hlbiBubyBiZXN0IG9wdGlvbiBjYW4gYmUgZGV0ZWN0ZWQsIGRlZmF1bHQgaXMgT3B0aW9uKCcsJywgJyInLCAnXFwnKQogKiBAcGFyYW0gbnVsbHxPcHRpb25zICRvcHRpb25zIC0gb3B0aW9ucyB0byB1c2UgZm9yIGRldGVjdGlvbiwgZGVmYXVsdCBpcyBPcHRpb25zOjphbGwoKQogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":39,"slug":"dbal-dataframe-factory","name":"dbal_dataframe_factory","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"QueryParameter","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"DbalDataFrameFactory","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPnxDb25uZWN0aW9uICRjb25uZWN0aW9uCiAqIEBwYXJhbSBzdHJpbmcgJHF1ZXJ5CiAqIEBwYXJhbSBRdWVyeVBhcmFtZXRlciAuLi4kcGFyYW1ldGVycwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":59,"slug":"from-dbal-limit-offset","name":"from_dbal_limit_offset","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"Table","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"order_by","type":[{"name":"OrderBy","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"page_size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"maximum","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DbalLimitOffsetExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDb25uZWN0aW9uICRjb25uZWN0aW9uCiAqIEBwYXJhbSBzdHJpbmd8VGFibGUgJHRhYmxlCiAqIEBwYXJhbSBhcnJheTxPcmRlckJ5PnxPcmRlckJ5ICRvcmRlcl9ieQogKiBAcGFyYW0gaW50ICRwYWdlX3NpemUKICogQHBhcmFtIG51bGx8aW50ICRtYXhpbXVtCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":86,"slug":"from-dbal-limit-offset-qb","name":"from_dbal_limit_offset_qb","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"queryBuilder","type":[{"name":"QueryBuilder","namespace":"Doctrine\\DBAL\\Query","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"page_size","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"maximum","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"offset","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"DbalLimitOffsetExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBDb25uZWN0aW9uICRjb25uZWN0aW9uCiAqIEBwYXJhbSBpbnQgJHBhZ2Vfc2l6ZQogKiBAcGFyYW0gbnVsbHxpbnQgJG1heGltdW0gLSBtYXhpbXVtIGNhbiBhbHNvIGJlIHRha2VuIGZyb20gYSBxdWVyeSBidWlsZGVyLCAkbWF4aW11bSBob3dldmVyIGlzIHVzZWQgcmVnYXJkbGVzcyBvZiB0aGUgcXVlcnkgYnVpbGRlciBpZiBpdCdzIHNldAogKiBAcGFyYW0gaW50ICRvZmZzZXQgLSBvZmZzZXQgY2FuIGFsc28gYmUgdGFrZW4gZnJvbSBhIHF1ZXJ5IGJ1aWxkZXIsICRvZmZzZXQgaG93ZXZlciBpcyB1c2VkIHJlZ2FyZGxlc3Mgb2YgdGhlIHF1ZXJ5IGJ1aWxkZXIgaWYgaXQncyBzZXQgdG8gbm9uIDAgdmFsdWUKICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":105,"slug":"from-dbal-key-set-qb","name":"from_dbal_key_set_qb","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"queryBuilder","type":[{"name":"QueryBuilder","namespace":"Doctrine\\DBAL\\Query","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key_set","type":[{"name":"KeySet","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DbalKeySetExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":115,"slug":"from-dbal-queries","name":"from_dbal_queries","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters_set","type":[{"name":"ParametersSet","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfFBhcmFtZXRlcnNTZXQgJHBhcmFtZXRlcnNfc2V0IC0gZWFjaCBvbmUgcGFyYW1ldGVycyBhcnJheSB3aWxsIGJlIGV2YWx1YXRlZCBhcyBuZXcgcXVlcnkKICogQHBhcmFtIGFycmF5PGludDwwLCBtYXg+fHN0cmluZywgRGJhbEFycmF5VHlwZXxEYmFsUGFyYW1ldGVyVHlwZXxEYmFsVHlwZXxzdHJpbmc+ICR0eXBlcwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":141,"slug":"dbal-from-queries","name":"dbal_from_queries","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters_set","type":[{"name":"ParametersSet","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBkZXByZWNhdGVkIHVzZSBmcm9tX2RiYWxfcXVlcmllcygpIGluc3RlYWQKICoKICogQHBhcmFtIG51bGx8UGFyYW1ldGVyc1NldCAkcGFyYW1ldGVyc19zZXQgLSBlYWNoIG9uZSBwYXJhbWV0ZXJzIGFycmF5IHdpbGwgYmUgZXZhbHVhdGVkIGFzIG5ldyBxdWVyeQogKiBAcGFyYW0gYXJyYXk8aW50PDAsIG1heD58c3RyaW5nLCBEYmFsQXJyYXlUeXBlfERiYWxQYXJhbWV0ZXJUeXBlfERiYWxUeXBlfHN0cmluZz4gJHR5cGVzCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":155,"slug":"from-dbal-query","name":"from_dbal_query","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPnxsaXN0PG1peGVkPiAkcGFyYW1ldGVycyAtIEBkZXByZWNhdGVkIHVzZSBEYmFsUXVlcnlFeHRyYWN0b3I6OndpdGhQYXJhbWV0ZXJzKCkgaW5zdGVhZAogKiBAcGFyYW0gYXJyYXk8aW50PDAsIG1heD58c3RyaW5nLCBEYmFsQXJyYXlUeXBlfERiYWxQYXJhbWV0ZXJUeXBlfERiYWxUeXBlfHN0cmluZz4gJHR5cGVzIC0gQGRlcHJlY2F0ZWQgdXNlIERiYWxRdWVyeUV4dHJhY3Rvcjo6d2l0aFR5cGVzKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":171,"slug":"dbal-from-query","name":"dbal_from_query","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parameters","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"types","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"DbalQueryExtractor","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBkZXByZWNhdGVkIHVzZSBmcm9tX2RiYWxfcXVlcnkoKSBpbnN0ZWFkCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPnxsaXN0PG1peGVkPiAkcGFyYW1ldGVycyAtIEBkZXByZWNhdGVkIHVzZSBEYmFsUXVlcnlFeHRyYWN0b3I6OndpdGhQYXJhbWV0ZXJzKCkgaW5zdGVhZAogKiBAcGFyYW0gYXJyYXk8aW50PDAsIG1heD58c3RyaW5nLCBEYmFsQXJyYXlUeXBlfERiYWxQYXJhbWV0ZXJUeXBlfERiYWxUeXBlfHN0cmluZz4gJHR5cGVzIC0gQGRlcHJlY2F0ZWQgdXNlIERiYWxRdWVyeUV4dHJhY3Rvcjo6d2l0aFR5cGVzKCkgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":197,"slug":"to-dbal-table-insert","name":"to_dbal_table_insert","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"InsertOptions","namespace":"Flow\\Doctrine\\Bulk","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"database_upsert"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEluc2VydCBuZXcgcm93cyBpbnRvIGEgZGF0YWJhc2UgdGFibGUuCiAqIEluc2VydCBjYW4gYWxzbyBiZSB1c2VkIGFzIGFuIHVwc2VydCB3aXRoIHRoZSBoZWxwIG9mIEluc2VydE9wdGlvbnMuCiAqIEluc2VydE9wdGlvbnMgYXJlIHBsYXRmb3JtIHNwZWNpZmljLCBzbyBwbGVhc2UgY2hvb3NlIHRoZSByaWdodCBvbmUgZm9yIHlvdXIgZGF0YWJhc2UuCiAqCiAqICAtIE15U1FMSW5zZXJ0T3B0aW9ucwogKiAgLSBQb3N0Z3JlU1FMSW5zZXJ0T3B0aW9ucwogKiAgLSBTcWxpdGVJbnNlcnRPcHRpb25zCiAqCiAqIEluIG9yZGVyIHRvIGNvbnRyb2wgdGhlIHNpemUgb2YgdGhlIHNpbmdsZSBpbnNlcnQsIHVzZSBEYXRhRnJhbWU6OmNodW5rU2l6ZSgpIG1ldGhvZCBqdXN0IGJlZm9yZSBjYWxsaW5nIERhdGFGcmFtZTo6bG9hZCgpLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD58Q29ubmVjdGlvbiAkY29ubmVjdGlvbgogKgogKiBAdGhyb3dzIEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbgogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":214,"slug":"to-dbal-table-update","name":"to_dbal_table_update","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"UpdateOptions","namespace":"Flow\\Doctrine\\Bulk","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"DbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqICBVcGRhdGUgZXhpc3Rpbmcgcm93cyBpbiBkYXRhYmFzZS4KICoKICogIEluIG9yZGVyIHRvIGNvbnRyb2wgdGhlIHNpemUgb2YgdGhlIHNpbmdsZSByZXF1ZXN0LCB1c2UgRGF0YUZyYW1lOjpjaHVua1NpemUoKSBtZXRob2QganVzdCBiZWZvcmUgY2FsbGluZyBEYXRhRnJhbWU6OmxvYWQoKS4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fENvbm5lY3Rpb24gJGNvbm5lY3Rpb24KICoKICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":233,"slug":"to-dbal-table-delete","name":"to_dbal_table_delete","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIERlbGV0ZSByb3dzIGZyb20gZGF0YWJhc2UgdGFibGUgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGRhdGEuCiAqCiAqIEluIG9yZGVyIHRvIGNvbnRyb2wgdGhlIHNpemUgb2YgdGhlIHNpbmdsZSByZXF1ZXN0LCB1c2UgRGF0YUZyYW1lOjpjaHVua1NpemUoKSBtZXRob2QganVzdCBiZWZvcmUgY2FsbGluZyBEYXRhRnJhbWU6OmxvYWQoKS4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fENvbm5lY3Rpb24gJGNvbm5lY3Rpb24KICoKICogQHRocm93cyBJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24KICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":248,"slug":"to-dbal-schema-table","name":"to_dbal_schema_table","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table_options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"types_map","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Table","namespace":"Doctrine\\DBAL\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnRzIGEgRmxvd1xFVExcU2NoZW1hIHRvIGEgRG9jdHJpbmVcREJBTFxTY2hlbWFcVGFibGUuCiAqCiAqIEBwYXJhbSBTY2hlbWEgJHNjaGVtYQogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBtaXhlZD4gJHRhYmxlX29wdGlvbnMKICogQHBhcmFtIGFycmF5PGNsYXNzLXN0cmluZzxcRmxvd1xUeXBlc1xUeXBlPG1peGVkPj4sIGNsYXNzLXN0cmluZzxcRG9jdHJpbmVcREJBTFxUeXBlc1xUeXBlPj4gJHR5cGVzX21hcAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":265,"slug":"table-schema-to-flow-schema","name":"table_schema_to_flow_schema","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"table","type":[{"name":"Table","namespace":"Doctrine\\DBAL\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"types_map","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnRzIGEgRG9jdHJpbmVcREJBTFxTY2hlbWFcVGFibGUgdG8gYSBGbG93XEVUTFxTY2hlbWEuCiAqCiAqIEBwYXJhbSBhcnJheTxjbGFzcy1zdHJpbmc8XEZsb3dcVHlwZXNcVHlwZTxtaXhlZD4+LCBjbGFzcy1zdHJpbmc8XERvY3RyaW5lXERCQUxcVHlwZXNcVHlwZT4+ICR0eXBlc19tYXAKICoKICogQHJldHVybiBTY2hlbWEKICov"},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":276,"slug":"postgresql-insert-options","name":"postgresql_insert_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"skip_conflicts","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"constraint","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"conflict_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"PostgreSQLInsertOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"database_upsert"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICRjb25mbGljdF9jb2x1bW5zCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":289,"slug":"mysql-insert-options","name":"mysql_insert_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"skip_conflicts","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"upsert","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"MySQLInsertOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":302,"slug":"sqlite-insert-options","name":"sqlite_insert_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"skip_conflicts","type":[{"name":"bool","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"conflict_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"SqliteInsertOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICRjb25mbGljdF9jb2x1bW5zCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":315,"slug":"postgresql-update-options","name":"postgresql_update_options","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"primary_key_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"update_columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"PostgreSQLUpdateOptions","namespace":"Flow\\Doctrine\\Bulk\\Dialect","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICRwcmltYXJ5X2tleV9jb2x1bW5zCiAqIEBwYXJhbSBhcnJheTxzdHJpbmc+ICR1cGRhdGVfY29sdW1ucwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":331,"slug":"to-dbal-transaction","name":"to_dbal_transaction","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"connection","type":[{"name":"Connection","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"loaders","type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"TransactionalDbalLoader","namespace":"Flow\\ETL\\Adapter\\Doctrine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4ZWN1dGUgbXVsdGlwbGUgbG9hZGVycyB3aXRoaW4gYSBkYXRhYmFzZSB0cmFuc2FjdGlvbi4KICogRWFjaCBiYXRjaCBvZiByb3dzIHdpbGwgYmUgcHJvY2Vzc2VkIGluIGl0cyBvd24gdHJhbnNhY3Rpb24uCiAqIElmIGFueSBsb2FkZXIgZmFpbHMsIHRoZSBlbnRpcmUgYmF0Y2ggd2lsbCBiZSByb2xsZWQgYmFjay4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fENvbm5lY3Rpb24gJGNvbm5lY3Rpb24KICogQHBhcmFtIExvYWRlciAuLi4kbG9hZGVycyAtIExvYWRlcnMgdG8gZXhlY3V0ZSB3aXRoaW4gdGhlIHRyYW5zYWN0aW9uCiAqCiAqIEB0aHJvd3MgSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":339,"slug":"pagination-key-asc","name":"pagination_key_asc","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ParameterType","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Doctrine\\DBAL\\Types","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Doctrine\\DBAL\\ParameterType::..."}],"return_type":[{"name":"Key","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":345,"slug":"pagination-key-desc","name":"pagination_key_desc","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ParameterType","namespace":"Doctrine\\DBAL","is_nullable":false,"is_variadic":false},{"name":"Type","namespace":"Doctrine\\DBAL\\Types","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Doctrine\\DBAL\\ParameterType::..."}],"return_type":[{"name":"Key","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-doctrine\/src\/Flow\/ETL\/Adapter\/Doctrine\/functions.php","start_line_in_file":351,"slug":"pagination-key-set","name":"pagination_key_set","namespace":"Flow\\ETL\\Adapter\\Doctrine","parameters":[{"name":"keys","type":[{"name":"Key","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"KeySet","namespace":"Flow\\ETL\\Adapter\\Doctrine\\Pagination","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"DOCTRINE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-excel\/src\/Flow\/ETL\/Adapter\/Excel\/DSL\/functions.php","start_line_in_file":20,"slug":"from-excel","name":"from_excel","namespace":"Flow\\ETL\\Adapter\\Excel\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExcelExtractor","namespace":"Flow\\ETL\\Adapter\\Excel","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"EXCEL","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-excel\/src\/Flow\/ETL\/Adapter\/Excel\/DSL\/functions.php","start_line_in_file":26,"slug":"to-excel","name":"to_excel","namespace":"Flow\\ETL\\Adapter\\Excel\\DSL","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExcelLoader","namespace":"Flow\\ETL\\Adapter\\Excel","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"EXCEL","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-excel\/src\/Flow\/ETL\/Adapter\/Excel\/DSL\/functions.php","start_line_in_file":32,"slug":"is-valid-excel-sheet-name","name":"is_valid_excel_sheet_name","namespace":"Flow\\ETL\\Adapter\\Excel\\DSL","parameters":[{"name":"sheet_name","type":[{"name":"ScalarFunction","namespace":"Flow\\ETL\\Function","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"IsValidExcelSheetName","namespace":"Flow\\ETL\\Adapter\\Excel\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"EXCEL","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-google-sheet\/src\/Flow\/ETL\/Adapter\/GoogleSheet\/functions.php","start_line_in_file":22,"slug":"from-google-sheet","name":"from_google_sheet","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","parameters":[{"name":"auth_config","type":[{"name":"Sheets","namespace":"Google\\Service","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"spreadsheet_id","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sheet_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"rows_per_page","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"GoogleSheetExtractor","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"GOOGLE_SHEET","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheXt0eXBlOiBzdHJpbmcsIHByb2plY3RfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXlfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXk6IHN0cmluZywgY2xpZW50X2VtYWlsOiBzdHJpbmcsIGNsaWVudF9pZDogc3RyaW5nLCBhdXRoX3VyaTogc3RyaW5nLCB0b2tlbl91cmk6IHN0cmluZywgYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsOiBzdHJpbmcsIGNsaWVudF94NTA5X2NlcnRfdXJsOiBzdHJpbmd9fFNoZWV0cyAkYXV0aF9jb25maWcKICogQHBhcmFtIHN0cmluZyAkc3ByZWFkc2hlZXRfaWQKICogQHBhcmFtIHN0cmluZyAkc2hlZXRfbmFtZQogKiBAcGFyYW0gYm9vbCAkd2l0aF9oZWFkZXIgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aEhlYWRlciBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gaW50ICRyb3dzX3Blcl9wYWdlIC0gaG93IG1hbnkgcm93cyBwZXIgcGFnZSB0byBmZXRjaCBmcm9tIEdvb2dsZSBTaGVldHMgQVBJIC0gQGRlcHJlY2F0ZWQgdXNlIHdpdGhSb3dzUGVyUGFnZSBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gYXJyYXl7ZGF0ZVRpbWVSZW5kZXJPcHRpb24\/OiBzdHJpbmcsIG1ham9yRGltZW5zaW9uPzogc3RyaW5nLCB2YWx1ZVJlbmRlck9wdGlvbj86IHN0cmluZ30gJG9wdGlvbnMgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aE9wdGlvbnMgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-google-sheet\/src\/Flow\/ETL\/Adapter\/GoogleSheet\/functions.php","start_line_in_file":56,"slug":"from-google-sheet-columns","name":"from_google_sheet_columns","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","parameters":[{"name":"auth_config","type":[{"name":"Sheets","namespace":"Google\\Service","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"spreadsheet_id","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sheet_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start_range_column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end_range_column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"with_header","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"rows_per_page","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1000"},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"GoogleSheetExtractor","namespace":"Flow\\ETL\\Adapter\\GoogleSheet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"GOOGLE_SHEET","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheXt0eXBlOiBzdHJpbmcsIHByb2plY3RfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXlfaWQ6IHN0cmluZywgcHJpdmF0ZV9rZXk6IHN0cmluZywgY2xpZW50X2VtYWlsOiBzdHJpbmcsIGNsaWVudF9pZDogc3RyaW5nLCBhdXRoX3VyaTogc3RyaW5nLCB0b2tlbl91cmk6IHN0cmluZywgYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsOiBzdHJpbmcsIGNsaWVudF94NTA5X2NlcnRfdXJsOiBzdHJpbmd9fFNoZWV0cyAkYXV0aF9jb25maWcKICogQHBhcmFtIHN0cmluZyAkc3ByZWFkc2hlZXRfaWQKICogQHBhcmFtIHN0cmluZyAkc2hlZXRfbmFtZQogKiBAcGFyYW0gc3RyaW5nICRzdGFydF9yYW5nZV9jb2x1bW4KICogQHBhcmFtIHN0cmluZyAkZW5kX3JhbmdlX2NvbHVtbgogKiBAcGFyYW0gYm9vbCAkd2l0aF9oZWFkZXIgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aEhlYWRlciBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gaW50ICRyb3dzX3Blcl9wYWdlIC0gaG93IG1hbnkgcm93cyBwZXIgcGFnZSB0byBmZXRjaCBmcm9tIEdvb2dsZSBTaGVldHMgQVBJLCBkZWZhdWx0IDEwMDAgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aFJvd3NQZXJQYWdlIG1ldGhvZCBpbnN0ZWFkCiAqIEBwYXJhbSBhcnJheXtkYXRlVGltZVJlbmRlck9wdGlvbj86IHN0cmluZywgbWFqb3JEaW1lbnNpb24\/OiBzdHJpbmcsIHZhbHVlUmVuZGVyT3B0aW9uPzogc3RyaW5nfSAkb3B0aW9ucyAtIEBkZXByZWNhdGVkIHVzZSB3aXRoT3B0aW9ucyBtZXRob2QgaW5zdGVhZAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-http\/src\/Flow\/ETL\/Adapter\/Http\/DSL\/functions.php","start_line_in_file":15,"slug":"from-dynamic-http-requests","name":"from_dynamic_http_requests","namespace":"Flow\\ETL\\Adapter\\Http","parameters":[{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"requestFactory","type":[{"name":"NextRequestFactory","namespace":"Flow\\ETL\\Adapter\\Http\\DynamicExtractor","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PsrHttpClientDynamicExtractor","namespace":"Flow\\ETL\\Adapter\\Http","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"HTTP","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-http\/src\/Flow\/ETL\/Adapter\/Http\/DSL\/functions.php","start_line_in_file":26,"slug":"from-static-http-requests","name":"from_static_http_requests","namespace":"Flow\\ETL\\Adapter\\Http","parameters":[{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"requests","type":[{"name":"iterable","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PsrHttpClientStaticExtractor","namespace":"Flow\\ETL\\Adapter\\Http","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"HTTP","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBpdGVyYWJsZTxSZXF1ZXN0SW50ZXJmYWNlPiAkcmVxdWVzdHMKICov"},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":30,"slug":"from-json","name":"from_json","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pointer","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"JsonExtractor","namespace":"Flow\\ETL\\Adapter\\JSON\\JSONMachine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"json"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aCAtIHN0cmluZyBpcyBpbnRlcm5hbGx5IHR1cm5lZCBpbnRvIHN0cmVhbQogKiBAcGFyYW0gP3N0cmluZyAkcG9pbnRlciAtIGlmIHlvdSB3YW50IHRvIGl0ZXJhdGUgb25seSByZXN1bHRzIG9mIGEgc3VidHJlZSwgdXNlIGEgcG9pbnRlciwgcmVhZCBtb3JlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9oYWxheGEvanNvbi1tYWNoaW5lI3BhcnNpbmctYS1zdWJ0cmVlIC0gQGRlcHJlY2F0ZSB1c2Ugd2l0aFBvaW50ZXIgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIG51bGx8U2NoZW1hICRzY2hlbWEgLSBlbmZvcmNlIHNjaGVtYSBvbiB0aGUgZXh0cmFjdGVkIGRhdGEgLSBAZGVwcmVjYXRlIHVzZSB3aXRoU2NoZW1hIG1ldGhvZCBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":52,"slug":"from-json-lines","name":"from_json_lines","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"JsonLinesExtractor","namespace":"Flow\\ETL\\Adapter\\JSON\\JSONMachine","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"jsonl"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFVzZWQgdG8gcmVhZCBmcm9tIGEgSlNPTiBsaW5lcyBodHRwczovL2pzb25saW5lcy5vcmcvIGZvcm1hdHRlZCBmaWxlLgogKgogKiBAcGFyYW0gUGF0aHxzdHJpbmcgJHBhdGggLSBzdHJpbmcgaXMgaW50ZXJuYWxseSB0dXJuZWQgaW50byBzdHJlYW0KICov"},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":66,"slug":"to-json","name":"to_json","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"flags","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"4194304"},{"name":"date_time_format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d\\\\TH:i:sP'"},{"name":"put_rows_in_new_lines","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"JsonLoader","namespace":"Flow\\ETL\\Adapter\\JSON","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gaW50ICRmbGFncyAtIFBIUCBKU09OIEZsYWdzIC0gQGRlcHJlY2F0ZSB1c2Ugd2l0aEZsYWdzIG1ldGhvZCBpbnN0ZWFkCiAqIEBwYXJhbSBzdHJpbmcgJGRhdGVfdGltZV9mb3JtYXQgLSBmb3JtYXQgZm9yIERhdGVUaW1lSW50ZXJmYWNlOjpmb3JtYXQoKSAtIEBkZXByZWNhdGUgdXNlIHdpdGhEYXRlVGltZUZvcm1hdCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gYm9vbCAkcHV0X3Jvd3NfaW5fbmV3X2xpbmVzIC0gaWYgeW91IHdhbnQgdG8gcHV0IGVhY2ggcm93IGluIGEgbmV3IGxpbmUgLSBAZGVwcmVjYXRlIHVzZSB3aXRoUm93c0luTmV3TGluZXMgbWV0aG9kIGluc3RlYWQKICoKICogQHJldHVybiBKc29uTG9hZGVyCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":86,"slug":"to-json-lines","name":"to_json_lines","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"JsonLinesLoader","namespace":"Flow\\ETL\\Adapter\\JSON","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFVzZWQgdG8gd3JpdGUgdG8gYSBKU09OIGxpbmVzIGh0dHBzOi8vanNvbmxpbmVzLm9yZy8gZm9ybWF0dGVkIGZpbGUuCiAqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKgogKiBAcmV0dXJuIEpzb25MaW5lc0xvYWRlcgogKi8="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":99,"slug":"schema-from-json-schema","name":"schema_from_json_schema","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"json_schema","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"request_factory","type":[{"name":"RequestFactoryInterface","namespace":"Psr\\Http\\Message","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgYSBKU09OIFNjaGVtYSAoaHR0cHM6Ly9qc29uLXNjaGVtYS5vcmcpIGRvY3VtZW50IGludG8gYSBGbG93IFNjaGVtYS4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbWl4ZWQ+fFBhdGh8c3RyaW5nICRqc29uX3NjaGVtYSAtIGRlY29kZWQgZG9jdW1lbnQsIHJhdyBKU09OIGRvY3VtZW50IG9yIGEgcGF0aCB0byBhIHNjaGVtYSBmaWxlCiAqIEBwYXJhbSBudWxsfENsaWVudEludGVyZmFjZSAkY2xpZW50IC0gUFNSLTE4IGh0dHAgY2xpZW50LCByZXF1aXJlZCB0byByZXNvbHZlIHJlbW90ZSBodHRwKHMpIHJlZmVyZW5jZXMKICogQHBhcmFtIG51bGx8UmVxdWVzdEZhY3RvcnlJbnRlcmZhY2UgJHJlcXVlc3RfZmFjdG9yeSAtIFBTUi0xNyByZXF1ZXN0IGZhY3RvcnksIHJlcXVpcmVkIHRvIHJlc29sdmUgcmVtb3RlIGh0dHAocykgcmVmZXJlbmNlcwogKi8="},{"repository_path":"src\/adapter\/etl-adapter-json\/src\/Flow\/ETL\/Adapter\/JSON\/functions.php","start_line_in_file":113,"slug":"schema-to-json-schema","name":"schema_to_json_schema","namespace":"Flow\\ETL\\Adapter\\JSON","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"JSON","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgYSBGbG93IFNjaGVtYSBpbnRvIGEgSlNPTiBTY2hlbWEgKGh0dHBzOi8vanNvbi1zY2hlbWEub3JnLCBkcmFmdCAyMDIwLTEyKSBkb2N1bWVudC4KICoKICogQHJldHVybiBhcnJheTxzdHJpbmcsIG1peGVkPgogKi8="},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":32,"slug":"from-parquet","name":"from_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Parquet","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Parquet\\Options::..."},{"name":"byte_order","type":[{"name":"ByteOrder","namespace":"Flow\\Parquet\\Binary","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Parquet\\Binary\\ByteOrder::..."},{"name":"offset","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ParquetExtractor","namespace":"Flow\\ETL\\Adapter\\Parquet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"parquet"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gYXJyYXk8c3RyaW5nPiAkY29sdW1ucyAtIGxpc3Qgb2YgY29sdW1ucyB0byByZWFkIGZyb20gcGFycXVldCBmaWxlIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoQ29sdW1uc2AgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIE9wdGlvbnMgJG9wdGlvbnMgLSBAZGVwcmVjYXRlZCB1c2UgYHdpdGhPcHRpb25zYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gQnl0ZU9yZGVyICRieXRlX29yZGVyIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoQnl0ZU9yZGVyYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxpbnQgJG9mZnNldCAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aE9mZnNldGAgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":62,"slug":"to-parquet","name":"to_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Parquet","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"compressions","type":[{"name":"Compressions","namespace":"Flow\\Parquet\\ParquetFile","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Parquet\\ParquetFile\\Compressions::..."},{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ParquetLoader","namespace":"Flow\\ETL\\Adapter\\Parquet","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"LOADER"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_writing","option":"parquet"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gbnVsbHxPcHRpb25zICRvcHRpb25zIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoT3B0aW9uc2AgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIENvbXByZXNzaW9ucyAkY29tcHJlc3Npb25zIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoQ29tcHJlc3Npb25zYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gbnVsbHxTY2hlbWEgJHNjaGVtYSAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aFNjaGVtYWAgbWV0aG9kIGluc3RlYWQKICov"},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":89,"slug":"array-to-generator","name":"array_to_generator","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Generator","namespace":"","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBhcnJheTxUPiAkZGF0YQogKgogKiBAcmV0dXJuIFxHZW5lcmF0b3I8VD4KICov"},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":97,"slug":"empty-generator","name":"empty_generator","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[],"return_type":[{"name":"Generator","namespace":"","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":103,"slug":"schema-to-parquet","name":"schema_to_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\Parquet\\ParquetFile","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-parquet\/src\/Flow\/ETL\/Adapter\/Parquet\/functions.php","start_line_in_file":109,"slug":"schema-from-parquet","name":"schema_from_parquet","namespace":"Flow\\ETL\\Adapter\\Parquet","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\Parquet\\ParquetFile","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PARQUET","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":15,"slug":"to-seal-upsert","name":"to_seal_upsert","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"engine","type":[{"name":"EngineInterface","namespace":"CmsIg\\Seal","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"index","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SealLoader","namespace":"Flow\\ETL\\Adapter\\Seal","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":21,"slug":"to-seal-delete","name":"to_seal_delete","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"engine","type":[{"name":"EngineInterface","namespace":"CmsIg\\Seal","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"index","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SealLoader","namespace":"Flow\\ETL\\Adapter\\Seal","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":27,"slug":"to-seal-schema","name":"to_seal_schema","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"index_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"identifier","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Schema","namespace":"CmsIg\\Seal\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-seal\/src\/Flow\/ETL\/Adapter\/Seal\/functions.php","start_line_in_file":33,"slug":"seal-schema-to-flow","name":"seal_schema_to_flow","namespace":"Flow\\ETL\\Adapter\\Seal","parameters":[{"name":"schema","type":[{"name":"Schema","namespace":"CmsIg\\Seal\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Schema","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SEAL","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/adapter\/etl-adapter-text\/src\/Flow\/ETL\/Adapter\/Text\/functions.php","start_line_in_file":20,"slug":"from-text","name":"from_text","namespace":"Flow\\ETL\\Adapter\\Text","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TextExtractor","namespace":"Flow\\ETL\\Adapter\\Text","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TEXT","type":"EXTRACTOR"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKi8="},{"repository_path":"src\/adapter\/etl-adapter-text\/src\/Flow\/ETL\/Adapter\/Text\/functions.php","start_line_in_file":32,"slug":"to-text","name":"to_text","namespace":"Flow\\ETL\\Adapter\\Text","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"new_line_separator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'\\n'"}],"return_type":[{"name":"Loader","namespace":"Flow\\ETL","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TEXT","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gc3RyaW5nICRuZXdfbGluZV9zZXBhcmF0b3IgLSBkZWZhdWx0IFBIUF9FT0wgLSBAZGVwcmVjYXRlZCB1c2Ugd2l0aE5ld0xpbmVTZXBhcmF0b3IgbWV0aG9kIGluc3RlYWQKICoKICogQHJldHVybiBMb2FkZXIKICov"},{"repository_path":"src\/adapter\/etl-adapter-xml\/src\/Flow\/ETL\/Adapter\/XML\/functions.php","start_line_in_file":36,"slug":"from-xml","name":"from_xml","namespace":"Flow\\ETL\\Adapter\\XML","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"xml_node_path","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"''"}],"return_type":[{"name":"XMLParserExtractor","namespace":"Flow\\ETL\\Adapter\\XML","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"XML","type":"EXTRACTOR"}},{"name":"DocumentationExample","namespace":"Flow\\ETL\\Attribute","arguments":{"topic":"data_frame","example":"data_reading","option":"xml"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqICBJbiBvcmRlciB0byBpdGVyYXRlIG9ubHkgb3ZlciA8ZWxlbWVudD4gbm9kZXMgdXNlIGBmcm9tX3htbCgkZmlsZSktPndpdGhYTUxOb2RlUGF0aCgncm9vdC9lbGVtZW50cy9lbGVtZW50JylgLgogKgogKiAgPHJvb3Q+CiAqICAgIDxlbGVtZW50cz4KICogICAgICA8ZWxlbWVudD48L2VsZW1lbnQ+CiAqICAgICAgPGVsZW1lbnQ+PC9lbGVtZW50PgogKiAgICA8ZWxlbWVudHM+CiAqICA8L3Jvb3Q+CiAqCiAqICBYTUwgTm9kZSBQYXRoIGRvZXMgbm90IHN1cHBvcnQgYXR0cmlidXRlcyBhbmQgaXQncyBub3QgeHBhdGgsIGl0IGlzIGp1c3QgYSBzZXF1ZW5jZQogKiAgb2Ygbm9kZSBuYW1lcyBzZXBhcmF0ZWQgd2l0aCBzbGFzaC4KICoKICogQHBhcmFtIFBhdGh8c3RyaW5nICRwYXRoCiAqIEBwYXJhbSBzdHJpbmcgJHhtbF9ub2RlX3BhdGggLSBAZGVwcmVjYXRlZCB1c2UgYGZyb21feG1sKCRmaWxlKS0+d2l0aFhNTE5vZGVQYXRoKCR4bWxOb2RlUGF0aClgIG1ldGhvZCBpbnN0ZWFkCiAqLw=="},{"repository_path":"src\/adapter\/etl-adapter-xml\/src\/Flow\/ETL\/Adapter\/XML\/functions.php","start_line_in_file":50,"slug":"to-xml","name":"to_xml","namespace":"Flow\\ETL\\Adapter\\XML","parameters":[{"name":"path","type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"root_element_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'rows'"},{"name":"row_element_name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'row'"},{"name":"attribute_prefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'_'"},{"name":"date_time_format","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'Y-m-d\\\\TH:i:s.uP'"},{"name":"xml_writer","type":[{"name":"XMLWriter","namespace":"Flow\\ETL\\Adapter\\XML","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\ETL\\Adapter\\XML\\XMLWriter\\DOMDocumentWriter::..."}],"return_type":[{"name":"XMLLoader","namespace":"Flow\\ETL\\Adapter\\XML\\Loader","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"XML","type":"LOADER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBQYXRofHN0cmluZyAkcGF0aAogKiBAcGFyYW0gc3RyaW5nICRyb290X2VsZW1lbnRfbmFtZSAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aFJvb3RFbGVtZW50TmFtZSgpYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRyb3dfZWxlbWVudF9uYW1lIC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoUm93RWxlbWVudE5hbWUoKWAgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIHN0cmluZyAkYXR0cmlidXRlX3ByZWZpeCAtIEBkZXByZWNhdGVkIHVzZSBgd2l0aEF0dHJpYnV0ZVByZWZpeCgpYCBtZXRob2QgaW5zdGVhZAogKiBAcGFyYW0gc3RyaW5nICRkYXRlX3RpbWVfZm9ybWF0IC0gQGRlcHJlY2F0ZWQgdXNlIGB3aXRoRGF0ZVRpbWVGb3JtYXQoKWAgbWV0aG9kIGluc3RlYWQKICogQHBhcmFtIFhNTFdyaXRlciAkeG1sX3dyaXRlcgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":32,"slug":"mount","name":"mount","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Mount","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":38,"slug":"partition","name":"partition","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Partition","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":44,"slug":"partitions","name":"partitions","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"partition","type":[{"name":"Partition","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Partitions","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":63,"slug":"path","name":"path","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"path","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Filesystem\\Path","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhdGggc3VwcG9ydHMgZ2xvYiBwYXR0ZXJucy4KICogRXhhbXBsZXM6CiAqICAtIHBhdGgoJyouY3N2JykgLSBhbnkgY3N2IGZpbGUgaW4gY3VycmVudCBkaXJlY3RvcnkKICogIC0gcGF0aCgnLyoqIC8gKi5jc3YnKSAtIGFueSBjc3YgZmlsZSBpbiBhbnkgc3ViZGlyZWN0b3J5IChyZW1vdmUgZW1wdHkgc3BhY2VzKQogKiAgLSBwYXRoKCcvZGlyL3BhcnRpdGlvbj0qIC8qLnBhcnF1ZXQnKSAtIGFueSBwYXJxdWV0IGZpbGUgaW4gZ2l2ZW4gcGFydGl0aW9uIGRpcmVjdG9yeS4KICoKICogR2xvYiBwYXR0ZXJuIGlzIGFsc28gc3VwcG9ydGVkIGJ5IHJlbW90ZSBmaWxlc3lzdGVtcyBsaWtlIEF6dXJlCiAqCiAqICAtIHBhdGgoJ2F6dXJlLWJsb2I6Ly9kaXJlY3RvcnkvKi5jc3YnKSAtIGFueSBjc3YgZmlsZSBpbiBnaXZlbiBkaXJlY3RvcnkKICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbnVsbHxib29sfGZsb2F0fGludHxzdHJpbmd8XFVuaXRFbnVtPnxQYXRoXE9wdGlvbnMgJG9wdGlvbnMKICov"},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":74,"slug":"path-real","name":"path_real","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"path","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Path","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFJlc29sdmUgcmVhbCBwYXRoIGZyb20gZ2l2ZW4gcGF0aC4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgbnVsbHxib29sfGZsb2F0fGludHxzdHJpbmd8XFVuaXRFbnVtPiAkb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":80,"slug":"native-local-filesystem","name":"native_local_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'file'"}],"return_type":[{"name":"NativeLocalFilesystem","namespace":"Flow\\Filesystem\\Local","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":90,"slug":"stdout-filesystem","name":"stdout_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'stdout'"}],"return_type":[{"name":"StdOutFilesystem","namespace":"Flow\\Filesystem\\Local","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyaXRlLW9ubHkgZmlsZXN5c3RlbSB1c2VmdWwgd2hlbiB3ZSBqdXN0IHdhbnQgdG8gd3JpdGUgdGhlIG91dHB1dCB0byBzdGRvdXQuCiAqIFRoZSBtYWluIHVzZSBjYXNlIGlzIGZvciBzdHJlYW1pbmcgZGF0YXNldHMgb3ZlciBodHRwLgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":99,"slug":"memory-filesystem","name":"memory_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'memory'"}],"return_type":[{"name":"MemoryFilesystem","namespace":"Flow\\Filesystem\\Local","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBtZW1vcnkgZmlsZXN5c3RlbSBhbmQgd3JpdGVzIGRhdGEgdG8gaXQgaW4gbWVtb3J5LgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":110,"slug":"fstab","name":"fstab","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"filesystems","type":[{"name":"Filesystem","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"FilesystemTable","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBmaWxlc3lzdGVtIHRhYmxlIHdpdGggZ2l2ZW4gZmlsZXN5c3RlbXMuCiAqIEZpbGVzeXN0ZW1zIGNhbiBiZSBhbHNvIG1vdW50ZWQgbGF0ZXIuCiAqIElmIG5vIGZpbGVzeXN0ZW1zIGFyZSBwcm92aWRlZCwgbG9jYWwgZmlsZXN5c3RlbSBpcyBtb3VudGVkLgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":126,"slug":"traceable-filesystem","name":"traceable_filesystem","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"filesystem","type":[{"name":"Filesystem","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"telemetryConfig","type":[{"name":"FilesystemTelemetryConfig","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TraceableFilesystem","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYSBmaWxlc3lzdGVtIHdpdGggdGVsZW1ldHJ5IHRyYWNpbmcgc3VwcG9ydC4KICogQWxsIGZpbGVzeXN0ZW0gYW5kIHN0cmVhbSBvcGVyYXRpb25zIHdpbGwgYmUgdHJhY2VkIGFjY29yZGluZyB0byB0aGUgY29uZmlndXJhdGlvbi4KICov"},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":135,"slug":"filesystem-telemetry-config","name":"filesystem_telemetry_config","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"telemetry","type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"FilesystemTelemetryOptions","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"FilesystemTelemetryConfig","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRlbGVtZXRyeSBjb25maWd1cmF0aW9uIGZvciB0aGUgZmlsZXN5c3RlbS4KICov"},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":150,"slug":"filesystem-telemetry-options","name":"filesystem_telemetry_options","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"trace_streams","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"collect_metrics","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"FilesystemTelemetryOptions","namespace":"Flow\\Filesystem\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBvcHRpb25zIGZvciBmaWxlc3lzdGVtIHRlbGVtZXRyeS4KICoKICogQHBhcmFtIGJvb2wgJHRyYWNlX3N0cmVhbXMgQ3JlYXRlIGEgc2luZ2xlIHNwYW4gcGVyIHN0cmVhbSBsaWZlY3ljbGUgKGRlZmF1bHQ6IE9OKQogKiBAcGFyYW0gYm9vbCAkY29sbGVjdF9tZXRyaWNzIENvbGxlY3QgbWV0cmljcyBmb3IgYnl0ZXMvb3BlcmF0aW9uIGNvdW50cyAoZGVmYXVsdDogT04pCiAqLw=="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":163,"slug":"file-copy","name":"file_copy","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"table","type":[{"name":"FilesystemTable","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"OperationOptions","namespace":"Flow\\Filesystem\\Operations","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Copy","namespace":"Flow\\Filesystem\\Operations","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvcHkgYSBmaWxlIGZyb20gb25lIHBhdGggdG8gYW5vdGhlciwgYWNyb3NzIGFueSBmaWxlc3lzdGVtcyBtb3VudGVkIGluIHRoZSB0YWJsZS4KICogQWx3YXlzIHN0cmVhbXMgYnl0ZXM7IHNhbWUtZmlsZXN5c3RlbSBjb3BpZXMgZG8gbm90IHVzZSBzZXJ2ZXItc2lkZSBvcHRpbWl6YXRpb25zCiAqIGJlY2F1c2UgYEZpbGVzeXN0ZW06Om12YCBpcyBhIG1vdmUsIG5vdCBhIGNvcHkuCiAqLw=="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":174,"slug":"file-move","name":"file_move","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"table","type":[{"name":"FilesystemTable","namespace":"Flow\\Filesystem","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"OperationOptions","namespace":"Flow\\Filesystem\\Operations","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Move","namespace":"Flow\\Filesystem\\Operations","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE1vdmUgYSBmaWxlIGZyb20gb25lIHBhdGggdG8gYW5vdGhlciwgYWNyb3NzIGFueSBmaWxlc3lzdGVtcyBtb3VudGVkIGluIHRoZSB0YWJsZS4KICogSW50cmEtZmlsZXN5c3RlbSBtb3ZlcyBkZWxlZ2F0ZSB0byBgRmlsZXN5c3RlbTo6bXZgIGZvciBzZXJ2ZXItc2lkZSBvcHRpbWl6YXRpb25zOwogKiBjcm9zcy1maWxlc3lzdGVtIG1vdmVzIHN0cmVhbS1jb3B5IHRoZW4gcmVtb3ZlIHRoZSBzb3VyY2UgKG5vbi1hdG9taWMpLgogKi8="},{"repository_path":"src\/lib\/filesystem\/src\/Flow\/Filesystem\/DSL\/functions.php","start_line_in_file":185,"slug":"operation-options","name":"operation_options","namespace":"Flow\\Filesystem\\DSL","parameters":[{"name":"chunkSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"8192"}],"return_type":[{"name":"OperationOptions","namespace":"Flow\\Filesystem\\Operations","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE9wdGlvbnMgc2hhcmVkIGJ5IGZpbGVzeXN0ZW0gb3BlcmF0aW9ucy4KICoKICogQHBhcmFtIGludCAkY2h1bmtTaXplIE51bWJlciBvZiBieXRlcyByZWFkL3dyaXR0ZW4gcGVyIGl0ZXJhdGlvbiB3aGVuIHN0cmVhbWluZyBhY3Jvc3MgZmlsZXN5c3RlbXMgKGRlZmF1bHQ6IDgxOTIpCiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":68,"slug":"type-structure","name":"type_structure","namespace":"Flow\\Types\\DSL","parameters":[{"name":"elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"optional_elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"allow_extra","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBhcnJheTxhcnJheS1rZXksIFR5cGU8VD4+ICRlbGVtZW50cwogKiBAcGFyYW0gYXJyYXk8YXJyYXkta2V5LCBUeXBlPFQ+PiAkb3B0aW9uYWxfZWxlbWVudHMKICoKICogQHJldHVybiBTdHJ1Y3R1cmVUeXBlPFQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":83,"slug":"type-union","name":"type_union","namespace":"Flow\\Types\\DSL","parameters":[{"name":"first","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"second","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"types","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICRmaXJzdAogKiBAcGFyYW0gVHlwZTxUPiAkc2Vjb25kCiAqIEBwYXJhbSBUeXBlPFQ+IC4uLiR0eXBlcwogKgogKiBAcmV0dXJuIFR5cGU8VD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":104,"slug":"type-intersection","name":"type_intersection","namespace":"Flow\\Types\\DSL","parameters":[{"name":"first","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"second","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"types","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICRmaXJzdAogKiBAcGFyYW0gVHlwZTxUPiAkc2Vjb25kCiAqIEBwYXJhbSBUeXBlPFQ+IC4uLiR0eXBlcwogKgogKiBAcmV0dXJuIFR5cGU8VD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":119,"slug":"type-numeric-string","name":"type_numeric_string","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxudW1lcmljLXN0cmluZz4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":132,"slug":"type-optional","name":"type_optional","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqCiAqIEByZXR1cm4gVHlwZTxUPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":143,"slug":"type-from-array","name":"type_from_array","namespace":"Flow\\Types\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPiAkZGF0YQogKgogKiBAcmV0dXJuIFR5cGU8bWl4ZWQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":154,"slug":"type-is-nullable","name":"type_is_nullable","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":176,"slug":"type-equals","name":"type_equals","namespace":"Flow\\Types\\DSL","parameters":[{"name":"left","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBUeXBlPG1peGVkPiAkbGVmdAogKiBAcGFyYW0gVHlwZTxtaXhlZD4gJHJpZ2h0CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":189,"slug":"types","name":"types","namespace":"Flow\\Types\\DSL","parameters":[{"name":"types","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Types","namespace":"Flow\\Types\\Type","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+IC4uLiR0eXBlcwogKgogKiBAcmV0dXJuIFR5cGVzPFQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":202,"slug":"type-list","name":"type_list","namespace":"Flow\\Types\\DSL","parameters":[{"name":"element","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICRlbGVtZW50CiAqCiAqIEByZXR1cm4gVHlwZTxsaXN0PFQ+PgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":217,"slug":"type-map","name":"type_map","namespace":"Flow\\Types\\DSL","parameters":[{"name":"key_type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"value_type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUS2V5IG9mIGFycmF5LWtleQogKiBAdGVtcGxhdGUgVFZhbHVlCiAqCiAqIEBwYXJhbSBUeXBlPFRLZXk+ICRrZXlfdHlwZQogKiBAcGFyYW0gVHlwZTxUVmFsdWU+ICR2YWx1ZV90eXBlCiAqCiAqIEByZXR1cm4gVHlwZTxhcnJheTxUS2V5LCBUVmFsdWU+PgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":226,"slug":"type-json","name":"type_json","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxKc29uPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":235,"slug":"type-datetime","name":"type_datetime","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZVRpbWVJbnRlcmZhY2U+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":244,"slug":"type-date","name":"type_date","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZVRpbWVJbnRlcmZhY2U+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":253,"slug":"type-time","name":"type_time","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZUludGVydmFsPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":262,"slug":"type-time-zone","name":"type_time_zone","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRGF0ZVRpbWVab25lPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":271,"slug":"type-xml","name":"type_xml","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRE9NRG9jdW1lbnR8WE1MRG9jdW1lbnQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":280,"slug":"type-xml-element","name":"type_xml_element","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxcRE9NRWxlbWVudHxFbGVtZW50PgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":289,"slug":"type-uuid","name":"type_uuid","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxVdWlkPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":298,"slug":"type-integer","name":"type_integer","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxpbnQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":307,"slug":"type-string","name":"type_string","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxzdHJpbmc+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":316,"slug":"type-float","name":"type_float","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxmbG9hdD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":325,"slug":"type-boolean","name":"type_boolean","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxib29sPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":338,"slug":"type-instance-of","name":"type_instance_of","namespace":"Flow\\Types\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICRjbGFzcwogKgogKiBAcmV0dXJuIFR5cGU8VD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":347,"slug":"type-object","name":"type_object","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxvYmplY3Q+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":356,"slug":"type-scalar","name":"type_scalar","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxib29sfGZsb2F0fGludHxzdHJpbmc+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":365,"slug":"type-resource","name":"type_resource","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxyZXNvdXJjZT4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":374,"slug":"type-array","name":"type_array","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxhcnJheTxtaXhlZD4+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":383,"slug":"type-callable","name":"type_callable","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxjYWxsYWJsZT4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":392,"slug":"type-null","name":"type_null","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxudWxsPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":401,"slug":"type-mixed","name":"type_mixed","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxtaXhlZD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":410,"slug":"type-positive-integer","name":"type_positive_integer","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxpbnQ8MCwgbWF4Pj4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":419,"slug":"type-non-empty-string","name":"type_non_empty_string","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxub24tZW1wdHktc3RyaW5nPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":432,"slug":"type-enum","name":"type_enum","namespace":"Flow\\Types\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIFVuaXRFbnVtCiAqCiAqIEBwYXJhbSBjbGFzcy1zdHJpbmc8VD4gJGNsYXNzCiAqCiAqIEByZXR1cm4gVHlwZTxUPgogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":445,"slug":"type-literal","name":"type_literal","namespace":"Flow\\Types\\DSL","parameters":[{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIGJvb2x8ZmxvYXR8aW50fHN0cmluZwogKgogKiBAcGFyYW0gVCAkdmFsdWUKICoKICogQHJldHVybiBUeXBlPFQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":454,"slug":"type-html","name":"type_html","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxIVE1MRG9jdW1lbnQ+CiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":463,"slug":"type-html-element","name":"type_html_element","namespace":"Flow\\Types\\DSL","parameters":[],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxIVE1MRWxlbWVudD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":475,"slug":"type-is","name":"type_is","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"typeClass","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqIEBwYXJhbSBjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+ICR0eXBlQ2xhc3MKICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":488,"slug":"type-is-any","name":"type_is_any","namespace":"Flow\\Types\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"typeClass","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"typeClasses","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUCiAqCiAqIEBwYXJhbSBUeXBlPFQ+ICR0eXBlCiAqIEBwYXJhbSBjbGFzcy1zdHJpbmc8VHlwZTxtaXhlZD4+ICR0eXBlQ2xhc3MKICogQHBhcmFtIGNsYXNzLXN0cmluZzxUeXBlPG1peGVkPj4gLi4uJHR5cGVDbGFzc2VzCiAqLw=="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":497,"slug":"get-type","name":"get_type","namespace":"Flow\\Types\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gVHlwZTxtaXhlZD4KICov"},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":510,"slug":"type-class-string","name":"type_class_string","namespace":"Flow\\Types\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gbnVsbHxjbGFzcy1zdHJpbmc8VD4gJGNsYXNzCiAqCiAqIEByZXR1cm4gKCRjbGFzcyBpcyBudWxsID8gVHlwZTxjbGFzcy1zdHJpbmc+IDogVHlwZTxjbGFzcy1zdHJpbmc8VD4+KQogKi8="},{"repository_path":"src\/lib\/types\/src\/Flow\/Types\/DSL\/functions.php","start_line_in_file":516,"slug":"dom-element-to-string","name":"dom_element_to_string","namespace":"Flow\\Types\\DSL","parameters":[{"name":"element","type":[{"name":"DOMElement","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"format_output","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"preserver_white_space","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"false","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TYPES","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":134,"slug":"column","name":"column","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnDefinition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbHVtbiBkZWZpbml0aW9uIGZvciBDUkVBVEUgVEFCTEUuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgQ29sdW1uIG5hbWUKICogQHBhcmFtIENvbHVtblR5cGUgJHR5cGUgQ29sdW1uIGRhdGEgdHlwZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":143,"slug":"catalog","name":"catalog","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"schemas","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Catalog","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYT4gJHNjaGVtYXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":154,"slug":"primary-key","name":"primary_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"PrimaryKeyConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBSSU1BUlkgS0VZIGNvbnN0cmFpbnQuCiAqCiAqIEBwYXJhbSBzdHJpbmcgLi4uJGNvbHVtbnMgQ29sdW1ucyB0aGF0IGZvcm0gdGhlIHByaW1hcnkga2V5CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":165,"slug":"unique-constraint","name":"unique_constraint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"UniqueConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFVOSVFVRSBjb25zdHJhaW50LgogKgogKiBAcGFyYW0gc3RyaW5nIC4uLiRjb2x1bW5zIENvbHVtbnMgdGhhdCBtdXN0IGJlIHVuaXF1ZSB0b2dldGhlcgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":178,"slug":"foreign-key","name":"foreign_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceTable","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ForeignKeyConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEZPUkVJR04gS0VZIGNvbnN0cmFpbnQuCiAqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGNvbHVtbnMgTG9jYWwgY29sdW1ucwogKiBAcGFyYW0gc3RyaW5nICRyZWZlcmVuY2VUYWJsZSBSZWZlcmVuY2VkIHRhYmxlCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHJlZmVyZW5jZUNvbHVtbnMgUmVmZXJlbmNlZCBjb2x1bW5zIChkZWZhdWx0cyB0byBzYW1lIGFzICRjb2x1bW5zIGlmIGVtcHR5KQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":187,"slug":"check-constraint","name":"check_constraint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"condition","type":[{"name":"Condition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CheckConstraint","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENIRUNLIGNvbnN0cmFpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":218,"slug":"create","name":"create","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"CreateFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZhY3RvcnkgZm9yIGJ1aWxkaW5nIENSRUFURSBzdGF0ZW1lbnRzLgogKgogKiBQcm92aWRlcyBhIHVuaWZpZWQgZW50cnkgcG9pbnQgZm9yIGFsbCBDUkVBVEUgb3BlcmF0aW9uczoKICogLSBjcmVhdGUoKS0+dGFibGUoKSAtIENSRUFURSBUQUJMRQogKiAtIGNyZWF0ZSgpLT50YWJsZUFzKCkgLSBDUkVBVEUgVEFCTEUgQVMKICogLSBjcmVhdGUoKS0+aW5kZXgoKSAtIENSRUFURSBJTkRFWAogKiAtIGNyZWF0ZSgpLT52aWV3KCkgLSBDUkVBVEUgVklFVwogKiAtIGNyZWF0ZSgpLT5tYXRlcmlhbGl6ZWRWaWV3KCkgLSBDUkVBVEUgTUFURVJJQUxJWkVEIFZJRVcKICogLSBjcmVhdGUoKS0+c2VxdWVuY2UoKSAtIENSRUFURSBTRVFVRU5DRQogKiAtIGNyZWF0ZSgpLT5zY2hlbWEoKSAtIENSRUFURSBTQ0hFTUEKICogLSBjcmVhdGUoKS0+cm9sZSgpIC0gQ1JFQVRFIFJPTEUKICogLSBjcmVhdGUoKS0+ZnVuY3Rpb24oKSAtIENSRUFURSBGVU5DVElPTgogKiAtIGNyZWF0ZSgpLT5wcm9jZWR1cmUoKSAtIENSRUFURSBQUk9DRURVUkUKICogLSBjcmVhdGUoKS0+dHJpZ2dlcigpIC0gQ1JFQVRFIFRSSUdHRVIKICogLSBjcmVhdGUoKS0+cnVsZSgpIC0gQ1JFQVRFIFJVTEUKICogLSBjcmVhdGUoKS0+ZXh0ZW5zaW9uKCkgLSBDUkVBVEUgRVhURU5TSU9OCiAqIC0gY3JlYXRlKCktPmNvbXBvc2l0ZVR5cGUoKSAtIENSRUFURSBUWVBFIChjb21wb3NpdGUpCiAqIC0gY3JlYXRlKCktPmVudW1UeXBlKCkgLSBDUkVBVEUgVFlQRSAoZW51bSkKICogLSBjcmVhdGUoKS0+cmFuZ2VUeXBlKCkgLSBDUkVBVEUgVFlQRSAocmFuZ2UpCiAqIC0gY3JlYXRlKCktPmRvbWFpbigpIC0gQ1JFQVRFIERPTUFJTgogKgogKiBFeGFtcGxlOiBjcmVhdGUoKS0+dGFibGUoJ3VzZXJzJyktPmNvbHVtbnMoY29sX2RlZignaWQnLCBjb2x1bW5fdHlwZV9zZXJpYWwoKSkpCiAqIEV4YW1wbGU6IGNyZWF0ZSgpLT5pbmRleCgnaWR4X2VtYWlsJyktPm9uKCd1c2VycycpLT5jb2x1bW5zKCdlbWFpbCcpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":247,"slug":"drop","name":"drop","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"DropFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZhY3RvcnkgZm9yIGJ1aWxkaW5nIERST1Agc3RhdGVtZW50cy4KICoKICogUHJvdmlkZXMgYSB1bmlmaWVkIGVudHJ5IHBvaW50IGZvciBhbGwgRFJPUCBvcGVyYXRpb25zOgogKiAtIGRyb3AoKS0+dGFibGUoKSAtIERST1AgVEFCTEUKICogLSBkcm9wKCktPmluZGV4KCkgLSBEUk9QIElOREVYCiAqIC0gZHJvcCgpLT52aWV3KCkgLSBEUk9QIFZJRVcKICogLSBkcm9wKCktPm1hdGVyaWFsaXplZFZpZXcoKSAtIERST1AgTUFURVJJQUxJWkVEIFZJRVcKICogLSBkcm9wKCktPnNlcXVlbmNlKCkgLSBEUk9QIFNFUVVFTkNFCiAqIC0gZHJvcCgpLT5zY2hlbWEoKSAtIERST1AgU0NIRU1BCiAqIC0gZHJvcCgpLT5yb2xlKCkgLSBEUk9QIFJPTEUKICogLSBkcm9wKCktPmZ1bmN0aW9uKCkgLSBEUk9QIEZVTkNUSU9OCiAqIC0gZHJvcCgpLT5wcm9jZWR1cmUoKSAtIERST1AgUFJPQ0VEVVJFCiAqIC0gZHJvcCgpLT50cmlnZ2VyKCkgLSBEUk9QIFRSSUdHRVIKICogLSBkcm9wKCktPnJ1bGUoKSAtIERST1AgUlVMRQogKiAtIGRyb3AoKS0+ZXh0ZW5zaW9uKCkgLSBEUk9QIEVYVEVOU0lPTgogKiAtIGRyb3AoKS0+dHlwZSgpIC0gRFJPUCBUWVBFCiAqIC0gZHJvcCgpLT5kb21haW4oKSAtIERST1AgRE9NQUlOCiAqIC0gZHJvcCgpLT5vd25lZCgpIC0gRFJPUCBPV05FRAogKgogKiBFeGFtcGxlOiBkcm9wKCktPnRhYmxlKCd1c2VycycsICdvcmRlcnMnKS0+aWZFeGlzdHMoKS0+Y2FzY2FkZSgpCiAqIEV4YW1wbGU6IGRyb3AoKS0+aW5kZXgoJ2lkeF9lbWFpbCcpLT5pZkV4aXN0cygpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":281,"slug":"alter","name":"alter","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AlterFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZhY3RvcnkgZm9yIGJ1aWxkaW5nIEFMVEVSIHN0YXRlbWVudHMuCiAqCiAqIFByb3ZpZGVzIGEgdW5pZmllZCBlbnRyeSBwb2ludCBmb3IgYWxsIEFMVEVSIG9wZXJhdGlvbnM6CiAqIC0gYWx0ZXIoKS0+dGFibGUoKSAtIEFMVEVSIFRBQkxFCiAqIC0gYWx0ZXIoKS0+aW5kZXgoKSAtIEFMVEVSIElOREVYCiAqIC0gYWx0ZXIoKS0+dmlldygpIC0gQUxURVIgVklFVwogKiAtIGFsdGVyKCktPm1hdGVyaWFsaXplZFZpZXcoKSAtIEFMVEVSIE1BVEVSSUFMSVpFRCBWSUVXCiAqIC0gYWx0ZXIoKS0+c2VxdWVuY2UoKSAtIEFMVEVSIFNFUVVFTkNFCiAqIC0gYWx0ZXIoKS0+c2NoZW1hKCkgLSBBTFRFUiBTQ0hFTUEKICogLSBhbHRlcigpLT5yb2xlKCkgLSBBTFRFUiBST0xFCiAqIC0gYWx0ZXIoKS0+ZnVuY3Rpb24oKSAtIEFMVEVSIEZVTkNUSU9OCiAqIC0gYWx0ZXIoKS0+cHJvY2VkdXJlKCkgLSBBTFRFUiBQUk9DRURVUkUKICogLSBhbHRlcigpLT50cmlnZ2VyKCkgLSBBTFRFUiBUUklHR0VSCiAqIC0gYWx0ZXIoKS0+ZXh0ZW5zaW9uKCkgLSBBTFRFUiBFWFRFTlNJT04KICogLSBhbHRlcigpLT5lbnVtVHlwZSgpIC0gQUxURVIgVFlQRSAoZW51bSkKICogLSBhbHRlcigpLT5kb21haW4oKSAtIEFMVEVSIERPTUFJTgogKgogKiBSZW5hbWUgb3BlcmF0aW9ucyBhcmUgYWxzbyB1bmRlciBhbHRlcigpOgogKiAtIGFsdGVyKCktPmluZGV4KCdvbGQnKS0+cmVuYW1lVG8oJ25ldycpCiAqIC0gYWx0ZXIoKS0+dmlldygnb2xkJyktPnJlbmFtZVRvKCduZXcnKQogKiAtIGFsdGVyKCktPnNjaGVtYSgnb2xkJyktPnJlbmFtZVRvKCduZXcnKQogKiAtIGFsdGVyKCktPnJvbGUoJ29sZCcpLT5yZW5hbWVUbygnbmV3JykKICogLSBhbHRlcigpLT50cmlnZ2VyKCdvbGQnKS0+b24oJ3RhYmxlJyktPnJlbmFtZVRvKCduZXcnKQogKgogKiBFeGFtcGxlOiBhbHRlcigpLT50YWJsZSgndXNlcnMnKS0+YWRkQ29sdW1uKGNvbF9kZWYoJ2VtYWlsJywgY29sdW1uX3R5cGVfdGV4dCgpKSkKICogRXhhbXBsZTogYWx0ZXIoKS0+c2VxdWVuY2UoJ3VzZXJfaWRfc2VxJyktPnJlc3RhcnQoMTAwMCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":292,"slug":"truncate-table","name":"truncate_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"TruncateFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Truncate","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRSVU5DQVRFIFRBQkxFIGJ1aWxkZXIuCiAqCiAqIEBwYXJhbSBzdHJpbmcgLi4uJHRhYmxlcyBUYWJsZSBuYW1lcyB0byB0cnVuY2F0ZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":310,"slug":"refresh-materialized-view","name":"refresh_materialized_view","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"RefreshMatViewOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\View\\RefreshMaterializedView","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFRlJFU0ggTUFURVJJQUxJWkVEIFZJRVcgYnVpbGRlci4KICoKICogRXhhbXBsZTogcmVmcmVzaF9tYXRlcmlhbGl6ZWRfdmlldygndXNlcl9zdGF0cycpCiAqIFByb2R1Y2VzOiBSRUZSRVNIIE1BVEVSSUFMSVpFRCBWSUVXIHVzZXJfc3RhdHMKICoKICogRXhhbXBsZTogcmVmcmVzaF9tYXRlcmlhbGl6ZWRfdmlldygndXNlcl9zdGF0cycpLT5jb25jdXJyZW50bHkoKS0+d2l0aERhdGEoKQogKiBQcm9kdWNlczogUkVGUkVTSCBNQVRFUklBTElaRUQgVklFVyBDT05DVVJSRU5UTFkgdXNlcl9zdGF0cyBXSVRIIERBVEEKICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBWaWV3IG5hbWUgKG1heSBpbmNsdWRlIHNjaGVtYSBhcyAic2NoZW1hLnZpZXciKQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNjaGVtYSBTY2hlbWEgbmFtZSAob3B0aW9uYWwsIG92ZXJyaWRlcyBwYXJzZWQgc2NoZW1hKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":319,"slug":"ref-action-cascade","name":"ref_action_cascade","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIENBU0NBREUgcmVmZXJlbnRpYWwgYWN0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":328,"slug":"ref-action-restrict","name":"ref_action_restrict","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIFJFU1RSSUNUIHJlZmVyZW50aWFsIGFjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":337,"slug":"ref-action-set-null","name":"ref_action_set_null","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIFNFVCBOVUxMIHJlZmVyZW50aWFsIGFjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":346,"slug":"ref-action-set-default","name":"ref_action_set_default","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIFNFVCBERUZBVUxUIHJlZmVyZW50aWFsIGFjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":355,"slug":"ref-action-no-action","name":"ref_action_no_action","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCBhIE5PIEFDVElPTiByZWZlcmVudGlhbCBhY3Rpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":370,"slug":"reindex-index","name":"reindex_index","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBJTkRFWCBzdGF0ZW1lbnQuCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5jb25jdXJyZW50bHkoKSwgLT52ZXJib3NlKCksIC0+dGFibGVzcGFjZSgpCiAqCiAqIEV4YW1wbGU6IHJlaW5kZXhfaW5kZXgoJ2lkeF91c2Vyc19lbWFpbCcpLT5jb25jdXJyZW50bHkoKQogKgogKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRoZSBpbmRleCBuYW1lIChtYXkgaW5jbHVkZSBzY2hlbWE6IHNjaGVtYS5pbmRleCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":385,"slug":"reindex-table","name":"reindex_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBUQUJMRSBzdGF0ZW1lbnQuCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5jb25jdXJyZW50bHkoKSwgLT52ZXJib3NlKCksIC0+dGFibGVzcGFjZSgpCiAqCiAqIEV4YW1wbGU6IHJlaW5kZXhfdGFibGUoJ3VzZXJzJyktPmNvbmN1cnJlbnRseSgpCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHRhYmxlIG5hbWUgKG1heSBpbmNsdWRlIHNjaGVtYTogc2NoZW1hLnRhYmxlKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":400,"slug":"reindex-schema","name":"reindex_schema","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBTQ0hFTUEgc3RhdGVtZW50LgogKgogKiBVc2UgY2hhaW5hYmxlIG1ldGhvZHM6IC0+Y29uY3VycmVudGx5KCksIC0+dmVyYm9zZSgpLCAtPnRhYmxlc3BhY2UoKQogKgogKiBFeGFtcGxlOiByZWluZGV4X3NjaGVtYSgncHVibGljJyktPmNvbmN1cnJlbnRseSgpCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIHNjaGVtYSBuYW1lCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":415,"slug":"reindex-database","name":"reindex_database","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ReindexFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index\\Reindex","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFN0YXJ0IGJ1aWxkaW5nIGEgUkVJTkRFWCBEQVRBQkFTRSBzdGF0ZW1lbnQuCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5jb25jdXJyZW50bHkoKSwgLT52ZXJib3NlKCksIC0+dGFibGVzcGFjZSgpCiAqCiAqIEV4YW1wbGU6IHJlaW5kZXhfZGF0YWJhc2UoJ215ZGInKS0+Y29uY3VycmVudGx5KCkKICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgZGF0YWJhc2UgbmFtZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":430,"slug":"index-col","name":"index_col","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"IndexColumn","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbmRleCBjb2x1bW4gc3BlY2lmaWNhdGlvbi4KICoKICogVXNlIGNoYWluYWJsZSBtZXRob2RzOiAtPmFzYygpLCAtPmRlc2MoKSwgLT5udWxsc0ZpcnN0KCksIC0+bnVsbHNMYXN0KCksIC0+b3BjbGFzcygpLCAtPmNvbGxhdGUoKQogKgogKiBFeGFtcGxlOiBpbmRleF9jb2woJ2VtYWlsJyktPmRlc2MoKS0+bnVsbHNMYXN0KCkKICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgY29sdW1uIG5hbWUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":445,"slug":"index-expr","name":"index_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expression","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"IndexColumn","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"SCHEMA"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbmRleCBjb2x1bW4gc3BlY2lmaWNhdGlvbiBmcm9tIGFuIGV4cHJlc3Npb24uCiAqCiAqIFVzZSBjaGFpbmFibGUgbWV0aG9kczogLT5hc2MoKSwgLT5kZXNjKCksIC0+bnVsbHNGaXJzdCgpLCAtPm51bGxzTGFzdCgpLCAtPm9wY2xhc3MoKSwgLT5jb2xsYXRlKCkKICoKICogRXhhbXBsZTogaW5kZXhfZXhwcihmbl9jYWxsKCdsb3dlcicsIGNvbCgnZW1haWwnKSkpLT5kZXNjKCkKICoKICogQHBhcmFtIEV4cHJlc3Npb24gJGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gaW5kZXgKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":454,"slug":"index-method-btree","name":"index_method_btree","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgQlRSRUUgaW5kZXggbWV0aG9kLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":463,"slug":"index-method-hash","name":"index_method_hash","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgSEFTSCBpbmRleCBtZXRob2QuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":472,"slug":"index-method-gist","name":"index_method_gist","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgR0lTVCBpbmRleCBtZXRob2QuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":481,"slug":"index-method-spgist","name":"index_method_spgist","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgU1BHSVNUIGluZGV4IG1ldGhvZC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":490,"slug":"index-method-gin","name":"index_method_gin","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgR0lOIGluZGV4IG1ldGhvZC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":499,"slug":"index-method-brin","name":"index_method_brin","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Index","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgQlJJTiBpbmRleCBtZXRob2QuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":511,"slug":"vacuum","name":"vacuum","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"VacuumFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZBQ1VVTSBidWlsZGVyLgogKgogKiBFeGFtcGxlOiB2YWN1dW0oKS0+dGFibGUoJ3VzZXJzJykKICogUHJvZHVjZXM6IFZBQ1VVTSB1c2VycwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":523,"slug":"analyze","name":"analyze","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AnalyzeFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBTkFMWVpFIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IGFuYWx5emUoKS0+dGFibGUoJ3VzZXJzJykKICogUHJvZHVjZXM6IEFOQUxZWkUgdXNlcnMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":537,"slug":"explain","name":"explain","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false},{"name":"InsertBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Insert","is_nullable":false,"is_variadic":false},{"name":"UpdateBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Update","is_nullable":false,"is_variadic":false},{"name":"DeleteBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Delete","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExplainFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFWFBMQUlOIGJ1aWxkZXIgZm9yIGEgcXVlcnkuCiAqCiAqIEV4YW1wbGU6IGV4cGxhaW4oc2VsZWN0KCktPmZyb20oJ3VzZXJzJykpCiAqIFByb2R1Y2VzOiBFWFBMQUlOIFNFTEVDVCAqIEZST00gdXNlcnMKICoKICogQHBhcmFtIERlbGV0ZUJ1aWxkZXJ8SW5zZXJ0QnVpbGRlcnxTZWxlY3RGaW5hbFN0ZXB8VXBkYXRlQnVpbGRlciAkcXVlcnkgUXVlcnkgdG8gZXhwbGFpbgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":549,"slug":"lock-table","name":"lock_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"LockFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExPQ0sgVEFCTEUgYnVpbGRlci4KICoKICogRXhhbXBsZTogbG9ja190YWJsZSgndXNlcnMnLCAnb3JkZXJzJyktPmFjY2Vzc0V4Y2x1c2l2ZSgpCiAqIFByb2R1Y2VzOiBMT0NLIFRBQkxFIHVzZXJzLCBvcmRlcnMgSU4gQUNDRVNTIEVYQ0xVU0lWRSBNT0RFCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":564,"slug":"comment","name":"comment","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"target","type":[{"name":"CommentTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CommentFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPTU1FTlQgT04gYnVpbGRlci4KICoKICogRXhhbXBsZTogY29tbWVudChDb21tZW50VGFyZ2V0OjpUQUJMRSwgJ3VzZXJzJyktPmlzKCdVc2VyIGFjY291bnRzIHRhYmxlJykKICogUHJvZHVjZXM6IENPTU1FTlQgT04gVEFCTEUgdXNlcnMgSVMgJ1VzZXIgYWNjb3VudHMgdGFibGUnCiAqCiAqIEBwYXJhbSBDb21tZW50VGFyZ2V0ICR0YXJnZXQgVGFyZ2V0IHR5cGUgKFRBQkxFLCBDT0xVTU4sIElOREVYLCBldGMuKQogKiBAcGFyYW0gc3RyaW5nICRuYW1lIFRhcmdldCBuYW1lICh1c2UgJ3RhYmxlLmNvbHVtbicgZm9yIENPTFVNTiB0YXJnZXRzKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":576,"slug":"cluster","name":"cluster","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ClusterFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENMVVNURVIgYnVpbGRlci4KICoKICogRXhhbXBsZTogY2x1c3RlcigpLT50YWJsZSgndXNlcnMnKS0+dXNpbmcoJ2lkeF91c2Vyc19wa2V5JykKICogUHJvZHVjZXM6IENMVVNURVIgdXNlcnMgVVNJTkcgaWR4X3VzZXJzX3BrZXkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":590,"slug":"discard","name":"discard","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"type","type":[{"name":"DiscardType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DiscardFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERJU0NBUkQgYnVpbGRlci4KICoKICogRXhhbXBsZTogZGlzY2FyZChEaXNjYXJkVHlwZTo6QUxMKQogKiBQcm9kdWNlczogRElTQ0FSRCBBTEwKICoKICogQHBhcmFtIERpc2NhcmRUeXBlICR0eXBlIFR5cGUgb2YgcmVzb3VyY2VzIHRvIGRpc2NhcmQgKEFMTCwgUExBTlMsIFNFUVVFTkNFUywgVEVNUCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":609,"slug":"grant","name":"grant","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"privileges","type":[{"name":"TablePrivilege","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"GrantOnStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdSQU5UIHByaXZpbGVnZXMgYnVpbGRlci4KICoKICogRXhhbXBsZTogZ3JhbnQoVGFibGVQcml2aWxlZ2U6OlNFTEVDVCktPm9uVGFibGUoJ3VzZXJzJyktPnRvKCdhcHBfdXNlcicpCiAqIFByb2R1Y2VzOiBHUkFOVCBTRUxFQ1QgT04gdXNlcnMgVE8gYXBwX3VzZXIKICoKICogRXhhbXBsZTogZ3JhbnQoVGFibGVQcml2aWxlZ2U6OkFMTCktPm9uQWxsVGFibGVzSW5TY2hlbWEoJ3B1YmxpYycpLT50bygnYWRtaW4nKQogKiBQcm9kdWNlczogR1JBTlQgQUxMIE9OIEFMTCBUQUJMRVMgSU4gU0NIRU1BIHB1YmxpYyBUTyBhZG1pbgogKgogKiBAcGFyYW0gc3RyaW5nfFRhYmxlUHJpdmlsZWdlIC4uLiRwcml2aWxlZ2VzIFRoZSBwcml2aWxlZ2VzIHRvIGdyYW50CiAqCiAqIEByZXR1cm4gR3JhbnRPblN0ZXAgQnVpbGRlciBmb3IgZ3JhbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":628,"slug":"grant-role","name":"grant_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"GrantRoleToStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdSQU5UIHJvbGUgYnVpbGRlci4KICoKICogRXhhbXBsZTogZ3JhbnRfcm9sZSgnYWRtaW4nKS0+dG8oJ3VzZXIxJykKICogUHJvZHVjZXM6IEdSQU5UIGFkbWluIFRPIHVzZXIxCiAqCiAqIEV4YW1wbGU6IGdyYW50X3JvbGUoJ2FkbWluJywgJ2RldmVsb3BlcicpLT50bygndXNlcjEnKS0+d2l0aEFkbWluT3B0aW9uKCkKICogUHJvZHVjZXM6IEdSQU5UIGFkbWluLCBkZXZlbG9wZXIgVE8gdXNlcjEgV0lUSCBBRE1JTiBPUFRJT04KICoKICogQHBhcmFtIHN0cmluZyAuLi4kcm9sZXMgVGhlIHJvbGVzIHRvIGdyYW50CiAqCiAqIEByZXR1cm4gR3JhbnRSb2xlVG9TdGVwIEJ1aWxkZXIgZm9yIGdyYW50IHJvbGUgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":647,"slug":"revoke","name":"revoke","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"privileges","type":[{"name":"TablePrivilege","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"RevokeOnStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVk9LRSBwcml2aWxlZ2VzIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJldm9rZShUYWJsZVByaXZpbGVnZTo6U0VMRUNUKS0+b25UYWJsZSgndXNlcnMnKS0+ZnJvbSgnYXBwX3VzZXInKQogKiBQcm9kdWNlczogUkVWT0tFIFNFTEVDVCBPTiB1c2VycyBGUk9NIGFwcF91c2VyCiAqCiAqIEV4YW1wbGU6IHJldm9rZShUYWJsZVByaXZpbGVnZTo6QUxMKS0+b25UYWJsZSgndXNlcnMnKS0+ZnJvbSgnYXBwX3VzZXInKS0+Y2FzY2FkZSgpCiAqIFByb2R1Y2VzOiBSRVZPS0UgQUxMIE9OIHVzZXJzIEZST00gYXBwX3VzZXIgQ0FTQ0FERQogKgogKiBAcGFyYW0gc3RyaW5nfFRhYmxlUHJpdmlsZWdlIC4uLiRwcml2aWxlZ2VzIFRoZSBwcml2aWxlZ2VzIHRvIHJldm9rZQogKgogKiBAcmV0dXJuIFJldm9rZU9uU3RlcCBCdWlsZGVyIGZvciByZXZva2Ugb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":666,"slug":"revoke-role","name":"revoke_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"RevokeRoleFromStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Grant","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVk9LRSByb2xlIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJldm9rZV9yb2xlKCdhZG1pbicpLT5mcm9tKCd1c2VyMScpCiAqIFByb2R1Y2VzOiBSRVZPS0UgYWRtaW4gRlJPTSB1c2VyMQogKgogKiBFeGFtcGxlOiByZXZva2Vfcm9sZSgnYWRtaW4nKS0+ZnJvbSgndXNlcjEnKS0+Y2FzY2FkZSgpCiAqIFByb2R1Y2VzOiBSRVZPS0UgYWRtaW4gRlJPTSB1c2VyMSBDQVNDQURFCiAqCiAqIEBwYXJhbSBzdHJpbmcgLi4uJHJvbGVzIFRoZSByb2xlcyB0byByZXZva2UKICoKICogQHJldHVybiBSZXZva2VSb2xlRnJvbVN0ZXAgQnVpbGRlciBmb3IgcmV2b2tlIHJvbGUgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":682,"slug":"set-role","name":"set_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"role","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SetRoleFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Session","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBST0xFIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHNldF9yb2xlKCdhZG1pbicpCiAqIFByb2R1Y2VzOiBTRVQgUk9MRSBhZG1pbgogKgogKiBAcGFyYW0gc3RyaW5nICRyb2xlIFRoZSByb2xlIHRvIHNldAogKgogKiBAcmV0dXJuIFNldFJvbGVGaW5hbFN0ZXAgQnVpbGRlciBmb3Igc2V0IHJvbGUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":696,"slug":"reset-role","name":"reset_role","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ResetRoleFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Session","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFU0VUIFJPTEUgYnVpbGRlci4KICoKICogRXhhbXBsZTogcmVzZXRfcm9sZSgpCiAqIFByb2R1Y2VzOiBSRVNFVCBST0xFCiAqCiAqIEByZXR1cm4gUmVzZXRSb2xlRmluYWxTdGVwIEJ1aWxkZXIgZm9yIHJlc2V0IHJvbGUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":712,"slug":"reassign-owned","name":"reassign_owned","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ReassignOwnedToStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Ownership","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFQVNTSUdOIE9XTkVEIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJlYXNzaWduX293bmVkKCdvbGRfcm9sZScpLT50bygnbmV3X3JvbGUnKQogKiBQcm9kdWNlczogUkVBU1NJR04gT1dORUQgQlkgb2xkX3JvbGUgVE8gbmV3X3JvbGUKICoKICogQHBhcmFtIHN0cmluZyAuLi4kcm9sZXMgVGhlIHJvbGVzIHdob3NlIG93bmVkIG9iamVjdHMgc2hvdWxkIGJlIHJlYXNzaWduZWQKICoKICogQHJldHVybiBSZWFzc2lnbk93bmVkVG9TdGVwIEJ1aWxkZXIgZm9yIHJlYXNzaWduIG93bmVkIG9wdGlvbnMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":731,"slug":"drop-owned","name":"drop_owned","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"roles","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"DropOwnedFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Ownership","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIERST1AgT1dORUQgYnVpbGRlci4KICoKICogRXhhbXBsZTogZHJvcF9vd25lZCgncm9sZTEnKQogKiBQcm9kdWNlczogRFJPUCBPV05FRCBCWSByb2xlMQogKgogKiBFeGFtcGxlOiBkcm9wX293bmVkKCdyb2xlMScsICdyb2xlMicpLT5jYXNjYWRlKCkKICogUHJvZHVjZXM6IERST1AgT1dORUQgQlkgcm9sZTEsIHJvbGUyIENBU0NBREUKICoKICogQHBhcmFtIHN0cmluZyAuLi4kcm9sZXMgVGhlIHJvbGVzIHdob3NlIG93bmVkIG9iamVjdHMgc2hvdWxkIGJlIGRyb3BwZWQKICoKICogQHJldHVybiBEcm9wT3duZWRGaW5hbFN0ZXAgQnVpbGRlciBmb3IgZHJvcCBvd25lZCBvcHRpb25zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":749,"slug":"func-arg","name":"func_arg","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FunctionArgument","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSBuZXcgZnVuY3Rpb24gYXJndW1lbnQgZm9yIHVzZSBpbiBmdW5jdGlvbi9wcm9jZWR1cmUgZGVmaW5pdGlvbnMuCiAqCiAqIEV4YW1wbGU6IGZ1bmNfYXJnKGNvbHVtbl90eXBlX2ludGVnZXIoKSkKICogRXhhbXBsZTogZnVuY19hcmcoY29sdW1uX3R5cGVfdGV4dCgpKS0+bmFtZWQoJ3VzZXJuYW1lJykKICogRXhhbXBsZTogZnVuY19hcmcoY29sdW1uX3R5cGVfaW50ZWdlcigpKS0+bmFtZWQoJ2NvdW50JyktPmRlZmF1bHQoJzAnKQogKiBFeGFtcGxlOiBmdW5jX2FyZyhjb2x1bW5fdHlwZV90ZXh0KCkpLT5vdXQoKQogKgogKiBAcGFyYW0gQ29sdW1uVHlwZSAkdHlwZSBUaGUgUG9zdGdyZVNRTCBkYXRhIHR5cGUgZm9yIHRoZSBhcmd1bWVudAogKgogKiBAcmV0dXJuIEZ1bmN0aW9uQXJndW1lbnQgQnVpbGRlciBmb3IgZnVuY3Rpb24gYXJndW1lbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":768,"slug":"call","name":"call","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"procedure","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CallFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSBDQUxMIHN0YXRlbWVudCBidWlsZGVyIGZvciBpbnZva2luZyBhIHByb2NlZHVyZS4KICoKICogRXhhbXBsZTogY2FsbCgndXBkYXRlX3N0YXRzJyktPndpdGgoMTIzKQogKiBQcm9kdWNlczogQ0FMTCB1cGRhdGVfc3RhdHMoMTIzKQogKgogKiBFeGFtcGxlOiBjYWxsKCdwcm9jZXNzX2RhdGEnKS0+d2l0aCgndGVzdCcsIDQyLCB0cnVlKQogKiBQcm9kdWNlczogQ0FMTCBwcm9jZXNzX2RhdGEoJ3Rlc3QnLCA0MiwgdHJ1ZSkKICoKICogQHBhcmFtIHN0cmluZyAkcHJvY2VkdXJlIFRoZSBuYW1lIG9mIHRoZSBwcm9jZWR1cmUgdG8gY2FsbAogKgogKiBAcmV0dXJuIENhbGxGaW5hbFN0ZXAgQnVpbGRlciBmb3IgY2FsbCBzdGF0ZW1lbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":787,"slug":"do-block","name":"do_block","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"code","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DoFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Function","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSBETyBzdGF0ZW1lbnQgYnVpbGRlciBmb3IgZXhlY3V0aW5nIGFuIGFub255bW91cyBjb2RlIGJsb2NrLgogKgogKiBFeGFtcGxlOiBkb19ibG9jaygnQkVHSU4gUkFJU0UgTk9USUNFICQkSGVsbG8gV29ybGQkJDsgRU5EOycpCiAqIFByb2R1Y2VzOiBETyAkJCBCRUdJTiBSQUlTRSBOT1RJQ0UgJCRIZWxsbyBXb3JsZCQkOyBFTkQ7ICQkIExBTkdVQUdFIHBscGdzcWwKICoKICogRXhhbXBsZTogZG9fYmxvY2soJ1NFTEVDVCAxJyktPmxhbmd1YWdlKCdzcWwnKQogKiBQcm9kdWNlczogRE8gJCQgU0VMRUNUIDEgJCQgTEFOR1VBR0Ugc3FsCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNvZGUgVGhlIGFub255bW91cyBjb2RlIGJsb2NrIHRvIGV4ZWN1dGUKICoKICogQHJldHVybiBEb0ZpbmFsU3RlcCBCdWlsZGVyIGZvciBETyBzdGF0ZW1lbnQgb3B0aW9ucwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":807,"slug":"type-attr","name":"type_attr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TypeAttribute","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema\\Type","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZXMgYSB0eXBlIGF0dHJpYnV0ZSBmb3IgY29tcG9zaXRlIHR5cGVzLgogKgogKiBFeGFtcGxlOiB0eXBlX2F0dHIoJ25hbWUnLCBjb2x1bW5fdHlwZV90ZXh0KCkpCiAqIFByb2R1Y2VzOiBuYW1lIHRleHQKICoKICogRXhhbXBsZTogdHlwZV9hdHRyKCdkZXNjcmlwdGlvbicsIGNvbHVtbl90eXBlX3RleHQoKSktPmNvbGxhdGUoJ2VuX1VTJykKICogUHJvZHVjZXM6IGRlc2NyaXB0aW9uIHRleHQgQ09MTEFURSAiZW5fVVMiCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lCiAqIEBwYXJhbSBDb2x1bW5UeXBlICR0eXBlIFRoZSBhdHRyaWJ1dGUgdHlwZQogKgogKiBAcmV0dXJuIFR5cGVBdHRyaWJ1dGUgVHlwZSBhdHRyaWJ1dGUgdmFsdWUgb2JqZWN0CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":816,"slug":"column-type-integer","name":"column_type_integer","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbnRlZ2VyIGRhdGEgdHlwZSAoUG9zdGdyZVNRTCBpbnQ0KS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":825,"slug":"column-type-smallint","name":"column_type_smallint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNtYWxsaW50IGRhdGEgdHlwZSAoUG9zdGdyZVNRTCBpbnQyKS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":834,"slug":"column-type-bigint","name":"column_type_bigint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJpZ2ludCBkYXRhIHR5cGUgKFBvc3RncmVTUUwgaW50OCkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":843,"slug":"column-type-boolean","name":"column_type_boolean","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJvb2xlYW4gZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":852,"slug":"column-type-text","name":"column_type_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRleHQgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":861,"slug":"column-type-varchar","name":"column_type_varchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHZhcmNoYXIgZGF0YSB0eXBlIHdpdGggbGVuZ3RoIGNvbnN0cmFpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":870,"slug":"column-type-char","name":"column_type_char","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNoYXIgZGF0YSB0eXBlIHdpdGggbGVuZ3RoIGNvbnN0cmFpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":879,"slug":"column-type-numeric","name":"column_type_numeric","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG51bWVyaWMgZGF0YSB0eXBlIHdpdGggb3B0aW9uYWwgcHJlY2lzaW9uIGFuZCBzY2FsZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":888,"slug":"column-type-decimal","name":"column_type_decimal","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRlY2ltYWwgZGF0YSB0eXBlIHdpdGggb3B0aW9uYWwgcHJlY2lzaW9uIGFuZCBzY2FsZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":897,"slug":"column-type-real","name":"column_type_real","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJlYWwgZGF0YSB0eXBlIChQb3N0Z3JlU1FMIGZsb2F0NCkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":906,"slug":"column-type-double-precision","name":"column_type_double_precision","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRvdWJsZSBwcmVjaXNpb24gZGF0YSB0eXBlIChQb3N0Z3JlU1FMIGZsb2F0OCkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":915,"slug":"column-type-date","name":"column_type_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRhdGUgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":924,"slug":"column-type-time","name":"column_type_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRpbWUgZGF0YSB0eXBlIHdpdGggb3B0aW9uYWwgcHJlY2lzaW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":933,"slug":"column-type-timestamp","name":"column_type_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRpbWVzdGFtcCBkYXRhIHR5cGUgd2l0aCBvcHRpb25hbCBwcmVjaXNpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":942,"slug":"column-type-timestamptz","name":"column_type_timestamptz","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRpbWVzdGFtcCB3aXRoIHRpbWUgem9uZSBkYXRhIHR5cGUgd2l0aCBvcHRpb25hbCBwcmVjaXNpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":951,"slug":"column-type-interval","name":"column_type_interval","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbnRlcnZhbCBkYXRhIHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":960,"slug":"column-type-uuid","name":"column_type_uuid","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFVVSUQgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":969,"slug":"column-type-json","name":"column_type_json","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":978,"slug":"column-type-jsonb","name":"column_type_jsonb","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":987,"slug":"column-type-bytea","name":"column_type_bytea","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJ5dGVhIGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":996,"slug":"column-type-xml","name":"column_type_xml","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBYTUwgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1005,"slug":"column-type-inet","name":"column_type_inet","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBpbmV0IGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1014,"slug":"column-type-cidr","name":"column_type_cidr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNpZHIgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1023,"slug":"column-type-macaddr","name":"column_type_macaddr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG1hY2FkZHIgZGF0YSB0eXBlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1032,"slug":"column-type-serial","name":"column_type_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNlcmlhbCBkYXRhIHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1041,"slug":"column-type-smallserial","name":"column_type_smallserial","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNtYWxsc2VyaWFsIGRhdGEgdHlwZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1050,"slug":"column-type-bigserial","name":"column_type_bigserial","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJpZ3NlcmlhbCBkYXRhIHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1059,"slug":"column-type-array","name":"column_type_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"elementType","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBkYXRhIHR5cGUgZnJvbSBhbiBlbGVtZW50IHR5cGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1071,"slug":"column-type-custom","name":"column_type_custom","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"typeName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGN1c3RvbSBkYXRhIHR5cGUuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHR5cGVOYW1lIFR5cGUgbmFtZQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNjaGVtYSBPcHRpb25hbCBzY2hlbWEgbmFtZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1084,"slug":"column-type-from-string","name":"column_type_from_string","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"typeName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhcnNlIGEgUG9zdGdyZVNRTCB0eXBlIHN0cmluZyBpbnRvIGEgQ29sdW1uVHlwZS4KICoKICogSGFuZGxlcyBhbGwgUG9zdGdyZVNRTCB0eXBlIHN5bnRheCBpbmNsdWRpbmcgcHJlY2lzaW9uLCBhcnJheXMsIGFuZCBzY2hlbWEtcXVhbGlmaWVkIHR5cGVzLgogKgogKiBAcGFyYW0gc3RyaW5nICR0eXBlTmFtZSBQb3N0Z3JlU1FMIHR5cGUgc3RyaW5nIChlLmcuLCAnaW50ZWdlcicsICdjaGFyYWN0ZXIgdmFyeWluZygyNTUpJywgJ3RleHRbXScpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1092,"slug":"value-type-text","name":"value_type_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1098,"slug":"value-type-varchar","name":"value_type_varchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1104,"slug":"value-type-char","name":"value_type_char","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1110,"slug":"value-type-bpchar","name":"value_type_bpchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1116,"slug":"value-type-int2","name":"value_type_int2","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1122,"slug":"value-type-smallint","name":"value_type_smallint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1128,"slug":"value-type-int4","name":"value_type_int4","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1134,"slug":"value-type-integer","name":"value_type_integer","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1140,"slug":"value-type-int8","name":"value_type_int8","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1146,"slug":"value-type-bigint","name":"value_type_bigint","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1152,"slug":"value-type-float4","name":"value_type_float4","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1158,"slug":"value-type-real","name":"value_type_real","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1164,"slug":"value-type-float8","name":"value_type_float8","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1170,"slug":"value-type-double","name":"value_type_double","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1176,"slug":"value-type-numeric","name":"value_type_numeric","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1182,"slug":"value-type-money","name":"value_type_money","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1188,"slug":"value-type-bool","name":"value_type_bool","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1194,"slug":"value-type-boolean","name":"value_type_boolean","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1200,"slug":"value-type-bytea","name":"value_type_bytea","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1206,"slug":"value-type-bit","name":"value_type_bit","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1212,"slug":"value-type-varbit","name":"value_type_varbit","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1218,"slug":"value-type-date","name":"value_type_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1224,"slug":"value-type-time","name":"value_type_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1230,"slug":"value-type-timetz","name":"value_type_timetz","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1236,"slug":"value-type-timestamp","name":"value_type_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1242,"slug":"value-type-timestamptz","name":"value_type_timestamptz","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1248,"slug":"value-type-interval","name":"value_type_interval","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1254,"slug":"value-type-json","name":"value_type_json","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1260,"slug":"value-type-jsonb","name":"value_type_jsonb","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1266,"slug":"value-type-uuid","name":"value_type_uuid","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1272,"slug":"value-type-inet","name":"value_type_inet","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1278,"slug":"value-type-cidr","name":"value_type_cidr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1284,"slug":"value-type-macaddr","name":"value_type_macaddr","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1290,"slug":"value-type-macaddr8","name":"value_type_macaddr8","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1296,"slug":"value-type-xml","name":"value_type_xml","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1302,"slug":"value-type-oid","name":"value_type_oid","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1308,"slug":"value-type-text-array","name":"value_type_text_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1314,"slug":"value-type-varchar-array","name":"value_type_varchar_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1320,"slug":"value-type-int2-array","name":"value_type_int2_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1326,"slug":"value-type-int4-array","name":"value_type_int4_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1332,"slug":"value-type-int8-array","name":"value_type_int8_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1338,"slug":"value-type-float4-array","name":"value_type_float4_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1344,"slug":"value-type-float8-array","name":"value_type_float8_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1350,"slug":"value-type-bool-array","name":"value_type_bool_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1356,"slug":"value-type-uuid-array","name":"value_type_uuid_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1362,"slug":"value-type-json-array","name":"value_type_json_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1368,"slug":"value-type-jsonb-array","name":"value_type_jsonb_array","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1384,"slug":"schema","name":"schema","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"sequences","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"views","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"materializedViews","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"functions","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"procedures","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"domains","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"extensions","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Schema","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVRhYmxlPiAkdGFibGVzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVNlcXVlbmNlPiAkc2VxdWVuY2VzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVZpZXc+ICR2aWV3cwogKiBAcGFyYW0gbGlzdDxTY2hlbWFNYXRlcmlhbGl6ZWRWaWV3PiAkbWF0ZXJpYWxpemVkVmlld3MKICogQHBhcmFtIGxpc3Q8U2NoZW1hRnVuY3Rpb24+ICRmdW5jdGlvbnMKICogQHBhcmFtIGxpc3Q8U2NoZW1hUHJvY2VkdXJlPiAkcHJvY2VkdXJlcwogKiBAcGFyYW0gbGlzdDxTY2hlbWFEb21haW4+ICRkb21haW5zCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUV4dGVuc2lvbj4gJGV4dGVuc2lvbnMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1420,"slug":"schema-table","name":"schema_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"primaryKey","type":[{"name":"PrimaryKey","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"indexes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"foreignKeys","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"uniqueConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"checkConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"excludeConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"triggers","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'public'"},{"name":"unlogged","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"partitionStrategy","type":[{"name":"PartitionStrategy","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"partitionColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"inherits","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"tablespace","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Table","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxTY2hlbWFDb2x1bW4+ICRjb2x1bW5zCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUluZGV4PiAkaW5kZXhlcwogKiBAcGFyYW0gbGlzdDxTY2hlbWFGb3JlaWduS2V5PiAkZm9yZWlnbktleXMKICogQHBhcmFtIGxpc3Q8U2NoZW1hVW5pcXVlQ29uc3RyYWludD4gJHVuaXF1ZUNvbnN0cmFpbnRzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUNoZWNrQ29uc3RyYWludD4gJGNoZWNrQ29uc3RyYWludHMKICogQHBhcmFtIGxpc3Q8U2NoZW1hRXhjbHVkZUNvbnN0cmFpbnQ+ICRleGNsdWRlQ29uc3RyYWludHMKICogQHBhcmFtIGxpc3Q8U2NoZW1hVHJpZ2dlcj4gJHRyaWdnZXJzCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHBhcnRpdGlvbkNvbHVtbnMKICogQHBhcmFtIGxpc3Q8c3RyaW5nPiAkaW5oZXJpdHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1465,"slug":"schema-table-options","name":"schema_table_options","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"foreignKeys","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"checkConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"excludeConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"triggers","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"unlogged","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"partitionStrategy","type":[{"name":"PartitionStrategy","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"partitionColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"inherits","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"tablespace","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TableOptions","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUZvcmVpZ25LZXk+ICRmb3JlaWduS2V5cwogKiBAcGFyYW0gbGlzdDxTY2hlbWFDaGVja0NvbnN0cmFpbnQ+ICRjaGVja0NvbnN0cmFpbnRzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUV4Y2x1ZGVDb25zdHJhaW50PiAkZXhjbHVkZUNvbnN0cmFpbnRzCiAqIEBwYXJhbSBsaXN0PFNjaGVtYVRyaWdnZXI+ICR0cmlnZ2VycwogKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRwYXJ0aXRpb25Db2x1bW5zCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGluaGVyaXRzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1490,"slug":"schema-column","name":"schema_column","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"isIdentity","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"identityGeneration","type":[{"name":"IdentityGeneration","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"isGenerated","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"generationExpression","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"ordinalPosition","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1515,"slug":"schema-column-integer","name":"schema_column_integer","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1524,"slug":"schema-column-smallint","name":"schema_column_smallint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1533,"slug":"schema-column-bigint","name":"schema_column_bigint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1542,"slug":"schema-column-serial","name":"schema_column_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1548,"slug":"schema-column-small-serial","name":"schema_column_small_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1554,"slug":"schema-column-big-serial","name":"schema_column_big_serial","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1560,"slug":"schema-column-boolean","name":"schema_column_boolean","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1569,"slug":"schema-column-text","name":"schema_column_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1578,"slug":"schema-column-varchar","name":"schema_column_varchar","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1588,"slug":"schema-column-char","name":"schema_column_char","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"length","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1598,"slug":"schema-column-numeric","name":"schema_column_numeric","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"scale","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1609,"slug":"schema-column-real","name":"schema_column_real","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1618,"slug":"schema-column-double-precision","name":"schema_column_double_precision","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1627,"slug":"schema-column-date","name":"schema_column_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1636,"slug":"schema-column-time","name":"schema_column_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1646,"slug":"schema-column-timestamp","name":"schema_column_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1656,"slug":"schema-column-timestamp-tz","name":"schema_column_timestamp_tz","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"precision","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1666,"slug":"schema-column-interval","name":"schema_column_interval","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1675,"slug":"schema-column-uuid","name":"schema_column_uuid","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1684,"slug":"schema-column-json","name":"schema_column_json","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1693,"slug":"schema-column-jsonb","name":"schema_column_jsonb","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1702,"slug":"schema-column-bytea","name":"schema_column_bytea","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1711,"slug":"schema-column-inet","name":"schema_column_inet","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1720,"slug":"schema-column-cidr","name":"schema_column_cidr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1729,"slug":"schema-column-macaddr","name":"schema_column_macaddr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1741,"slug":"schema-primary-key","name":"schema_primary_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"PrimaryKey","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1751,"slug":"schema-foreign-key","name":"schema_foreign_key","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceTable","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"referenceColumns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"referenceSchema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'public'"},{"name":"onUpdate","type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Schema\\ReferentialAction::..."},{"name":"onDelete","type":[{"name":"ReferentialAction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Schema\\ReferentialAction::..."},{"name":"deferrable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"initiallyDeferred","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"ForeignKey","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRyZWZlcmVuY2VDb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1779,"slug":"schema-unique","name":"schema_unique","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"nullsNotDistinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"UniqueConstraint","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1785,"slug":"schema-check","name":"schema_check","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expression","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"noInherit","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CheckConstraint","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1791,"slug":"schema-exclude","name":"schema_exclude","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ExcludeConstraint","namespace":"Flow\\PostgreSql\\Schema\\Constraint","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1800,"slug":"schema-index","name":"schema_index","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"unique","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"method","type":[{"name":"IndexMethod","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\Schema\\IndexMethod::..."},{"name":"primary","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"predicate","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Index","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxzdHJpbmc+ICRjb2x1bW5zCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1812,"slug":"schema-sequence","name":"schema_sequence","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"dataType","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'bigint'"},{"name":"startValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"minValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"maxValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"incrementBy","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"cycle","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"cacheValue","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"ownedByTable","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"ownedByColumn","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Sequence","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1839,"slug":"schema-view","name":"schema_view","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"isUpdatable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"View","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1848,"slug":"schema-materialized-view","name":"schema_materialized_view","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"indexes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"MaterializedView","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUluZGV4PiAkaW5kZXhlcwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1857,"slug":"schema-function","name":"schema_function","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"returnType","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"argumentTypes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"language","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'sql'"},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"isStrict","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"volatility","type":[{"name":"FunctionVolatility","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Func","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGFyZ3VtZW50VHlwZXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1873,"slug":"schema-procedure","name":"schema_procedure","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"argumentTypes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"language","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'sql'"},{"name":"definition","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Procedure","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJGFyZ3VtZW50VHlwZXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1886,"slug":"schema-trigger","name":"schema_trigger","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tableName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"timing","type":[{"name":"TriggerTiming","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"events","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"functionName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"forEachRow","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"whenCondition","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Trigger","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBub24tZW1wdHktbGlzdDxUcmlnZ2VyRXZlbnQ+ICRldmVudHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1902,"slug":"schema-domain","name":"schema_domain","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"baseType","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nullable","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"default","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"checkConstraints","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Domain","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBsaXN0PFNjaGVtYUNoZWNrQ29uc3RyYWludD4gJGNoZWNrQ29uc3RyYWludHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1913,"slug":"schema-extension","name":"schema_extension","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"version","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Extension","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1922,"slug":"client-catalog-provider","name":"client_catalog_provider","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"client","type":[{"name":"Client","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schemaNames","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"exclusionPolicy","type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSA\/bGlzdDxzdHJpbmc+ICRzY2hlbWFOYW1lcwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1931,"slug":"exclude-any","name":"exclude_any","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"policies","type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1937,"slug":"exclude-exact","name":"exclude_exact","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1943,"slug":"exclude-starts-with","name":"exclude_starts_with","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"prefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1949,"slug":"exclude-ends-with","name":"exclude_ends_with","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"suffix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1955,"slug":"exclude-pattern","name":"exclude_pattern","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"pattern","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1961,"slug":"exclude-schema","name":"exclude_schema","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1967,"slug":"exclude-scoped","name":"exclude_scoped","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"policy","type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"type","type":[{"name":"SchemaObjectType","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"ExclusionPolicy","namespace":"Flow\\PostgreSql\\Schema\\Exclusion","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1976,"slug":"manual-catalog-provider","name":"manual_catalog_provider","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"catalog","type":[{"name":"Catalog","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"CatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1982,"slug":"chain-catalog-provider","name":"chain_catalog_provider","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"providers","type":[{"name":"CatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ChainCatalogProvider","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":1991,"slug":"catalog-comparator","name":"catalog_comparator","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"renameStrategy","type":[{"name":"RenameStrategy","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"viewDependencyResolver","type":[{"name":"ViewDependencyResolver","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"tableOrderStrategy","type":[{"name":"ExecutionOrderStrategy","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"dropIfExists","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CatalogComparator","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBudWxsfEV4ZWN1dGlvbk9yZGVyU3RyYXRlZ3k8XEZsb3dcUG9zdGdyZVNxbFxTY2hlbWFcVGFibGU+ICR0YWJsZU9yZGVyU3RyYXRlZ3kKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2006,"slug":"ast-view-dependency-resolver","name":"ast_view_dependency_resolver","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AstViewDependencyResolver","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2012,"slug":"noop-view-dependency-resolver","name":"noop_view_dependency_resolver","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"NoopViewDependencyResolver","namespace":"Flow\\PostgreSql\\Schema\\Diff","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2018,"slug":"foreign-key-dependency-order","name":"foreign_key_dependency_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ForeignKeyDependencyOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2027,"slug":"no-execution-order","name":"no_execution_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"NoExecutionOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gTm9FeGVjdXRpb25PcmRlcjxtaXhlZD4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2033,"slug":"view-dependency-order","name":"view_dependency_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ViewDependencyOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/schema.php","start_line_in_file":2039,"slug":"materialized-view-dependency-order","name":"materialized_view_dependency_order","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"MaterializedViewDependencyOrder","namespace":"Flow\\PostgreSql\\Schema","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":115,"slug":"select","name":"select","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"SelectBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBTRUxFQ1QgcXVlcnkgYnVpbGRlci4KICoKICogQHBhcmFtIEV4cHJlc3Npb258c3RyaW5nIC4uLiRleHByZXNzaW9ucyBDb2x1bW5zIHRvIHNlbGVjdC4gSWYgZW1wdHksIHJldHVybnMgU2VsZWN0U2VsZWN0U3RlcC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":132,"slug":"parsed-select","name":"parsed_select","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ParsedSelect","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNlbGVjdEZpbmFsU3RlcCBmcm9tIGEgcmF3IFNRTCBTRUxFQ1Qgc3RyaW5nLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":144,"slug":"with","name":"with","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"ctes","type":[{"name":"CTE","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"WithBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\With","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFdJVEggY2xhdXNlIGJ1aWxkZXIgZm9yIENURXMuCiAqCiAqIEV4YW1wbGU6IHdpdGgoY3RlKCd1c2VycycsICRzdWJxdWVyeSkpLT5zZWxlY3Qoc3RhcigpKS0+ZnJvbSh0YWJsZSgndXNlcnMnKSkKICogRXhhbXBsZTogd2l0aChjdGUoJ2EnLCAkcTEpLCBjdGUoJ2InLCAkcTIpKS0+cmVjdXJzaXZlKCktPnNlbGVjdCguLi4pLT5mcm9tKHRhYmxlKCdhJykpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":157,"slug":"insert","name":"insert","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"InsertIntoStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Insert","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBJTlNFUlQgcXVlcnkgYnVpbGRlci4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":173,"slug":"bulk-insert","name":"bulk_insert","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"rowCount","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BulkInsert","namespace":"Flow\\PostgreSql\\QueryBuilder\\Insert","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBvcHRpbWl6ZWQgYnVsayBJTlNFUlQgcXVlcnkgZm9yIGhpZ2gtcGVyZm9ybWFuY2UgbXVsdGktcm93IGluc2VydHMuCiAqCiAqIFVubGlrZSBpbnNlcnQoKSB3aGljaCB1c2VzIGltbXV0YWJsZSBidWlsZGVyIHBhdHRlcm5zIChPKG7CsikgZm9yIG4gcm93cyksCiAqIHRoaXMgZnVuY3Rpb24gZ2VuZXJhdGVzIFNRTCBkaXJlY3RseSB1c2luZyBzdHJpbmcgb3BlcmF0aW9ucyAoTyhuKSBjb21wbGV4aXR5KS4KICoKICogQHBhcmFtIHN0cmluZyAkdGFibGUgVGFibGUgbmFtZQogKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRjb2x1bW5zIENvbHVtbiBuYW1lcwogKiBAcGFyYW0gaW50ICRyb3dDb3VudCBOdW1iZXIgb2Ygcm93cyB0byBpbnNlcnQKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":182,"slug":"update","name":"update","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"UpdateTableStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Update","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBVUERBVEUgcXVlcnkgYnVpbGRlci4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":191,"slug":"delete","name":"delete","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"DeleteFromStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Delete","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBERUxFVEUgcXVlcnkgYnVpbGRlci4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":203,"slug":"merge","name":"merge","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"alias","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MergeUsingStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Merge","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBNRVJHRSBxdWVyeSBidWlsZGVyLgogKgogKiBAcGFyYW0gc3RyaW5nICR0YWJsZSBUYXJnZXQgdGFibGUgbmFtZQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGFsaWFzIE9wdGlvbmFsIHRhYmxlIGFsaWFzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":217,"slug":"copy","name":"copy","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"CopyFactory","namespace":"Flow\\PostgreSql\\QueryBuilder\\Factory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBDT1BZIHF1ZXJ5IGJ1aWxkZXIgZm9yIGRhdGEgaW1wb3J0L2V4cG9ydC4KICoKICogVXNhZ2U6CiAqICAgY29weSgpLT5mcm9tKCd1c2VycycpLT5maWxlKCcvdG1wL3VzZXJzLmNzdicpLT5mb3JtYXQoQ29weUZvcm1hdDo6Q1NWKQogKiAgIGNvcHkoKS0+dG8oJ3VzZXJzJyktPmZpbGUoJy90bXAvdXNlcnMuY3N2JyktPmZvcm1hdChDb3B5Rm9ybWF0OjpDU1YpCiAqICAgY29weSgpLT50b1F1ZXJ5KHNlbGVjdCguLi4pKS0+ZmlsZSgnL3RtcC9kYXRhLmNzdicpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":229,"slug":"listen","name":"listen","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"channel","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ListenFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Listen","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExJU1RFTiBzdGF0ZW1lbnQgdG8gc3Vic2NyaWJlIHRoZSBjdXJyZW50IHNlc3Npb24gdG8gYSBub3RpZmljYXRpb24gY2hhbm5lbC4KICoKICogVXNhZ2U6CiAqICAgbGlzdGVuKCdteV9jaGFubmVsJyktPnRvU3FsKCkgIC8vIExJU1RFTiBteV9jaGFubmVsCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":241,"slug":"unlisten","name":"unlisten","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"channel","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"UnlistenFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Unlisten","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBVTkxJU1RFTiBzdGF0ZW1lbnQgdG8gdW5zdWJzY3JpYmUgdGhlIGN1cnJlbnQgc2Vzc2lvbiBmcm9tIGEgbm90aWZpY2F0aW9uIGNoYW5uZWwuCiAqCiAqIFVzYWdlOgogKiAgIHVubGlzdGVuKCdteV9jaGFubmVsJyktPnRvU3FsKCkgIC8vIFVOTElTVEVOIG15X2NoYW5uZWwKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":254,"slug":"notify","name":"notify","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"channel","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"NotifyFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Notify","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE5PVElGWSBzdGF0ZW1lbnQgdG8gc2VuZCBhIG5vdGlmaWNhdGlvbiBvbiBhIGNoYW5uZWwsIG9wdGlvbmFsbHkgd2l0aCBhIHBheWxvYWQuCiAqCiAqIFVzYWdlOgogKiAgIG5vdGlmeSgnbXlfY2hhbm5lbCcpLT50b1NxbCgpICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTk9USUZZIG15X2NoYW5uZWwKICogICBub3RpZnkoJ215X2NoYW5uZWwnKS0+d2l0aFBheWxvYWQoJ2hlbGxvJyktPnRvU3FsKCkgICAgIC8vIE5PVElGWSBteV9jaGFubmVsLCAnaGVsbG8nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":275,"slug":"col","name":"col","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Column","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbHVtbiByZWZlcmVuY2UgZXhwcmVzc2lvbi4KICoKICogQ2FuIGJlIHVzZWQgaW4gdHdvIG1vZGVzOgogKiAtIFBhcnNlIG1vZGU6IGNvbCgndXNlcnMuaWQnKSBvciBjb2woJ3NjaGVtYS50YWJsZS5jb2x1bW4nKSAtIHBhcnNlcyBkb3Qtc2VwYXJhdGVkIHN0cmluZwogKiAtIEV4cGxpY2l0IG1vZGU6IGNvbCgnaWQnLCAndXNlcnMnKSBvciBjb2woJ2lkJywgJ3VzZXJzJywgJ3NjaGVtYScpIC0gc2VwYXJhdGUgYXJndW1lbnRzCiAqCiAqIFdoZW4gJHRhYmxlIG9yICRzY2hlbWEgaXMgcHJvdmlkZWQsICRjb2x1bW4gbXVzdCBiZSBhIHBsYWluIGNvbHVtbiBuYW1lIChubyBkb3RzKS4KICoKICogQHBhcmFtIHN0cmluZyAkY29sdW1uIENvbHVtbiBuYW1lLCBvciBkb3Qtc2VwYXJhdGVkIHBhdGggbGlrZSAidGFibGUuY29sdW1uIiBvciAic2NoZW1hLnRhYmxlLmNvbHVtbiIKICogQHBhcmFtIG51bGx8c3RyaW5nICR0YWJsZSBUYWJsZSBuYW1lIChvcHRpb25hbCwgdHJpZ2dlcnMgZXhwbGljaXQgbW9kZSkKICogQHBhcmFtIG51bGx8c3RyaW5nICRzY2hlbWEgU2NoZW1hIG5hbWUgKG9wdGlvbmFsLCByZXF1aXJlcyAkdGFibGUpCiAqCiAqIEB0aHJvd3MgSW52YWxpZEV4cHJlc3Npb25FeGNlcHRpb24gd2hlbiAkc2NoZW1hIGlzIHByb3ZpZGVkIHdpdGhvdXQgJHRhYmxlLCBvciB3aGVuICRjb2x1bW4gY29udGFpbnMgZG90cyBpbiBleHBsaWNpdCBtb2RlCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":302,"slug":"star","name":"star","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"table","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Star","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFTEVDVCAqIGV4cHJlc3Npb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":318,"slug":"literal","name":"literal","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"value","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Literal","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxpdGVyYWwgdmFsdWUgZm9yIHVzZSBpbiBxdWVyaWVzLgogKgogKiBBdXRvbWF0aWNhbGx5IGRldGVjdHMgdGhlIHR5cGUgYW5kIGNyZWF0ZXMgdGhlIGFwcHJvcHJpYXRlIGxpdGVyYWw6CiAqIC0gbGl0ZXJhbCgnaGVsbG8nKSBjcmVhdGVzIGEgc3RyaW5nIGxpdGVyYWwKICogLSBsaXRlcmFsKDQyKSBjcmVhdGVzIGFuIGludGVnZXIgbGl0ZXJhbAogKiAtIGxpdGVyYWwoMy4xNCkgY3JlYXRlcyBhIGZsb2F0IGxpdGVyYWwKICogLSBsaXRlcmFsKHRydWUpIGNyZWF0ZXMgYSBib29sZWFuIGxpdGVyYWwKICogLSBsaXRlcmFsKG51bGwpIGNyZWF0ZXMgYSBOVUxMIGxpdGVyYWwKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":333,"slug":"param","name":"param","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"position","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Parameter","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHBvc2l0aW9uYWwgcGFyYW1ldGVyICgkMSwgJDIsIGV0Yy4pLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":342,"slug":"parameters","name":"parameters","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"count","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"startAt","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"}],"return_type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEByZXR1cm4gbGlzdDxQYXJhbWV0ZXI+CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":368,"slug":"func","name":"func","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"FunctionCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZ1bmN0aW9uIGNhbGwgZXhwcmVzc2lvbi4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBGdW5jdGlvbiBuYW1lIChjYW4gaW5jbHVkZSBzY2hlbWEgbGlrZSAicGdfY2F0YWxvZy5ub3ciKQogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGFyZ3MgRnVuY3Rpb24gYXJndW1lbnRzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":402,"slug":"agg","name":"agg","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhZ2dyZWdhdGUgZnVuY3Rpb24gY2FsbCAoQ09VTlQsIFNVTSwgQVZHLCBldGMuKS4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBBZ2dyZWdhdGUgZnVuY3Rpb24gbmFtZQogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGFyZ3MgRnVuY3Rpb24gYXJndW1lbnRzCiAqIEBwYXJhbSBib29sICRkaXN0aW5jdCBVc2UgRElTVElOQ1QgbW9kaWZpZXIKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":416,"slug":"agg-count","name":"agg_count","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDT1VOVCgqKSBhZ2dyZWdhdGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":429,"slug":"count-all","name":"count_all","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDT1VOVCgqKSBhZ2dyZWdhdGUuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":438,"slug":"agg-sum","name":"agg_sum","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBTVU0gYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":447,"slug":"agg-avg","name":"agg_avg","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"distinct","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBBVkcgYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":456,"slug":"agg-min","name":"agg_min","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBNSU4gYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":465,"slug":"agg-max","name":"agg_max","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AggregateCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBNQVggYWdncmVnYXRlLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":476,"slug":"coalesce","name":"coalesce","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Coalesce","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPQUxFU0NFIGV4cHJlc3Npb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gY29hbGVzY2UKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":487,"slug":"nullif","name":"nullif","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr1","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"expr2","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"NullIf","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE5VTExJRiBleHByZXNzaW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":501,"slug":"greatest","name":"greatest","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Greatest","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdSRUFURVNUIGV4cHJlc3Npb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gY29tcGFyZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":514,"slug":"least","name":"least","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Least","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExFQVNUIGV4cHJlc3Npb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gY29tcGFyZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":528,"slug":"cast","name":"cast","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"dataType","type":[{"name":"ColumnType","namespace":"Flow\\PostgreSql\\QueryBuilder\\Schema","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TypeCast","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHR5cGUgY2FzdCBleHByZXNzaW9uLgogKgogKiBAcGFyYW0gRXhwcmVzc2lvbnxzdHJpbmcgJGV4cHIgRXhwcmVzc2lvbiB0byBjYXN0CiAqIEBwYXJhbSBDb2x1bW5UeXBlICRkYXRhVHlwZSBUYXJnZXQgZGF0YSB0eXBlICh1c2UgY29sdW1uX3R5cGVfKiBmdW5jdGlvbnMpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":543,"slug":"current-timestamp","name":"current_timestamp","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SQLValueFunctionExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNRTCBzdGFuZGFyZCBDVVJSRU5UX1RJTUVTVEFNUCBmdW5jdGlvbi4KICoKICogUmV0dXJucyB0aGUgY3VycmVudCBkYXRlIGFuZCB0aW1lIChhdCB0aGUgc3RhcnQgb2YgdGhlIHRyYW5zYWN0aW9uKS4KICogVXNlZnVsIGFzIGEgY29sdW1uIGRlZmF1bHQgdmFsdWUgb3IgaW4gU0VMRUNUIHF1ZXJpZXMuCiAqCiAqIEV4YW1wbGU6IGNvbHVtbignY3JlYXRlZF9hdCcsIGNvbHVtbl90eXBlX3RpbWVzdGFtcCgpKS0+ZGVmYXVsdChjdXJyZW50X3RpbWVzdGFtcCgpKQogKiBFeGFtcGxlOiBzZWxlY3QoKS0+c2VsZWN0KGN1cnJlbnRfdGltZXN0YW1wKCktPmFzKCdub3cnKSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":558,"slug":"current-date","name":"current_date","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SQLValueFunctionExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNRTCBzdGFuZGFyZCBDVVJSRU5UX0RBVEUgZnVuY3Rpb24uCiAqCiAqIFJldHVybnMgdGhlIGN1cnJlbnQgZGF0ZSAoYXQgdGhlIHN0YXJ0IG9mIHRoZSB0cmFuc2FjdGlvbikuCiAqIFVzZWZ1bCBhcyBhIGNvbHVtbiBkZWZhdWx0IHZhbHVlIG9yIGluIFNFTEVDVCBxdWVyaWVzLgogKgogKiBFeGFtcGxlOiBjb2x1bW4oJ2JpcnRoX2RhdGUnLCBjb2x1bW5fdHlwZV9kYXRlKCkpLT5kZWZhdWx0KGN1cnJlbnRfZGF0ZSgpKQogKiBFeGFtcGxlOiBzZWxlY3QoKS0+c2VsZWN0KGN1cnJlbnRfZGF0ZSgpLT5hcygndG9kYXknKSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":573,"slug":"current-time","name":"current_time","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SQLValueFunctionExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNRTCBzdGFuZGFyZCBDVVJSRU5UX1RJTUUgZnVuY3Rpb24uCiAqCiAqIFJldHVybnMgdGhlIGN1cnJlbnQgdGltZSAoYXQgdGhlIHN0YXJ0IG9mIHRoZSB0cmFuc2FjdGlvbikuCiAqIFVzZWZ1bCBhcyBhIGNvbHVtbiBkZWZhdWx0IHZhbHVlIG9yIGluIFNFTEVDVCBxdWVyaWVzLgogKgogKiBFeGFtcGxlOiBjb2x1bW4oJ3N0YXJ0X3RpbWUnLCBjb2x1bW5fdHlwZV90aW1lKCkpLT5kZWZhdWx0KGN1cnJlbnRfdGltZSgpKQogKiBFeGFtcGxlOiBzZWxlY3QoKS0+c2VsZWN0KGN1cnJlbnRfdGltZSgpLT5hcygnbm93X3RpbWUnKSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":586,"slug":"case-when","name":"case_when","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"whenClauses","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"elseResult","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"operand","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"null","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CaseExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENBU0UgZXhwcmVzc2lvbi4KICoKICogQHBhcmFtIG5vbi1lbXB0eS1saXN0PFdoZW5DbGF1c2U+ICR3aGVuQ2xhdXNlcyBXSEVOIGNsYXVzZXMKICogQHBhcmFtIG51bGx8RXhwcmVzc2lvbnxzdHJpbmcgJGVsc2VSZXN1bHQgRUxTRSByZXN1bHQgKG9wdGlvbmFsKQogKiBAcGFyYW0gbnVsbHxFeHByZXNzaW9ufHN0cmluZyAkb3BlcmFuZCBDQVNFIG9wZXJhbmQgZm9yIHNpbXBsZSBDQVNFIChvcHRpb25hbCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":602,"slug":"when","name":"when","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"condition","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"result","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"WhenClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFdIRU4gY2xhdXNlIGZvciBDQVNFIGV4cHJlc3Npb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":614,"slug":"sub-select","name":"sub_select","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Subquery","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHN1YnF1ZXJ5IGV4cHJlc3Npb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":628,"slug":"array-expr","name":"array_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ArrayExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBleHByZXNzaW9uLgogKgogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGVsZW1lbnRzIEFycmF5IGVsZW1lbnRzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":641,"slug":"row-expr","name":"row_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"elements","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RowExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJvdyBleHByZXNzaW9uLgogKgogKiBAcGFyYW0gbGlzdDxFeHByZXNzaW9ufHN0cmluZz4gJGVsZW1lbnRzIFJvdyBlbGVtZW50cwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":652,"slug":"binary-expr","name":"binary_expr","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"operator","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGJpbmFyeSBleHByZXNzaW9uIChsZWZ0IG9wIHJpZ2h0KS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":670,"slug":"window-func","name":"window_func","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"args","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"partitionBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"orderBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"WindowFunction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHdpbmRvdyBmdW5jdGlvbi4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBGdW5jdGlvbiBuYW1lCiAqIEBwYXJhbSBsaXN0PEV4cHJlc3Npb258c3RyaW5nPiAkYXJncyBGdW5jdGlvbiBhcmd1bWVudHMKICogQHBhcmFtIGxpc3Q8RXhwcmVzc2lvbnxzdHJpbmc+ICRwYXJ0aXRpb25CeSBQQVJUSVRJT04gQlkgZXhwcmVzc2lvbnMKICogQHBhcmFtIGxpc3Q8T3JkZXJCeT4gJG9yZGVyQnkgT1JERVIgQlkgaXRlbXMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":691,"slug":"concat","name":"concat","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbmNhdGVuYXRlIGV4cHJlc3Npb25zIHdpdGggdGhlIHx8IG9wZXJhdG9yLgogKgogKiBFeGFtcGxlOiBjb25jYXQoY29sKCdzY2hlbWEnKSwgbGl0ZXJhbCgnLicpLCBjb2woJ3RhYmxlJykpCiAqIFByb2R1Y2VzOiBzY2hlbWEgfHwgJy4nIHx8IHRhYmxlCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgQXQgbGVhc3QgMiBleHByZXNzaW9ucyB0byBjb25jYXRlbmF0ZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":721,"slug":"table","name":"table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"schema","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Table","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRhYmxlIHJlZmVyZW5jZS4KICoKICogU3VwcG9ydHMgZG90IG5vdGF0aW9uIGZvciBzY2hlbWEtcXVhbGlmaWVkIG5hbWVzOiAicHVibGljLnVzZXJzIiBvciBleHBsaWNpdCBzY2hlbWEgcGFyYW1ldGVyLgogKiBEb3VibGUtcXVvdGVkIGlkZW50aWZpZXJzIHByZXNlcnZlIGRvdHM6ICcibXkudGFibGUiJyBjcmVhdGVzIGEgc2luZ2xlIGlkZW50aWZpZXIuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJG5hbWUgVGFibGUgbmFtZSAobWF5IGluY2x1ZGUgc2NoZW1hIGFzICJzY2hlbWEudGFibGUiKQogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHNjaGVtYSBTY2hlbWEgbmFtZSAob3B0aW9uYWwsIG92ZXJyaWRlcyBwYXJzZWQgc2NoZW1hKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":736,"slug":"derived","name":"derived","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"alias","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DerivedTable","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGRlcml2ZWQgdGFibGUgKHN1YnF1ZXJ5IGluIEZST00gY2xhdXNlKS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":750,"slug":"lateral","name":"lateral","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"reference","type":[{"name":"TableReference","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Lateral","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExBVEVSQUwgc3VicXVlcnkuCiAqCiAqIEBwYXJhbSBUYWJsZVJlZmVyZW5jZSAkcmVmZXJlbmNlIFRoZSBzdWJxdWVyeSBvciB0YWJsZSBmdW5jdGlvbiByZWZlcmVuY2UKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":762,"slug":"table-func","name":"table_func","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"function","type":[{"name":"FunctionCall","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"withOrdinality","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"TableFunction","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRhYmxlIGZ1bmN0aW9uIHJlZmVyZW5jZS4KICoKICogQHBhcmFtIEZ1bmN0aW9uQ2FsbCAkZnVuY3Rpb24gVGhlIHRhYmxlLXZhbHVlZCBmdW5jdGlvbgogKiBAcGFyYW0gYm9vbCAkd2l0aE9yZGluYWxpdHkgV2hldGhlciB0byBhZGQgV0lUSCBPUkRJTkFMSVRZCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":781,"slug":"values-table","name":"values_table","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"rows","type":[{"name":"RowExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ValuesTable","namespace":"Flow\\PostgreSql\\QueryBuilder\\Table","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZBTFVFUyBjbGF1c2UgYXMgYSB0YWJsZSByZWZlcmVuY2UuCiAqCiAqIFVzYWdlOgogKiAgIHNlbGVjdCgpLT5mcm9tKAogKiAgICAgICB2YWx1ZXNfdGFibGUoCiAqICAgICAgICAgICByb3dfZXhwcihbbGl0ZXJhbCgxKSwgbGl0ZXJhbCgnQWxpY2UnKV0pLAogKiAgICAgICAgICAgcm93X2V4cHIoW2xpdGVyYWwoMiksIGxpdGVyYWwoJ0JvYicpXSkKICogICAgICAgKS0+YXMoJ3QnLCBbJ2lkJywgJ25hbWUnXSkKICogICApCiAqCiAqIEdlbmVyYXRlczogU0VMRUNUICogRlJPTSAoVkFMVUVTICgxLCAnQWxpY2UnKSwgKDIsICdCb2InKSkgQVMgdChpZCwgbmFtZSkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":790,"slug":"order-by","name":"order_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"direction","type":[{"name":"SortDirection","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\SortDirection::..."},{"name":"nulls","type":[{"name":"NullsPosition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\NullsPosition::..."}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPUkRFUiBCWSBpdGVtLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":802,"slug":"asc","name":"asc","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nulls","type":[{"name":"NullsPosition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\NullsPosition::..."}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPUkRFUiBCWSBpdGVtIHdpdGggQVNDIGRpcmVjdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":811,"slug":"desc","name":"desc","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"nulls","type":[{"name":"NullsPosition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\NullsPosition::..."}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPUkRFUiBCWSBpdGVtIHdpdGggREVTQyBkaXJlY3Rpb24uCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":825,"slug":"cte","name":"cte","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columnNames","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"materialization","type":[{"name":"CTEMaterialization","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\CTEMaterialization::..."},{"name":"recursive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"CTE","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENURSAoQ29tbW9uIFRhYmxlIEV4cHJlc3Npb24pLgogKgogKiBAcGFyYW0gc3RyaW5nICRuYW1lIENURSBuYW1lCiAqIEBwYXJhbSBTZWxlY3RGaW5hbFN0ZXAgJHF1ZXJ5IENURSBxdWVyeQogKiBAcGFyYW0gYXJyYXk8c3RyaW5nPiAkY29sdW1uTmFtZXMgQ29sdW1uIGFsaWFzZXMgKG9wdGlvbmFsKQogKiBAcGFyYW0gQ1RFTWF0ZXJpYWxpemF0aW9uICRtYXRlcmlhbGl6YXRpb24gTWF0ZXJpYWxpemF0aW9uIGhpbnQKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":847,"slug":"window-def","name":"window_def","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"partitionBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"orderBy","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"frame","type":[{"name":"WindowFrame","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"WindowDefinition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHdpbmRvdyBkZWZpbml0aW9uIGZvciBXSU5ET1cgY2xhdXNlLgogKgogKiBAcGFyYW0gc3RyaW5nICRuYW1lIFdpbmRvdyBuYW1lCiAqIEBwYXJhbSBsaXN0PEV4cHJlc3Npb258c3RyaW5nPiAkcGFydGl0aW9uQnkgUEFSVElUSU9OIEJZIGV4cHJlc3Npb25zCiAqIEBwYXJhbSBsaXN0PE9yZGVyQnk+ICRvcmRlckJ5IE9SREVSIEJZIGl0ZW1zCiAqIEBwYXJhbSBudWxsfFdpbmRvd0ZyYW1lICRmcmFtZSBXaW5kb3cgZnJhbWUgc3BlY2lmaWNhdGlvbgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":867,"slug":"window-frame","name":"window_frame","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"mode","type":[{"name":"FrameMode","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"start","type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"end","type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"exclusion","type":[{"name":"FrameExclusion","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\FrameExclusion::..."}],"return_type":[{"name":"WindowFrame","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHdpbmRvdyBmcmFtZSBzcGVjaWZpY2F0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":880,"slug":"frame-current-row","name":"frame_current_row","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBDVVJSRU5UIFJPVy4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":889,"slug":"frame-unbounded-preceding","name":"frame_unbounded_preceding","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBVTkJPVU5ERUQgUFJFQ0VESU5HLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":898,"slug":"frame-unbounded-following","name":"frame_unbounded_following","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBVTkJPVU5ERUQgRk9MTE9XSU5HLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":907,"slug":"frame-preceding","name":"frame_preceding","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"offset","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBOIFBSRUNFRElORy4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":916,"slug":"frame-following","name":"frame_following","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"offset","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FrameBound","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZyYW1lIGJvdW5kIGZvciBOIEZPTExPV0lORy4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":929,"slug":"lock-for","name":"lock_for","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"strength","type":[{"name":"LockStrength","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"waitPolicy","type":[{"name":"LockWaitPolicy","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Clause\\LockWaitPolicy::..."}],"return_type":[{"name":"LockingClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxvY2tpbmcgY2xhdXNlIChGT1IgVVBEQVRFLCBGT1IgU0hBUkUsIGV0Yy4pLgogKgogKiBAcGFyYW0gTG9ja1N0cmVuZ3RoICRzdHJlbmd0aCBMb2NrIHN0cmVuZ3RoCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHRhYmxlcyBUYWJsZXMgdG8gbG9jayAoZW1wdHkgZm9yIGFsbCkKICogQHBhcmFtIExvY2tXYWl0UG9saWN5ICR3YWl0UG9saWN5IFdhaXQgcG9saWN5CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":943,"slug":"for-update","name":"for_update","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"LockingClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEZPUiBVUERBVEUgbG9ja2luZyBjbGF1c2UuCiAqCiAqIEBwYXJhbSBsaXN0PHN0cmluZz4gJHRhYmxlcyBUYWJsZXMgdG8gbG9jayAoZW1wdHkgZm9yIGFsbCkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":954,"slug":"for-share","name":"for_share","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"tables","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"LockingClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEZPUiBTSEFSRSBsb2NraW5nIGNsYXVzZS4KICoKICogQHBhcmFtIGxpc3Q8c3RyaW5nPiAkdGFibGVzIFRhYmxlcyB0byBsb2NrIChlbXB0eSBmb3IgYWxsKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":963,"slug":"on-conflict-nothing","name":"on_conflict_nothing","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"target","type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"OnConflictClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPTiBDT05GTElDVCBETyBOT1RISU5HIGNsYXVzZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":975,"slug":"on-conflict-update","name":"on_conflict_update","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"target","type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"updates","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OnConflictClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPTiBDT05GTElDVCBETyBVUERBVEUgY2xhdXNlLgogKgogKiBAcGFyYW0gQ29uZmxpY3RUYXJnZXQgJHRhcmdldCBDb25mbGljdCB0YXJnZXQgKGNvbHVtbnMgb3IgY29uc3RyYWludCkKICogQHBhcmFtIGFycmF5PHN0cmluZywgRXhwcmVzc2lvbnxzdHJpbmc+ICR1cGRhdGVzIENvbHVtbiB1cGRhdGVzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":989,"slug":"conflict-columns","name":"conflict_columns","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbmZsaWN0IHRhcmdldCBmb3IgT04gQ09ORkxJQ1QgKGNvbHVtbnMpLgogKgogKiBAcGFyYW0gbGlzdDxzdHJpbmc+ICRjb2x1bW5zIENvbHVtbnMgdGhhdCBkZWZpbmUgdW5pcXVlbmVzcwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":998,"slug":"conflict-constraint","name":"conflict_constraint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConflictTarget","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbmZsaWN0IHRhcmdldCBmb3IgT04gQ09ORkxJQ1QgT04gQ09OU1RSQUlOVC4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1009,"slug":"returning","name":"returning","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expressions","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ReturningClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVFVSTklORyBjbGF1c2UuCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAuLi4kZXhwcmVzc2lvbnMgRXhwcmVzc2lvbnMgdG8gcmV0dXJuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1020,"slug":"returning-all","name":"returning_all","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ReturningClause","namespace":"Flow\\PostgreSql\\QueryBuilder\\Clause","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJFVFVSTklORyAqIGNsYXVzZS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1032,"slug":"begin","name":"begin","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"BeginOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJFR0lOIHRyYW5zYWN0aW9uIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IGJlZ2luKCktPmlzb2xhdGlvbkxldmVsKElzb2xhdGlvbkxldmVsOjpTRVJJQUxJWkFCTEUpLT5yZWFkT25seSgpCiAqIFByb2R1Y2VzOiBCRUdJTiBJU09MQVRJT04gTEVWRUwgU0VSSUFMSVpBQkxFIFJFQUQgT05MWQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1044,"slug":"commit","name":"commit","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"CommitOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPTU1JVCB0cmFuc2FjdGlvbiBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBjb21taXQoKS0+YW5kQ2hhaW4oKQogKiBQcm9kdWNlczogQ09NTUlUIEFORCBDSEFJTgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1056,"slug":"rollback","name":"rollback","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"RollbackOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJPTExCQUNLIHRyYW5zYWN0aW9uIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJvbGxiYWNrKCktPnRvU2F2ZXBvaW50KCdteV9zYXZlcG9pbnQnKQogKiBQcm9kdWNlczogUk9MTEJBQ0sgVE8gU0FWRVBPSU5UIG15X3NhdmVwb2ludAogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1068,"slug":"savepoint","name":"savepoint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SavepointFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNBVkVQT0lOVC4KICoKICogRXhhbXBsZTogc2F2ZXBvaW50KCdteV9zYXZlcG9pbnQnKQogKiBQcm9kdWNlczogU0FWRVBPSU5UIG15X3NhdmVwb2ludAogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1080,"slug":"release-savepoint","name":"release_savepoint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SavepointFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFJlbGVhc2UgYSBTQVZFUE9JTlQuCiAqCiAqIEV4YW1wbGU6IHJlbGVhc2Vfc2F2ZXBvaW50KCdteV9zYXZlcG9pbnQnKQogKiBQcm9kdWNlczogUkVMRUFTRSBteV9zYXZlcG9pbnQKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1092,"slug":"set-transaction","name":"set_transaction","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SetTransactionOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBUUkFOU0FDVElPTiBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBzZXRfdHJhbnNhY3Rpb24oKS0+aXNvbGF0aW9uTGV2ZWwoSXNvbGF0aW9uTGV2ZWw6OlNFUklBTElaQUJMRSktPnJlYWRPbmx5KCkKICogUHJvZHVjZXM6IFNFVCBUUkFOU0FDVElPTiBJU09MQVRJT04gTEVWRUwgU0VSSUFMSVpBQkxFLCBSRUFEIE9OTFkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1104,"slug":"set-session-transaction","name":"set_session_transaction","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"SetTransactionOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBTRVNTSU9OIENIQVJBQ1RFUklTVElDUyBBUyBUUkFOU0FDVElPTiBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBzZXRfc2Vzc2lvbl90cmFuc2FjdGlvbigpLT5pc29sYXRpb25MZXZlbChJc29sYXRpb25MZXZlbDo6U0VSSUFMSVpBQkxFKQogKiBQcm9kdWNlczogU0VUIFNFU1NJT04gQ0hBUkFDVEVSSVNUSUNTIEFTIFRSQU5TQUNUSU9OIElTT0xBVElPTiBMRVZFTCBTRVJJQUxJWkFCTEUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1116,"slug":"transaction-snapshot","name":"transaction_snapshot","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"snapshotId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SetTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNFVCBUUkFOU0FDVElPTiBTTkFQU0hPVCBidWlsZGVyLgogKgogKiBFeGFtcGxlOiB0cmFuc2FjdGlvbl9zbmFwc2hvdCgnMDAwMDAwMDMtMDAwMDAwMUEtMScpCiAqIFByb2R1Y2VzOiBTRVQgVFJBTlNBQ1RJT04gU05BUFNIT1QgJzAwMDAwMDAzLTAwMDAwMDFBLTEnCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1128,"slug":"prepare-transaction","name":"prepare_transaction","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"transactionId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PreparedTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBSRVBBUkUgVFJBTlNBQ1RJT04gYnVpbGRlci4KICoKICogRXhhbXBsZTogcHJlcGFyZV90cmFuc2FjdGlvbignbXlfdHJhbnNhY3Rpb24nKQogKiBQcm9kdWNlczogUFJFUEFSRSBUUkFOU0FDVElPTiAnbXlfdHJhbnNhY3Rpb24nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1140,"slug":"commit-prepared","name":"commit_prepared","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"transactionId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PreparedTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENPTU1JVCBQUkVQQVJFRCBidWlsZGVyLgogKgogKiBFeGFtcGxlOiBjb21taXRfcHJlcGFyZWQoJ215X3RyYW5zYWN0aW9uJykKICogUHJvZHVjZXM6IENPTU1JVCBQUkVQQVJFRCAnbXlfdHJhbnNhY3Rpb24nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1152,"slug":"rollback-prepared","name":"rollback_prepared","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"transactionId","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PreparedTransactionFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Transaction","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJPTExCQUNLIFBSRVBBUkVEIGJ1aWxkZXIuCiAqCiAqIEV4YW1wbGU6IHJvbGxiYWNrX3ByZXBhcmVkKCdteV90cmFuc2FjdGlvbicpCiAqIFByb2R1Y2VzOiBST0xMQkFDSyBQUkVQQVJFRCAnbXlfdHJhbnNhY3Rpb24nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1175,"slug":"declare-cursor","name":"declare_cursor","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"cursorName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false},{"name":"Sql","namespace":"Flow\\PostgreSql\\QueryBuilder","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"DeclareCursorOptionsStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Cursor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIERlY2xhcmUgYSBzZXJ2ZXItc2lkZSBjdXJzb3IgZm9yIGEgcXVlcnkuCiAqCiAqIEN1cnNvcnMgbXVzdCBiZSBkZWNsYXJlZCB3aXRoaW4gYSB0cmFuc2FjdGlvbiBhbmQgcHJvdmlkZSBtZW1vcnktZWZmaWNpZW50CiAqIGl0ZXJhdGlvbiBvdmVyIGxhcmdlIHJlc3VsdCBzZXRzIHZpYSBGRVRDSCBjb21tYW5kcy4KICoKICogRXhhbXBsZSB3aXRoIHF1ZXJ5IGJ1aWxkZXI6CiAqICAgZGVjbGFyZV9jdXJzb3IoJ215X2N1cnNvcicsIHNlbGVjdChzdGFyKCkpLT5mcm9tKHRhYmxlKCd1c2VycycpKSktPm5vU2Nyb2xsKCkKICogICBQcm9kdWNlczogREVDTEFSRSBteV9jdXJzb3IgTk8gU0NST0xMIENVUlNPUiBGT1IgU0VMRUNUICogRlJPTSB1c2VycwogKgogKiBFeGFtcGxlIHdpdGggcmF3IFNRTDoKICogICBkZWNsYXJlX2N1cnNvcignbXlfY3Vyc29yJywgJ1NFTEVDVCAqIEZST00gdXNlcnMgV0hFUkUgYWN0aXZlID0gdHJ1ZScpLT53aXRoSG9sZCgpCiAqICAgUHJvZHVjZXM6IERFQ0xBUkUgbXlfY3Vyc29yIE5PIFNDUk9MTCBDVVJTT1IgV0lUSCBIT0xEIEZPUiBTRUxFQ1QgKiBGUk9NIHVzZXJzIFdIRVJFIGFjdGl2ZSA9IHRydWUKICoKICogQHBhcmFtIHN0cmluZyAkY3Vyc29yTmFtZSBVbmlxdWUgY3Vyc29yIG5hbWUKICogQHBhcmFtIFNlbGVjdEZpbmFsU3RlcHxTcWx8c3RyaW5nICRxdWVyeSBRdWVyeSB0byBpdGVyYXRlIG92ZXIKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1196,"slug":"fetch","name":"fetch","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"cursorName","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"FetchCursorBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Cursor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEZldGNoIHJvd3MgZnJvbSBhIGN1cnNvci4KICoKICogRXhhbXBsZTogZmV0Y2goJ215X2N1cnNvcicpLT5mb3J3YXJkKDEwMCkKICogUHJvZHVjZXM6IEZFVENIIEZPUldBUkQgMTAwIG15X2N1cnNvcgogKgogKiBFeGFtcGxlOiBmZXRjaCgnbXlfY3Vyc29yJyktPmFsbCgpCiAqIFByb2R1Y2VzOiBGRVRDSCBBTEwgbXlfY3Vyc29yCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGN1cnNvck5hbWUgQ3Vyc29yIHRvIGZldGNoIGZyb20KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/query.php","start_line_in_file":1213,"slug":"close-cursor","name":"close_cursor","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"cursorName","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CloseCursorFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Cursor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENsb3NlIGEgY3Vyc29yLgogKgogKiBFeGFtcGxlOiBjbG9zZV9jdXJzb3IoJ215X2N1cnNvcicpCiAqIFByb2R1Y2VzOiBDTE9TRSBteV9jdXJzb3IKICoKICogRXhhbXBsZTogY2xvc2VfY3Vyc29yKCkgLSBjbG9zZXMgYWxsIGN1cnNvcnMKICogUHJvZHVjZXM6IENMT1NFIEFMTAogKgogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGN1cnNvck5hbWUgQ3Vyc29yIHRvIGNsb3NlLCBvciBudWxsIHRvIGNsb3NlIGFsbAogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":42,"slug":"eq","name":"eq","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBlcXVhbGl0eSBjb21wYXJpc29uIChjb2x1bW4gPSB2YWx1ZSkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":55,"slug":"ne","name":"ne","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5vdC1lcXVhbCBjb21wYXJpc29uIChjb2x1bW4gIT0gdmFsdWUpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":68,"slug":"lt","name":"lt","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxlc3MtdGhhbiBjb21wYXJpc29uIChjb2x1bW4gPCB2YWx1ZSkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":81,"slug":"le","name":"le","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxlc3MtdGhhbi1vci1lcXVhbCBjb21wYXJpc29uIChjb2x1bW4gPD0gdmFsdWUpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":94,"slug":"gt","name":"gt","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGdyZWF0ZXItdGhhbiBjb21wYXJpc29uIChjb2x1bW4gPiB2YWx1ZSkuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":107,"slug":"ge","name":"ge","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Comparison","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGdyZWF0ZXItdGhhbi1vci1lcXVhbCBjb21wYXJpc29uIChjb2x1bW4gPj0gdmFsdWUpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":120,"slug":"between","name":"between","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"low","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"high","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"not","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Between","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJFVFdFRU4gY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":139,"slug":"in","name":"in_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"values","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"In","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJTiBjb25kaXRpb24uCiAqCiAqIEBwYXJhbSBFeHByZXNzaW9ufHN0cmluZyAkZXhwciBFeHByZXNzaW9uIHRvIGNoZWNrCiAqIEBwYXJhbSBsaXN0PEV4cHJlc3Npb24+ICR2YWx1ZXMgTGlzdCBvZiB2YWx1ZXMgKG11c3QgYmUgbm9uLWVtcHR5KQogKgogKiBAdGhyb3dzIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gd2hlbiB2YWx1ZXMgYXJyYXkgaXMgZW1wdHkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":156,"slug":"is-null","name":"is_null","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"not","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"IsNull","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJUyBOVUxMIGNvbmRpdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":165,"slug":"like","name":"like","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"caseInsensitive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"negated","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Like","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExJS0UgY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":183,"slug":"similar-to","name":"similar_to","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SimilarTo","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNJTUlMQVIgVE8gY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":195,"slug":"distinct-from","name":"distinct_from","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"not","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"IsDistinctFrom","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJUyBESVNUSU5DVCBGUk9NIGNvbmRpdGlvbi4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":208,"slug":"exists","name":"exists","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"subquery","type":[{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Exists","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFWElTVFMgY29uZGl0aW9uLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":223,"slug":"any","name":"any_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"operator","type":[{"name":"ComparisonOperator","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"arrayOrSubquery","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBTlkgY29uZGl0aW9uIHdpdGggYSBzdWJxdWVyeSBvciBhcnJheSBleHByZXNzaW9uLgogKgogKiBFeGFtcGxlOiBhbnlfKGNvbCgnaWQnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpFUSwgc2VsZWN0KGNvbCgndXNlcl9pZCcpKS0+ZnJvbSh0YWJsZSgnb3JkZXJzJykpKQogKiBFeGFtcGxlOiBhbnlfKGNvbCgnYXR0bnVtJywgJ2EnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpFUSwgY29sKCdjb25rZXknLCAnY29uJykpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":243,"slug":"all","name":"all_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"operator","type":[{"name":"ComparisonOperator","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"arrayOrSubquery","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"SelectFinalStep","namespace":"Flow\\PostgreSql\\QueryBuilder\\Select","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBTEwgY29uZGl0aW9uIHdpdGggYSBzdWJxdWVyeSBvciBhcnJheSBleHByZXNzaW9uLgogKgogKiBFeGFtcGxlOiBhbGxfKGNvbCgnaWQnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpFUSwgc2VsZWN0KGNvbCgndXNlcl9pZCcpKS0+ZnJvbSh0YWJsZSgnb3JkZXJzJykpKQogKiBFeGFtcGxlOiBhbGxfKGNvbCgndmFsdWUnKSwgQ29tcGFyaXNvbk9wZXJhdG9yOjpHVCwgY29sKCd0aHJlc2hvbGRzJykpCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":262,"slug":"is-true","name":"is_true","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BooleanCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYW4gZXhwcmVzc2lvbiBhcyBhIGJvb2xlYW4gY29uZGl0aW9uIGZvciB1c2UgaW4gV0hFUkUvSEFWSU5HL0pPSU4gT04uCiAqCiAqIEV4YW1wbGU6IGlzX3RydWUoY29sKCdpc19hY3RpdmUnKSkg4oCUIHVzZXMgYSBib29sZWFuIGNvbHVtbiBpbiBXSEVSRSBjbGF1c2UuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":274,"slug":"not-like","name":"not_like","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"caseInsensitive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"Like","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE5PVCBMSUtFIGNvbmRpdGlvbi4KICoKICogRXhhbXBsZTogbm90X2xpa2UoY29sKCduYW1lJyksIGxpdGVyYWwoJ3BnXyUnKSkKICogUHJvZHVjZXM6IG5hbWUgTk9UIExJS0UgJ3BnXyUnCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":302,"slug":"conditions","name":"conditions","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"ConditionBuilder","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGNvbmRpdGlvbiBidWlsZGVyIGZvciBmbHVlbnQgY29uZGl0aW9uIGNvbXBvc2l0aW9uLgogKgogKiBUaGlzIGJ1aWxkZXIgYWxsb3dzIGluY3JlbWVudGFsIGNvbmRpdGlvbiBidWlsZGluZyB3aXRoIGEgZmx1ZW50IEFQSToKICoKICogYGBgcGhwCiAqICRidWlsZGVyID0gY29uZGl0aW9ucygpOwogKgogKiBpZiAoJGhhc0ZpbHRlcikgewogKiAgICAgJGJ1aWxkZXIgPSAkYnVpbGRlci0+YW5kKGVxKGNvbCgnc3RhdHVzJyksIGxpdGVyYWwoJ2FjdGl2ZScpKSk7CiAqIH0KICoKICogaWYgKCEkYnVpbGRlci0+aXNFbXB0eSgpKSB7CiAqICAgICAkcXVlcnkgPSBzZWxlY3QoKS0+ZnJvbSh0YWJsZSgndXNlcnMnKSktPndoZXJlKCRidWlsZGVyKTsKICogfQogKiBgYGAKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":313,"slug":"and","name":"and_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"conditions","type":[{"name":"Condition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"AndCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgY29uZGl0aW9ucyB3aXRoIEFORC4KICoKICogQHBhcmFtIENvbmRpdGlvbiAuLi4kY29uZGl0aW9ucyBDb25kaXRpb25zIHRvIGNvbWJpbmUKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":324,"slug":"or","name":"or_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"conditions","type":[{"name":"Condition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"OrCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgY29uZGl0aW9ucyB3aXRoIE9SLgogKgogKiBAcGFyYW0gQ29uZGl0aW9uIC4uLiRjb25kaXRpb25zIENvbmRpdGlvbnMgdG8gY29tYmluZQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":336,"slug":"not","name":"not_","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expression","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"NotCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5lZ2F0ZSBhIGNvbmRpdGlvbiBvciBleHByZXNzaW9uIHdpdGggTk9ULgogKgogKiBBY2NlcHRzIGJvdGggQ29uZGl0aW9uIGFuZCBFeHByZXNzaW9uIOKAlCBOT1QgYWx3YXlzIHByb2R1Y2VzIGEgYm9vbGVhbiByZXN1bHQuCiAqIENhbiBiZSB1c2VkIGluIFdIRVJFIGNsYXVzZXMgYW5kIFNFTEVDVCBsaXN0cyAodmlhIC0+YXMoJ2FsaWFzJykpLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":348,"slug":"json-contains","name":"json_contains","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGNvbnRhaW5zIGNvbmRpdGlvbiAoQD4pLgogKgogKiBFeGFtcGxlOiBqc29uX2NvbnRhaW5zKGNvbCgnbWV0YWRhdGEnKSwgbGl0ZXJhbF9qc29uKCd7ImNhdGVnb3J5IjogImVsZWN0cm9uaWNzIn0nKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhIEA+ICd7ImNhdGVnb3J5IjogImVsZWN0cm9uaWNzIn0nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":364,"slug":"json-contained-by","name":"json_contained_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGlzIGNvbnRhaW5lZCBieSBjb25kaXRpb24gKDxAKS4KICoKICogRXhhbXBsZToganNvbl9jb250YWluZWRfYnkoY29sKCdtZXRhZGF0YScpLCBsaXRlcmFsX2pzb24oJ3siY2F0ZWdvcnkiOiAiZWxlY3Ryb25pY3MiLCAicHJpY2UiOiAxMDB9JykpCiAqIFByb2R1Y2VzOiBtZXRhZGF0YSA8QCAneyJjYXRlZ29yeSI6ICJlbGVjdHJvbmljcyIsICJwcmljZSI6IDEwMH0nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":381,"slug":"json-get","name":"json_get","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gZmllbGQgYWNjZXNzIGV4cHJlc3Npb24gKC0+KS4KICogUmV0dXJucyBKU09OLgogKgogKiBFeGFtcGxlOiBqc29uX2dldChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCdjYXRlZ29yeScpKQogKiBQcm9kdWNlczogbWV0YWRhdGEgLT4gJ2NhdGVnb3J5JwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":398,"slug":"json-get-text","name":"json_get_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gZmllbGQgYWNjZXNzIGV4cHJlc3Npb24gKC0+PikuCiAqIFJldHVybnMgdGV4dC4KICoKICogRXhhbXBsZToganNvbl9nZXRfdGV4dChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCduYW1lJykpCiAqIFByb2R1Y2VzOiBtZXRhZGF0YSAtPj4gJ25hbWUnCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":415,"slug":"json-path","name":"json_path","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gcGF0aCBhY2Nlc3MgZXhwcmVzc2lvbiAoIz4pLgogKiBSZXR1cm5zIEpTT04uCiAqCiAqIEV4YW1wbGU6IGpzb25fcGF0aChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCd7Y2F0ZWdvcnksbmFtZX0nKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhICM+ICd7Y2F0ZWdvcnksbmFtZX0nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":432,"slug":"json-path-text","name":"json_path_text","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"path","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"BinaryExpression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gcGF0aCBhY2Nlc3MgZXhwcmVzc2lvbiAoIz4+KS4KICogUmV0dXJucyB0ZXh0LgogKgogKiBFeGFtcGxlOiBqc29uX3BhdGhfdGV4dChjb2woJ21ldGFkYXRhJyksIGxpdGVyYWxfc3RyaW5nKCd7Y2F0ZWdvcnksbmFtZX0nKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhICM+PiAne2NhdGVnb3J5LG5hbWV9JwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":448,"slug":"json-exists","name":"json_exists","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGtleSBleGlzdHMgY29uZGl0aW9uICg\/KS4KICoKICogRXhhbXBsZToganNvbl9leGlzdHMoY29sKCdtZXRhZGF0YScpLCBsaXRlcmFsX3N0cmluZygnY2F0ZWdvcnknKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhID8gJ2NhdGVnb3J5JwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":464,"slug":"json-exists-any","name":"json_exists_any","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGFueSBrZXkgZXhpc3RzIGNvbmRpdGlvbiAoP3wpLgogKgogKiBFeGFtcGxlOiBqc29uX2V4aXN0c19hbnkoY29sKCdtZXRhZGF0YScpLCBhcnJheV9leHByKFtsaXRlcmFsKCdjYXRlZ29yeScpLCBsaXRlcmFsKCduYW1lJyldKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhID98IGFycmF5WydjYXRlZ29yeScsICduYW1lJ10KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":480,"slug":"json-exists-all","name":"json_exists_all","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"keys","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT05CIGFsbCBrZXlzIGV4aXN0IGNvbmRpdGlvbiAoPyYpLgogKgogKiBFeGFtcGxlOiBqc29uX2V4aXN0c19hbGwoY29sKCdtZXRhZGF0YScpLCBhcnJheV9leHByKFtsaXRlcmFsKCdjYXRlZ29yeScpLCBsaXRlcmFsKCduYW1lJyldKSkKICogUHJvZHVjZXM6IG1ldGFkYXRhID8mIGFycmF5WydjYXRlZ29yeScsICduYW1lJ10KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":496,"slug":"array-contains","name":"array_contains","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBjb250YWlucyBjb25kaXRpb24gKEA+KS4KICoKICogRXhhbXBsZTogYXJyYXlfY29udGFpbnMoY29sKCd0YWdzJyksIGFycmF5X2V4cHIoW2xpdGVyYWwoJ3NhbGUnKV0pKQogKiBQcm9kdWNlczogdGFncyBAPiBBUlJBWVsnc2FsZSddCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":512,"slug":"array-contained-by","name":"array_contained_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBpcyBjb250YWluZWQgYnkgY29uZGl0aW9uICg8QCkuCiAqCiAqIEV4YW1wbGU6IGFycmF5X2NvbnRhaW5lZF9ieShjb2woJ3RhZ3MnKSwgYXJyYXlfZXhwcihbbGl0ZXJhbCgnc2FsZScpLCBsaXRlcmFsKCdmZWF0dXJlZCcpLCBsaXRlcmFsKCduZXcnKV0pKQogKiBQcm9kdWNlczogdGFncyA8QCBBUlJBWVsnc2FsZScsICdmZWF0dXJlZCcsICduZXcnXQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":528,"slug":"array-overlap","name":"array_overlap","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"left","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"right","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhcnJheSBvdmVybGFwIGNvbmRpdGlvbiAoJiYpLgogKgogKiBFeGFtcGxlOiBhcnJheV9vdmVybGFwKGNvbCgndGFncycpLCBhcnJheV9leHByKFtsaXRlcmFsKCdzYWxlJyksIGxpdGVyYWwoJ2ZlYXR1cmVkJyldKSkKICogUHJvZHVjZXM6IHRhZ3MgJiYgQVJSQVlbJ3NhbGUnLCAnZmVhdHVyZWQnXQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":546,"slug":"regex-match","name":"regex_match","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG1hdGNoIGNvbmRpdGlvbiAofikuCiAqIENhc2Utc2Vuc2l0aXZlLgogKgogKiBFeGFtcGxlOiByZWdleF9tYXRjaChjb2woJ2VtYWlsJyksIGxpdGVyYWxfc3RyaW5nKCcuKkBnbWFpbFxcLmNvbScpKQogKgogKiBQcm9kdWNlczogZW1haWwgfiAnLipAZ21haWxcLmNvbScKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":564,"slug":"regex-imatch","name":"regex_imatch","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG1hdGNoIGNvbmRpdGlvbiAofiopLgogKiBDYXNlLWluc2Vuc2l0aXZlLgogKgogKiBFeGFtcGxlOiByZWdleF9pbWF0Y2goY29sKCdlbWFpbCcpLCBsaXRlcmFsX3N0cmluZygnLipAZ21haWxcXC5jb20nKSkKICoKICogUHJvZHVjZXM6IGVtYWlsIH4qICcuKkBnbWFpbFwuY29tJwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":582,"slug":"not-regex-match","name":"not_regex_match","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG5vdCBtYXRjaCBjb25kaXRpb24gKCF+KS4KICogQ2FzZS1zZW5zaXRpdmUuCiAqCiAqIEV4YW1wbGU6IG5vdF9yZWdleF9tYXRjaChjb2woJ2VtYWlsJyksIGxpdGVyYWxfc3RyaW5nKCcuKkBzcGFtXFwuY29tJykpCiAqCiAqIFByb2R1Y2VzOiBlbWFpbCAhfiAnLipAc3BhbVwuY29tJwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":600,"slug":"not-regex-imatch","name":"not_regex_imatch","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"expr","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"pattern","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBPU0lYIHJlZ2V4IG5vdCBtYXRjaCBjb25kaXRpb24gKCF+KikuCiAqIENhc2UtaW5zZW5zaXRpdmUuCiAqCiAqIEV4YW1wbGU6IG5vdF9yZWdleF9pbWF0Y2goY29sKCdlbWFpbCcpLCBsaXRlcmFsX3N0cmluZygnLipAc3BhbVxcLmNvbScpKQogKgogKiBQcm9kdWNlczogZW1haWwgIX4qICcuKkBzcGFtXC5jb20nCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/condition.php","start_line_in_file":616,"slug":"text-search-match","name":"text_search_match","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"document","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"query","type":[{"name":"Expression","namespace":"Flow\\PostgreSql\\QueryBuilder\\Expression","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OperatorCondition","namespace":"Flow\\PostgreSql\\QueryBuilder\\Condition","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGZ1bGwtdGV4dCBzZWFyY2ggbWF0Y2ggY29uZGl0aW9uIChAQCkuCiAqCiAqIEV4YW1wbGU6IHRleHRfc2VhcmNoX21hdGNoKGNvbCgnZG9jdW1lbnQnKSwgZnVuYygndG9fdHNxdWVyeScsIFtsaXRlcmFsKCdlbmdsaXNoJyksIGxpdGVyYWwoJ2hlbGxvICYgd29ybGQnKV0pKQogKiBQcm9kdWNlczogZG9jdW1lbnQgQEAgdG9fdHNxdWVyeSgnZW5nbGlzaCcsICdoZWxsbyAmIHdvcmxkJykKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":33,"slug":"sql-parser","name":"sql_parser","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"Parser","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":39,"slug":"sql-parse","name":"sql_parse","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":49,"slug":"sql-fingerprint","name":"sql_fingerprint","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFJldHVybnMgYSBmaW5nZXJwcmludCBvZiB0aGUgZ2l2ZW4gU1FMIHF1ZXJ5LgogKiBMaXRlcmFsIHZhbHVlcyBhcmUgbm9ybWFsaXplZCBzbyB0aGV5IHdvbid0IGFmZmVjdCB0aGUgZmluZ2VycHJpbnQuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":60,"slug":"sql-normalize","name":"sql_normalize","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5vcm1hbGl6ZSBTUUwgcXVlcnkgYnkgcmVwbGFjaW5nIGxpdGVyYWwgdmFsdWVzIGFuZCBuYW1lZCBwYXJhbWV0ZXJzIHdpdGggcG9zaXRpb25hbCBwYXJhbWV0ZXJzLgogKiBXSEVSRSBpZCA9IDppZCB3aWxsIGJlIGNoYW5nZWQgaW50byBXSEVSRSBpZCA9ICQxCiAqIFdIRVJFIGlkID0gMSB3aWxsIGJlIGNoYW5nZWQgaW50byBXSEVSRSBpZCA9ICQxLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":70,"slug":"sql-normalize-utility","name":"sql_normalize_utility","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5vcm1hbGl6ZSB1dGlsaXR5IFNRTCBzdGF0ZW1lbnRzIChEREwgbGlrZSBDUkVBVEUsIEFMVEVSLCBEUk9QKS4KICogVGhpcyBoYW5kbGVzIERETCBzdGF0ZW1lbnRzIGRpZmZlcmVudGx5IGZyb20gcGdfbm9ybWFsaXplKCkgd2hpY2ggaXMgb3B0aW1pemVkIGZvciBETUwuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":81,"slug":"sql-split","name":"sql_split","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFNwbGl0IHN0cmluZyB3aXRoIG11bHRpcGxlIFNRTCBzdGF0ZW1lbnRzIGludG8gYXJyYXkgb2YgaW5kaXZpZHVhbCBzdGF0ZW1lbnRzLgogKgogKiBAcmV0dXJuIGFycmF5PHN0cmluZz4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":90,"slug":"sql-deparse-options","name":"sql_deparse_options","namespace":"Flow\\PostgreSql\\DSL","parameters":[],"return_type":[{"name":"DeparseOptions","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBEZXBhcnNlT3B0aW9ucyBmb3IgY29uZmlndXJpbmcgU1FMIGZvcm1hdHRpbmcuCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":104,"slug":"sql-deparse","name":"sql_deparse","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"DeparseOptions","namespace":"Flow\\PostgreSql","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbnZlcnQgYSBQYXJzZWRRdWVyeSBBU1QgYmFjayB0byBTUUwgc3RyaW5nLgogKgogKiBXaGVuIGNhbGxlZCB3aXRob3V0IG9wdGlvbnMsIHJldHVybnMgdGhlIFNRTCBhcyBhIHNpbXBsZSBzdHJpbmcuCiAqIFdoZW4gY2FsbGVkIHdpdGggRGVwYXJzZU9wdGlvbnMsIGFwcGxpZXMgZm9ybWF0dGluZyAocHJldHR5LXByaW50aW5nLCBpbmRlbnRhdGlvbiwgZXRjLikuCiAqCiAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gaWYgZGVwYXJzaW5nIGZhaWxzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":120,"slug":"sql-format","name":"sql_format","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"DeparseOptions","namespace":"Flow\\PostgreSql","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhcnNlIGFuZCBmb3JtYXQgU1FMIHF1ZXJ5IHdpdGggcHJldHR5IHByaW50aW5nLgogKgogKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgZnVuY3Rpb24gdGhhdCBwYXJzZXMgU1FMIGFuZCByZXR1cm5zIGl0IGZvcm1hdHRlZC4KICoKICogQHBhcmFtIHN0cmluZyAkc3FsIFRoZSBTUUwgcXVlcnkgdG8gZm9ybWF0CiAqIEBwYXJhbSBudWxsfERlcGFyc2VPcHRpb25zICRvcHRpb25zIEZvcm1hdHRpbmcgb3B0aW9ucyAoZGVmYXVsdHMgdG8gcHJldHR5LXByaW50IGVuYWJsZWQpCiAqCiAqIEB0aHJvd3MgXFJ1bnRpbWVFeGNlcHRpb24gaWYgcGFyc2luZyBvciBkZXBhcnNpbmcgZmFpbHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":132,"slug":"sql-summary","name":"sql_summary","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"},{"name":"truncateLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdlbmVyYXRlIGEgc3VtbWFyeSBvZiBwYXJzZWQgcXVlcmllcyBpbiBwcm90b2J1ZiBmb3JtYXQuCiAqIFVzZWZ1bCBmb3IgcXVlcnkgbW9uaXRvcmluZyBhbmQgbG9nZ2luZyB3aXRob3V0IGZ1bGwgQVNUIG92ZXJoZWFkLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":147,"slug":"sql-to-paginated-query","name":"sql_to_paginated_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"offset","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"0"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGEgcGFnaW5hdGVkIHF1ZXJ5IHdpdGggTElNSVQgYW5kIE9GRlNFVC4KICoKICogQHBhcmFtIHN0cmluZyAkc3FsIFRoZSBTUUwgcXVlcnkgdG8gcGFnaW5hdGUKICogQHBhcmFtIGludCAkbGltaXQgTWF4aW11bSBudW1iZXIgb2Ygcm93cyB0byByZXR1cm4KICogQHBhcmFtIGludCAkb2Zmc2V0IE51bWJlciBvZiByb3dzIHRvIHNraXAgKHJlcXVpcmVzIE9SREVSIEJZIGluIHF1ZXJ5KQogKgogKiBAcmV0dXJuIHN0cmluZyBUaGUgcGFnaW5hdGVkIFNRTCBxdWVyeQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":164,"slug":"sql-to-limited-query","name":"sql_to_limited_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSB0byBsaW1pdCByZXN1bHRzIHRvIGEgc3BlY2lmaWMgbnVtYmVyIG9mIHJvd3MuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHNxbCBUaGUgU1FMIHF1ZXJ5IHRvIGxpbWl0CiAqIEBwYXJhbSBpbnQgJGxpbWl0IE1heGltdW0gbnVtYmVyIG9mIHJvd3MgdG8gcmV0dXJuCiAqCiAqIEByZXR1cm4gc3RyaW5nIFRoZSBsaW1pdGVkIFNRTCBxdWVyeQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":183,"slug":"sql-to-count-query","name":"sql_to_count_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGEgQ09VTlQgcXVlcnkgZm9yIHBhZ2luYXRpb24uCiAqCiAqIFdyYXBzIHRoZSBxdWVyeSBpbjogU0VMRUNUIENPVU5UKCopIEZST00gKC4uLikgQVMgX2NvdW50X3N1YnEKICogUmVtb3ZlcyBPUkRFUiBCWSBhbmQgTElNSVQvT0ZGU0VUIGZyb20gdGhlIGlubmVyIHF1ZXJ5LgogKgogKiBAcGFyYW0gc3RyaW5nICRzcWwgVGhlIFNRTCBxdWVyeSB0byB0cmFuc2Zvcm0KICoKICogQHJldHVybiBzdHJpbmcgVGhlIENPVU5UIHF1ZXJ5CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":205,"slug":"sql-to-keyset-query","name":"sql_to_keyset_query","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"columns","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"cursor","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGEga2V5c2V0IChjdXJzb3ItYmFzZWQpIHBhZ2luYXRlZCBxdWVyeS4KICoKICogTW9yZSBlZmZpY2llbnQgdGhhbiBPRkZTRVQgZm9yIGxhcmdlIGRhdGFzZXRzIC0gdXNlcyBpbmRleGVkIFdIRVJFIGNvbmRpdGlvbnMuCiAqIEF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBleGlzdGluZyBxdWVyeSBwYXJhbWV0ZXJzIGFuZCBhcHBlbmRzIGtleXNldCBwbGFjZWhvbGRlcnMgYXQgdGhlIGVuZC4KICoKICogQHBhcmFtIHN0cmluZyAkc3FsIFRoZSBTUUwgcXVlcnkgdG8gcGFnaW5hdGUgKG11c3QgaGF2ZSBPUkRFUiBCWSkKICogQHBhcmFtIGludCAkbGltaXQgTWF4aW11bSBudW1iZXIgb2Ygcm93cyB0byByZXR1cm4KICogQHBhcmFtIGxpc3Q8S2V5c2V0Q29sdW1uPiAkY29sdW1ucyBDb2x1bW5zIGZvciBrZXlzZXQgcGFnaW5hdGlvbiAobXVzdCBtYXRjaCBPUkRFUiBCWSkKICogQHBhcmFtIG51bGx8bGlzdDxudWxsfGJvb2x8ZmxvYXR8aW50fHN0cmluZz4gJGN1cnNvciBWYWx1ZXMgZnJvbSBsYXN0IHJvdyBvZiBwcmV2aW91cyBwYWdlIChudWxsIGZvciBmaXJzdCBwYWdlKQogKgogKiBAcmV0dXJuIHN0cmluZyBUaGUgcGFnaW5hdGVkIFNRTCBxdWVyeQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":220,"slug":"sql-keyset-column","name":"sql_keyset_column","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"column","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"order","type":[{"name":"SortOrder","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\AST\\Transformers\\SortOrder::..."}],"return_type":[{"name":"KeysetColumn","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEtleXNldENvbHVtbiBmb3Iga2V5c2V0IHBhZ2luYXRpb24uCiAqCiAqIEBwYXJhbSBzdHJpbmcgJGNvbHVtbiBDb2x1bW4gbmFtZSAoY2FuIGluY2x1ZGUgdGFibGUgYWxpYXMgbGlrZSAidS5pZCIpCiAqIEBwYXJhbSBTb3J0T3JkZXIgJG9yZGVyIFNvcnQgb3JkZXIgKEFTQyBvciBERVNDKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":229,"slug":"sql-query-columns","name":"sql_query_columns","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Columns","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgY29sdW1ucyBmcm9tIGEgcGFyc2VkIFNRTCBxdWVyeS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":238,"slug":"sql-query-tables","name":"sql_query_tables","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Tables","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgdGFibGVzIGZyb20gYSBwYXJzZWQgU1FMIHF1ZXJ5LgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":247,"slug":"sql-query-functions","name":"sql_query_functions","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Functions","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgZnVuY3Rpb25zIGZyb20gYSBwYXJzZWQgU1FMIHF1ZXJ5LgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":256,"slug":"sql-query-order-by","name":"sql_query_order_by","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"query","type":[{"name":"ParsedQuery","namespace":"Flow\\PostgreSql","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"OrderBy","namespace":"Flow\\PostgreSql\\Extractors","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEV4dHJhY3QgT1JERVIgQlkgY2xhdXNlcyBmcm9tIGEgcGFyc2VkIFNRTCBxdWVyeS4KICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":270,"slug":"sql-query-depth","name":"sql_query_depth","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEdldCB0aGUgbWF4aW11bSBuZXN0aW5nIGRlcHRoIG9mIGEgU1FMIHF1ZXJ5LgogKgogKiBFeGFtcGxlOgogKiAtICJTRUxFQ1QgKiBGUk9NIHQiID0+IDEKICogLSAiU0VMRUNUICogRlJPTSAoU0VMRUNUICogRlJPTSB0KSIgPT4gMgogKiAtICJTRUxFQ1QgKiBGUk9NIChTRUxFQ1QgKiBGUk9NIChTRUxFQ1QgKiBGUk9NIHQpKSIgPT4gMwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":287,"slug":"sql-to-explain","name":"sql_to_explain","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"sql","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"config","type":[{"name":"ExplainConfig","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFRyYW5zZm9ybSBhIFNRTCBxdWVyeSBpbnRvIGFuIEVYUExBSU4gcXVlcnkuCiAqCiAqIFJldHVybnMgdGhlIG1vZGlmaWVkIFNRTCB3aXRoIEVYUExBSU4gd3JhcHBlZCBhcm91bmQgaXQuCiAqIERlZmF1bHRzIHRvIEVYUExBSU4gQU5BTFlaRSB3aXRoIEpTT04gZm9ybWF0IGZvciBlYXN5IHBhcnNpbmcuCiAqCiAqIEBwYXJhbSBzdHJpbmcgJHNxbCBUaGUgU1FMIHF1ZXJ5IHRvIGV4cGxhaW4KICogQHBhcmFtIG51bGx8RXhwbGFpbkNvbmZpZyAkY29uZmlnIEVYUExBSU4gY29uZmlndXJhdGlvbiAoZGVmYXVsdHMgdG8gZm9yQW5hbHlzaXMoKSkKICoKICogQHJldHVybiBzdHJpbmcgVGhlIEVYUExBSU4gcXVlcnkKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":307,"slug":"sql-explain-config","name":"sql_explain_config","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"analyze","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"verbose","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"costs","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"buffers","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"timing","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"format","type":[{"name":"ExplainFormat","namespace":"Flow\\PostgreSql\\QueryBuilder\\Utility","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\QueryBuilder\\Utility\\ExplainFormat::..."}],"return_type":[{"name":"ExplainConfig","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFeHBsYWluQ29uZmlnIGZvciBjdXN0b21pemluZyBFWFBMQUlOIG9wdGlvbnMuCiAqCiAqIEBwYXJhbSBib29sICRhbmFseXplIFdoZXRoZXIgdG8gYWN0dWFsbHkgZXhlY3V0ZSB0aGUgcXVlcnkgKEFOQUxZWkUpCiAqIEBwYXJhbSBib29sICR2ZXJib3NlIEluY2x1ZGUgdmVyYm9zZSBvdXRwdXQKICogQHBhcmFtIGJvb2wgJGNvc3RzIEluY2x1ZGUgY29zdCBlc3RpbWF0ZXMgKGRlZmF1bHQgdHJ1ZSkKICogQHBhcmFtIGJvb2wgJGJ1ZmZlcnMgSW5jbHVkZSBidWZmZXIgdXNhZ2Ugc3RhdGlzdGljcyAocmVxdWlyZXMgYW5hbHl6ZSkKICogQHBhcmFtIGJvb2wgJHRpbWluZyBJbmNsdWRlIHRpbWluZyBpbmZvcm1hdGlvbiAocmVxdWlyZXMgYW5hbHl6ZSkKICogQHBhcmFtIEV4cGxhaW5Gb3JtYXQgJGZvcm1hdCBPdXRwdXQgZm9ybWF0IChKU09OIHJlY29tbWVuZGVkIGZvciBwYXJzaW5nKQogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":329,"slug":"sql-explain-modifier","name":"sql_explain_modifier","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"config","type":[{"name":"ExplainConfig","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ExplainModifier","namespace":"Flow\\PostgreSql\\AST\\Transformers","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFeHBsYWluTW9kaWZpZXIgZm9yIHRyYW5zZm9ybWluZyBxdWVyaWVzIGludG8gRVhQTEFJTiBxdWVyaWVzLgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":342,"slug":"sql-explain-parse","name":"sql_explain_parse","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"jsonOutput","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Plan","namespace":"Flow\\PostgreSql\\Explain\\Plan","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFBhcnNlIEVYUExBSU4gSlNPTiBvdXRwdXQgaW50byBhIFBsYW4gb2JqZWN0LgogKgogKiBAcGFyYW0gc3RyaW5nICRqc29uT3V0cHV0IFRoZSBKU09OIG91dHB1dCBmcm9tIEVYUExBSU4gKEZPUk1BVCBKU09OKQogKgogKiBAcmV0dXJuIFBsYW4gVGhlIHBhcnNlZCBleGVjdXRpb24gcGxhbgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/parser.php","start_line_in_file":355,"slug":"sql-analyze","name":"sql_analyze","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"plan","type":[{"name":"Plan","namespace":"Flow\\PostgreSql\\Explain\\Plan","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PlanAnalyzer","namespace":"Flow\\PostgreSql\\Explain\\Analyzer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHBsYW4gYW5hbHl6ZXIgZm9yIGFuYWx5emluZyBFWFBMQUlOIHBsYW5zLgogKgogKiBAcGFyYW0gUGxhbiAkcGxhbiBUaGUgZXhlY3V0aW9uIHBsYW4gdG8gYW5hbHl6ZQogKgogKiBAcmV0dXJuIFBsYW5BbmFseXplciBUaGUgYW5hbHl6ZXIgZm9yIGV4dHJhY3RpbmcgaW5zaWdodHMKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":45,"slug":"pgsql-connection","name":"pgsql_connection","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"connectionString","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgZnJvbSBhIGNvbm5lY3Rpb24gc3RyaW5nLgogKgogKiBBY2NlcHRzIGxpYnBxLXN0eWxlIGNvbm5lY3Rpb24gc3RyaW5nczoKICogLSBLZXktdmFsdWUgZm9ybWF0OiAiaG9zdD1sb2NhbGhvc3QgcG9ydD01NDMyIGRibmFtZT1teWRiIHVzZXI9bXl1c2VyIHBhc3N3b3JkPXNlY3JldCIKICogLSBVUkkgZm9ybWF0OiAicG9zdGdyZXNxbDovL3VzZXI6cGFzc3dvcmRAbG9jYWxob3N0OjU0MzIvZGJuYW1lIgogKgogKiBAZXhhbXBsZQogKiAkcGFyYW1zID0gcGdzcWxfY29ubmVjdGlvbignaG9zdD1sb2NhbGhvc3QgZGJuYW1lPW15ZGInKTsKICogJHBhcmFtcyA9IHBnc3FsX2Nvbm5lY3Rpb24oJ3Bvc3RncmVzcWw6Ly91c2VyOnBhc3NAbG9jYWxob3N0L215ZGInKTsKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":67,"slug":"pgsql-connection-dsn","name":"pgsql_connection_dsn","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"dsn","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgZnJvbSBhIERTTiBzdHJpbmcuCiAqCiAqIFBhcnNlcyBzdGFuZGFyZCBQb3N0Z3JlU1FMIERTTiBmb3JtYXQgY29tbW9ubHkgdXNlZCBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZXMKICogKGUuZy4sIERBVEFCQVNFX1VSTCkuIFN1cHBvcnRzIHBvc3RncmVzOi8vLCBwb3N0Z3Jlc3FsOi8vLCBhbmQgcGdzcWw6Ly8gc2NoZW1lcy4KICoKICogQHBhcmFtIHN0cmluZyAkZHNuIERTTiBzdHJpbmcgaW4gZm9ybWF0OiBwb3N0Z3JlczovL3VzZXI6cGFzc3dvcmRAaG9zdDpwb3J0L2RhdGFiYXNlP29wdGlvbnMKICoKICogQHRocm93cyBDbGllbnRcRHNuUGFyc2VyRXhjZXB0aW9uIElmIHRoZSBEU04gY2Fubm90IGJlIHBhcnNlZAogKgogKiBAZXhhbXBsZQogKiAkcGFyYW1zID0gcGdzcWxfY29ubmVjdGlvbl9kc24oJ3Bvc3RncmVzOi8vbXl1c2VyOnNlY3JldEBsb2NhbGhvc3Q6NTQzMi9teWRiJyk7CiAqICRwYXJhbXMgPSBwZ3NxbF9jb25uZWN0aW9uX2RzbigncG9zdGdyZXNxbDovL3VzZXI6cGFzc0BkYi5leGFtcGxlLmNvbS9hcHA\/c3NsbW9kZT1yZXF1aXJlJyk7CiAqICRwYXJhbXMgPSBwZ3NxbF9jb25uZWN0aW9uX2RzbigncGdzcWw6Ly91c2VyOnBhc3NAbG9jYWxob3N0L215ZGInKTsgLy8gU3ltZm9ueS9Eb2N0cmluZSBmb3JtYXQKICogJHBhcmFtcyA9IHBnc3FsX2Nvbm5lY3Rpb25fZHNuKGdldGVudignREFUQUJBU0VfVVJMJykpOwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":94,"slug":"pgsql-connection-params","name":"pgsql_connection_params","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"database","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'localhost'"},{"name":"port","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"5432"},{"name":"user","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"password","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"options","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjb25uZWN0aW9uIHBhcmFtZXRlcnMgZnJvbSBpbmRpdmlkdWFsIHZhbHVlcy4KICoKICogQWxsb3dzIHNwZWNpZnlpbmcgY29ubmVjdGlvbiBwYXJhbWV0ZXJzIGluZGl2aWR1YWxseSBmb3IgYmV0dGVyIHR5cGUgc2FmZXR5CiAqIGFuZCBJREUgc3VwcG9ydC4KICoKICogQHBhcmFtIHN0cmluZyAkZGF0YWJhc2UgRGF0YWJhc2UgbmFtZSAocmVxdWlyZWQpCiAqIEBwYXJhbSBzdHJpbmcgJGhvc3QgSG9zdG5hbWUgKGRlZmF1bHQ6IGxvY2FsaG9zdCkKICogQHBhcmFtIGludCAkcG9ydCBQb3J0IG51bWJlciAoZGVmYXVsdDogNTQzMikKICogQHBhcmFtIG51bGx8c3RyaW5nICR1c2VyIFVzZXJuYW1lIChvcHRpb25hbCkKICogQHBhcmFtIG51bGx8c3RyaW5nICRwYXNzd29yZCBQYXNzd29yZCAob3B0aW9uYWwpCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJG9wdGlvbnMgQWRkaXRpb25hbCBsaWJwcSBvcHRpb25zCiAqCiAqIEBleGFtcGxlCiAqICRwYXJhbXMgPSBwZ3NxbF9jb25uZWN0aW9uX3BhcmFtcygKICogICAgIGRhdGFiYXNlOiAnbXlkYicsCiAqICAgICBob3N0OiAnbG9jYWxob3N0JywKICogICAgIHVzZXI6ICdteXVzZXInLAogKiAgICAgcGFzc3dvcmQ6ICdzZWNyZXQnLAogKiApOwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":125,"slug":"pgsql-client","name":"pgsql_client","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"params","type":[{"name":"ConnectionParameters","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"valueConverters","type":[{"name":"ValueConverters","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"context","type":[{"name":"Context","namespace":"Flow\\PostgreSql\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Client","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBvc3RncmVTUUwgY2xpZW50IHVzaW5nIGV4dC1wZ3NxbC4KICoKICogVGhlIGNsaWVudCBjb25uZWN0cyBpbW1lZGlhdGVseSBhbmQgaXMgcmVhZHkgdG8gZXhlY3V0ZSBxdWVyaWVzLgogKgogKiBAcGFyYW0gQ2xpZW50XENvbm5lY3Rpb25QYXJhbWV0ZXJzICRwYXJhbXMgQ29ubmVjdGlvbiBwYXJhbWV0ZXJzCiAqIEBwYXJhbSBudWxsfFZhbHVlQ29udmVydGVycyAkdmFsdWVDb252ZXJ0ZXJzIEN1c3RvbSB0eXBlIGNvbnZlcnRlcnMgKG9wdGlvbmFsKQogKiBAcGFyYW0gbnVsbHxDb250ZXh0ICRjb250ZXh0IEJhc2UgbWFwcGVyIENvbnRleHQg4oCUIHRoZSBDbGllbnQgZW5yaWNoZXMgaXQgd2l0aCBzcWwvcGFyYW1ldGVycy9zZWxmIHBlciBxdWVyeSBiZWZvcmUgaGFuZGluZyBpdCB0byBSb3dNYXBwZXI6Om1hcCgpCiAqCiAqIEB0aHJvd3MgQ29ubmVjdGlvbkV4Y2VwdGlvbiBJZiBjb25uZWN0aW9uIGZhaWxzCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":142,"slug":"postgresql-context","name":"postgresql_context","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"catalog","type":[{"name":"Catalog","namespace":"Flow\\PostgreSql\\Schema","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Context","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJvd01hcHBlciBDb250ZXh0IHNlZWRlZCB3aXRoIHVzZXItc3VwcGxpZWQga2V5L3ZhbHVlIGRhdGEgYW5kIGFuIG9wdGlvbmFsIENhdGFsb2cuCiAqCiAqIFRoZSBDb250ZXh0IGlzIGxhdGVyIGVucmljaGVkIHdpdGggYSBRdWVyeSAoc3FsICsgcGFyYW1ldGVycykgYW5kIHRoZSBleGVjdXRpbmcgQ2xpZW50IGJ5IHRoZQogKiBQb3N0Z3JlU1FMIENsaWVudCBiZWZvcmUgYmVpbmcgaGFuZGVkIHRvIFJvd01hcHBlcjo6bWFwKCkuCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIG1peGVkPiAkZGF0YSBVc2VyLXN1cHBsaWVkIGtleS92YWx1ZSBwYWlycwogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":175,"slug":"postgresql-telemetry-options","name":"postgresql_telemetry_options","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"traceQueries","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"transactionSpans","type":[{"name":"TransactionSpanMode","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\PostgreSql\\Client\\Telemetry\\TransactionSpanMode::..."},{"name":"collectMetrics","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"logQueries","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"maxQueryLength","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"1000"},{"name":"includeParameters","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"maxParameters","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"10"},{"name":"maxParameterLength","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"100"}],"return_type":[{"name":"PostgreSqlTelemetryOptions","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSB0ZWxlbWV0cnkgb3B0aW9ucyBmb3IgUG9zdGdyZVNRTCBjbGllbnQgaW5zdHJ1bWVudGF0aW9uLgogKgogKiBDb250cm9scyB3aGljaCB0ZWxlbWV0cnkgc2lnbmFscyAodHJhY2VzLCBtZXRyaWNzLCBsb2dzKSBhcmUgZW5hYmxlZAogKiBhbmQgaG93IHF1ZXJ5IGluZm9ybWF0aW9uIGlzIGNhcHR1cmVkLgogKgogKiBAcGFyYW0gYm9vbCAkdHJhY2VRdWVyaWVzIENyZWF0ZSBzcGFucyBmb3IgcXVlcnkgZXhlY3V0aW9uIChkZWZhdWx0OiB0cnVlKQogKiBAcGFyYW0gVHJhbnNhY3Rpb25TcGFuTW9kZSAkdHJhbnNhY3Rpb25TcGFucyBIb3cgdHJhbnNhY3Rpb25zIGFyZSB0cmFjZWQ6IEdST1VQRUQgKGRlZmF1bHQpLCBQRVJfT1BFUkFUSU9OIG9yIE9GRgogKiBAcGFyYW0gYm9vbCAkY29sbGVjdE1ldHJpY3MgQ29sbGVjdCBkdXJhdGlvbiBhbmQgcm93IGNvdW50IG1ldHJpY3MgKGRlZmF1bHQ6IHRydWUpCiAqIEBwYXJhbSBib29sICRsb2dRdWVyaWVzIExvZyBleGVjdXRlZCBxdWVyaWVzIChkZWZhdWx0OiBmYWxzZSkKICogQHBhcmFtIG51bGx8aW50ICRtYXhRdWVyeUxlbmd0aCBNYXhpbXVtIHF1ZXJ5IHRleHQgbGVuZ3RoIGluIHRlbGVtZXRyeSAoZGVmYXVsdDogMTAwMCwgbnVsbCA9IHVubGltaXRlZCkKICogQHBhcmFtIGJvb2wgJGluY2x1ZGVQYXJhbWV0ZXJzIEluY2x1ZGUgcXVlcnkgcGFyYW1ldGVycyBpbiB0ZWxlbWV0cnkgKGRlZmF1bHQ6IGZhbHNlLCBzZWN1cml0eSBjb25zaWRlcmF0aW9uKQogKgogKiBAZXhhbXBsZQogKiAvLyBEZWZhdWx0IG9wdGlvbnMgKHRyYWNlcyBhbmQgbWV0cmljcyBlbmFibGVkKQogKiAkb3B0aW9ucyA9IHBvc3RncmVzcWxfdGVsZW1ldHJ5X29wdGlvbnMoKTsKICoKICogLy8gRW5hYmxlIHF1ZXJ5IGxvZ2dpbmcKICogJG9wdGlvbnMgPSBwb3N0Z3Jlc3FsX3RlbGVtZXRyeV9vcHRpb25zKGxvZ1F1ZXJpZXM6IHRydWUpOwogKgogKiAvLyBNZXRyaWNzIG9ubHksIG5vIHNwYW5zCiAqICRvcHRpb25zID0gcG9zdGdyZXNxbF90ZWxlbWV0cnlfb3B0aW9ucygKICogICAgIHRyYWNlUXVlcmllczogZmFsc2UsCiAqICAgICB0cmFuc2FjdGlvblNwYW5zOiBUcmFuc2FjdGlvblNwYW5Nb2RlOjpPRkYsCiAqICAgICBjb2xsZWN0TWV0cmljczogdHJ1ZSwKICogKTsKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":213,"slug":"postgresql-telemetry-config","name":"postgresql_telemetry_config","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"telemetry","type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"PostgreSqlTelemetryOptions","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"PostgreSqlTelemetryConfig","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSB0ZWxlbWV0cnkgY29uZmlndXJhdGlvbiBmb3IgUG9zdGdyZVNRTCBjbGllbnQuCiAqCiAqIEJ1bmRsZXMgdGVsZW1ldHJ5IGluc3RhbmNlLCBjbG9jaywgYW5kIG9wdGlvbnMgbmVlZGVkIHRvIGluc3RydW1lbnQgYSBQb3N0Z3JlU1FMIGNsaWVudC4KICoKICogQHBhcmFtIFRlbGVtZXRyeSAkdGVsZW1ldHJ5IFRoZSB0ZWxlbWV0cnkgaW5zdGFuY2UKICogQHBhcmFtIENsb2NrSW50ZXJmYWNlICRjbG9jayBDbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gbnVsbHxQb3N0Z3JlU3FsVGVsZW1ldHJ5T3B0aW9ucyAkb3B0aW9ucyBUZWxlbWV0cnkgb3B0aW9ucyAoZGVmYXVsdDogYWxsIGVuYWJsZWQpCiAqCiAqIEBleGFtcGxlCiAqICRjb25maWcgPSBwb3N0Z3Jlc3FsX3RlbGVtZXRyeV9jb25maWcoCiAqICAgICB0ZWxlbWV0cnkocmVzb3VyY2UoWydzZXJ2aWNlLm5hbWUnID0+ICdteS1hcHAnXSkpLAogKiAgICAgbmV3IFN5c3RlbUNsb2NrKCksCiAqICk7CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":259,"slug":"traceable-postgresql-client","name":"traceable_postgresql_client","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"client","type":[{"name":"Client","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"telemetryConfig","type":[{"name":"PostgreSqlTelemetryConfig","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TraceableClient","namespace":"Flow\\PostgreSql\\Client\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYSBQb3N0Z3JlU1FMIGNsaWVudCB3aXRoIHRlbGVtZXRyeSBpbnN0cnVtZW50YXRpb24uCiAqCiAqIFJldHVybnMgYSBkZWNvcmF0b3IgdGhhdCBhZGRzIHNwYW5zLCBtZXRyaWNzLCBhbmQgbG9ncyB0byBhbGwKICogcXVlcnkgYW5kIHRyYW5zYWN0aW9uIG9wZXJhdGlvbnMgZm9sbG93aW5nIE9wZW5UZWxlbWV0cnkgY29udmVudGlvbnMuCiAqCiAqIEBwYXJhbSBDbGllbnRcQ2xpZW50ICRjbGllbnQgVGhlIFBvc3RncmVTUUwgY2xpZW50IHRvIGluc3RydW1lbnQKICogQHBhcmFtIFBvc3RncmVTcWxUZWxlbWV0cnlDb25maWcgJHRlbGVtZXRyeUNvbmZpZyBUZWxlbWV0cnkgY29uZmlndXJhdGlvbgogKgogKiBAZXhhbXBsZQogKiAkY2xpZW50ID0gcGdzcWxfY2xpZW50KHBnc3FsX2Nvbm5lY3Rpb24oJ2hvc3Q9bG9jYWxob3N0IGRibmFtZT1teWRiJykpOwogKgogKiAkdHJhY2VhYmxlQ2xpZW50ID0gdHJhY2VhYmxlX3Bvc3RncmVzcWxfY2xpZW50KAogKiAgICAgJGNsaWVudCwKICogICAgIHBvc3RncmVzcWxfdGVsZW1ldHJ5X2NvbmZpZygKICogICAgICAgICB0ZWxlbWV0cnkocmVzb3VyY2UoWydzZXJ2aWNlLm5hbWUnID0+ICdteS1hcHAnXSkpLAogKiAgICAgICAgIG5ldyBTeXN0ZW1DbG9jaygpLAogKiAgICAgICAgIHBvc3RncmVzcWxfdGVsZW1ldHJ5X29wdGlvbnMoCiAqICAgICAgICAgICAgIHRyYWNlUXVlcmllczogdHJ1ZSwKICogICAgICAgICAgICAgdHJhbnNhY3Rpb25TcGFuczogVHJhbnNhY3Rpb25TcGFuTW9kZTo6R1JPVVBFRCwKICogICAgICAgICAgICAgY29sbGVjdE1ldHJpY3M6IHRydWUsCiAqICAgICAgICAgICAgIGxvZ1F1ZXJpZXM6IHRydWUsCiAqICAgICAgICAgICAgIG1heFF1ZXJ5TGVuZ3RoOiA1MDAsCiAqICAgICAgICAgKSwKICogICAgICksCiAqICk7CiAqCiAqIC8vIEFsbCBvcGVyYXRpb25zIG5vdyB0cmFjZWQKICogJHRyYWNlYWJsZUNsaWVudC0+dHJhbnNhY3Rpb24oZnVuY3Rpb24gKENsaWVudCAkY2xpZW50KSB7CiAqICAgICAkdXNlciA9ICRjbGllbnQtPmZldGNoU2luZ2xlKCdTRUxFQ1QgKiBGUk9NIHVzZXJzIFdIRVJFIGlkID0gJDEnLCBbMTIzXSk7CiAqICAgICAkY2xpZW50LT5leGVjdXRlKCdVUERBVEUgdXNlcnMgU0VUIGxhc3RfbG9naW4gPSBOT1coKSBXSEVSRSBpZCA9ICQxJywgWzEyM10pOwogKiB9KTsKICov"},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":299,"slug":"constructor-mapper","name":"constructor_mapper","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ConstructorMapper","namespace":"Flow\\PostgreSql\\Client\\RowMapper","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICRjbGFzcwogKgogKiBAcmV0dXJuIENvbnN0cnVjdG9yTWFwcGVyPFQ+CiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":314,"slug":"type-mapper","name":"type_mapper","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"type","type":[{"name":"Type","namespace":"Flow\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"next","type":[{"name":"RowMapper","namespace":"Flow\\PostgreSql\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TypeMapper","namespace":"Flow\\PostgreSql\\Client\\RowMapper","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEB0ZW1wbGF0ZSBUVHlwZQogKiBAdGVtcGxhdGUgVE91dAogKgogKiBAcGFyYW0gRmxvd1R5cGU8VFR5cGU+ICR0eXBlCiAqIEBwYXJhbSBudWxsfFJvd01hcHBlcjxUT3V0PiAkbmV4dAogKgogKiBAcmV0dXJuICgkbmV4dCBpcyBudWxsID8gVHlwZU1hcHBlcjxUVHlwZSwgVFR5cGU+IDogVHlwZU1hcHBlcjxUVHlwZSwgVE91dD4pCiAqLw=="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":342,"slug":"static-factory-mapper","name":"static_factory_mapper","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"class","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"method","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"StaticFactoryMapper","namespace":"Flow\\PostgreSql\\Client\\RowMapper","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJvdyBtYXBwZXIgYmFja2VkIGJ5IGEgcHVibGljIHN0YXRpYyBmYWN0b3J5IG1ldGhvZC4KICoKICogVGhlIGZhY3RvcnkgbWV0aG9kIG11c3QgYWNjZXB0IGEgc2luZ2xlIGFycmF5PHN0cmluZywgbWl4ZWQ+ICRyb3cgYW5kIHJldHVybgogKiBhbiBpbnN0YW5jZSBvZiB0aGUgdGFyZ2V0IGNsYXNzLiBJZiB5b3VyIGZhY3RvcnkgbmVlZHMgYWNjZXNzIHRvIHRoZSBtYXBwaW5nCiAqIENvbnRleHQgKHNxbC9wYXJhbWV0ZXJzL2NsaWVudC9jYXRhbG9nL3VzZXItZGF0YSksIGltcGxlbWVudCBSb3dNYXBwZXIgZGlyZWN0bHkuCiAqCiAqIEB0ZW1wbGF0ZSBUIG9mIG9iamVjdAogKgogKiBAcGFyYW0gY2xhc3Mtc3RyaW5nPFQ+ICRjbGFzcwogKiBAcGFyYW0gbm9uLWVtcHR5LXN0cmluZyAkbWV0aG9kCiAqCiAqIEByZXR1cm4gU3RhdGljRmFjdG9yeU1hcHBlcjxUPgogKi8="},{"repository_path":"src\/lib\/postgresql\/src\/Flow\/PostgreSql\/DSL\/client.php","start_line_in_file":371,"slug":"typed","name":"typed","namespace":"Flow\\PostgreSql\\DSL","parameters":[{"name":"value","type":[{"name":"mixed","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":false,"is_nullable":true,"is_variadic":false,"default_value":null},{"name":"targetType","type":[{"name":"ValueType","namespace":"Flow\\PostgreSql\\Client\\Types","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TypedValue","namespace":"Flow\\PostgreSql\\Client","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PG_QUERY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIFdyYXAgYSB2YWx1ZSB3aXRoIGV4cGxpY2l0IFBvc3RncmVTUUwgdHlwZSBpbmZvcm1hdGlvbiBmb3IgcGFyYW1ldGVyIGJpbmRpbmcuCiAqCiAqIFVzZSB3aGVuIGF1dG8tZGV0ZWN0aW9uIGlzbid0IHN1ZmZpY2llbnQgb3Igd2hlbiB5b3UgbmVlZCB0byBzcGVjaWZ5CiAqIHRoZSBleGFjdCBQb3N0Z3JlU1FMIHR5cGUgKHNpbmNlIG9uZSBQSFAgdHlwZSBjYW4gbWFwIHRvIG11bHRpcGxlIFBvc3RncmVTUUwgdHlwZXMpOgogKiAtIGludCBjb3VsZCBiZSBJTlQyLCBJTlQ0LCBvciBJTlQ4CiAqIC0gc3RyaW5nIGNvdWxkIGJlIFRFWFQsIFZBUkNIQVIsIG9yIENIQVIKICogLSBhcnJheSBtdXN0IGFsd2F5cyB1c2UgdHlwZWQoKSBzaW5jZSBhdXRvLWRldGVjdGlvbiBjYW5ub3QgZGV0ZXJtaW5lIGVsZW1lbnQgdHlwZQogKiAtIERhdGVUaW1lSW50ZXJmYWNlIGNvdWxkIGJlIFRJTUVTVEFNUCBvciBUSU1FU1RBTVBUWgogKiAtIEpzb24gY291bGQgYmUgSlNPTiBvciBKU09OQgogKgogKiBAcGFyYW0gbWl4ZWQgJHZhbHVlIFRoZSB2YWx1ZSB0byBiaW5kCiAqIEBwYXJhbSBWYWx1ZVR5cGUgJHRhcmdldFR5cGUgVGhlIFBvc3RncmVTUUwgdHlwZSB0byBjb252ZXJ0IHRoZSB2YWx1ZSB0bwogKgogKiBAZXhhbXBsZQogKiAkY2xpZW50LT5mZXRjaCgKICogICAgICdTRUxFQ1QgKiBGUk9NIHVzZXJzIFdIRVJFIGlkID0gJDEgQU5EIHRhZ3MgPSAkMicsCiAqICAgICBbCiAqICAgICAgICAgdHlwZWQoJzU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCcsIFZhbHVlVHlwZTo6VVVJRCksCiAqICAgICAgICAgdHlwZWQoWyd0YWcxJywgJ3RhZzInXSwgVmFsdWVUeXBlOjpURVhUX0FSUkFZKSwKICogICAgIF0KICogKTsKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":126,"slug":"trace-id","name":"trace_id","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"hex","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"TraceId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlSWQuCiAqCiAqIElmIGEgaGV4IHN0cmluZyBpcyBwcm92aWRlZCwgY3JlYXRlcyBhIFRyYWNlSWQgZnJvbSBpdC4KICogT3RoZXJ3aXNlLCBnZW5lcmF0ZXMgYSBuZXcgcmFuZG9tIFRyYWNlSWQuCiAqCiAqIEBwYXJhbSBudWxsfHN0cmluZyAkaGV4IE9wdGlvbmFsIDMyLWNoYXJhY3RlciBoZXhhZGVjaW1hbCBzdHJpbmcKICoKICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBoZXggc3RyaW5nIGlzIGludmFsaWQKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":146,"slug":"span-id","name":"span_id","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"hex","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SpanId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5JZC4KICoKICogSWYgYSBoZXggc3RyaW5nIGlzIHByb3ZpZGVkLCBjcmVhdGVzIGEgU3BhbklkIGZyb20gaXQuCiAqIE90aGVyd2lzZSwgZ2VuZXJhdGVzIGEgbmV3IHJhbmRvbSBTcGFuSWQuCiAqCiAqIEBwYXJhbSBudWxsfHN0cmluZyAkaGV4IE9wdGlvbmFsIDE2LWNoYXJhY3RlciBoZXhhZGVjaW1hbCBzdHJpbmcKICoKICogQHRocm93cyBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBoZXggc3RyaW5nIGlzIGludmFsaWQKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":161,"slug":"baggage","name":"baggage","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"entries","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Baggage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhZ2dhZ2UuCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJGVudHJpZXMgSW5pdGlhbCBrZXktdmFsdWUgZW50cmllcwogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":175,"slug":"context","name":"context","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"baggage","type":[{"name":"Baggage","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Context","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJvb3QgQ29udGV4dCAobm8gYWN0aXZlIHNwYW4pLgogKgogKiBBIHNwYW4gY3JlYXRlZCBpbiB0aGlzIGNvbnRleHQgYmVjb21lcyBhIG5ldyB0cmFjZSByb290LiBBdHRhY2ggYW4gYWN0aXZlIHNwYW4gd2l0aAogKiBDb250ZXh0Ojp3aXRoQWN0aXZlU3BhbigpIHRvIG1ha2Ugc3Vic2VxdWVudCBzcGFucyBpdHMgY2hpbGRyZW4uCiAqCiAqIEBwYXJhbSBudWxsfEJhZ2dhZ2UgJGJhZ2dhZ2UgT3B0aW9uYWwgQmFnZ2FnZSB0byB1c2UKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":189,"slug":"memory-context-storage","name":"memory_context_storage","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"context","type":[{"name":"Context","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MemoryContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeUNvbnRleHRTdG9yYWdlLgogKgogKiBJbi1tZW1vcnkgY29udGV4dCBzdG9yYWdlIGZvciBzdG9yaW5nIGFuZCByZXRyaWV2aW5nIHRoZSBjdXJyZW50IGNvbnRleHQuCiAqIEEgc2luZ2xlIGluc3RhbmNlIHNob3VsZCBiZSBzaGFyZWQgYWNyb3NzIGFsbCBwcm92aWRlcnMgd2l0aGluIGEgcmVxdWVzdCBsaWZlY3ljbGUuCiAqCiAqIEBwYXJhbSBudWxsfENvbnRleHQgJGNvbnRleHQgT3B0aW9uYWwgaW5pdGlhbCBjb250ZXh0CiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":200,"slug":"resource","name":"resource","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"Resource","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFJlc291cmNlLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBhcnJheTxhcnJheS1rZXksIG1peGVkPnxib29sfFxEYXRlVGltZUludGVyZmFjZXxmbG9hdHxpbnR8c3RyaW5nfFxUaHJvd2FibGU+fEF0dHJpYnV0ZXMgJGF0dHJpYnV0ZXMgUmVzb3VyY2UgYXR0cmlidXRlcwogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":213,"slug":"span-context","name":"span_context","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"traceId","type":[{"name":"TraceId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"spanId","type":[{"name":"SpanId","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"parentSpanId","type":[{"name":"SpanId","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SpanContext","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5Db250ZXh0LgogKgogKiBAcGFyYW0gVHJhY2VJZCAkdHJhY2VJZCBUaGUgdHJhY2UgSUQKICogQHBhcmFtIFNwYW5JZCAkc3BhbklkIFRoZSBzcGFuIElECiAqIEBwYXJhbSBudWxsfFNwYW5JZCAkcGFyZW50U3BhbklkIE9wdGlvbmFsIHBhcmVudCBzcGFuIElECiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":226,"slug":"span-event","name":"span_event","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"timestamp","type":[{"name":"DateTimeImmutable","namespace":"","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"GenericEvent","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5FdmVudCAoR2VuZXJpY0V2ZW50KSB3aXRoIGFuIGV4cGxpY2l0IHRpbWVzdGFtcC4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBFdmVudCBuYW1lCiAqIEBwYXJhbSBcRGF0ZVRpbWVJbW11dGFibGUgJHRpbWVzdGFtcCBFdmVudCB0aW1lc3RhbXAKICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58Ym9vbHxcRGF0ZVRpbWVJbnRlcmZhY2V8ZmxvYXR8aW50fHN0cmluZ3xcVGhyb3dhYmxlPnxBdHRyaWJ1dGVzICRhdHRyaWJ1dGVzIEV2ZW50IGF0dHJpYnV0ZXMKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":238,"slug":"span-link","name":"span_link","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"context","type":[{"name":"SpanContext","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"SpanLink","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNwYW5MaW5rLgogKgogKiBAcGFyYW0gU3BhbkNvbnRleHQgJGNvbnRleHQgVGhlIGxpbmtlZCBzcGFuIGNvbnRleHQKICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58Ym9vbHxcRGF0ZVRpbWVJbnRlcmZhY2V8ZmxvYXR8aW50fHN0cmluZ3xcVGhyb3dhYmxlPnxBdHRyaWJ1dGVzICRhdHRyaWJ1dGVzIExpbmsgYXR0cmlidXRlcwogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":254,"slug":"span-limits","name":"span_limits","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributeCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"eventCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"linkCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributePerEventCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributePerLinkCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributeValueLengthLimit","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SpanLimits","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBTcGFuTGltaXRzIGNvbmZpZ3VyYXRpb24uCiAqCiAqIEBwYXJhbSBpbnQgJGF0dHJpYnV0ZUNvdW50TGltaXQgTWF4aW11bSBudW1iZXIgb2YgYXR0cmlidXRlcyBwZXIgc3BhbgogKiBAcGFyYW0gaW50ICRldmVudENvdW50TGltaXQgTWF4aW11bSBudW1iZXIgb2YgZXZlbnRzIHBlciBzcGFuCiAqIEBwYXJhbSBpbnQgJGxpbmtDb3VudExpbWl0IE1heGltdW0gbnVtYmVyIG9mIGxpbmtzIHBlciBzcGFuCiAqIEBwYXJhbSBpbnQgJGF0dHJpYnV0ZVBlckV2ZW50Q291bnRMaW1pdCBNYXhpbXVtIG51bWJlciBvZiBhdHRyaWJ1dGVzIHBlciBldmVudAogKiBAcGFyYW0gaW50ICRhdHRyaWJ1dGVQZXJMaW5rQ291bnRMaW1pdCBNYXhpbXVtIG51bWJlciBvZiBhdHRyaWJ1dGVzIHBlciBsaW5rCiAqIEBwYXJhbSBudWxsfGludCAkYXR0cmlidXRlVmFsdWVMZW5ndGhMaW1pdCBNYXhpbXVtIGxlbmd0aCBmb3Igc3RyaW5nIGF0dHJpYnV0ZSB2YWx1ZXMgKG51bGwgPSB1bmxpbWl0ZWQpCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":279,"slug":"log-record-limits","name":"log_record_limits","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributeCountLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"128"},{"name":"attributeValueLengthLimit","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"LogRecordLimits","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBMb2dSZWNvcmRMaW1pdHMgY29uZmlndXJhdGlvbi4KICoKICogQHBhcmFtIGludCAkYXR0cmlidXRlQ291bnRMaW1pdCBNYXhpbXVtIG51bWJlciBvZiBhdHRyaWJ1dGVzIHBlciBsb2cgcmVjb3JkCiAqIEBwYXJhbSBudWxsfGludCAkYXR0cmlidXRlVmFsdWVMZW5ndGhMaW1pdCBNYXhpbXVtIGxlbmd0aCBmb3Igc3RyaW5nIGF0dHJpYnV0ZSB2YWx1ZXMgKG51bGwgPSB1bmxpbWl0ZWQpCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":290,"slug":"metric-limits","name":"metric_limits","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"cardinalityLimit","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"2000"}],"return_type":[{"name":"MetricLimits","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBNZXRyaWNMaW1pdHMgY29uZmlndXJhdGlvbi4KICoKICogQHBhcmFtIGludCAkY2FyZGluYWxpdHlMaW1pdCBNYXhpbXVtIG51bWJlciBvZiB1bmlxdWUgYXR0cmlidXRlIGNvbWJpbmF0aW9ucyBwZXIgaW5zdHJ1bWVudAogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":301,"slug":"void-span-processor","name":"void_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidSpanProcessor","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRTcGFuUHJvY2Vzc29yLgogKgogKiBOby1vcCBzcGFuIHByb2Nlc3NvciB0aGF0IGRpc2NhcmRzIGFsbCBkYXRhLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":312,"slug":"void-metric-processor","name":"void_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidMetricProcessor","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRNZXRyaWNQcm9jZXNzb3IuCiAqCiAqIE5vLW9wIG1ldHJpYyBwcm9jZXNzb3IgdGhhdCBkaXNjYXJkcyBhbGwgZGF0YS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":323,"slug":"void-log-processor","name":"void_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidLogProcessor","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRMb2dQcm9jZXNzb3IuCiAqCiAqIE5vLW9wIGxvZyBwcm9jZXNzb3IgdGhhdCBkaXNjYXJkcyBhbGwgZGF0YS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":334,"slug":"void-exporter","name":"void_exporter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"VoidExporter","namespace":"Flow\\Telemetry\\Provider\\Void","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZvaWRFeHBvcnRlci4KICoKICogTm8tb3AgdW5pZmllZCBleHBvcnRlciB0aGF0IGRpc2NhcmRzIGxvZ3MsIG1ldHJpY3MsIGFuZCBzcGFucy4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":348,"slug":"memory-exporter","name":"memory_exporter","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"maxEntriesPerSignal","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"MemoryExporter","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeUV4cG9ydGVyLgogKgogKiBVbmlmaWVkIGV4cG9ydGVyIHRoYXQgc3RvcmVzIGxvZ3MsIG1ldHJpY3MsIGFuZCBzcGFucyBpbiBtZW1vcnkgZm9yIGRpcmVjdCBhY2Nlc3MuCiAqIFVzZWZ1bCBmb3IgdGVzdGluZyBhbmQgaW5zcGVjdGlvbiB3aXRob3V0IHNlcmlhbGl6YXRpb24uCiAqCiAqIEBwYXJhbSBudWxsfGludCAkbWF4RW50cmllc1BlclNpZ25hbCBtYXhpbXVtIGVudHJpZXMgcmV0YWluZWQgcGVyIHNpZ25hbCB0eXBlOyBudWxsIGtlZXBzIGV2ZXJ5dGhpbmcKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":360,"slug":"memory-span-processor","name":"memory_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MemorySpanProcessor","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeVNwYW5Qcm9jZXNzb3IuCiAqCiAqIEBwYXJhbSBFeHBvcnRlciAkZXhwb3J0ZXIgVGhlIGV4cG9ydGVyIHRvIHNlbmQgc3BhbnMgdG8KICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBleHBvcnRlcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":374,"slug":"memory-metric-processor","name":"memory_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MemoryMetricProcessor","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeU1ldHJpY1Byb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBtZXRyaWNzIHRvCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":388,"slug":"memory-log-processor","name":"memory_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MemoryLogProcessor","namespace":"Flow\\Telemetry\\Provider\\Memory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1lbW9yeUxvZ1Byb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBsb2dzIHRvCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":406,"slug":"tracer-provider","name":"tracer_provider","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"SpanProcessor","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sampler","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."},{"name":"limits","type":[{"name":"SpanLimits","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\SpanLimits::..."},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"TracerProvider","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlclByb3ZpZGVyLgogKgogKiBAcGFyYW0gU3BhblByb2Nlc3NvciAkcHJvY2Vzc29yIFRoZSBwcm9jZXNzb3IgZm9yIHNwYW5zCiAqIEBwYXJhbSBDbG9ja0ludGVyZmFjZSAkY2xvY2sgVGhlIGNsb2NrIGZvciB0aW1lc3RhbXBzCiAqIEBwYXJhbSBDb250ZXh0U3RvcmFnZSAkY29udGV4dFN0b3JhZ2UgU3RvcmFnZSBmb3IgY29udGV4dCBwcm9wYWdhdGlvbgogKiBAcGFyYW0gU2FtcGxlciAkc2FtcGxlciBTYW1wbGluZyBzdHJhdGVneSBmb3Igc3BhbnMKICogQHBhcmFtIFNwYW5MaW1pdHMgJGxpbWl0cyBMaW1pdHMgZm9yIHNwYW4gYXR0cmlidXRlcywgZXZlbnRzLCBhbmQgbGlua3MKICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIHJ1bnRpbWUgVGhyb3dhYmxlcyByYWlzZWQgYnkgdGhlIHByb2Nlc3NvcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":427,"slug":"logger-provider","name":"logger_provider","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"LogProcessor","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"limits","type":[{"name":"LogRecordLimits","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Logger\\LogRecordLimits::..."},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"LoggerProvider","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExvZ2dlclByb3ZpZGVyLgogKgogKiBAcGFyYW0gTG9nUHJvY2Vzc29yICRwcm9jZXNzb3IgVGhlIHByb2Nlc3NvciBmb3IgbG9ncwogKiBAcGFyYW0gQ2xvY2tJbnRlcmZhY2UgJGNsb2NrIFRoZSBjbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gQ29udGV4dFN0b3JhZ2UgJGNvbnRleHRTdG9yYWdlIFN0b3JhZ2UgZm9yIHNwYW4gY29ycmVsYXRpb24KICogQHBhcmFtIExvZ1JlY29yZExpbWl0cyAkbGltaXRzIExpbWl0cyBmb3IgbG9nIHJlY29yZCBhdHRyaWJ1dGVzCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBydW50aW1lIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBwcm9jZXNzb3IKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":448,"slug":"meter-provider","name":"meter_provider","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"MetricProcessor","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"temporality","type":[{"name":"AggregationTemporality","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\AggregationTemporality::..."},{"name":"exemplarFilter","type":[{"name":"ExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\Exemplar\\TraceBasedExemplarFilter::..."},{"name":"limits","type":[{"name":"MetricLimits","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\MetricLimits::..."},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"MeterProvider","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1ldGVyUHJvdmlkZXIuCiAqCiAqIEBwYXJhbSBNZXRyaWNQcm9jZXNzb3IgJHByb2Nlc3NvciBUaGUgcHJvY2Vzc29yIGZvciBtZXRyaWNzCiAqIEBwYXJhbSBDbG9ja0ludGVyZmFjZSAkY2xvY2sgVGhlIGNsb2NrIGZvciB0aW1lc3RhbXBzCiAqIEBwYXJhbSBBZ2dyZWdhdGlvblRlbXBvcmFsaXR5ICR0ZW1wb3JhbGl0eSBBZ2dyZWdhdGlvbiB0ZW1wb3JhbGl0eSBmb3IgbWV0cmljcwogKiBAcGFyYW0gRXhlbXBsYXJGaWx0ZXIgJGV4ZW1wbGFyRmlsdGVyIEZpbHRlciBmb3IgZXhlbXBsYXIgc2FtcGxpbmcgKGRlZmF1bHQ6IFRyYWNlQmFzZWRFeGVtcGxhckZpbHRlcikKICogQHBhcmFtIE1ldHJpY0xpbWl0cyAkbGltaXRzIENhcmRpbmFsaXR5IGxpbWl0cyBmb3IgbWV0cmljIGluc3RydW1lbnRzCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBydW50aW1lIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBwcm9jZXNzb3IKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":471,"slug":"telemetry","name":"telemetry","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"resource","type":[{"name":"Resource","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"tracerProvider","type":[{"name":"TracerProvider","namespace":"Flow\\Telemetry\\Tracer","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"meterProvider","type":[{"name":"MeterProvider","namespace":"Flow\\Telemetry\\Meter","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"loggerProvider","type":[{"name":"LoggerProvider","namespace":"Flow\\Telemetry\\Logger","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG5ldyBUZWxlbWV0cnkgaW5zdGFuY2Ugd2l0aCB0aGUgZ2l2ZW4gcHJvdmlkZXJzLgogKgogKiBJZiBwcm92aWRlcnMgYXJlIG5vdCBzcGVjaWZpZWQsIHZvaWQgcHJvdmlkZXJzIChuby1vcCkgYXJlIHVzZWQuCiAqCiAqIEBwYXJhbSBcRmxvd1xUZWxlbWV0cnlcUmVzb3VyY2UgJHJlc291cmNlIFRoZSByZXNvdXJjZSBkZXNjcmliaW5nIHRoZSBlbnRpdHkgcHJvZHVjaW5nIHRlbGVtZXRyeQogKiBAcGFyYW0gbnVsbHxUcmFjZXJQcm92aWRlciAkdHJhY2VyUHJvdmlkZXIgVGhlIHRyYWNlciBwcm92aWRlciAobnVsbCBmb3Igdm9pZC9kaXNhYmxlZCkKICogQHBhcmFtIG51bGx8TWV0ZXJQcm92aWRlciAkbWV0ZXJQcm92aWRlciBUaGUgbWV0ZXIgcHJvdmlkZXIgKG51bGwgZm9yIHZvaWQvZGlzYWJsZWQpCiAqIEBwYXJhbSBudWxsfExvZ2dlclByb3ZpZGVyICRsb2dnZXJQcm92aWRlciBUaGUgbG9nZ2VyIHByb3ZpZGVyIChudWxsIGZvciB2b2lkL2Rpc2FibGVkKQogKiBAcGFyYW0gRXJyb3JIYW5kbGVyICRlcnJvckhhbmRsZXIgSGFuZGxlciBwcm9wYWdhdGVkIHRvIGRlZmF1bHQgdm9pZCBwcm92aWRlcnMgd2hlbiBleHBsaWNpdCBvbmVzIGFyZSBub3Qgc3VwcGxpZWQKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":507,"slug":"instrumentation-scope","name":"instrumentation_scope","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"name","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"version","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'unknown'"},{"name":"schemaUrl","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Attributes::..."}],"return_type":[{"name":"InstrumentationScope","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBJbnN0cnVtZW50YXRpb25TY29wZS4KICoKICogQHBhcmFtIHN0cmluZyAkbmFtZSBUaGUgaW5zdHJ1bWVudGF0aW9uIHNjb3BlIG5hbWUKICogQHBhcmFtIHN0cmluZyAkdmVyc2lvbiBUaGUgaW5zdHJ1bWVudGF0aW9uIHNjb3BlIHZlcnNpb24KICogQHBhcmFtIG51bGx8c3RyaW5nICRzY2hlbWFVcmwgT3B0aW9uYWwgc2NoZW1hIFVSTAogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":524,"slug":"batching-span-processor","name":"batching_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"batchSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"512"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"BatchingSpanProcessor","namespace":"Flow\\Telemetry\\Tracer\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhdGNoaW5nU3BhblByb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBzcGFucyB0bwogKiBAcGFyYW0gaW50ICRiYXRjaFNpemUgTnVtYmVyIG9mIHNwYW5zIHRvIGNvbGxlY3QgYmVmb3JlIGV4cG9ydGluZyAoZGVmYXVsdCA1MTIpCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":539,"slug":"pass-through-span-processor","name":"pass_through_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"PassThroughSpanProcessor","namespace":"Flow\\Telemetry\\Tracer\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhc3NUaHJvdWdoU3BhblByb2Nlc3Nvci4KICoKICogQHBhcmFtIEV4cG9ydGVyICRleHBvcnRlciBUaGUgZXhwb3J0ZXIgdG8gc2VuZCBzcGFucyB0bwogKiBAcGFyYW0gRXJyb3JIYW5kbGVyICRlcnJvckhhbmRsZXIgSGFuZGxlciBmb3IgVGhyb3dhYmxlcyByYWlzZWQgYnkgdGhlIGV4cG9ydGVyCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":554,"slug":"batching-metric-processor","name":"batching_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"batchSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"512"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"BatchingMetricProcessor","namespace":"Flow\\Telemetry\\Meter\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhdGNoaW5nTWV0cmljUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIG1ldHJpY3MgdG8KICogQHBhcmFtIGludCAkYmF0Y2hTaXplIE51bWJlciBvZiBtZXRyaWNzIHRvIGNvbGxlY3QgYmVmb3JlIGV4cG9ydGluZyAoZGVmYXVsdCA1MTIpCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":569,"slug":"pass-through-metric-processor","name":"pass_through_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"PassThroughMetricProcessor","namespace":"Flow\\Telemetry\\Meter\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhc3NUaHJvdWdoTWV0cmljUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIG1ldHJpY3MgdG8KICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBleHBvcnRlcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":584,"slug":"batching-log-processor","name":"batching_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"batchSize","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"512"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"BatchingLogProcessor","namespace":"Flow\\Telemetry\\Logger\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEJhdGNoaW5nTG9nUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIGxvZ3MgdG8KICogQHBhcmFtIGludCAkYmF0Y2hTaXplIE51bWJlciBvZiBsb2dzIHRvIGNvbGxlY3QgYmVmb3JlIGV4cG9ydGluZyAoZGVmYXVsdCA1MTIpCiAqIEBwYXJhbSBFcnJvckhhbmRsZXIgJGVycm9ySGFuZGxlciBIYW5kbGVyIGZvciBUaHJvd2FibGVzIHJhaXNlZCBieSB0aGUgZXhwb3J0ZXIKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":599,"slug":"pass-through-log-processor","name":"pass_through_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"exporter","type":[{"name":"Exporter","namespace":"Flow\\Telemetry\\Exporter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"PassThroughLogProcessor","namespace":"Flow\\Telemetry\\Logger\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhc3NUaHJvdWdoTG9nUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gRXhwb3J0ZXIgJGV4cG9ydGVyIFRoZSBleHBvcnRlciB0byBzZW5kIGxvZ3MgdG8KICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JIYW5kbGVyIEhhbmRsZXIgZm9yIFRocm93YWJsZXMgcmFpc2VkIGJ5IHRoZSBleHBvcnRlcgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":614,"slug":"pipeline-log-processor","name":"pipeline_log_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"middleware","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sink","type":[{"name":"LogSink","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PipelineLogProcessor","namespace":"Flow\\Telemetry\\Logger\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBpcGVsaW5lTG9nUHJvY2Vzc29yOiBydW4gZWFjaCBsb2cgZW50cnkgdGhyb3VnaCBhbiBvcmRlcmVkIGNoYWluIG9mCiAqIG1pZGRsZXdhcmUsIHRoZW4gZm9yd2FyZCB0aGUgc3Vydml2b3JzIHRvIGEgc2luZ2xlIHNpbmsuCiAqCiAqIEBwYXJhbSBsaXN0PExvZ01pZGRsZXdhcmU+ICRtaWRkbGV3YXJlIHJ1biBpbiBvcmRlcjsgdGhlIGZpcnN0IHRvIGRyb3AgYW4gZW50cnkgc2hvcnQtY2lyY3VpdHMgdGhlIHJlc3QKICogQHBhcmFtIExvZ1NpbmsgJHNpbmsgdGhlIHRlcm1pbmFsIHByb2Nlc3NvciB0aGF0IGV4cG9ydHMgc3Vydml2aW5nIGVudHJpZXMKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":626,"slug":"enriching-log-middleware","name":"enriching_log_middleware","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributes","type":[{"name":"Attributes","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false},{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"EnrichingLogMiddleware","namespace":"Flow\\Telemetry\\Logger\\Middleware","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFbnJpY2hpbmdMb2dNaWRkbGV3YXJlIHRoYXQgbWVyZ2VzIGRlZmF1bHQgYXR0cmlidXRlcyBpbnRvIGV2ZXJ5IGxvZwogKiBlbnRyeS4gQXR0cmlidXRlcyBzZXQgYXQgdGhlIGNhbGwgc2l0ZSB3aW4gb3ZlciB0aGVzZSBkZWZhdWx0cy4KICoKICogQHBhcmFtIGFycmF5PHN0cmluZywgYXJyYXk8YXJyYXkta2V5LCBtaXhlZD58Ym9vbHxcRGF0ZVRpbWVJbnRlcmZhY2V8ZmxvYXR8aW50fHN0cmluZ3xcVGhyb3dhYmxlPnxBdHRyaWJ1dGVzICRhdHRyaWJ1dGVzCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":637,"slug":"attribute-filtering-log-middleware","name":"attribute_filtering_log_middleware","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AttributeFilteringLogMiddleware","namespace":"Flow\\Telemetry\\Logger\\Middleware","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXJpbmdMb2dNaWRkbGV3YXJlIHRoYXQgZHJvcHMgbG9nIGVudHJpZXMgbWF0Y2hpbmcgdGhlIGZpbHRlci4KICoKICogQHBhcmFtIEF0dHJpYnV0ZUZpbHRlciAkZmlsdGVyIFRoZSBhdHRyaWJ1dGUgZmlsdGVyIHRvIGFwcGx5CiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":648,"slug":"severity-filtering-log-middleware","name":"severity_filtering_log_middleware","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"minimumSeverity","type":[{"name":"Severity","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Logger\\Severity::..."}],"return_type":[{"name":"SeverityFilteringLogMiddleware","namespace":"Flow\\Telemetry\\Logger\\Middleware","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNldmVyaXR5RmlsdGVyaW5nTG9nTWlkZGxld2FyZSB0aGF0IGRyb3BzIGxvZyBlbnRyaWVzIGJlbG93IGEgbWluaW11bSBzZXZlcml0eS4KICoKICogQHBhcmFtIFNldmVyaXR5ICRtaW5pbXVtU2V2ZXJpdHkgTWluaW11bSBzZXZlcml0eSBsZXZlbCAoZGVmYXVsdDogSU5GTykKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":662,"slug":"attribute-rule","name":"attribute_rule","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"path","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"mode","type":[{"name":"MatchMode","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"expected","type":[{"name":"DateTimeInterface","namespace":"","is_nullable":false,"is_variadic":false},{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false},{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"caseSensitive","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"AttributeRule","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHNpbmdsZSBhdHRyaWJ1dGUtbWF0Y2hpbmcgcnVsZSBmb3IgYW4gQXR0cmlidXRlRmlsdGVyLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nPnxzdHJpbmcgJHBhdGggYXR0cmlidXRlIHBhdGg6IGEgdG9wLWxldmVsIGtleSwgb3Igc2VnbWVudHMgZGVzY2VuZGluZyBpbnRvIG5lc3RlZCBhcnJheSB2YWx1ZXMKICogQHBhcmFtIE1hdGNoTW9kZSAkbW9kZSBjb21wYXJpc29uIGFwcGxpZWQgYmV0d2VlbiB0aGUgdmFsdWUgYXQgdGhlIHBhdGggYW5kIHRoZSBleHBlY3RlZCB2YWx1ZQogKiBAcGFyYW0gYm9vbHxEYXRlVGltZUludGVyZmFjZXxmbG9hdHxpbnR8c3RyaW5nICRleHBlY3RlZCBleHBlY3RlZCB2YWx1ZSAobXVzdCBiZSBhIHN0cmluZyBmb3IgdGhlIHBhdHRlcm4gbW9kZXMpCiAqIEBwYXJhbSBib29sICRjYXNlU2Vuc2l0aXZlIGFwcGxpZXMgdG8gdGhlIHN1YnN0cmluZyBtb2RlcyBvbmx5IChTVEFSVFNfV0lUSCwgRU5EU19XSVRILCBDT05UQUlOUykKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":675,"slug":"all","name":"all","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matchers","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"All","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgbWF0Y2hlcnMgc28gdGhhdCBldmVyeSBvbmUgbXVzdCBtYXRjaCAobG9naWNhbCBBTkQpLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":684,"slug":"any","name":"any","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matchers","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"Any","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENvbWJpbmUgbWF0Y2hlcnMgc28gdGhhdCBhdCBsZWFzdCBvbmUgbXVzdCBtYXRjaCAobG9naWNhbCBPUikuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":693,"slug":"not","name":"not","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matcher","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Not","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIE5lZ2F0ZSBhIG1hdGNoZXIgKGxvZ2ljYWwgTk9UKS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":712,"slug":"attribute-filter","name":"attribute_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"matcher","type":[{"name":"Matcher","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"exclude","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"sources","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[...]"},{"name":"cacheDir","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"cacheDirPermissions","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"448"}],"return_type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXIgZnJvbSBhIG1hdGNoZXIuCiAqCiAqIEBwYXJhbSBNYXRjaGVyICRtYXRjaGVyIHRoZSBtYXRjaGVyIHRvIGV2YWx1YXRlIGFnYWluc3QgYSBzaWduYWwncyBhdHRyaWJ1dGVzIChjb21wb3NlIHdpdGggYWxsKCksIGFueSgpLCBub3QoKSkKICogQHBhcmFtIGJvb2wgJGV4Y2x1ZGUgd2hlbiB0cnVlIChkZWZhdWx0KSBhIG1hdGNoIGRyb3BzIHRoZSBzaWduYWw7IHdoZW4gZmFsc2Ugb25seSBtYXRjaGluZyBzaWduYWxzIGFyZSBrZXB0CiAqIEBwYXJhbSBsaXN0PEF0dHJpYnV0ZVNvdXJjZT4gJHNvdXJjZXMgd2hpY2ggYXR0cmlidXRlIHNldHMgdG8gaW5zcGVjdCAoc2lnbmFsLCByZXNvdXJjZSBhbmQvb3Igc2NvcGUpOyB0aGUgbWF0Y2hlciBpcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9SLWNvbWJpbmVkIGFjcm9zcyB0aGVtLCBkZWZhdWx0aW5nIHRvIHRoZSBzaWduYWwncyBvd24gYXR0cmlidXRlcwogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJGNhY2hlRGlyIGRpcmVjdG9yeSBmb3IgdGhlIGdlbmVyYXRlZCBtYXRjaGVyIGZpbGUgKGRlZmF1bHRzIHRvIHRoZSBzeXN0ZW0gdGVtcCBkaXJlY3RvcnkpLiBJdCBpcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGByZXF1aXJlYGQsIHNvIGl0IE1VU1QgYmUgdHJ1c3RlZCAtIG5vdCB3cml0YWJsZSBieSB1bnRydXN0ZWQgdXNlcnMuIFByZWZlciBhbgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGxpY2F0aW9uLXByaXZhdGUgZGlyZWN0b3J5IG92ZXIgdGhlIHNoYXJlZCBzeXN0ZW0gdGVtcCBpbiBtdWx0aS10ZW5hbnQgZW52aXJvbm1lbnRzLgogKiBAcGFyYW0gaW50ICRjYWNoZURpclBlcm1pc3Npb25zIG1vZGUgYXBwbGllZCB3aGVuIHRoZSBjYWNoZSBkaXJlY3RvcnkgaXMgY3JlYXRlZCAob2N0YWwsIHN1YmplY3QgdG8gdW1hc2s7IGRlZmF1bHRzCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gMDcwMCAtIG93bmVyIG9ubHksIHNpbmNlIHRoZSBkaXJlY3RvcnkgaG9sZHMgYHJlcXVpcmVgZCBQSFApCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":729,"slug":"attribute-filtering-metric-processor","name":"attribute_filtering_metric_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"MetricProcessor","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AttributeFilteringMetricProcessor","namespace":"Flow\\Telemetry\\Meter\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXJpbmdNZXRyaWNQcm9jZXNzb3IuCiAqCiAqIEBwYXJhbSBNZXRyaWNQcm9jZXNzb3IgJHByb2Nlc3NvciBUaGUgcHJvY2Vzc29yIHRvIHdyYXAKICogQHBhcmFtIEF0dHJpYnV0ZUZpbHRlciAkZmlsdGVyIFRoZSBhdHRyaWJ1dGUgZmlsdGVyIHRvIGFwcGx5CiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":743,"slug":"attribute-filtering-span-processor","name":"attribute_filtering_span_processor","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"processor","type":[{"name":"SpanProcessor","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"AttributeFilteringSpanProcessor","namespace":"Flow\\Telemetry\\Tracer\\Processor","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVGaWx0ZXJpbmdTcGFuUHJvY2Vzc29yLgogKgogKiBAcGFyYW0gU3BhblByb2Nlc3NvciAkcHJvY2Vzc29yIFRoZSBwcm9jZXNzb3IgdG8gd3JhcAogKiBAcGFyYW0gQXR0cmlidXRlRmlsdGVyICRmaWx0ZXIgVGhlIGF0dHJpYnV0ZSBmaWx0ZXIgdG8gYXBwbHkKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":762,"slug":"console-exporter","name":"console_exporter","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"colors","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"maxLogBodyLength","type":[{"name":"int","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"100"},{"name":"logOptions","type":[{"name":"ConsoleLogOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Provider\\Console\\ConsoleLogOptions::..."},{"name":"metricOptions","type":[{"name":"ConsoleMetricOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Provider\\Console\\ConsoleMetricOptions::..."},{"name":"spanOptions","type":[{"name":"ConsoleSpanOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Provider\\Console\\ConsoleSpanOptions::..."}],"return_type":[{"name":"ConsoleExporter","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHVuaWZpZWQgQ29uc29sZUV4cG9ydGVyIGZvciBsb2dzLCBtZXRyaWNzLCBhbmQgc3BhbnMuCiAqCiAqIE91dHB1dHMgdGVsZW1ldHJ5IHRvIHRoZSBjb25zb2xlIHdpdGggQVNDSUkgdGFibGUgZm9ybWF0dGluZyBhbmQgb3B0aW9uYWwgQU5TSSBjb2xvcnMuCiAqCiAqIEBwYXJhbSBib29sICRjb2xvcnMgV2hldGhlciB0byB1c2UgQU5TSSBjb2xvcnMgKGRlZmF1bHQ6IHRydWUpCiAqIEBwYXJhbSBudWxsfGludCAkbWF4TG9nQm9keUxlbmd0aCBNYXhpbXVtIGxlbmd0aCBmb3IgbG9nIGJvZHkrYXR0cmlidXRlcyBjb2x1bW4gKG51bGwgPSBubyBsaW1pdCkKICogQHBhcmFtIENvbnNvbGVMb2dPcHRpb25zICRsb2dPcHRpb25zIERpc3BsYXkgb3B0aW9ucyBmb3IgbG9nIHJlY29yZHMKICogQHBhcmFtIENvbnNvbGVNZXRyaWNPcHRpb25zICRtZXRyaWNPcHRpb25zIERpc3BsYXkgb3B0aW9ucyBmb3IgbWV0cmljcwogKiBAcGFyYW0gQ29uc29sZVNwYW5PcHRpb25zICRzcGFuT3B0aW9ucyBEaXNwbGF5IG9wdGlvbnMgZm9yIHNwYW5zCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":776,"slug":"console-span-options","name":"console_span_options","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleSpanOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlU3Bhbk9wdGlvbnMgd2l0aCBhbGwgZGlzcGxheSBvcHRpb25zIGVuYWJsZWQgKGRlZmF1bHQgYmVoYXZpb3IpLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":785,"slug":"console-span-options-minimal","name":"console_span_options_minimal","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleSpanOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlU3Bhbk9wdGlvbnMgd2l0aCBtaW5pbWFsIGRpc3BsYXkgKGxlZ2FjeSBjb21wYWN0IGZvcm1hdCkuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":794,"slug":"console-log-options","name":"console_log_options","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleLogOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTG9nT3B0aW9ucyB3aXRoIGFsbCBkaXNwbGF5IG9wdGlvbnMgZW5hYmxlZCAoZGVmYXVsdCBiZWhhdmlvcikuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":803,"slug":"console-log-options-minimal","name":"console_log_options_minimal","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleLogOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTG9nT3B0aW9ucyB3aXRoIG1pbmltYWwgZGlzcGxheSAobGVnYWN5IGNvbXBhY3QgZm9ybWF0KS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":812,"slug":"console-metric-options","name":"console_metric_options","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleMetricOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTWV0cmljT3B0aW9ucyB3aXRoIGFsbCBkaXNwbGF5IG9wdGlvbnMgZW5hYmxlZCAoZGVmYXVsdCBiZWhhdmlvcikuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":821,"slug":"console-metric-options-minimal","name":"console_metric_options_minimal","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ConsoleMetricOptions","namespace":"Flow\\Telemetry\\Provider\\Console","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBDb25zb2xlTWV0cmljT3B0aW9ucyB3aXRoIG1pbmltYWwgZGlzcGxheSAobGVnYWN5IGNvbXBhY3QgZm9ybWF0KS4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":830,"slug":"always-on-exemplar-filter","name":"always_on_exemplar_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOnExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPbkV4ZW1wbGFyRmlsdGVyLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":839,"slug":"always-off-exemplar-filter","name":"always_off_exemplar_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOffExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPZmZFeGVtcGxhckZpbHRlci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":848,"slug":"trace-based-exemplar-filter","name":"trace_based_exemplar_filter","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"TraceBasedExemplarFilter","namespace":"Flow\\Telemetry\\Meter\\Exemplar","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlQmFzZWRFeGVtcGxhckZpbHRlci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":857,"slug":"always-on-sampler","name":"always_on_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOnSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPblNhbXBsZXIuIFJlY29yZHMgYW5kIHNhbXBsZXMgZXZlcnkgc3Bhbi4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":866,"slug":"always-off-sampler","name":"always_off_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"AlwaysOffSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBbHdheXNPZmZTYW1wbGVyLiBEcm9wcyBldmVyeSBzcGFuLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":877,"slug":"trace-id-ratio-based-sampler","name":"trace_id_ratio_based_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"ratio","type":[{"name":"float","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"TraceIdRatioBasedSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRyYWNlSWRSYXRpb0Jhc2VkU2FtcGxlci4gU2FtcGxlcyBhIGRldGVybWluaXN0aWMgZnJhY3Rpb24gb2YgdHJhY2VzLgogKgogKiBAcGFyYW0gZmxvYXQgJHJhdGlvIFNhbXBsaW5nIHByb2JhYmlsaXR5IGJldHdlZW4gMC4wIGFuZCAxLjAKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":889,"slug":"parent-based-sampler","name":"parent_based_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"root","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."}],"return_type":[{"name":"ParentBasedSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFBhcmVudEJhc2VkU2FtcGxlci4gSG9ub3JzIHRoZSBwYXJlbnQgc3BhbidzIHNhbXBsaW5nIGRlY2lzaW9uLCBmYWxsaW5nCiAqIGJhY2sgdG8gdGhlIHJvb3Qgc2FtcGxlciBmb3Igc3BhbnMgd2l0aG91dCBhIHBhcmVudC4KICoKICogQHBhcmFtIFNhbXBsZXIgJHJvb3QgU2FtcGxlciB1c2VkIGZvciByb290IHNwYW5zIChubyBwYXJlbnQpCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":905,"slug":"attribute-matching-sampler","name":"attribute_matching_sampler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"filter","type":[{"name":"AttributeFilter","namespace":"Flow\\Telemetry\\Filter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"delegate","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."}],"return_type":[{"name":"AttributeMatchingSampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBdHRyaWJ1dGVNYXRjaGluZ1NhbXBsZXIuIERyb3BzIHNwYW5zIHdob3NlIHN0YXJ0LXRpbWUgYXR0cmlidXRlcyBtYXRjaAogKiB0aGUgZmlsdGVyIChvciBrZWVwcyBPTkxZIG1hdGNoaW5nIHNwYW5zIHdoZW4gdGhlIGZpbHRlcidzIGV4Y2x1ZGUgaXMgZmFsc2UpLCBhbmQKICogZGVmZXJzIGFsbCBvdGhlciBzcGFucyB0byB0aGUgZGVsZWdhdGUgc2FtcGxlci4KICoKICogT25seSBhdHRyaWJ1dGVzIGF2YWlsYWJsZSBhdCBzcGFuIHN0YXJ0IGFyZSB2aXNpYmxlOyBhdHRyaWJ1dGVzIGFkZGVkIGxhdGVyIGFyZSBub3QuCiAqCiAqIEBwYXJhbSBBdHRyaWJ1dGVGaWx0ZXIgJGZpbHRlciBUaGUgYXR0cmlidXRlIGZpbHRlciBldmFsdWF0ZWQgYWdhaW5zdCB0aGUgc3BhbidzIHN0YXJ0IGF0dHJpYnV0ZXMKICogQHBhcmFtIFNhbXBsZXIgJGRlbGVnYXRlIFNhbXBsZXIgdGhhdCBkZWNpZGVzIHNwYW5zIHdoaWNoIGRvIG5vdCBtYXRjaCAoZGVmYXVsdDogQWx3YXlzT25TYW1wbGVyKQogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":919,"slug":"propagation-context","name":"propagation_context","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"spanContext","type":[{"name":"SpanContext","namespace":"Flow\\Telemetry\\Tracer","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"baggage","type":[{"name":"Baggage","namespace":"Flow\\Telemetry\\Context","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"PropagationContext","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"TYPE"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFByb3BhZ2F0aW9uQ29udGV4dC4KICoKICogQHBhcmFtIG51bGx8U3BhbkNvbnRleHQgJHNwYW5Db250ZXh0IE9wdGlvbmFsIHNwYW4gY29udGV4dAogKiBAcGFyYW0gbnVsbHxCYWdnYWdlICRiYWdnYWdlIE9wdGlvbmFsIGJhZ2dhZ2UKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":930,"slug":"array-carrier","name":"array_carrier","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"data","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ArrayCarrier","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBBcnJheUNhcnJpZXIuCiAqCiAqIEBwYXJhbSBhcnJheTxzdHJpbmcsIHN0cmluZz4gJGRhdGEgSW5pdGlhbCBjYXJyaWVyIGRhdGEKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":939,"slug":"superglobal-carrier","name":"superglobal_carrier","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"SuperglobalCarrier","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFN1cGVyZ2xvYmFsQ2Fycmllci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":948,"slug":"w3c-trace-context","name":"w3c_trace_context","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"W3CTraceContext","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFczQ1RyYWNlQ29udGV4dCBwcm9wYWdhdG9yLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":957,"slug":"w3c-baggage","name":"w3c_baggage","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"W3CBaggage","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFczQ0JhZ2dhZ2UgcHJvcGFnYXRvci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":968,"slug":"composite-propagator","name":"composite_propagator","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"propagators","type":[{"name":"Propagator","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"CompositePropagator","namespace":"Flow\\Telemetry\\Propagation","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENvbXBvc2l0ZVByb3BhZ2F0b3IuCiAqCiAqIEBwYXJhbSBQcm9wYWdhdG9yIC4uLiRwcm9wYWdhdG9ycyBUaGUgcHJvcGFnYXRvcnMgdG8gY29tYmluZQogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":979,"slug":"chain-detector","name":"chain_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"detectors","type":[{"name":"ResourceDetector","namespace":"Flow\\Telemetry\\Resource","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"ChainDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENoYWluRGV0ZWN0b3IuCiAqCiAqIEBwYXJhbSBSZXNvdXJjZURldGVjdG9yIC4uLiRkZXRlY3RvcnMgVGhlIGRldGVjdG9ycyB0byBjaGFpbgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":988,"slug":"os-detector","name":"os_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"OsDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPc0RldGVjdG9yLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":997,"slug":"host-detector","name":"host_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"HostDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEhvc3REZXRlY3Rvci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1006,"slug":"process-detector","name":"process_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ProcessDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFByb2Nlc3NEZXRlY3Rvci4KICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1015,"slug":"environment-detector","name":"environment_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"EnvironmentDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBFbnZpcm9ubWVudERldGVjdG9yLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1024,"slug":"composer-detector","name":"composer_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ComposerDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENvbXBvc2VyRGV0ZWN0b3IuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1036,"slug":"git-detector","name":"git_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"workingDirectory","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"gitBinary","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'git'"}],"return_type":[{"name":"GitDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEdpdERldGVjdG9yLgogKgogKiBAcGFyYW0gbnVsbHxzdHJpbmcgJHdvcmtpbmdEaXJlY3RvcnkgRGlyZWN0b3J5IHRvIHJ1biBnaXQgaW4gKGRlZmF1bHQ6IGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkpCiAqIEBwYXJhbSBzdHJpbmcgJGdpdEJpbmFyeSBQYXRoIHRvIHRoZSBnaXQgYmluYXJ5IChkZWZhdWx0OiAiZ2l0IiwgcmVzb2x2ZWQgZnJvbSAkUEFUSCkKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1047,"slug":"manual-detector","name":"manual_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"attributes","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ManualDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIE1hbnVhbERldGVjdG9yLgogKgogKiBAcGFyYW0gYXJyYXk8c3RyaW5nLCBhcnJheTxhcnJheS1rZXksIG1peGVkPnxib29sfFxEYXRlVGltZUludGVyZmFjZXxmbG9hdHxpbnR8c3RyaW5nfFxUaHJvd2FibGU+ICRhdHRyaWJ1dGVzIFJlc291cmNlIGF0dHJpYnV0ZXMKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1059,"slug":"caching-detector","name":"caching_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"detector","type":[{"name":"ResourceDetector","namespace":"Flow\\Telemetry\\Resource","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"cachePath","type":[{"name":"string","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"CachingDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIENhY2hpbmdEZXRlY3Rvci4KICoKICogQHBhcmFtIFJlc291cmNlRGV0ZWN0b3IgJGRldGVjdG9yIFRoZSBkZXRlY3RvciB0byB3cmFwCiAqIEBwYXJhbSBudWxsfHN0cmluZyAkY2FjaGVQYXRoIENhY2hlIGZpbGUgcGF0aCAoZGVmYXVsdDogc3lzX2dldF90ZW1wX2RpcigpL2Zsb3dfdGVsZW1ldHJ5X3Jlc291cmNlLmNhY2hlKQogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1070,"slug":"resource-detector","name":"resource_detector","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"detectors","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"}],"return_type":[{"name":"ChainDetector","namespace":"Flow\\Telemetry\\Resource\\Detector","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHJlc291cmNlIGRldGVjdG9yIGNoYWluLgogKgogKiBAcGFyYW0gYXJyYXk8UmVzb3VyY2VEZXRlY3Rvcj4gJGRldGVjdG9ycyBPcHRpb25hbCBjdXN0b20gZGV0ZWN0b3JzIChlbXB0eSA9IHVzZSBkZWZhdWx0cykKICov"},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1089,"slug":"error-log-handler","name":"error_log_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"messageType","type":[{"name":"ErrorLogMessageType","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogMessageType::..."},{"name":"expandNewlines","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"},{"name":"messagePrefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'[flow-telemetry]'"}],"return_type":[{"name":"ErrorLogHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSB0aGUgZGVmYXVsdCBFcnJvckxvZ0hhbmRsZXIuIFdyaXRlcyB2aWEgUEhQJ3MgZXJyb3JfbG9nKCkuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1102,"slug":"stream-error-handler","name":"stream_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"destination","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filePermissions","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"420"},{"name":"createDirectories","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"messagePrefix","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'[flow-telemetry]'"}],"return_type":[{"name":"StreamHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFN0cmVhbUhhbmRsZXIuIEFwcGVuZHMgZm9ybWF0dGVkIFRocm93YWJsZXMgKG9uZSBwZXIgbGluZSkgdG8gYSBmaWxlCiAqIHBhdGggb3IgcGhwOi8vIHN0cmVhbSB3cmFwcGVyLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1115,"slug":"syslog-error-handler","name":"syslog_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"ident","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'flow-telemetry'"},{"name":"facility","type":[{"name":"SyslogFacility","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogFacility::..."},{"name":"logOpts","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"1"},{"name":"severity","type":[{"name":"SyslogSeverity","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogSeverity::..."}],"return_type":[{"name":"SyslogHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFN5c2xvZ0hhbmRsZXIuIFdyaXRlcyB2aWEgb3BlbmxvZy9zeXNsb2cvY2xvc2Vsb2cuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1128,"slug":"udp-syslog-error-handler","name":"udp_syslog_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"port","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"514"},{"name":"ident","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'flow-telemetry'"},{"name":"facility","type":[{"name":"SyslogFacility","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogFacility::..."},{"name":"severity","type":[{"name":"SyslogSeverity","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\SyslogSeverity::..."}],"return_type":[{"name":"UdpSyslogHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFVkcFN5c2xvZ0hhbmRsZXIuIFNlbmRzIFJGQyA1NDI0LXN0eWxlIHN5c2xvZyBmcmFtZXMgb3ZlciBVRFAuCiAqLw=="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1142,"slug":"composite-error-handler","name":"composite_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[{"name":"handlers","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":true,"default_value":null}],"return_type":[{"name":"CompositeErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEZhbiBlcnJvcnMgb3V0IHRvIG11bHRpcGxlIGhhbmRsZXJzLgogKi8="},{"repository_path":"src\/lib\/telemetry\/src\/Flow\/Telemetry\/DSL\/functions.php","start_line_in_file":1151,"slug":"null-error-handler","name":"null_error_handler","namespace":"Flow\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"NullErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIERpc2NhcmQgZXZlcnkgZXJyb3IuIFVzZSBvbmx5IGluIHRlc3RzIG9yIGZvciBleHBsaWNpdCBzaWxlbmNlLgogKi8="},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":29,"slug":"azurite-url-factory","name":"azurite_url_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'localhost'"},{"name":"port","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'10000'"},{"name":"secure","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"false"}],"return_type":[{"name":"AzuriteURLFactory","namespace":"Flow\\Azure\\SDK\\BlobService\\URLFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":38,"slug":"azure-shared-key-authorization-factory","name":"azure_shared_key_authorization_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"account","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"key","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"SharedKeyFactory","namespace":"Flow\\Azure\\SDK\\AuthorizationFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":48,"slug":"azure-blob-service-config","name":"azure_blob_service_config","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"account","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"container","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"Configuration","namespace":"Flow\\Azure\\SDK\\BlobService","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":54,"slug":"azure-url-factory","name":"azure_url_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"host","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'blob.core.windows.net'"}],"return_type":[{"name":"AzureURLFactory","namespace":"Flow\\Azure\\SDK\\BlobService\\URLFactory","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":60,"slug":"azure-http-factory","name":"azure_http_factory","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"request_factory","type":[{"name":"RequestFactoryInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"stream_factory","type":[{"name":"StreamFactoryInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"HttpFactory","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/lib\/azure-sdk\/src\/Flow\/Azure\/SDK\/DSL\/functions.php","start_line_in_file":68,"slug":"azure-blob-service","name":"azure_blob_service","namespace":"Flow\\Azure\\SDK\\DSL","parameters":[{"name":"configuration","type":[{"name":"Configuration","namespace":"Flow\\Azure\\SDK\\BlobService","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"azure_authorization_factory","type":[{"name":"AuthorizationFactory","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"azure_http_factory","type":[{"name":"HttpFactory","namespace":"Flow\\Azure\\SDK","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"azure_url_factory","type":[{"name":"URLFactory","namespace":"Flow\\Azure\\SDK","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"logger","type":[{"name":"LoggerInterface","namespace":"Psr\\Log","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"BlobServiceInterface","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_SDK","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/filesystem\/azure\/src\/Flow\/Filesystem\/Bridge\/Azure\/DSL\/functions.php","start_line_in_file":16,"slug":"azure-filesystem-options","name":"azure_filesystem_options","namespace":"Flow\\Filesystem\\Bridge\\Azure\\DSL","parameters":[],"return_type":[{"name":"Options","namespace":"Flow\\Filesystem\\Bridge\\Azure","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/filesystem\/azure\/src\/Flow\/Filesystem\/Bridge\/Azure\/DSL\/functions.php","start_line_in_file":22,"slug":"azure-filesystem","name":"azure_filesystem","namespace":"Flow\\Filesystem\\Bridge\\Azure\\DSL","parameters":[{"name":"blob_service","type":[{"name":"BlobServiceInterface","namespace":"Flow\\Azure\\SDK","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Filesystem\\Bridge\\Azure","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Filesystem\\Bridge\\Azure\\Options::..."},{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'azure-blob'"}],"return_type":[{"name":"AzureBlobFilesystem","namespace":"Flow\\Filesystem\\Bridge\\Azure","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"AZURE_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/filesystem\/async-aws\/src\/Flow\/Filesystem\/Bridge\/AsyncAWS\/DSL\/functions.php","start_line_in_file":20,"slug":"aws-s3-client","name":"aws_s3_client","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS\\DSL","parameters":[{"name":"configuration","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"S3Client","namespace":"AsyncAws\\S3","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"S3_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIEBwYXJhbSBhcnJheTxDb25maWd1cmF0aW9uOjpPUFRJT05fKiwgbnVsbHxzdHJpbmc+ICRjb25maWd1cmF0aW9uIC0gZm9yIGRldGFpbHMgcGxlYXNlIHNlZSBodHRwczovL2FzeW5jLWF3cy5jb20vY2xpZW50cy9zMy5odG1sCiAqLw=="},{"repository_path":"src\/bridge\/filesystem\/async-aws\/src\/Flow\/Filesystem\/Bridge\/AsyncAWS\/DSL\/functions.php","start_line_in_file":26,"slug":"aws-s3-filesystem","name":"aws_s3_filesystem","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS\\DSL","parameters":[{"name":"bucket","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"s3Client","type":[{"name":"S3Client","namespace":"AsyncAws\\S3","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"options","type":[{"name":"Options","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Filesystem\\Bridge\\AsyncAWS\\Options::..."},{"name":"protocol","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"'aws-s3'"}],"return_type":[{"name":"AsyncAWSS3Filesystem","namespace":"Flow\\Filesystem\\Bridge\\AsyncAWS","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"S3_FILESYSTEM","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":40,"slug":"value-normalizer","name":"value_normalizer","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[],"return_type":[{"name":"ValueNormalizer","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFZhbHVlTm9ybWFsaXplciBmb3IgY29udmVydGluZyBhcmJpdHJhcnkgUEhQIHZhbHVlcyB0byBUZWxlbWV0cnkgYXR0cmlidXRlIHR5cGVzLgogKgogKiBUaGUgbm9ybWFsaXplciBoYW5kbGVzOgogKiAtIG51bGwg4oaSICdudWxsJyBzdHJpbmcKICogLSBzY2FsYXJzIChzdHJpbmcsIGludCwgZmxvYXQsIGJvb2wpIOKGkiB1bmNoYW5nZWQKICogLSBEYXRlVGltZUludGVyZmFjZSDihpIgdW5jaGFuZ2VkCiAqIC0gVGhyb3dhYmxlIOKGkiB1bmNoYW5nZWQKICogLSBhcnJheXMg4oaSIHJlY3Vyc2l2ZWx5IG5vcm1hbGl6ZWQKICogLSBvYmplY3RzIHdpdGggX190b1N0cmluZygpIOKGkiBzdHJpbmcgY2FzdAogKiAtIG9iamVjdHMgd2l0aG91dCBfX3RvU3RyaW5nKCkg4oaSIGNsYXNzIG5hbWUKICogLSBvdGhlciB0eXBlcyDihpIgZ2V0X2RlYnVnX3R5cGUoKSByZXN1bHQKICoKICogRXhhbXBsZSB1c2FnZToKICogYGBgcGhwCiAqICRub3JtYWxpemVyID0gdmFsdWVfbm9ybWFsaXplcigpOwogKiAkbm9ybWFsaXplZCA9ICRub3JtYWxpemVyLT5ub3JtYWxpemUoJHZhbHVlKTsKICogYGBgCiAqLw=="},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":73,"slug":"severity-mapper","name":"severity_mapper","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[{"name":"customMapping","type":[{"name":"array","namespace":null,"is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"SeverityMapper","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFNldmVyaXR5TWFwcGVyIGZvciBtYXBwaW5nIE1vbm9sb2cgbGV2ZWxzIHRvIFRlbGVtZXRyeSBzZXZlcml0aWVzLgogKgogKiBAcGFyYW0gbnVsbHxhcnJheTxpbnQsIFNldmVyaXR5PiAkY3VzdG9tTWFwcGluZyBPcHRpb25hbCBjdXN0b20gbWFwcGluZyAoTW9ub2xvZyBMZXZlbCB2YWx1ZSA9PiBUZWxlbWV0cnkgU2V2ZXJpdHkpCiAqCiAqIEV4YW1wbGUgd2l0aCBkZWZhdWx0IG1hcHBpbmc6CiAqIGBgYHBocAogKiAkbWFwcGVyID0gc2V2ZXJpdHlfbWFwcGVyKCk7CiAqIGBgYAogKgogKiBFeGFtcGxlIHdpdGggY3VzdG9tIG1hcHBpbmc6CiAqIGBgYHBocAogKiB1c2UgTW9ub2xvZ1xMZXZlbDsKICogdXNlIEZsb3dcVGVsZW1ldHJ5XExvZ2dlclxTZXZlcml0eTsKICoKICogJG1hcHBlciA9IHNldmVyaXR5X21hcHBlcihbCiAqICAgICBMZXZlbDo6RGVidWctPnZhbHVlID0+IFNldmVyaXR5OjpERUJVRywKICogICAgIExldmVsOjpJbmZvLT52YWx1ZSA9PiBTZXZlcml0eTo6SU5GTywKICogICAgIExldmVsOjpOb3RpY2UtPnZhbHVlID0+IFNldmVyaXR5OjpXQVJOLCAgLy8gQ3VzdG9tOiBOT1RJQ0Ug4oaSIFdBUk4gaW5zdGVhZCBvZiBJTkZPCiAqICAgICBMZXZlbDo6V2FybmluZy0+dmFsdWUgPT4gU2V2ZXJpdHk6OldBUk4sCiAqICAgICBMZXZlbDo6RXJyb3ItPnZhbHVlID0+IFNldmVyaXR5OjpFUlJPUiwKICogICAgIExldmVsOjpDcml0aWNhbC0+dmFsdWUgPT4gU2V2ZXJpdHk6OkZBVEFMLAogKiAgICAgTGV2ZWw6OkFsZXJ0LT52YWx1ZSA9PiBTZXZlcml0eTo6RkFUQUwsCiAqICAgICBMZXZlbDo6RW1lcmdlbmN5LT52YWx1ZSA9PiBTZXZlcml0eTo6RkFUQUwsCiAqIF0pOwogKiBgYGAKICov"},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":107,"slug":"log-record-converter","name":"log_record_converter","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[{"name":"severityMapper","type":[{"name":"SeverityMapper","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"valueNormalizer","type":[{"name":"ValueNormalizer","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"LogRecordConverter","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIExvZ1JlY29yZENvbnZlcnRlciBmb3IgY29udmVydGluZyBNb25vbG9nIExvZ1JlY29yZCB0byBUZWxlbWV0cnkgTG9nUmVjb3JkLgogKgogKiBUaGUgY29udmVydGVyIGhhbmRsZXM6CiAqIC0gU2V2ZXJpdHkgbWFwcGluZyBmcm9tIE1vbm9sb2cgTGV2ZWwgdG8gVGVsZW1ldHJ5IFNldmVyaXR5CiAqIC0gTWVzc2FnZSBib2R5IGNvbnZlcnNpb24KICogLSBDaGFubmVsIGFuZCBsZXZlbCBuYW1lIGFzIG1vbm9sb2cuKiBhdHRyaWJ1dGVzCiAqIC0gQ29udGV4dCB2YWx1ZXMgYXMgY29udGV4dC4qIGF0dHJpYnV0ZXMgKFRocm93YWJsZXMgdXNlIHNldEV4Y2VwdGlvbigpKQogKiAtIEV4dHJhIHZhbHVlcyBhcyBleHRyYS4qIGF0dHJpYnV0ZXMKICoKICogQHBhcmFtIG51bGx8U2V2ZXJpdHlNYXBwZXIgJHNldmVyaXR5TWFwcGVyIEN1c3RvbSBzZXZlcml0eSBtYXBwZXIgKGRlZmF1bHRzIHRvIHN0YW5kYXJkIG1hcHBpbmcpCiAqIEBwYXJhbSBudWxsfFZhbHVlTm9ybWFsaXplciAkdmFsdWVOb3JtYWxpemVyIEN1c3RvbSB2YWx1ZSBub3JtYWxpemVyIChkZWZhdWx0cyB0byBzdGFuZGFyZCBub3JtYWxpemVyKQogKgogKiBFeGFtcGxlIHVzYWdlOgogKiBgYGBwaHAKICogJGNvbnZlcnRlciA9IGxvZ19yZWNvcmRfY29udmVydGVyKCk7CiAqICR0ZWxlbWV0cnlSZWNvcmQgPSAkY29udmVydGVyLT5jb252ZXJ0KCRtb25vbG9nUmVjb3JkKTsKICogYGBgCiAqCiAqIEV4YW1wbGUgd2l0aCBjdXN0b20gbWFwcGVyOgogKiBgYGBwaHAKICogJGNvbnZlcnRlciA9IGxvZ19yZWNvcmRfY29udmVydGVyKAogKiAgICAgc2V2ZXJpdHlNYXBwZXI6IHNldmVyaXR5X21hcHBlcihbCiAqICAgICAgICAgTGV2ZWw6OkRlYnVnLT52YWx1ZSA9PiBTZXZlcml0eTo6VFJBQ0UsCiAqICAgICBdKQogKiApOwogKiBgYGAKICov"},{"repository_path":"src\/bridge\/monolog\/telemetry\/src\/Flow\/Bridge\/Monolog\/Telemetry\/DSL\/functions.php","start_line_in_file":149,"slug":"telemetry-handler","name":"telemetry_handler","namespace":"Flow\\Bridge\\Monolog\\Telemetry\\DSL","parameters":[{"name":"logger","type":[{"name":"Logger","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"converter","type":[{"name":"LogRecordConverter","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Monolog\\Telemetry\\LogRecordConverter::..."},{"name":"level","type":[{"name":"Level","namespace":"Monolog","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Monolog\\Level::..."},{"name":"bubble","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"TelemetryHandler","namespace":"Flow\\Bridge\\Monolog\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"MONOLOG_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFRlbGVtZXRyeUhhbmRsZXIgZm9yIGZvcndhcmRpbmcgTW9ub2xvZyBsb2dzIHRvIEZsb3cgVGVsZW1ldHJ5LgogKgogKiBAcGFyYW0gTG9nZ2VyICRsb2dnZXIgVGhlIEZsb3cgVGVsZW1ldHJ5IGxvZ2dlciB0byBmb3J3YXJkIGxvZ3MgdG8KICogQHBhcmFtIExvZ1JlY29yZENvbnZlcnRlciAkY29udmVydGVyIENvbnZlcnRlciB0byB0cmFuc2Zvcm0gTW9ub2xvZyBMb2dSZWNvcmQgdG8gVGVsZW1ldHJ5IExvZ1JlY29yZAogKiBAcGFyYW0gTGV2ZWwgJGxldmVsIFRoZSBtaW5pbXVtIGxvZ2dpbmcgbGV2ZWwgYXQgd2hpY2ggdGhpcyBoYW5kbGVyIHdpbGwgYmUgdHJpZ2dlcmVkCiAqIEBwYXJhbSBib29sICRidWJibGUgV2hldGhlciBtZXNzYWdlcyBoYW5kbGVkIGJ5IHRoaXMgaGFuZGxlciBzaG91bGQgYnViYmxlIHVwIHRvIG90aGVyIGhhbmRsZXJzCiAqCiAqIEV4YW1wbGUgdXNhZ2U6CiAqIGBgYHBocAogKiB1c2UgTW9ub2xvZ1xMb2dnZXIgYXMgTW9ub2xvZ0xvZ2dlcjsKICogdXNlIGZ1bmN0aW9uIEZsb3dcQnJpZGdlXE1vbm9sb2dcVGVsZW1ldHJ5XERTTFx0ZWxlbWV0cnlfaGFuZGxlcjsKICogdXNlIGZ1bmN0aW9uIEZsb3dcVGVsZW1ldHJ5XERTTFx0ZWxlbWV0cnk7CiAqCiAqICR0ZWxlbWV0cnkgPSB0ZWxlbWV0cnkoKTsKICogJGxvZ2dlciA9ICR0ZWxlbWV0cnktPmxvZ2dlcignbXktYXBwJyk7CiAqCiAqICRtb25vbG9nID0gbmV3IE1vbm9sb2dMb2dnZXIoJ2NoYW5uZWwnKTsKICogJG1vbm9sb2ctPnB1c2hIYW5kbGVyKHRlbGVtZXRyeV9oYW5kbGVyKCRsb2dnZXIpKTsKICoKICogJG1vbm9sb2ctPmluZm8oJ1VzZXIgbG9nZ2VkIGluJywgWyd1c2VyX2lkJyA9PiAxMjNdKTsKICogLy8g4oaSIEZvcndhcmRlZCB0byBGbG93IFRlbGVtZXRyeSB3aXRoIElORk8gc2V2ZXJpdHkKICogYGBgCiAqCiAqIEV4YW1wbGUgd2l0aCBjdXN0b20gY29udmVydGVyOgogKiBgYGBwaHAKICogJGNvbnZlcnRlciA9IGxvZ19yZWNvcmRfY29udmVydGVyKAogKiAgICAgc2V2ZXJpdHlNYXBwZXI6IHNldmVyaXR5X21hcHBlcihbCiAqICAgICAgICAgTGV2ZWw6OkRlYnVnLT52YWx1ZSA9PiBTZXZlcml0eTo6VFJBQ0UsCiAqICAgICBdKQogKiApOwogKiAkbW9ub2xvZy0+cHVzaEhhbmRsZXIodGVsZW1ldHJ5X2hhbmRsZXIoJGxvZ2dlciwgJGNvbnZlcnRlcikpOwogKiBgYGAKICov"},{"repository_path":"src\/bridge\/symfony\/http-foundation-telemetry\/src\/Flow\/Bridge\/Symfony\/HttpFoundationTelemetry\/DSL\/functions.php","start_line_in_file":16,"slug":"symfony-request-carrier","name":"symfony_request_carrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry\\DSL","parameters":[{"name":"request","type":[{"name":"Request","namespace":"Symfony\\Component\\HttpFoundation","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RequestCarrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SYMFONY_HTTP_FOUNDATION_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/symfony\/http-foundation-telemetry\/src\/Flow\/Bridge\/Symfony\/HttpFoundationTelemetry\/DSL\/functions.php","start_line_in_file":22,"slug":"symfony-response-carrier","name":"symfony_response_carrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry\\DSL","parameters":[{"name":"response","type":[{"name":"Response","namespace":"Symfony\\Component\\HttpFoundation","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ResponseCarrier","namespace":"Flow\\Bridge\\Symfony\\HttpFoundationTelemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"SYMFONY_HTTP_FOUNDATION_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/psr7\/telemetry\/src\/Flow\/Bridge\/Psr7\/Telemetry\/DSL\/functions.php","start_line_in_file":16,"slug":"psr7-request-carrier","name":"psr7_request_carrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry\\DSL","parameters":[{"name":"request","type":[{"name":"ServerRequestInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"RequestCarrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PSR7_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/psr7\/telemetry\/src\/Flow\/Bridge\/Psr7\/Telemetry\/DSL\/functions.php","start_line_in_file":22,"slug":"psr7-response-carrier","name":"psr7_response_carrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry\\DSL","parameters":[{"name":"response","type":[{"name":"ResponseInterface","namespace":"Psr\\Http\\Message","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"ResponseCarrier","namespace":"Flow\\Bridge\\Psr7\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PSR7_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/psr18\/telemetry\/src\/Flow\/Bridge\/Psr18\/Telemetry\/DSL\/functions.php","start_line_in_file":15,"slug":"psr18-traceable-client","name":"psr18_traceable_client","namespace":"Flow\\Bridge\\Psr18\\Telemetry\\DSL","parameters":[{"name":"client","type":[{"name":"ClientInterface","namespace":"Psr\\Http\\Client","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"telemetry","type":[{"name":"Telemetry","namespace":"Flow\\Telemetry","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null}],"return_type":[{"name":"PSR18TraceableClient","namespace":"Flow\\Bridge\\Psr18\\Telemetry","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"PSR18_TELEMETRY_BRIDGE","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":null},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":48,"slug":"otlp-json-serializer","name":"otlp_json_serializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"JsonSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIEpTT04gc2VyaWFsaXplciBmb3IgT1RMUC4KICoKICogUmV0dXJucyBhIEpzb25TZXJpYWxpemVyIHRoYXQgY29udmVydHMgdGVsZW1ldHJ5IGRhdGEgdG8gT1RMUCBKU09OIHdpcmUgZm9ybWF0LgogKiBVc2UgdGhpcyB3aXRoIEN1cmxUcmFuc3BvcnQgZm9yIEpTT04gb3ZlciBIVFRQLgogKgogKiBFeGFtcGxlIHVzYWdlOgogKiBgYGBwaHAKICogJHNlcmlhbGl6ZXIgPSBvdGxwX2pzb25fc2VyaWFsaXplcigpOwogKiAkdHJhbnNwb3J0ID0gb3RscF9jdXJsX3RyYW5zcG9ydCgkZW5kcG9pbnQsICRzZXJpYWxpemVyKTsKICogYGBgCiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":69,"slug":"otlp-protobuf-serializer","name":"otlp_protobuf_serializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"ProtobufSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIFByb3RvYnVmIHNlcmlhbGl6ZXIgZm9yIE9UTFAuCiAqCiAqIFJldHVybnMgYSBQcm90b2J1ZlNlcmlhbGl6ZXIgdGhhdCBjb252ZXJ0cyB0ZWxlbWV0cnkgZGF0YSB0byBPVExQIFByb3RvYnVmIGJpbmFyeSBmb3JtYXQuCiAqIFVzZSB0aGlzIHdpdGggQ3VybFRyYW5zcG9ydCBmb3IgUHJvdG9idWYgb3ZlciBIVFRQLCBvciB3aXRoIEdycGNUcmFuc3BvcnQuCiAqCiAqIFJlcXVpcmVzOgogKiAtIGdvb2dsZS9wcm90b2J1ZiBwYWNrYWdlCiAqCiAqIEV4YW1wbGUgdXNhZ2U6CiAqIGBgYHBocAogKiAkc2VyaWFsaXplciA9IG90bHBfcHJvdG9idWZfc2VyaWFsaXplcigpOwogKiAkdHJhbnNwb3J0ID0gb3RscF9jdXJsX3RyYW5zcG9ydCgkZW5kcG9pbnQsICRzZXJpYWxpemVyKTsKICogYGBgCiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":93,"slug":"otlp-grpc-transport","name":"otlp_grpc_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"endpoint","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"headers","type":[{"name":"array","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"[]"},{"name":"insecure","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"},{"name":"timeoutMs","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"250"},{"name":"shutdownTimeoutMs","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"5000"},{"name":"failover","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGdSUEMgdHJhbnNwb3J0IGZvciBPVExQIGVuZHBvaW50cy4KICoKICogQ3JlYXRlcyBhIEdycGNUcmFuc3BvcnQgY29uZmlndXJlZCB0byBzZW5kIHRlbGVtZXRyeSBkYXRhIHRvIGFuIE9UTFAtY29tcGF0aWJsZQogKiBlbmRwb2ludCB1c2luZyBnUlBDIHByb3RvY29sIHdpdGggUHJvdG9idWYgc2VyaWFsaXphdGlvbi4gT1RMUC9nUlBDIG1hbmRhdGVzCiAqIFByb3RvYnVmLCBzbyB0aGUgc2VyaWFsaXplciBpcyBidWlsdCBpbnRlcm5hbGx5IGFuZCBub3QgY29uZmlndXJhYmxlLgogKgogKiBSZXF1aXJlczoKICogLSBleHQtZ3JwYyBQSFAgZXh0ZW5zaW9uCiAqIC0gZ29vZ2xlL3Byb3RvYnVmIHBhY2thZ2UKICoKICogQHBhcmFtIHN0cmluZyAkZW5kcG9pbnQgZ1JQQyBlbmRwb2ludCAoZS5nLiwgJ2xvY2FsaG9zdDo0MzE3JykKICogQHBhcmFtIGFycmF5PHN0cmluZywgc3RyaW5nPiAkaGVhZGVycyBBZGRpdGlvbmFsIGhlYWRlcnMgKG1ldGFkYXRhKSB0byBpbmNsdWRlIGluIHJlcXVlc3RzCiAqIEBwYXJhbSBib29sICRpbnNlY3VyZSBXaGV0aGVyIHRvIHVzZSBpbnNlY3VyZSBjaGFubmVsIGNyZWRlbnRpYWxzIChkZWZhdWx0IHRydWUgZm9yIGxvY2FsIGRldikKICogQHBhcmFtIGludCAkdGltZW91dE1zIFBlci1jYWxsIGRlYWRsaW5lIGluIG1pbGxpc2Vjb25kcyAoY292ZXJzIGNvbm5lY3QgKyBzZW5kICsgcmVjZWl2ZSkKICogQHBhcmFtIGludCAkc2h1dGRvd25UaW1lb3V0TXMgV2FsbC1jbG9jayBidWRnZXQgZm9yIGRyYWluaW5nIHBlbmRpbmcgY2FsbHMgYXQgc2h1dGRvd24KICogQHBhcmFtID9UcmFuc3BvcnQgJGZhaWxvdmVyIE9wdGlvbmFsIGZhaWxvdmVyIHRyYW5zcG9ydCByZWNlaXZpbmcgcHJpb3IgYmF0Y2hlcyB3aGVuIHByaW1hcnkgZmFpbHMKICov"},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":108,"slug":"otlp-curl-options","name":"otlp_curl_options","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"CurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBjdXJsIHRyYW5zcG9ydCBvcHRpb25zIGZvciBPVExQLgogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":129,"slug":"otlp-curl-transport","name":"otlp_curl_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"endpoint","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"serializer","type":[{"name":"JsonSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false},{"name":"ProtobufSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer\\JsonSerializer::..."},{"name":"options","type":[{"name":"CurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Transport\\CurlTransportOptions::..."},{"name":"failover","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHN5bmNocm9ub3VzIGN1cmwgdHJhbnNwb3J0IGZvciBPVExQIGVuZHBvaW50cy4KICoKICogQ3JlYXRlcyBhIEN1cmxUcmFuc3BvcnQgdGhhdCBkcml2ZXMgZWFjaCByZXF1ZXN0IHRvIGNvbXBsZXRpb24gYW5kIHJlcG9ydHMgdGhlCiAqIG91dGNvbWUgaW1tZWRpYXRlbHkgKHJldHVybnMgb24gc3VjY2VzcywgdGhyb3dzIG9uIGZhaWx1cmUpLiBPVExQL0hUVFAgYWxsb3dzCiAqIEpTT04gb3IgUHJvdG9idWYgZW5jb2Rpbmc7IGRlZmF1bHRzIHRvIEpTT04uIEtlZXBpbmcgZXhwb3J0IG9mZiB0aGUgYXBwbGljYXRpb24KICogaG90IHBhdGggaXMgdGhlIGpvYiBvZiB0aGUgYmF0Y2hpbmcgcHJvY2Vzc29yIGluIGZyb250IG9mIHRoZSBleHBvcnRlci4KICoKICogUmVxdWlyZXM6IGV4dC1jdXJsIFBIUCBleHRlbnNpb24KICoKICogQHBhcmFtIHN0cmluZyAkZW5kcG9pbnQgT1RMUCBlbmRwb2ludCBVUkwgKGUuZy4sICdodHRwOi8vbG9jYWxob3N0OjQzMTgnKQogKiBAcGFyYW0gSnNvblNlcmlhbGl6ZXJ8UHJvdG9idWZTZXJpYWxpemVyICRzZXJpYWxpemVyIFNlcmlhbGl6ZXIgZm9yIGVuY29kaW5nIHRlbGVtZXRyeSBkYXRhIChKU09OIG9yIFByb3RvYnVmKQogKiBAcGFyYW0gQ3VybFRyYW5zcG9ydE9wdGlvbnMgJG9wdGlvbnMgVHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24gb3B0aW9ucwogKiBAcGFyYW0gP1RyYW5zcG9ydCAkZmFpbG92ZXIgT3B0aW9uYWwgZmFpbG92ZXIgdHJhbnNwb3J0IHJlY2VpdmluZyB0aGUgYmF0Y2ggd2hlbiB0aGUgcHJpbWFyeSBmYWlscwogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":142,"slug":"otlp-async-curl-options","name":"otlp_async_curl_options","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[],"return_type":[{"name":"AsyncCurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhc3luYyBjdXJsIHRyYW5zcG9ydCBvcHRpb25zIGZvciBPVExQLgogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":157,"slug":"otlp-async-curl-transport","name":"otlp_async_curl_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"endpoint","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"serializer","type":[{"name":"JsonSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false},{"name":"ProtobufSerializer","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Serializer\\JsonSerializer::..."},{"name":"options","type":[{"name":"AsyncCurlTransportOptions","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Bridge\\Telemetry\\OTLP\\Transport\\AsyncCurlTransportOptions::..."},{"name":"failover","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":true,"is_variadic":false}],"has_default_value":true,"is_nullable":true,"is_variadic":false,"default_value":"null"},{"name":"error_handler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBhc3luY2hyb25vdXMgY3VybCB0cmFuc3BvcnQgZm9yIE9UTFAgZW5kcG9pbnRzLgogKgogKiBAcGFyYW0gc3RyaW5nICRlbmRwb2ludCBPVExQIGVuZHBvaW50IFVSTCAoZS5nLiwgJ2h0dHA6Ly9sb2NhbGhvc3Q6NDMxOCcpCiAqIEBwYXJhbSBKc29uU2VyaWFsaXplcnxQcm90b2J1ZlNlcmlhbGl6ZXIgJHNlcmlhbGl6ZXIgU2VyaWFsaXplciBmb3IgZW5jb2RpbmcgdGVsZW1ldHJ5IGRhdGEgKEpTT04gb3IgUHJvdG9idWYpCiAqIEBwYXJhbSBBc3luY0N1cmxUcmFuc3BvcnRPcHRpb25zICRvcHRpb25zIFRyYW5zcG9ydCBjb25maWd1cmF0aW9uIG9wdGlvbnMKICogQHBhcmFtID9UcmFuc3BvcnQgJGZhaWxvdmVyIE9wdGlvbmFsIGZhaWxvdmVyIHRyYW5zcG9ydCByZWNlaXZpbmcgcHJpb3IgYmF0Y2hlcyB3aGVuIHByaW1hcnkgZmFpbHMKICogQHBhcmFtIEVycm9ySGFuZGxlciAkZXJyb3JfaGFuZGxlciBIYW5kbGVyIGZvciBmYWlsdXJlcyByZWFwZWQgb24gc2VuZCgpL3RpY2soKS9zaHV0ZG93bigpIChubyBmYWlsb3ZlcikKICov"},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":179,"slug":"otlp-stream-transport","name":"otlp_stream_transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"destination","type":[{"name":"string","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"filePermissions","type":[{"name":"int","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"420"},{"name":"createDirectories","type":[{"name":"bool","namespace":null,"is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"true"}],"return_type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHN0cmVhbSB0cmFuc3BvcnQgZm9yIE9UTFAgdGhhdCB3cml0ZXMgSlNPTkwgdG8gYSBzaW5nbGUgZGVzdGluYXRpb24uCiAqCiAqIEFjY2VwdHMgYW4gYWJzb2x1dGUgZmlsZSBwYXRoIG9yIGEgcGhwOi8vIHN0cmVhbSB3cmFwcGVyIHN1Y2ggYXMKICogJ3BocDovL3N0ZG91dCcsICdwaHA6Ly9zdGRlcnInLCAncGhwOi8vbWVtb3J5Jywgb3IgJ3BocDovL3RlbXAnLiBFYWNoCiAqIGV4cG9ydCgpIGNhbGwgYXBwZW5kcyBvbmUgSlNPTiBMaW5lIHVuZGVyIExPQ0tfRVggc28gY29uY3VycmVudCB3cml0ZXJzCiAqIGludGVybGVhdmUgYXQgbGluZSBib3VuZGFyaWVzLiBUaGUgJGZpbGVQZXJtaXNzaW9ucyBhbmQgJGNyZWF0ZURpcmVjdG9yaWVzCiAqIHBhcmFtZXRlcnMgYXBwbHkgb25seSB3aGVuIHRoZSBkZXN0aW5hdGlvbiBpcyBhIGZpbGUgcGF0aC4KICoKICogUGVyIHRoZSBPVExQIEZpbGUgRXhwb3J0ZXIgc3BlYyBvbmx5IEpTT04gZW5jb2RpbmcgaXMgc3VwcG9ydGVkLgogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":202,"slug":"otlp-exporter","name":"otlp_exporter","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"transport","type":[{"name":"Transport","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Transport","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"errorHandler","type":[{"name":"ErrorHandler","namespace":"Flow\\Telemetry\\ErrorHandler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\ErrorHandler\\ErrorLogHandler::..."}],"return_type":[{"name":"OTLPExporter","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\Exporter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhbiBPVExQIGV4cG9ydGVyIHRoYXQgZGlzcGF0Y2hlcyBsb2dzLCBtZXRyaWNzLCBhbmQgc3BhbnMgdGhyb3VnaCBhIHNpbmdsZSB0cmFuc3BvcnQuCiAqCiAqIEV4YW1wbGUgdXNhZ2U6CiAqIGBgYHBocAogKiAkZXhwb3J0ZXIgPSBvdGxwX2V4cG9ydGVyKCR0cmFuc3BvcnQpOwogKiAkc3BhblByb2Nlc3NvciA9IGJhdGNoaW5nX3NwYW5fcHJvY2Vzc29yKCRleHBvcnRlcik7CiAqICRtZXRyaWNQcm9jZXNzb3IgPSBiYXRjaGluZ19tZXRyaWNfcHJvY2Vzc29yKCRleHBvcnRlcik7CiAqICRsb2dQcm9jZXNzb3IgPSBiYXRjaGluZ19sb2dfcHJvY2Vzc29yKCRleHBvcnRlcik7CiAqIGBgYAogKgogKiBAcGFyYW0gVHJhbnNwb3J0ICR0cmFuc3BvcnQgVGhlIHRyYW5zcG9ydCBmb3Igc2VuZGluZyB0ZWxlbWV0cnkgZGF0YQogKiBAcGFyYW0gRXJyb3JIYW5kbGVyICRlcnJvckhhbmRsZXIgSGFuZGxlciBmb3IgVGhyb3dhYmxlcyByYWlzZWQgYnkgdGhlIHRyYW5zcG9ydAogKi8="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":216,"slug":"otlp-tracer-provider","name":"otlp_tracer_provider","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"processor","type":[{"name":"SpanProcessor","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"sampler","type":[{"name":"Sampler","namespace":"Flow\\Telemetry\\Tracer\\Sampler","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Tracer\\Sampler\\AlwaysOnSampler::..."},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Context\\MemoryContextStorage::..."}],"return_type":[{"name":"TracerProvider","namespace":"Flow\\Telemetry\\Tracer","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIHRyYWNlciBwcm92aWRlciBjb25maWd1cmVkIGZvciBPVExQIGV4cG9ydC4KICoKICogQHBhcmFtIFNwYW5Qcm9jZXNzb3IgJHByb2Nlc3NvciBUaGUgcHJvY2Vzc29yIGZvciBoYW5kbGluZyBzcGFucwogKiBAcGFyYW0gQ2xvY2tJbnRlcmZhY2UgJGNsb2NrIFRoZSBjbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gU2FtcGxlciAkc2FtcGxlciBUaGUgc2FtcGxlciBmb3IgZGVjaWRpbmcgd2hldGhlciB0byByZWNvcmQgc3BhbnMKICogQHBhcmFtIENvbnRleHRTdG9yYWdlICRjb250ZXh0U3RvcmFnZSBUaGUgY29udGV4dCBzdG9yYWdlIGZvciBwcm9wYWdhdGluZyB0cmFjZSBjb250ZXh0CiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":233,"slug":"otlp-meter-provider","name":"otlp_meter_provider","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"processor","type":[{"name":"MetricProcessor","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"temporality","type":[{"name":"AggregationTemporality","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Meter\\AggregationTemporality::..."}],"return_type":[{"name":"MeterProvider","namespace":"Flow\\Telemetry\\Meter","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIG1ldGVyIHByb3ZpZGVyIGNvbmZpZ3VyZWQgZm9yIE9UTFAgZXhwb3J0LgogKgogKiBAcGFyYW0gTWV0cmljUHJvY2Vzc29yICRwcm9jZXNzb3IgVGhlIHByb2Nlc3NvciBmb3IgaGFuZGxpbmcgbWV0cmljcwogKiBAcGFyYW0gQ2xvY2tJbnRlcmZhY2UgJGNsb2NrIFRoZSBjbG9jayBmb3IgdGltZXN0YW1wcwogKiBAcGFyYW0gQWdncmVnYXRpb25UZW1wb3JhbGl0eSAkdGVtcG9yYWxpdHkgVGhlIGFnZ3JlZ2F0aW9uIHRlbXBvcmFsaXR5IGZvciBtZXRyaWNzCiAqLw=="},{"repository_path":"src\/bridge\/telemetry\/otlp\/src\/Flow\/Bridge\/Telemetry\/OTLP\/DSL\/functions.php","start_line_in_file":249,"slug":"otlp-logger-provider","name":"otlp_logger_provider","namespace":"Flow\\Bridge\\Telemetry\\OTLP\\DSL","parameters":[{"name":"processor","type":[{"name":"LogProcessor","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"clock","type":[{"name":"ClockInterface","namespace":"Psr\\Clock","is_nullable":false,"is_variadic":false}],"has_default_value":false,"is_nullable":false,"is_variadic":false,"default_value":null},{"name":"contextStorage","type":[{"name":"ContextStorage","namespace":"Flow\\Telemetry\\Context","is_nullable":false,"is_variadic":false}],"has_default_value":true,"is_nullable":false,"is_variadic":false,"default_value":"Flow\\Telemetry\\Context\\MemoryContextStorage::..."}],"return_type":[{"name":"LoggerProvider","namespace":"Flow\\Telemetry\\Logger","is_nullable":false,"is_variadic":false}],"attributes":[{"name":"DocumentationDSL","namespace":"Flow\\ETL\\Attribute","arguments":{"module":"TELEMETRY_OTLP","type":"HELPER"}}],"scalar_function_chain":false,"doc_comment":"LyoqCiAqIENyZWF0ZSBhIGxvZ2dlciBwcm92aWRlciBjb25maWd1cmVkIGZvciBPVExQIGV4cG9ydC4KICoKICogQHBhcmFtIExvZ1Byb2Nlc3NvciAkcHJvY2Vzc29yIFRoZSBwcm9jZXNzb3IgZm9yIGhhbmRsaW5nIGxvZyByZWNvcmRzCiAqIEBwYXJhbSBDbG9ja0ludGVyZmFjZSAkY2xvY2sgVGhlIGNsb2NrIGZvciB0aW1lc3RhbXBzCiAqIEBwYXJhbSBDb250ZXh0U3RvcmFnZSAkY29udGV4dFN0b3JhZ2UgVGhlIGNvbnRleHQgc3RvcmFnZSBmb3IgcHJvcGFnYXRpbmcgY29udGV4dAogKi8="}] \ No newline at end of file