Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package steampipe for openSUSE:Factory 
checked in at 2026-02-24 15:39:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/steampipe (Old)
 and      /work/SRC/openSUSE:Factory/.steampipe.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "steampipe"

Tue Feb 24 15:39:16 2026 rev:16 rq:1334605 version:2.3.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/steampipe/steampipe.changes      2026-02-17 
16:53:33.170992878 +0100
+++ /work/SRC/openSUSE:Factory/.steampipe.new.1977/steampipe.changes    
2026-02-24 15:39:57.833809430 +0100
@@ -1,0 +2,10 @@
+Mon Feb 23 08:15:40 UTC 2026 - Felix Niederwanger <[email protected]>
+
+- Update to version 2.3.6:
+  * v2.3.6
+  * Update FDW version to 2.1.5 and SDK to v5.13.2 (#4939)
+  * Fix date and timestamptz display. closes #4450
+  * Add steampipe architecture and development context to CLAUDE.md
+  * Add release process documentation to CLAUDE.md
+
+-------------------------------------------------------------------

Old:
----
  steampipe-2.3.5.obscpio

New:
----
  steampipe-2.3.6.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ steampipe.spec ++++++
--- /var/tmp/diff_new_pack.NSEv7P/_old  2026-02-24 15:39:58.801849490 +0100
+++ /var/tmp/diff_new_pack.NSEv7P/_new  2026-02-24 15:39:58.805849656 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           steampipe
-Version:        2.3.5
+Version:        2.3.6
 Release:        0
 Summary:        Query various APIs and services via SQL language
 License:               AGPL-3.0-only
@@ -25,7 +25,7 @@
 Source:         %{name}-%{version}.tar.gz
 Source1:        vendor.tar.gz
 BuildRequires:  golang-packaging
-BuildRequires:  golang(API) >= 1.22
+BuildRequires:  golang(API) >= 1.24
 %{go_nostrip}
 
 %description

++++++ _service ++++++
--- /var/tmp/diff_new_pack.NSEv7P/_old  2026-02-24 15:39:58.845851312 +0100
+++ /var/tmp/diff_new_pack.NSEv7P/_new  2026-02-24 15:39:58.849851477 +0100
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="manual">
     <param name="url">https://github.com/turbot/steampipe.git</param>
     <param name="scm">git</param>
-    <param name="revision">v2.3.5</param>
+    <param name="revision">v2.3.6</param>
        <param name="versionformat">@PARENT_TAG@</param>
        <param name="versionrewrite-pattern">v(.*)</param>
        <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.NSEv7P/_old  2026-02-24 15:39:58.873852470 +0100
+++ /var/tmp/diff_new_pack.NSEv7P/_new  2026-02-24 15:39:58.877852636 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/turbot/steampipe.git</param>
-              <param 
name="changesrevision">a4b708bcc1939d72853932b78db51ba8d92227ac</param></service></servicedata>
+              <param 
name="changesrevision">b713a4cdc6a1799531d0f8192713b6b7f6b3725e</param></service></servicedata>
 (No newline at EOF)
 

++++++ steampipe-2.3.5.obscpio -> steampipe-2.3.6.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/steampipe-2.3.5/.github/workflows/11-test-acceptance.yaml 
new/steampipe-2.3.6/.github/workflows/11-test-acceptance.yaml
--- old/steampipe-2.3.5/.github/workflows/11-test-acceptance.yaml       
2026-02-06 08:59:35.000000000 +0100
+++ new/steampipe-2.3.6/.github/workflows/11-test-acceptance.yaml       
2026-02-20 10:26:24.000000000 +0100
@@ -101,6 +101,7 @@
           - "blank_aggregators"
           - "search_path"
           - "chaos_and_query"
+          - "date_time_types"
           - "dynamic_schema"
           - "dynamic_aggregators"
           - "cache"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/steampipe-2.3.5/CHANGELOG.md 
new/steampipe-2.3.6/CHANGELOG.md
--- old/steampipe-2.3.5/CHANGELOG.md    2026-02-06 08:59:35.000000000 +0100
+++ new/steampipe-2.3.6/CHANGELOG.md    2026-02-20 10:26:24.000000000 +0100
@@ -1,3 +1,7 @@
+## v2.3.6 [2026-02-20]
+_Bug fixes_
+- Fix `date` and `timestamptz` display formatting in query results. 
([#4450](https://github.com/turbot/steampipe/issues/4450))
+
 ## v2.3.5 [2026-02-06]
 _Bug fixes_
 - Fix autocomplete regression where suggestions disappear when typing a table 
name after `from `. ([#4928](https://github.com/turbot/steampipe/issues/4928))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/steampipe-2.3.5/CLAUDE.md 
new/steampipe-2.3.6/CLAUDE.md
--- old/steampipe-2.3.5/CLAUDE.md       1970-01-01 01:00:00.000000000 +0100
+++ new/steampipe-2.3.6/CLAUDE.md       2026-02-20 10:26:24.000000000 +0100
@@ -0,0 +1,433 @@
+# Steampipe
+
+Steampipe is a zero-ETL tool that lets you query cloud APIs using SQL. It 
embeds PostgreSQL and uses a Foreign Data Wrapper (FDW) to translate SQL 
queries into API calls via a plugin system.
+
+## Architecture Overview
+
+```
+┌──────────────────────────────────────────────────────────────────────┐
+│  User: steampipe query "SELECT * FROM aws_s3_bucket WHERE region='us-east-1'"
+└──────────────┬───────────────────────────────────────────────────────┘
+               │
+       ┌───────▼────────┐
+       │  Steampipe CLI  │  ← This repo (turbot/steampipe)
+       │  (Cobra + Go)   │
+       └───────┬─────────┘
+               │ Starts/manages
+       ┌───────▼──────────────┐
+       │  Embedded PostgreSQL  │  (v14, port 9193)
+       │  + FDW Extension      │  ← turbot/steampipe-postgres-fdw
+       └───────┬──────────────┘
+               │ gRPC
+       ┌───────▼──────────────┐
+       │  Plugin Process       │  Built with turbot/steampipe-plugin-sdk
+       │  (e.g. steampipe-    │
+       │   plugin-aws)        │
+       └───────┬──────────────┘
+               │ API calls
+       ┌───────▼──────────────┐
+       │  Cloud API / Service  │
+       └──────────────────────┘
+```
+
+### Query Flow
+
+1. User executes SQL (interactive REPL or batch mode)
+2. Steampipe CLI ensures PostgreSQL + FDW + plugins are running
+3. SQL goes to PostgreSQL, which routes foreign table access to the FDW
+4. FDW translates the query (columns, WHERE quals, LIMIT, ORDER BY) into a 
gRPC `ExecuteRequest`
+5. Plugin receives the request, calls the appropriate API, streams rows back 
via gRPC
+6. FDW converts rows to PostgreSQL tuples, returns to the query engine
+7. PostgreSQL applies any remaining filters/joins/aggregations and returns 
results
+
+### Key Design Decisions
+
+- **Process-per-plugin**: Each plugin is a separate OS process, communicating 
via gRPC (using HashiCorp go-plugin)
+- **Qual pushdown**: WHERE clauses are pushed to plugins so they can filter at 
the API level (e.g. `region = 'us-east-1'` becomes an API parameter)
+- **Limit pushdown**: LIMIT is pushed to plugins when sort order can also be 
pushed
+- **Streaming**: Rows are streamed progressively, not buffered
+- **Caching**: Two-level caching (query cache in plugin manager, connection 
cache per-plugin)
+
+## Repository Map
+
+### This Repo: `turbot/steampipe` (CLI)
+
+The Steampipe CLI manages the database lifecycle, plugin installation, and 
provides the query interface.
+
+```
+steampipe/
+├── main.go                          # Entry point: system checks, then 
cmd.Execute()
+├── cmd/                             # Cobra commands
+│   ├── root.go                      # Root command, global flags
+│   ├── query.go                     # `steampipe query` - interactive/batch 
SQL
+│   ├── service.go                   # `steampipe service` - start/stop/status 
of DB service
+│   ├── plugin.go                    # `steampipe plugin` - 
install/update/list/uninstall
+│   ├── plugin_manager.go           # Plugin manager daemon process
+│   ├── login.go                     # `steampipe login` - Turbot Pipes auth
+│   └── completion.go               # Shell completion
+├── pkg/
+│   ├── db/
+│   │   ├── db_local/               # PostgreSQL process management (start, 
stop, install, backup)
+│   │   ├── db_client/              # Database client (pgx connection pool, 
query execution, sessions)
+│   │   └── db_common/              # Shared DB interfaces and types
+│   ├── steampipeconfig/            # HCL config loading (connections, 
options, connection state)
+│   ├── connection/                  # Connection refresh, state tracking, 
config file watcher
+│   ├── pluginmanager_service/      # gRPC plugin manager (starts plugins, 
manages lifecycle)
+│   ├── pluginmanager/              # Plugin manager state persistence
+│   ├── interactive/                # Interactive REPL (go-prompt, 
autocomplete, metaqueries)
+│   ├── query/                      # Query execution (init, 
batch/interactive, history, results)
+│   ├── ociinstaller/               # OCI image installer for DB binaries and 
FDW
+│   ├── introspection/              # Internal metadata tables 
(steampipe_connection, steampipe_plugin, etc.)
+│   ├── constants/                  # App constants (ports, schemas, env vars, 
exit codes)
+│   ├── options/                    # Config option types (database, general, 
plugin)
+│   ├── initialisation/             # Startup initialization (DB client, 
services, cloud metadata)
+│   ├── export/                     # Query result export (snapshots)
+│   ├── display/                    # Output formatting
+│   ├── cmdconfig/                  # CLI flag configuration via viper
+│   └── ...                         # error_helpers, statushooks, utils, etc.
+├── tests/
+│   ├── acceptance/                 # Acceptance test suite
+│   ├── dockertesting/             # Docker-based tests
+│   └── manual_testing/            # Manual test scripts
+└── .ai/                            # AI development guides (see below)
+```
+
+#### Key Internal Flows
+
+**Service startup** (`steampipe service start` or implicit on `steampipe 
query`):
+1. `db_local.StartServices()` ensures PostgreSQL is installed (via OCI images)
+2. Starts PostgreSQL process with the FDW extension loaded
+3. Starts plugin manager, loads plugin processes
+4. Refreshes all connections (creates/updates foreign table schemas)
+5. Creates internal metadata tables (`steampipe_internal` schema)
+
+**Database client** (`pkg/db/db_client/`):
+- Uses `jackc/pgx/v5` connection pool
+- Manages per-session search paths (so each query sees the right schemas)
+- Executes queries and streams results back
+
+**Interactive mode** (`pkg/interactive/`):
+- Uses a fork of `c-bata/go-prompt` for the REPL
+- Provides autocomplete for table names, columns, SQL keywords
+- Supports metaqueries (`.inspect`, `.tables`, `.help`, etc.)
+
+**Plugin management** (`steampipe plugin install aws`):
+- Downloads OCI image from registry → extracts to `~/.steampipe/plugins/`
+- On next query, plugin manager starts the plugin process
+- FDW imports foreign schema (creates foreign tables for each plugin table)
+
+### Related Repo: `turbot/steampipe-postgres-fdw` (FDW)
+
+The Foreign Data Wrapper is a PostgreSQL extension written in C + Go. It 
bridges PostgreSQL and plugins.
+
+```
+steampipe-postgres-fdw/
+├── fdw/                    # C code: PostgreSQL extension callbacks
+│   ├── fdw.c              # FDW init, handler registration (FdwRoutine)
+│   ├── query.c            # Query planning: column extraction, sort/limit 
pushdown
+│   └── common.h           # Core C structs (ConversionInfo, FdwPlanState, 
FdwExecState)
+├── hub/                    # Go code: query engine that talks to plugins
+│   ├── hub_base.go        # Planning (GetRelSize, GetPathKeys) and scan 
management
+│   ├── hub_remote.go      # Remote hub: connection pooling, iterator creation
+│   ├── scan_iterator.go   # Row streaming from plugin via gRPC
+│   └── connection_factory.go # Plugin connection caching
+├── fdw.go                  # Go↔C bridge: exported functions 
(goFdwBeginForeignScan, etc.)
+├── quals.go                # PostgreSQL restrictions → protobuf Quals 
conversion
+├── schema.go               # Plugin schema → CREATE FOREIGN TABLE SQL
+├── helpers.go              # C↔Go type conversion (Go values ↔ PostgreSQL 
Datums)
+└── types/                  # Go type definitions (Relation, Options, PathKeys)
+```
+
+#### FDW Lifecycle (per query)
+
+| Phase | C Callback | Go Function | What Happens |
+|-------|-----------|-------------|--------------|
+| Planning | `fdwGetForeignRelSize` | `Hub.GetRelSize()` | Estimate row count 
and width |
+| Planning | `fdwGetForeignPaths` | `Hub.GetPathKeys()` | Generate access 
paths (for join optimization) |
+| Planning | `fdwGetForeignPlan` | - | Choose plan, serialize state |
+| Execution | `fdwBeginForeignScan` | `Hub.GetIterator()` | Convert quals, 
create scan iterator |
+| Execution | `fdwIterateForeignScan` | `iterator.Next()` | Fetch rows, 
convert to Datums |
+| Cleanup | `fdwEndForeignScan` | `iterator.Close()` | Cleanup, collect scan 
metadata |
+
+#### Qual Pushdown
+
+WHERE clauses are converted from PostgreSQL's internal representation to 
protobuf `Qual` messages:
+- `column = value` → `Qual{FieldName, "=", value}`
+- `column IN (a, b)` → `Qual{FieldName, "=", ListValue}`
+- `column IS NULL` → `NullTest` qual
+- `column LIKE '%pattern%'` → `Qual{FieldName, "~~", value}`
+- Boolean expressions (AND/OR) are handled recursively
+- Volatile functions and self-references are excluded (left for PostgreSQL to 
filter)
+
+### Related Repo: `turbot/steampipe-plugin-sdk` (Plugin SDK)
+
+The SDK provides the framework for building plugins. Plugin authors only write 
API-specific code.
+
+```
+steampipe-plugin-sdk/
+├── plugin/                 # Core plugin framework
+│   ├── plugin.go          # Plugin struct, initialization, execution 
orchestration
+│   ├── table.go           # Table definition (columns, List/Get config, 
hydrate config)
+│   ├── column.go          # Column definition (name, type, transform, hydrate 
func)
+│   ├── table_fetch.go     # Fetch orchestration: Get vs List decision, row 
building
+│   ├── query_data.go      # QueryData: quals, key columns, streaming, 
pagination
+│   ├── row_data.go        # Row building: parallel hydrate execution, 
transform application
+│   ├── key_column.go      # Key column definitions (required/optional/any_of, 
operators)
+│   ├── hydrate_config.go  # Hydrate config: dependencies, retry, ignore, 
concurrency
+│   ├── hydrate_error.go   # Error wrapping: retry with backoff, error ignoring
+│   └── serve.go           # Plugin startup: gRPC server registration
+├── grpc/                   # gRPC server implementation (PluginServer)
+│   ├── pluginServer.go    # RPC methods: Execute, GetSchema, 
SetConnectionConfig, etc.
+│   └── proto/             # Protobuf definitions (plugin.proto)
+├── query_cache/            # Query result caching
+├── rate_limiter/           # Token bucket rate limiting with scoped instances
+├── connection/             # Per-connection in-memory caching (Ristretto)
+├── transform/              # Data transformation functions (FromField, 
FromGo, NullIfZero, etc.)
+└── row_stream/             # Row streaming channel management
+```
+
+#### Plugin Execution Model
+
+When a query hits a plugin table:
+
+1. **Get vs List decision**: If all required key columns have `=` quals → Get 
call. Otherwise → List call.
+2. **List hydrate** runs first, streaming items via 
`QueryData.StreamListItem()`
+3. **Row building** (per item, in parallel):
+   - Start all hydrate functions (respecting dependency graph)
+   - Hydrates without dependencies run concurrently
+   - Each hydrate is wrapped with retry + ignore error logic
+   - Rate limiters throttle API calls per scope (connection, region, service)
+4. **Transform chain** applied per column: 
`FromField("Name").Transform(toLower).NullIfZero()`
+5. **Row streamed** back to FDW via gRPC
+
+#### Key Types
+
+```
+Plugin              → Top-level struct, holds TableMap, config, caches
+Table               → Name, Columns, List/Get config, HydrateConfig
+Column              → Name, Type, Transform, optional Hydrate function
+KeyColumn           → Column name, operators, required/optional/any_of
+HydrateFunc         → func(ctx, *QueryData, *HydrateData) (interface{}, error)
+QueryData           → Quals, key columns, streaming, connection config
+TransformCall       → Chain of FromXXX → Transform → NullIfZero
+```
+
+### Related Repo: `turbot/pipe-fittings` (Shared Library)
+
+Shared infrastructure library used by Steampipe, Flowpipe, and Powerpipe.
+
+```
+pipe-fittings/
+├── modconfig/              # Mod resources: Mod, HclResource, ModTreeItem 
interfaces
+├── connection/             # Connection types (48+ implementations: AWS, 
Azure, GCP, GitHub, etc.)
+│   └── PipelingConnection  # Core interface: Resolve(), Validate(), GetEnv(), 
CtyValue()
+├── parse/                  # HCL parsing engine (decoder, body processing, 
custom types)
+├── constants/              # Shared constants across Turbot products
+├── utils/                  # Plugin utilities, string helpers, file ops
+├── credential/             # Credential management
+├── schema/                 # Resource schema definitions
+├── versionmap/             # Dependency version management
+├── modinstaller/           # Mod dependency installation
+├── ociinstaller/           # OCI image installation
+└── backend/                # PostgreSQL connector
+```
+
+Steampipe imports pipe-fittings as `github.com/turbot/pipe-fittings/v2`. Key 
usage:
+- `modconfig.SteampipeConnection` for connection configuration types
+- `constants` for shared database and cloud constants
+- `utils` for common helper functions
+- `connection` types for Turbot Pipes integration
+
+## Development Guide
+
+### Building
+
+```bash
+go build -o steampipe
+```
+
+### Testing
+
+```bash
+# Unit tests
+go test ./...
+
+# Acceptance tests (local) - sets up a temp install dir, installs chaos 
plugins, runs all tests
+tests/acceptance/run-local.sh
+
+# Run a single acceptance test file
+tests/acceptance/run-local.sh 001.query.bats
+```
+
+`run-local.sh` creates a temporary `STEAMPIPE_INSTALL_DIR`, runs `steampipe 
plugin install chaos chaosdynamic`, then delegates to `run.sh`. This isolates 
tests from your real `~/.steampipe` installation. The `steampipe` binary must 
already be on your `PATH` (build it first with `go build -o steampipe` and add 
it or use `go install`).
+
+### Local Development with Related Repos
+
+#### Dependency Chain
+
+```
+pipe-fittings          (shared library, no Turbot dependencies)
+       ↑
+steampipe-plugin-sdk   (depends on nothing Turbot-specific)
+       ↑
+steampipe-postgres-fdw (depends on pipe-fittings + steampipe-plugin-sdk)
+       ↑
+steampipe              (depends on pipe-fittings + steampipe-plugin-sdk)
+```
+
+Changes flow upward: a change in `pipe-fittings` can affect all three 
consumers. A change in `steampipe-plugin-sdk` affects `steampipe` and 
`steampipe-postgres-fdw`. The FDW and CLI are independent of each other.
+
+#### Using `go.mod` Replace Directives
+
+Steampipe's `go.mod` has **commented-out replace directives** that point to 
sibling directories:
+
+```go
+replace (
+    github.com/c-bata/go-prompt => github.com/turbot/go-prompt 
v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50
+// github.com/turbot/pipe-fittings/v2 => ../pipe-fittings
+//  github.com/turbot/steampipe-plugin-sdk/v5 => ../steampipe-plugin-sdk
+)
+```
+
+**To develop against a local `pipe-fittings` or `steampipe-plugin-sdk`**, 
uncomment the relevant line(s). This tells Go to use your local checkout 
instead of the published module version. This is essential when:
+
+- You need to change `pipe-fittings` or `steampipe-plugin-sdk` alongside 
`steampipe`
+- You're debugging an issue that spans repos (e.g. a config parsing bug in 
pipe-fittings that manifests in steampipe)
+- You want to test unreleased SDK or pipe-fittings changes with the CLI
+
+**Important**: The `go.mod` expects sibling directories (`../pipe-fittings`, 
`../steampipe-plugin-sdk`). The local workspace should look like:
+
+```
+turbot/
+├── steampipe/                  # this repo
+├── steampipe-postgres-fdw/     # FDW
+├── steampipe-plugin-sdk/       # plugin SDK
+└── pipe-fittings/              # shared library
+```
+
+**Remember to re-comment the replace directives before committing** — they 
should never be checked in uncommented, as CI and other developers won't have 
the same local paths. The `go-prompt` replace is permanent (it points to 
Turbot's fork, not a local path).
+
+The `steampipe-postgres-fdw` repo does **not** have pre-configured replace 
directives for local development. If you need to develop the FDW against local 
copies, add them manually:
+
+```go
+// in steampipe-postgres-fdw/go.mod
+replace (
+    github.com/turbot/pipe-fittings/v2 => ../pipe-fittings
+    github.com/turbot/steampipe-plugin-sdk/v5 => ../steampipe-plugin-sdk
+)
+```
+
+#### Cross-Repo Change Workflow
+
+When a change spans multiple repos (e.g. adding a new config field):
+
+1. Make the change in the lowest dependency first (e.g. `pipe-fittings`)
+2. Uncomment the replace directive in the consumer repo (`steampipe`)
+3. Build and test locally with the replace active
+4. Once working, publish the dependency (merge + tag a release)
+5. Update `go.mod` in the consumer to reference the new version: `go get 
github.com/turbot/pipe-fittings/[email protected]`
+6. Re-comment the replace directive
+7. Commit and PR the consumer repo
+
+### Key Directories for Common Tasks
+
+| Task | Where to Look |
+|------|--------------|
+| Fix a CLI command | `cmd/` (command definition) + relevant `pkg/` package |
+| Fix query execution | `pkg/query/`, `pkg/db/db_client/` |
+| Fix interactive mode | `pkg/interactive/` |
+| Fix plugin install/management | `pkg/ociinstaller/`, 
`pkg/pluginmanager_service/` |
+| Fix connection handling | `pkg/steampipeconfig/`, `pkg/connection/` |
+| Fix DB startup/shutdown | `pkg/db/db_local/` |
+| Fix autocomplete | `pkg/interactive/interactive_client_autocomplete.go` |
+| Fix service management | `cmd/service.go`, `pkg/db/db_local/` |
+| Change internal tables | `pkg/introspection/` |
+| Change config parsing | `pkg/steampipeconfig/load_config.go`, pipe-fittings |
+| Fix FDW query planning | `steampipe-postgres-fdw/fdw/` (C) + `hub/` (Go) |
+| Fix qual pushdown | `steampipe-postgres-fdw/quals.go` |
+| Fix type conversion | `steampipe-postgres-fdw/helpers.go` |
+| Fix plugin SDK behavior | `steampipe-plugin-sdk/plugin/` |
+| Fix hydrate execution | `steampipe-plugin-sdk/plugin/table_fetch.go`, 
`row_data.go` |
+| Fix caching | `steampipe-plugin-sdk/query_cache/` |
+| Fix rate limiting | `steampipe-plugin-sdk/rate_limiter/` |
+
+### Important Constants
+
+- **Default DB port**: 9193 (`pkg/constants/db.go`)
+- **PostgreSQL version**: 14.19.0
+- **FDW version**: 2.1.4
+- **Internal schema**: `steampipe_internal`
+- **Install directory**: `~/.steampipe/`
+- **Plugin directory**: `~/.steampipe/plugins/`
+- **Config directory**: `~/.steampipe/config/`
+- **Log directory**: `~/.steampipe/logs/`
+
+### Branching and Workflow
+
+- **Base branch**: `develop` for all work
+- **Main branch**: `main` (releases merge here)
+- **Release branch**: `v2.3.x` (or similar version branch)
+- **Bug fixes**: Use the 2-commit pattern (see `.ai/docs/bug-fix-prs.md`)
+- **PR titles**: End with `closes #XXXX` for bug fixes
+- **Merge-to-develop PRs**: When merging a release or feature branch into 
`develop`, the PR title must be `Merge branch '<branchname>' into develop` 
(e.g. `Merge branch 'v2.3.x' into develop`)
+- **Small PRs**: One logical change per PR
+
+### AI Development Guides
+
+The `.ai/` directory contains detailed guides for AI-assisted development:
+- `.ai/docs/bug-fix-prs.md` - Two-commit bug fix pattern (demonstrate bug, 
then fix)
+- `.ai/docs/bug-workflow.md` - Creating GitHub bug issues
+- `.ai/docs/test-generation-guide.md` - Writing effective Go tests
+- `.ai/docs/parallel-coordination.md` - Coordinating parallel AI agents
+- `.ai/templates/` - PR description templates
+
+## Release Process
+
+Follow these steps in order to perform a release:
+
+### 1. Changelog
+- Draft a changelog entry in `CHANGELOG.md` matching the style of existing 
entries.
+- Use today's date and the next patch version.
+
+### 2. Commit
+- Commit message for release changelog changes should be the version number, 
e.g. `v2.3.5`.
+
+### 3. Release Issue
+- Use the `.github/ISSUE_TEMPLATE/release_issue.md` template.
+- Title: `Steampipe v<version>`, label: `release`.
+
+### 4. PRs
+1. **Against `develop`**: Title should be `Merge branch '<branchname>' into 
develop`.
+2. **Against `main`**: Title should be `Release Steampipe v<version>`.
+   - Body format:
+     ```
+     ## Release Issue
+     [Steampipe v<version>](link-to-release-issue)
+
+     ## Checklist
+     - [ ] Confirmed that version has been correctly upgraded.
+     ```
+   - Tag the release issue to the PR (add `release` label).
+
+### 5. steampipe.io Changelog
+- Create a changelog PR in the `turbot/steampipe.io` repo.
+- Branch off `main`, branch name: `sp-<version without dots>` (e.g. `sp-235`).
+- Add a file at 
`content/changelog/<year>/<YYYYMMDD>-steampipe-cli-v<version-with-dashes>.md`.
+- Frontmatter format:
+  ```
+  ---
+  title: Steampipe CLI v<version> - <short summary>
+  publishedAt: "<YYYY-MM-DD>T10:00:00"
+  permalink: steampipe-cli-v<version-with-dashes>
+  tags: cli
+  ---
+  ```
+- Body should match the changelog content from `CHANGELOG.md`.
+- PR title: `Steampipe CLI v<version>`, base: `main`.
+
+### 6. Deploy steampipe.io
+- After the steampipe.io changelog PR is merged, trigger the `Deploy 
steampipe.io` workflow in `turbot/steampipe.io` from `main`.
+
+### 7. Close Release Issue
+- Check off all items in the release issue checklist as steps are completed.
+- Close the release issue once all steps are done.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/steampipe-2.3.5/go.mod new/steampipe-2.3.6/go.mod
--- old/steampipe-2.3.5/go.mod  2026-02-06 08:59:35.000000000 +0100
+++ new/steampipe-2.3.6/go.mod  2026-02-20 10:26:24.000000000 +0100
@@ -17,7 +17,7 @@
        github.com/fatih/color v1.18.0
        github.com/fsnotify/fsnotify v1.9.0
        github.com/gertd/go-pluralize v0.2.1
-       github.com/go-git/go-git/v5 v5.16.2
+       github.com/go-git/go-git/v5 v5.16.5
        github.com/google/uuid v1.6.0
        github.com/hashicorp/go-hclog v1.6.3
        github.com/hashicorp/go-plugin v1.7.0
@@ -40,8 +40,8 @@
        github.com/spf13/viper v1.20.1
        github.com/thediveo/enumflag/v2 v2.0.7
        github.com/turbot/go-kit v1.3.0
-       github.com/turbot/pipe-fittings/v2 v2.7.2
-       github.com/turbot/steampipe-plugin-sdk/v5 v5.13.0
+       github.com/turbot/pipe-fittings/v2 v2.7.3
+       github.com/turbot/steampipe-plugin-sdk/v5 v5.13.2
        github.com/turbot/terraform-components 
v0.0.0-20250114051614-04b806a9cbed
        github.com/zclconf/go-cty v1.16.3 // indirect
        golang.org/x/exp v0.0.0-20250305212735-054e65f0b394
@@ -161,7 +161,7 @@
        github.com/tklauser/numcpus v0.10.0 // indirect
        github.com/tkrajina/go-reflector v0.5.8 // indirect
        github.com/turbot/pipes-sdk-go v0.12.1 // indirect
-       github.com/ulikunitz/xz v0.5.14 // indirect
+       github.com/ulikunitz/xz v0.5.15 // indirect
        github.com/xlab/treeprint v1.2.0 // indirect
        github.com/zclconf/go-cty-yaml v1.1.0 // indirect
        
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc 
v0.60.0 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/steampipe-2.3.5/go.sum new/steampipe-2.3.6/go.sum
--- old/steampipe-2.3.5/go.sum  2026-02-06 08:59:35.000000000 +0100
+++ new/steampipe-2.3.6/go.sum  2026-02-20 10:26:24.000000000 +0100
@@ -828,8 +828,8 @@
 github.com/go-git/go-billy/v5 v5.6.2/go.mod 
h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
 github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 
h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
 github.com/go-git/go-git-fixtures/v4 
v4.3.2-0.20231010084843-55a94097c399/go.mod 
h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
-github.com/go-git/go-git/v5 v5.16.2 
h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
-github.com/go-git/go-git/v5 v5.16.2/go.mod 
h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
+github.com/go-git/go-git/v5 v5.16.5 
h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
+github.com/go-git/go-git/v5 v5.16.5/go.mod 
h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod 
h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod 
h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod 
h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -1258,17 +1258,17 @@
 github.com/turbot/go-kit v1.3.0/go.mod 
h1:piKJMYCF8EYmKf+D2B78Csy7kOHGmnQVOWingtLKWWQ=
 github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50 
h1:zs87uA6QZsYLk4RRxDOIxt8ro/B2V6HzoMWm05Lo7ao=
 github.com/turbot/go-prompt 
v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50/go.mod 
h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
-github.com/turbot/pipe-fittings/v2 v2.7.2 
h1:fwyzK8tlQJK0SNGLxlZORT7pUI6ghkZwM+wIpf+LMW8=
-github.com/turbot/pipe-fittings/v2 v2.7.2/go.mod 
h1:V619+tgfLaqoEXFDNzA2p24TBZVf4IkDL9FDLQecMnE=
+github.com/turbot/pipe-fittings/v2 v2.7.3 
h1:DacY/pc8zERJYXszkomJCOi1YDK3e2chJ1HEN6GCzgU=
+github.com/turbot/pipe-fittings/v2 v2.7.3/go.mod 
h1:VYqcgGrYDLsGxn1r4dOkkEh5/KDEgJgUU+nf0SAODY0=
 github.com/turbot/pipes-sdk-go v0.12.1 
h1:mF9Z9Mr6F0uqlWjd1mQn+jqT24GPvWDFDrFTvmkazHc=
 github.com/turbot/pipes-sdk-go v0.12.1/go.mod 
h1:iQE0ebN74yqiCRrfv7izxVMRcNlZftPWWDPsMFwejt4=
-github.com/turbot/steampipe-plugin-sdk/v5 v5.13.0 
h1:6GSmiKsPdMd2X1ULK17Q/8UQvNOpyub4F2a5nmMGkis=
-github.com/turbot/steampipe-plugin-sdk/v5 v5.13.0/go.mod 
h1:C4Ogzsd9ea97e7MJF3g/5k/8S0Ec8/iqAlPmr6zGXHA=
+github.com/turbot/steampipe-plugin-sdk/v5 v5.13.2 
h1:4SSI20DCC0N3ItU1HGytCaxaekQMKpYuMOySezQ32zQ=
+github.com/turbot/steampipe-plugin-sdk/v5 v5.13.2/go.mod 
h1:qmfaXKt9z+TgUaFoKkKzwZAwYA5h2Mf/3yuoc+P6otY=
 github.com/turbot/terraform-components v0.0.0-20250114051614-04b806a9cbed 
h1:1ROP+kYJ0vaJu04qpQO5V2PVrUqG7VZmYXzcyP/yDT0=
 github.com/turbot/terraform-components 
v0.0.0-20250114051614-04b806a9cbed/go.mod 
h1:QJMOFtDVHtXLCJr6luh4oFgk6dtdCImDh7XbIXxnGsc=
 github.com/ulikunitz/xz v0.5.10/go.mod 
h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
-github.com/ulikunitz/xz v0.5.14 h1:uv/0Bq533iFdnMHZdRBTOlaNMdb1+ZxXIlHDZHIHcvg=
-github.com/ulikunitz/xz v0.5.14/go.mod 
h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
+github.com/ulikunitz/xz v0.5.15/go.mod 
h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
 github.com/xlab/treeprint v1.2.0 
h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
 github.com/xlab/treeprint v1.2.0/go.mod 
h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
 github.com/yuin/goldmark v1.1.25/go.mod 
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/steampipe-2.3.5/pkg/constants/db.go 
new/steampipe-2.3.6/pkg/constants/db.go
--- old/steampipe-2.3.5/pkg/constants/db.go     2026-02-06 08:59:35.000000000 
+0100
+++ new/steampipe-2.3.6/pkg/constants/db.go     2026-02-20 10:26:24.000000000 
+0100
@@ -28,7 +28,7 @@
 // constants for installing db and fdw images
 const (
        DatabaseVersion = "14.19.0"
-       FdwVersion      = "2.1.4"
+       FdwVersion      = "2.1.5"
 
        // PostgresImageRef is the OCI Image ref for the database binaries
        PostgresImageRef    = "ghcr.io/turbot/steampipe/db:14.19.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/steampipe-2.3.5/pkg/db/db_client/db_client_execute.go 
new/steampipe-2.3.6/pkg/db/db_client/db_client_execute.go
--- old/steampipe-2.3.5/pkg/db/db_client/db_client_execute.go   2026-02-06 
08:59:35.000000000 +0100
+++ new/steampipe-2.3.6/pkg/db/db_client/db_client_execute.go   2026-02-20 
10:26:24.000000000 +0100
@@ -272,8 +272,15 @@
 func (c *DbClient) startQuery(ctx context.Context, conn *pgx.Conn, query 
string, args ...any) (rows pgx.Rows, err error) {
        doneChan := make(chan bool)
        go func() {
-               // start asynchronous query
-               rows, err = conn.Query(ctx, query, args...)
+               // Request text format for timestamptz so PostgreSQL returns 
the value
+               // formatted in the session timezone, matching psql behavior.
+               // By default pgx uses binary format which loses session 
timezone info.
+               queryArgs := make([]any, 0, len(args)+1)
+               queryArgs = append(queryArgs, pgx.QueryResultFormatsByOID{
+                       pgtype.TimestamptzOID: pgx.TextFormatCode,
+               })
+               queryArgs = append(queryArgs, args...)
+               rows, err = conn.Query(ctx, query, queryArgs...)
                close(doneChan)
        }()
 
@@ -351,6 +358,26 @@
                                        elements := utils.Map(arr, func(e 
interface{}) string { return e.(string) })
                                        result[i] = strings.Join(elements, ",")
                                }
+                       case "_DATE":
+                               if arr, ok := columnValue.([]interface{}); ok {
+                                       elements := utils.Map(arr, func(e 
interface{}) string {
+                                               if t, ok := e.(time.Time); ok {
+                                                       return 
t.Format("2006-01-02")
+                                               }
+                                               return fmt.Sprintf("%v", e)
+                                       })
+                                       result[i] = strings.Join(elements, ",")
+                               }
+                       case "_TIMESTAMPTZ":
+                               if arr, ok := columnValue.([]interface{}); ok {
+                                       elements := utils.Map(arr, func(e 
interface{}) string {
+                                               if t, ok := e.(time.Time); ok {
+                                                       return 
t.Format(time.RFC3339)
+                                               }
+                                               return fmt.Sprintf("%v", e)
+                                       })
+                                       result[i] = strings.Join(elements, ",")
+                               }
                        case "INET":
                                if inet, ok := columnValue.(netip.Prefix); ok {
                                        result[i] = 
strings.TrimSuffix(inet.String(), "/32")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/steampipe-2.3.5/pkg/db/db_client/db_client_execute_test.go 
new/steampipe-2.3.6/pkg/db/db_client/db_client_execute_test.go
--- old/steampipe-2.3.5/pkg/db/db_client/db_client_execute_test.go      
1970-01-01 01:00:00.000000000 +0100
+++ new/steampipe-2.3.6/pkg/db/db_client/db_client_execute_test.go      
2026-02-20 10:26:24.000000000 +0100
@@ -0,0 +1,159 @@
+package db_client
+
+import (
+       "os"
+       "strings"
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+)
+
+// TestTimestamptzTextFormatImplemented verifies that the timestamptz wire 
protocol fix is in place.
+// Reference: https://github.com/turbot/steampipe/issues/4450
+//
+// This test verifies that startQuery uses QueryResultFormatsByOID to request 
text format
+// for timestamptz columns, ensuring PostgreSQL formats values using the 
session timezone.
+//
+// Without this fix, pgx uses binary protocol which loses session timezone 
info, causing
+// timestamptz values to display in the local machine timezone instead of the 
session timezone.
+func TestTimestamptzTextFormatImplemented(t *testing.T) {
+       // Read the db_client_execute.go file to verify the fix is present
+       content, err := os.ReadFile("db_client_execute.go")
+       require.NoError(t, err, "should be able to read db_client_execute.go")
+
+       sourceCode := string(content)
+
+       // Verify QueryResultFormatsByOID is used
+       assert.Contains(t, sourceCode, "pgx.QueryResultFormatsByOID",
+               "QueryResultFormatsByOID must be used to specify format for 
specific column types")
+
+       // Verify TimestamptzOID is referenced
+       assert.Contains(t, sourceCode, "pgtype.TimestamptzOID",
+               "TimestamptzOID must be specified to request text format for 
timestamptz columns")
+
+       // Verify TextFormatCode is used
+       assert.Contains(t, sourceCode, "pgx.TextFormatCode",
+               "TextFormatCode must be used to request text format")
+
+       // Verify the fix is in startQuery function
+       funcStart := strings.Index(sourceCode, "func (c *DbClient) startQuery")
+       assert.NotEqual(t, -1, funcStart, "startQuery function must exist")
+
+       // Extract just the startQuery function for more precise checking
+       funcEnd := strings.Index(sourceCode[funcStart:], "\nfunc ")
+       if funcEnd == -1 {
+               funcEnd = len(sourceCode)
+       } else {
+               funcEnd += funcStart
+       }
+       startQueryFunc := sourceCode[funcStart:funcEnd]
+
+       // Verify all three components are in startQuery
+       assert.Contains(t, startQueryFunc, "QueryResultFormatsByOID",
+               "QueryResultFormatsByOID must be in startQuery function")
+       assert.Contains(t, startQueryFunc, "TimestamptzOID",
+               "TimestamptzOID must be in startQuery function")
+       assert.Contains(t, startQueryFunc, "TextFormatCode",
+               "TextFormatCode must be in startQuery function")
+
+       // Verify there's a comment explaining the fix
+       hasComment := strings.Contains(startQueryFunc, "session timezone") ||
+               strings.Contains(startQueryFunc, "text format for timestamptz") 
||
+               strings.Contains(startQueryFunc, "Request text format")
+       assert.True(t, hasComment,
+               "Comment should explain why text format is needed for 
timestamptz")
+
+       // Verify queryArgs are constructed and used
+       assert.Contains(t, startQueryFunc, "queryArgs",
+               "queryArgs variable must be used to prepend format 
specification")
+       assert.Contains(t, startQueryFunc, "conn.Query(ctx, query, 
queryArgs...)",
+               "conn.Query must use queryArgs instead of args directly")
+}
+
+// TestTimestamptzFormatCorrectness verifies the format specification structure
+func TestTimestamptzFormatCorrectness(t *testing.T) {
+       content, err := os.ReadFile("db_client_execute.go")
+       require.NoError(t, err, "should be able to read db_client_execute.go")
+
+       sourceCode := string(content)
+
+       // Verify the QueryResultFormatsByOID is constructed as the first 
element
+       // This is critical - it must be the first argument before actual query 
parameters
+       assert.Contains(t, sourceCode, "queryArgs := make([]any, 0, 
len(args)+1)",
+               "queryArgs must be allocated with capacity for format spec + 
args")
+
+       // Verify format spec is appended first
+       lines := strings.Split(sourceCode, "\n")
+       var foundMake, foundAppendFormat, foundAppendArgs bool
+       var makeIdx, appendFormatIdx, appendArgsIdx int
+
+       for i, line := range lines {
+               if strings.Contains(line, "queryArgs := make([]any, 0, 
len(args)+1)") {
+                       foundMake = true
+                       makeIdx = i
+               }
+               if strings.Contains(line, "queryArgs = append(queryArgs, 
pgx.QueryResultFormatsByOID{") {
+                       foundAppendFormat = true
+                       appendFormatIdx = i
+               }
+               if strings.Contains(line, "queryArgs = append(queryArgs, 
args...)") {
+                       foundAppendArgs = true
+                       appendArgsIdx = i
+               }
+       }
+
+       assert.True(t, foundMake, "queryArgs must be allocated")
+       assert.True(t, foundAppendFormat, "format spec must be appended to 
queryArgs")
+       assert.True(t, foundAppendArgs, "original args must be appended to 
queryArgs")
+
+       // Verify correct order: make -> append format spec -> append args
+       if foundMake && foundAppendFormat && foundAppendArgs {
+               assert.Less(t, makeIdx, appendFormatIdx,
+                       "queryArgs must be allocated before appending format 
spec")
+               assert.Less(t, appendFormatIdx, appendArgsIdx,
+                       "format spec must be appended before original args")
+       }
+}
+
+// TestTimestamptzFormatDoesNotAffectOtherTypes verifies only timestamptz 
format is changed
+func TestTimestamptzFormatDoesNotAffectOtherTypes(t *testing.T) {
+       content, err := os.ReadFile("db_client_execute.go")
+       require.NoError(t, err, "should be able to read db_client_execute.go")
+
+       sourceCode := string(content)
+
+       // Find the QueryResultFormatsByOID map construction
+       funcStart := strings.Index(sourceCode, "func (c *DbClient) startQuery")
+       require.NotEqual(t, -1, funcStart, "startQuery function must exist")
+
+       funcEnd := strings.Index(sourceCode[funcStart:], "\nfunc ")
+       if funcEnd == -1 {
+               funcEnd = len(sourceCode)
+       } else {
+               funcEnd += funcStart
+       }
+       startQueryFunc := sourceCode[funcStart:funcEnd]
+
+       // Verify ONLY TimestamptzOID is in the map (no other OIDs)
+       // This ensures we don't accidentally change format for other types
+       otherOIDs := []string{
+               "DateOID",
+               "TimestampOID",
+               "TimeOID",
+               "IntervalOID",
+               "JSONOID",
+               "JSONBOID",
+       }
+
+       for _, oid := range otherOIDs {
+               assert.NotContains(t, startQueryFunc, "pgtype."+oid,
+                       "Should not change format for "+oid+" - only 
timestamptz needs text format")
+       }
+
+       // Verify there's only one entry in QueryResultFormatsByOID
+       // Count how many times we see "OID:" in the map definition
+       oidCount := strings.Count(startQueryFunc, "OID:")
+       assert.Equal(t, 1, oidCount,
+               "QueryResultFormatsByOID should have exactly one entry 
(TimestamptzOID)")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/steampipe-2.3.5/tests/acceptance/test_data/templates/expected_6.json 
new/steampipe-2.3.6/tests/acceptance/test_data/templates/expected_6.json
--- old/steampipe-2.3.5/tests/acceptance/test_data/templates/expected_6.json    
2026-02-06 08:59:35.000000000 +0100
+++ new/steampipe-2.3.6/tests/acceptance/test_data/templates/expected_6.json    
2026-02-20 10:26:24.000000000 +0100
@@ -115,7 +115,7 @@
     "booleancolumn": true,
     "cidrrange": "10.1.2.3/32",
     "currency": "$922,337,203,685,477.57",
-    "date1": "1978-02-05 00:00:00",
+    "date1": "1978-02-05",
     "floatcolumn": 4.681642125488754,
     "integercolumn1": 3278,
     "integercolumn2": 21445454,
@@ -147,7 +147,7 @@
     "textcolumn3": "This is a very long text for the PostgreSQL text column",
     "time1": "08:00:00",
     "timestamp1": "2016-06-22 19:10:25",
-    "timestamp2": "2016-06-23T07:40:25+05:30",
+    "timestamp2": "2016-06-23T02:10:25Z",
     "uuidcolumn": "6948df80-14bd-4e04-8842-7668d9c001f5",
     "xmldata": "<book><title>Manual</title><chapter>...</chapter></book>"
    }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/steampipe-2.3.5/tests/acceptance/test_files/date_time_types.bats 
new/steampipe-2.3.6/tests/acceptance/test_files/date_time_types.bats
--- old/steampipe-2.3.5/tests/acceptance/test_files/date_time_types.bats        
1970-01-01 01:00:00.000000000 +0100
+++ new/steampipe-2.3.6/tests/acceptance/test_files/date_time_types.bats        
2026-02-20 10:26:24.000000000 +0100
@@ -0,0 +1,159 @@
+load "$LIB_BATS_ASSERT/load.bash"
+load "$LIB_BATS_SUPPORT/load.bash"
+
+# Test DATE, TIMESTAMP, TIMESTAMPTZ display formatting
+# Verifies fix for issue #4450
+
+@test "DATE displays without time component" {
+  run steampipe query "select '1984-01-01'::date as date_val" --output json
+  echo "$output" | jq -e '.rows[0].date_val == "1984-01-01"'
+  assert_success
+}
+
+@test "DATE with table output" {
+  run steampipe query "select '2024-02-29'::date as leap_date"
+  assert_output --partial "2024-02-29"
+  refute_output --partial "00:00:00"
+}
+
+@test "DATE NULL value" {
+  run steampipe query "select null::date as null_date" --output json
+  echo "$output" | jq -e '.rows[0].null_date == null'
+  assert_success
+}
+
+@test "TIMESTAMPTZ displays with UTC timezone" {
+  run steampipe query "select '1984-01-01T00:00:00Z'::timestamptz as tstz" 
--output json
+  echo "$output" | jq -e '.rows[0].tstz == "1984-01-01T00:00:00Z"'
+  assert_success
+}
+
+@test "TIMESTAMPTZ with table output" {
+  run steampipe query "select '2024-01-15T10:30:45Z'::timestamptz as tstz"
+  assert_output --partial "2024-01-15T10:30:45Z"
+}
+
+@test "TIMESTAMPTZ respects session timezone" {
+  # Default session timezone is UTC
+  run steampipe query "show timezone" --output json
+  echo "$output" | jq -e '.rows[0].TimeZone == "UTC"'
+  assert_success
+}
+
+@test "TIMESTAMPTZ NULL value" {
+  run steampipe query "select null::timestamptz as null_tstz" --output json
+  echo "$output" | jq -e '.rows[0].null_tstz == null'
+  assert_success
+}
+
+@test "TIMESTAMP displays without timezone" {
+  run steampipe query "select '1984-01-01 12:30:45'::timestamp as ts" --output 
json
+  echo "$output" | jq -e '.rows[0].ts == "1984-01-01 12:30:45"'
+  assert_success
+}
+
+@test "TIME displays correctly" {
+  run steampipe query "select '15:30:45'::time as time_val" --output json
+  echo "$output" | jq -e '.rows[0].time_val == "15:30:45"'
+  assert_success
+}
+
+@test "INTERVAL displays correctly" {
+  run steampipe query "select '1 year 2 months 3 days'::interval as 
interval_val"
+  assert_output --partial "1 year 2 mons 3 days"
+}
+
+@test "Multiple date/time types together" {
+  run steampipe query "select '2024-01-15'::date as d, '2024-01-15 
10:30:00'::timestamp as ts, '2024-01-15T10:30:00Z'::timestamptz as tstz" 
--output json
+
+  # Verify DATE has no time component
+  echo "$output" | jq -e '.rows[0].d == "2024-01-15"'
+  assert_success
+
+  # Verify TIMESTAMP has time but no timezone
+  echo "$output" | jq -e '.rows[0].ts == "2024-01-15 10:30:00"'
+  assert_success
+
+  # Verify TIMESTAMPTZ has timezone
+  echo "$output" | jq -e '.rows[0].tstz == "2024-01-15T10:30:00Z"'
+  assert_success
+}
+
+@test "DATE CSV output" {
+  run steampipe query "select '1984-01-01'::date as date_val" --output csv
+  assert_output --partial "date_val"
+  assert_output --partial "1984-01-01"
+  refute_output --partial "00:00:00"
+}
+
+@test "TIMESTAMPTZ CSV output" {
+  run steampipe query "select '1984-01-01T00:00:00Z'::timestamptz as tstz" 
--output csv
+  assert_output --partial "tstz"
+  assert_output --partial "1984-01-01T00:00:00Z"
+}
+
+@test "DATE line output" {
+  run steampipe query "select '1984-01-01'::date as date_val" --output line
+  assert_output --partial "date_val"
+  assert_output --partial "1984-01-01"
+  refute_output --partial "00:00:00"
+}
+
+@test "DATE array" {
+  run steampipe query "select array['2024-01-01'::date, '2024-12-31'::date] as 
date_array" --output json
+  # Array format may vary, just verify it contains the dates without time 
component
+  echo "$output" | jq -r '.rows[0].date_array' | grep "2024-01-01"
+  assert_success
+  echo "$output" | jq -r '.rows[0].date_array' | grep "2024-12-31"
+  assert_success
+  # Verify no time component in array values
+  refute_output --partial "00:00:00"
+}
+
+@test "TIMESTAMPTZ edge case - leap year" {
+  run steampipe query "select '2024-02-29T23:59:59Z'::timestamptz as 
leap_tstz" --output json
+  echo "$output" | jq -e '.rows[0].leap_tstz == "2024-02-29T23:59:59Z"'
+  assert_success
+}
+
+@test "TIMESTAMPTZ edge case - year 1" {
+  run steampipe query "select '0001-01-01T00:00:00Z'::timestamptz as min_tstz" 
--output json
+  assert_success
+}
+
+@test "DATE comparison preserves semantics" {
+  # Verify that DATE values can be compared correctly
+  run steampipe query "select ('2024-01-15'::date > '2024-01-01'::date) as 
result" --output json
+  echo "$output" | jq -e '.rows[0].result == true'
+  assert_success
+}
+
+@test "now() returns timestamptz in UTC" {
+  run steampipe query "select now() as now_val" --output json
+  # Should end with Z or +00:00 or +00 (UTC timezone indicators)
+  # Extract the value and check it contains UTC timezone marker
+  now_val=$(echo "$output" | jq -r '.rows[0].now_val')
+  echo "now() returned: $now_val"
+  # Check for Z suffix or +00:00 or +00 offset
+  echo "$now_val" | grep -E '(Z|(\+|-)?00:?00)$'
+  assert_success
+}
+
+@test "current_date returns date without time" {
+  run steampipe query "select current_date as today" --output json
+  # Should not contain time component (no colons for time)
+  today=$(echo "$output" | jq -r '.rows[0].today')
+  echo "current_date returned: $today"
+  # Verify it matches YYYY-MM-DD format without time
+  echo "$today" | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'
+  assert_success
+}
+
+function teardown_file() {
+  # list running processes
+  ps -ef | grep steampipe
+
+  # check if any processes are running
+  num=$(ps aux | grep steampipe | grep -v bats | grep -v grep | grep -v 
tests/acceptance | wc -l | tr -d ' ')
+  assert_equal $num 0
+}

++++++ steampipe.obsinfo ++++++
--- /var/tmp/diff_new_pack.NSEv7P/_old  2026-02-24 15:40:00.161905774 +0100
+++ /var/tmp/diff_new_pack.NSEv7P/_new  2026-02-24 15:40:00.169906105 +0100
@@ -1,5 +1,5 @@
 name: steampipe
-version: 2.3.5
-mtime: 1770364775
-commit: a4b708bcc1939d72853932b78db51ba8d92227ac
+version: 2.3.6
+mtime: 1771579584
+commit: b713a4cdc6a1799531d0f8192713b6b7f6b3725e
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/steampipe/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.steampipe.new.1977/vendor.tar.gz differ: char 27, 
line 1

Reply via email to