diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 000000000..5592118f6 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run -p xtask --" diff --git a/Cargo.lock b/Cargo.lock index 386a1c52a..8a843c4d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -782,6 +782,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +[[package]] +name = "camino" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d07aa9a93b00c76f71bc35d598bed923f6d4f3a9ca5c24b7737ae1a292841c0" + [[package]] name = "cast" version = "0.3.0" @@ -1236,6 +1242,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dir-test" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62c013fe825864f3e4593f36426c1fa7a74f5603f13ca8d1af7a990c1cd94a79" +dependencies = [ + "dir-test-macros", +] + +[[package]] +name = "dir-test-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42f54d7b4a6bc2400fe5b338e35d1a335787585375322f49c5d5fe7b243da7e" +dependencies = [ + "glob", + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "directories" version = "5.0.1" @@ -1322,6 +1349,19 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "download_regression_tests" +version = "0.0.0" +dependencies = [ + "anyhow", + "camino", + "pgt_query", + "pgt_statement_splitter", + "regex", + "serde", + "serde_json", +] + [[package]] name = "drop_bomb" version = "0.1.5" @@ -3024,6 +3064,31 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "pgt_pretty_print" +version = "0.0.0" +dependencies = [ + "camino", + "dir-test", + "insta", + "pgt_pretty_print_codegen", + "pgt_query", + "pgt_statement_splitter", +] + +[[package]] +name = "pgt_pretty_print_codegen" +version = "0.0.0" +dependencies = [ + "anyhow", + "convert_case", + "proc-macro2", + "prost-reflect", + "protox", + "quote", + "ureq", +] + [[package]] name = "pgt_query" version = "0.0.0" @@ -5618,6 +5683,19 @@ dependencies = [ "zip", ] +[[package]] +name = "xtask_agentic" +version = "0.0.0" +dependencies = [ + "anyhow", + "bpaf", + "pgt_pretty_print", + "pgt_query", + "serde", + "serde_json", + "xtask", +] + [[package]] name = "xtask_codegen" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 84fed3d18..17c3d4d4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,13 @@ [workspace] -members = ["crates/*", "lib/*", "xtask/codegen", "xtask/rules_check", "docs/codegen"] +members = [ + "crates/*", + "lib/*", + "xtask/codegen", + "xtask/rules_check", + "xtask/agentic", + "xtask/download_regression_tests", + "docs/codegen", +] resolver = "2" [workspace.package] @@ -23,7 +31,9 @@ biome_js_syntax = "0.5.7" biome_rowan = "0.5.7" biome_string_case = "0.5.8" bpaf = { version = "0.9.15", features = ["derive"] } +camino = "1.1.9" crossbeam = "0.8.4" +dir-test = "0.4.1" enumflags2 = "0.7.11" ignore = "0.4.23" indexmap = { version = "2.6.0", features = ["serde"] } @@ -78,6 +88,8 @@ pgt_lexer_codegen = { path = "./crates/pgt_lexer_codegen", version = "0 pgt_lsp = { path = "./crates/pgt_lsp", version = "0.0.0" } pgt_markup = { path = "./crates/pgt_markup", version = "0.0.0" } pgt_plpgsql_check = { path = "./crates/pgt_plpgsql_check", version = "0.0.0" } +pgt_pretty_print = { path = "./crates/pgt_pretty_print", version = "0.0.0" } +pgt_pretty_print_codegen = { path = "./crates/pgt_pretty_print_codegen", version = "0.0.0" } pgt_query = { path = "./crates/pgt_query", version = "0.0.0" } pgt_query_ext = { path = "./crates/pgt_query_ext", version = "0.0.0" } pgt_query_macros = { path = "./crates/pgt_query_macros", version = "0.0.0" } diff --git a/STATE.md b/STATE.md new file mode 100644 index 000000000..2240117ff --- /dev/null +++ b/STATE.md @@ -0,0 +1,56 @@ +# Pretty Print Formatter State + +## Current Phase: Code Quality Improvements - COMPLETED ✅ + +## Last Completed Work +- Fixed all forbidden patterns in nodes.rs: + - Removed length-based formatting logic (e.g., `if items.len() > 3`) + - Eliminated manual child node parsing patterns (e.g., `if let Some(pgt_query::protobuf::node::Node::List(list))`) + - Enhanced List implementation with context-aware formatting +- Added helper functions for common string formatting patterns +- Cleaned up ObjectOpfamily/ObjectOpclass handling +- Fixed clippy warnings and compilation errors + +## Issues Found and Fixed + +### 1. Length-based Formatting ✅ FIXED +- **Issue**: Code changing formatting behavior based on list length +- **Locations**: InsertStmt (line 1159), AExprList (line 1258) +- **Solution**: Use consistent formatting with SoftOrSpace, let renderer decide breaks + +### 2. Manual Child Node Parsing ✅ FIXED +- **Issue**: Parent nodes manually inspecting child node types instead of calling `to_tokens()` +- **Locations**: + - DropStmt (line 1742) + - RangeFunction (line 2228) + - DefElem instances (lines 3019, 3100, 3172, 3277) + - RenameStmt (line 6314) + - AlterObjectSchemaStmt (line 6489) + - AlterOwnerStmt (line 6581) +- **Solution**: Use `node.to_tokens(e)` and enhanced List context handling + +### 3. Code Quality Improvements ✅ FIXED +- Added EventEmitter helper methods for string formatting +- Consolidated identical if blocks in List implementation +- Fixed clippy warnings (collapsible if/else, unused code, etc.) +- Improved ObjectOpfamily/ObjectOpclass logic with cleaner pattern matching + +## Architecture Improvements Made +- **Proper separation of concerns**: Parent nodes call `child.to_tokens(e)` +- **Context-aware child formatting**: List node uses EventEmitter context functions +- **Helper functions**: Common string formatting patterns abstracted +- **Consistent patterns**: No hardcoded conditional logic based on lengths or types + +## Documentation Updates +- Updated `agentic/pretty_printer.md` with new forbidden patterns +- Added string formatting helper guidance +- Added manual child node parsing prevention rules + +## Code Quality Status +- All forbidden patterns eliminated ✅ +- Clippy warnings addressed ✅ +- Compilation successful ✅ +- Architecture follows clean separation of concerns ✅ + +## Notes for Resumption +This architectural cleanup phase is complete. All forbidden patterns have been eliminated and the codebase now follows proper parent-child delegation patterns with context-aware formatting. The next phase would be to continue with the main formatting task using the improved, clean architecture. \ No newline at end of file diff --git a/agentic/agentic_loop.md b/agentic/agentic_loop.md new file mode 100644 index 000000000..e97d8f948 --- /dev/null +++ b/agentic/agentic_loop.md @@ -0,0 +1,212 @@ +# Agentic Loop Guide for AI Agents + +## Your Mission + +You are an autonomous AI agent executing long-running tasks. You MUST maintain state, track progress, and enable task resumption across sessions. Follow this guide precisely. + +## Critical Requirements + +### 1. Always Maintain State + +You MUST use these tools to persist your progress: + +#### TodoWrite Tool (MANDATORY) +``` +Use TodoWrite to maintain a persistent TODO list that survives between sessions. +Update it: +- When starting any task +- After completing each item +- When discovering new work +- Before any long operation +- At regular intervals +``` + +#### STATE.md File (MANDATORY) +Create and update a STATE.md file with: +- Current phase of work +- Completed items with outcomes +- In-progress work +- Remaining tasks +- Key learnings and patterns discovered +- Blocking issues +- Notes for resumption + +### 2. Signal Completion + +**CRITICAL**: When your task is complete, output exactly: +``` +TASK COMPLETE +``` + +This enables automated systems to detect completion. + +If there is still work left to do, output: +``` +CONTINUE +``` + + +### 3. Work Systematically + +#### Phase 1: Discovery +- List ALL items to process +- Count total work +- Create initial TODO list +- Document scope in STATE.md + +#### Phase 2: Analysis +- Review each item against criteria +- Identify specific issues +- Add each issue to TODO list with specific names +- Update STATE.md with findings + +#### Phase 3: Implementation +- Mark current item as "in_progress" in TODO +- Apply fixes systematically +- Test each change +- Mark item as "completed" immediately after success +- Document successful patterns in STATE.md + +#### Phase 4: Validation +- Run comprehensive tests +- Verify all success criteria met +- Ensure no regressions +- Update final state + +### 4. Handle Interruptions Gracefully + +Since you may be interrupted at any time: +- Update TodoWrite before starting any task +- Write progress to STATE.md after each milestone +- Make changes incrementally +- Test as you go +- Leave clear notes about current state + +### 5. Be Specific + +When tracking work: +- Use exact file names: "Fix test_formatter__create_stmt_0_60" +- NOT vague descriptions: "Fix some tests" +- Include line numbers when relevant +- Document the specific fix applied + +### 6. Learn and Document + +When you discover patterns: +- Add them to STATE.md immediately +- Apply the same fix to similar issues +- Document what worked and why +- Share context for future sessions + +## Your Workflow + +``` +START: +1. Read the task instructions in the .md file +2. Check for existing STATE.md - if exists, read it +3. Initialize or update TodoWrite with current work +4. Begin systematic execution + +DURING WORK: +1. Update TODO status before starting each item +2. Work on ONE item at a time +3. Test changes immediately +4. Mark items complete as soon as done +5. Update STATE.md with learnings +6. Check remaining work regularly + +WHEN BLOCKED: +1. Document the blocker in STATE.md +2. Add a TODO for resolving it +3. Move to next unblocked item +4. Leave clear notes for resumption + +COMPLETION: +1. Verify all TODOs are complete +2. Run final validation +3. Update STATE.md with final status +4. Output "TASK COMPLETE" +``` + +## Example TODO Management + +``` +# Starting work +TodoWrite: [ + {content: "Analyze all test failures", status: "pending", priority: "high", id: "1"}, + {content: "Fix create_stmt formatting", status: "pending", priority: "high", id: "2"} +] + +# During work +TodoWrite: [ + {content: "Analyze all test failures", status: "completed", priority: "high", id: "1"}, + {content: "Fix create_stmt formatting", status: "in_progress", priority: "high", id: "2"}, + {content: "Fix line length in alter_stmt", status: "pending", priority: "medium", id: "3"} +] + +# Important: Only ONE item should ever be "in_progress" +``` + +## Example STATE.md Updates + +```markdown +# Pretty Printer Formatting State + +## Current Phase: Implementation + +## Completed Fixes: +1. ✅ composite_type_stmt_0_60 - Added indentation using indent_start/end +2. ✅ partition_elem_0_60 - Reused CreateStmt fix + +## In Progress: +- Fixing create_stmt_0_60 line breaks + +## Learnings: +- Use Soft instead of SoftOrSpace around parentheses for compact formatting +- CreateStmt indentation fix applies to all table definitions + +## Next Steps: +- Test remaining 3 failures +- Apply similar patterns where applicable +``` + +## Testing Your Changes + +Always verify your work: +```bash +# Test specific change +cargo test -p package test_name -- --show-output + +# Check for failures +cargo test -p package 2>&1 | grep "FAILED" + +# Accept valid changes +cargo insta accept +``` + +## Remember + +1. **You are autonomous** - Make decisions based on patterns you learn +2. **You are persistent** - Your state survives interruptions +3. **You are systematic** - Work through items methodically +4. **You are thorough** - Document everything for resumption +5. **You complete tasks** - Output "TASK COMPLETE" when done + +## Common Pitfalls to Avoid + +- ❌ Working on multiple items simultaneously +- ❌ Forgetting to update TODO status +- ❌ Making changes without testing +- ❌ Vague TODO descriptions +- ❌ Not documenting learnings +- ❌ Forgetting to output "TASK COMPLETE" after everything is completed +- ❌ Forgetting to output "CONTINUE" when there is still work left to do + +## Your Success Metrics + +- ✅ All TODOs marked complete +- ✅ STATE.md fully updated +- ✅ All tests passing +- ✅ Learnings documented + +Follow this guide to execute tasks successfully across multiple sessions while maintaining perfect state tracking. diff --git a/agentic/implement_pretty_print_tokens.md b/agentic/implement_pretty_print_tokens.md new file mode 100644 index 000000000..a84cb0aab --- /dev/null +++ b/agentic/implement_pretty_print_tokens.md @@ -0,0 +1,265 @@ +# Autonomous PostgreSQL Pretty Printer Implementation and Formatting + +You are an autonomous Rust code generator building and improving a PostgreSQL pretty printer by implementing ToTokens traits for AST nodes and ensuring all output is properly formatted. + +## REQUIRED READING: +Before starting, you MUST read these additional files in the agentic directory for complete context and guidelines: + +1. **`agentic/sql_formatter_improvements.md`** - Contains detailed formatting principles, EventEmitter usage patterns, and code examples +2. **`agentic/fix_remaining_formatter_failures.md`** - Contains the comprehensive workflow for reviewing and fixing all formatter tests systematically + +These files contain critical information about formatting rules, indentation hierarchy, line breaking strategies, and testing workflows that are essential for this task. + +## PROJECT CONTEXT: +This is a PostgreSQL pretty printer that takes parsed AST nodes and converts them back into well-formatted SQL code. Many AST nodes already have ToTokens implementations, but they need to be improved to produce better formatting. + +Your goal is to: +1. Implement ToTokens for any remaining unimplemented nodes +2. Fix and improve existing implementations to produce properly formatted output +3. Ensure all tests pass with correctly formatted SQL that respects line length limits + +## YOUR INFINITE LOOP TASK: + +1. **Run all pretty printer tests** to identify failing tests: `cargo test -p pgt_pretty_print` +2. **Pick the next failing test** from the output +3. **Examine the test file** in `crates/pgt_pretty_print/tests/data/` to understand the SQL +4. **Use pgFormatter for inspiration**: `pg_format crates/pgt_pretty_print/tests/data/[test_file].sql` +5. **Read the current snapshot** if it exists to see the current output +6. **Find the relevant ToTokens implementation** in `crates/pgt_pretty_print/src/nodes.rs` +7. **Improve the formatting**: + - Add proper line breaks with + - Add indentation for subordinate clauses + - Ensure line length compliance (60 chars max) + - Follow the indentation hierarchy rules +8. **Run the specific test** to check your changes +9. **Read the updated snapshot** to verify the output looks correct +10. **Run all tests again** to ensure no regressions +11. **Repeat from step 1** until all tests pass + +## CRITICAL RULES: + +- **NEVER EVER add comments to Rust code** - ZERO // comments, ZERO /* */ comments in implementations +- **NEVER manually implement nested nodes** - Always call .to_tokens(e) on child nodes, never implement their logic +- **Use existing ToTokens implementations** - If a node already has ToTokens, call it, don't reimplement +- **ALWAYS use enum accessor methods** - Use `self.field()` NOT `EnumType::try_from(self.field).unwrap()` for enum fields + - Example: `self.jointype()` returns `JoinType` enum directly + - Example: `self.op()` returns the operation enum directly + - Never use manual try_from conversions for protobuf enum fields +- **Line length must be ≤ 60 characters** (except for JSON content) +- **JSON Exception**: Do NOT format JSON strings/objects - accept longer line widths for JSON content +- **Use pgFormatter as inspiration** - Run `pg_format` on test files to see ideal formatting + +## GROUP AND CONTEXT SYSTEM: + +- **Complex nodes MUST create groups**: `e.group_start(GroupKind::NodeName, None, false);` and `e.group_end();` +- **Simple nodes NO groups**: String, AConst, and other leaf nodes emit tokens directly +- **Context-aware formatting**: Use `e.is_within_group(GroupKind::ParentType)` to adapt behavior +- **Semicolons for top-level statements**: Use `if e.is_top_level() { e.token(TokenKind::SEMICOLON); }` +- **Never maintain explicit context state** - always introspect the event stream + +## FORBIDDEN PATTERNS: +- `// Handle XYZ formatting directly` - NEVER add explanatory comments +- `if let Some(node::Node::SomeType(inner)) = &node.node { /* manual implementation */ }` - NEVER manually implement child nodes +- Always use: `child_node.to_tokens(e)` instead of manual implementations + +## FILE PATHS: +- Target file for implementations: `crates/pgt_pretty_print/src/nodes.rs` +- Single-statement test files: `crates/pgt_pretty_print/tests/data/single/*.sql` +- Multi-statement test files: `crates/pgt_pretty_print/tests/data/multi/*.sql` +- Snapshot files: `crates/pgt_pretty_print/tests/snapshots/tests__test_formatter__*.snap` +- AST structure reference: `crates/pgt_query/src/protobuf.rs` + +## TOOLS AVAILABLE: +- Read: Read any file +- Write: Create new files +- Edit/MultiEdit: Modify existing files +- Bash: Run commands like cargo check, cargo test +- Grep: Search for patterns in files +- ast-grep: Use ast-grep (https://ast-grep.github.io/) for advanced code pattern searching and analysis + +## FORMATTING PRINCIPLES: + +### Indentation Hierarchy +1. **Main statement keywords** (CREATE, ALTER, MERGE, etc.) - Base level (no indent) +2. **Primary clauses** (SELECT, FROM, WHERE, etc.) - Base level +3. **Optional/subordinate clauses** (TO, DO, OPTIONS, VERSION, etc.) - Indented 1 level +4. **Sub-clauses within actions** (SET assignments, VALUES lists) - Indented 2 levels +5. **Complex nested structures** - Additional indentation as needed + +### Line Breaking Strategy +- Use `LineType::SoftOrSpace` or `LineType::Soft` before major clauses +- Keep related parts together when possible +- Break at natural clause boundaries (WHERE, ORDER BY, GROUP BY) +- Respect 60 character line limit (except JSON content) + +### Context-Aware Formatting +Use EventEmitter context helpers when needed: +- `e.is_within_group(GroupKind::SelectStmt)` - Check if within a specific statement type +- `e.parent_group()` - Get immediate parent group for conditional formatting +- Most formatting should be consistent regardless of context + +## TESTING WORKFLOW: + +1. **Run all tests to find failures**: + ```bash + cargo test -p pgt_pretty_print + ``` + +2. **Run specific failing test**: + ```bash + cargo test -p pgt_pretty_print test_formatter__[test_name] -- --show-output + ``` + +3. **Use pgFormatter for ideal formatting**: + ```bash + pg_format crates/pgt_pretty_print/tests/data/[test_file].sql + ``` + +4. **Review snapshot after changes**: + ```bash + cat crates/pgt_pretty_print/tests/snapshots/tests__test_formatter__[test_name].snap + ``` + +5. **Accept valid changes**: + ```bash + cargo insta review + ``` + +## CORRECT IMPLEMENTATION PATTERN: +```rust +// Complex node with group +impl ToTokens for SomeComplexNode { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::SomeComplexNode, None, false); + + // Using enum accessor methods - ALWAYS use this pattern + match self.jointype() { // ✅ CORRECT - use accessor method + JoinType::JoinInner => e.token(TokenKind::INNER_KW), + JoinType::JoinLeft => e.token(TokenKind::LEFT_KW), + _ => {} + } + + e.token(TokenKind::KEYWORD("SELECT".to_string())); + if let Some(ref child) = self.some_child { + child.to_tokens(e); // ✅ CORRECT - delegate to existing ToTokens + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +// Simple leaf node without group +impl ToTokens for SomeSimpleNode { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.value.clone())); + } +} + +// Context-aware node +impl ToTokens for ContextSensitiveNode { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ContextSensitiveNode, None, false); + + if e.is_within_group(GroupKind::UpdateStmt) { + // UPDATE SET formatting: column = value + } else { + // SELECT formatting: value AS alias + } + + e.group_end(); + } +} +``` + +## WRONG IMPLEMENTATION PATTERN (FORBIDDEN): +```rust +impl ToTokens for SomeNode { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::SomeNode, None, false); + + // ❌ FORBIDDEN - using try_from for enum conversion + match JoinType::try_from(self.jointype).unwrap() { + JoinType::JoinInner => e.token(TokenKind::INNER_KW), + _ => {} + } + + if let Some(ref child) = self.some_child { + // Handle child formatting directly ❌ FORBIDDEN COMMENT + if let Some(node::Node::ChildType(inner)) = &child.node { + // ❌ FORBIDDEN - manual implementation of child + e.token(TokenKind::IDENT(inner.name.clone())); + } + } + + e.group_end(); + } +} +``` + +## COMMON FORMATTING PATTERNS: + +### ALTER Statements +```rust +// Always indent optional clauses +e.indent_start(); +e.line(LineType::SoftOrSpace); +e.token(TokenKind::VERSION_KW); +e.space(); +version.to_tokens(e); +e.indent_end(); +``` + +### Lists and Parameters +```rust +for (i, item) in items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); // Allow breaking between items + } + item.to_tokens(e); +} +``` + +### Hierarchical Structures (MERGE, etc.) +```rust +// Indent actions under WHEN clauses +e.indent_start(); // Level 1 +e.line(LineType::SoftOrSpace); +e.token(TokenKind::UPDATE_KW); +e.space(); +e.token(TokenKind::SET_KW); +e.indent_start(); // Level 2 for SET items +// ... +e.indent_end(); // End level 2 +e.indent_end(); // End level 1 +``` + +## KEY CONTEXT RULES: +- **Complex nodes** (statements, expressions, structured data) MUST use groups with GroupKind +- **Simple leaf nodes** (String, AConst) emit tokens directly without groups +- **Context-sensitive nodes** use `e.is_within_group(GroupKind::ParentType)` to adapt formatting +- **Top-level statements** use `e.is_top_level()` to add semicolons +- **Always delegate** to existing ToTokens implementations + +## ACTION PLAN: +1. Start by running all tests to see the current state +2. Focus on tests that fail due to line length violations or poor formatting +3. Systematically improve each ToTokens implementation +4. Verify each change produces better formatted output +5. Continue until all tests pass with properly formatted SQL + +## Completion Signal Requirements + +**CRITICAL**: ONLY when ALL tests pass and formatting is complete, output this exact phrase: + +`TASK COMPLETE` + +This allows automated scripts to detect task completion reliably. + +If not ALL tests pass or there is formatting work left to do, output `CONTINUE` instead. + +Continue this loop indefinitely until all tests pass with properly formatted output. diff --git a/agentic/pretty_printer.md b/agentic/pretty_printer.md new file mode 100644 index 000000000..683477d98 --- /dev/null +++ b/agentic/pretty_printer.md @@ -0,0 +1,470 @@ +# SQL Pretty Printer Formatting Guide + +## Overview +This guide explains how to improve the SQL pretty printer formatting. The goal is to format SQL statements that respect line length limits while maintaining readability. + +## Key Principles + +### 1. Use pgFormatter for inspiration +Always use `pg_format path/to/input/file.sql` to get inspiration from pgFormatter - it provides good baseline formatting that we can adapt. + +### 2. Respect Line Length Limits +- Maximum line length is 60 characters for tests (configurable) +- Only break when necessary, keep related parts together when possible +- **JSON Exception**: Do NOT format JSON strings/objects - accept longer line widths for JSON content + +### 3. Focus on proper indentation +Indentation is the primary way to show SQL statement hierarchy and improve readability. + +The key principle: Main statement keywords stay at base level, subordinate/optional clauses get indented. + +#### Indentation Hierarchy Rules: +1. **Main statement keywords** (CREATE, ALTER, MERGE, etc.) - Base level (no indent) +2. **Primary clauses** (SELECT, FROM, WHERE, etc.) - Base level +3. **Optional/subordinate clauses** (TO, DO, OPTIONS, VERSION, etc.) - Indented 1 level +4. **Sub-clauses within actions** (SET assignments, VALUES lists) - Indented 2 levels +5. **Complex nested structures** - Additional indentation as needed + +```sql +-- GOOD: Proper indentation hierarchy +CREATE RULE rule_name AS ON event + TO table_name -- Optional clause indented + DO action; -- Optional clause indented + +ALTER FOREIGN DATA WRAPPER fdw_name + HANDLER handler_func -- Optional clause indented + OPTIONS ( -- Optional clause indented + host 'example.com' + ); + +MERGE INTO target_table t +USING source_table s ON t.id = s.id -- Primary clause, base level +WHEN MATCHED THEN -- Primary clause, base level + UPDATE SET -- Action indented 1 level + column = value -- Sub-action indented 2 levels +WHEN NOT MATCHED THEN + INSERT (columns) -- Action indented 1 level + VALUES (values); -- Sub-action indented 2 levels +``` + +```sql +-- BAD: No indentation - hard to read hierarchy +CREATE RULE rule_name AS ON event +TO table_name +DO action; + +-- BAD: Inconsistent indentation +ALTER FOREIGN DATA WRAPPER fdw_name + HANDLER handler_func +OPTIONS (host 'example.com'); +``` + +## EventEmitter Usage Guide + +### Basic Events +```rust +// Tokens - actual SQL keywords and identifiers +e.token(TokenKind::SELECT_KW); +e.token(TokenKind::IDENT("table_name".to_string())); + +// Spacing +e.space(); // Single space +e.line(LineType::SoftOrSpace); // Smart line break (space or newline) +e.line(LineType::Soft); // Line break if group doesn't fit +e.line(LineType::Hard); // Forced line break + +// Indentation +e.indent_start(); // Increase indentation level +e.indent_end(); // Decrease indentation level + +// Groups (use existing groups only!) +e.group_start(GroupKind::SelectStmt); +e.group_end(); +``` + +### Line Break Types +- `SoftOrSpace`: Becomes a space if the group fits on one line, newline if it doesn't +- `Soft`: Disappears if the group fits on one line, newline if it doesn't +- `Hard`: Always creates a line break + +### Context-Aware Formatting Helpers + +The EventEmitter provides helper methods to check the current formatting context: + +```rust +// Check if currently within a specific group type +if e.is_within_group(GroupKind::SelectStmt) { + // Apply SELECT-specific formatting + e.line(LineType::SoftOrSpace); +} else { + // Apply default formatting + e.space(); +} + +// Get the immediate parent group type +match e.parent_group() { + Some(GroupKind::InsertStmt) => { + // Apply INSERT-specific formatting for sub-expressions + e.indent_start(); + // ... + e.indent_end(); + } + Some(GroupKind::AlterUserMappingStmt) => { + // Apply ALTER USER MAPPING-specific formatting + e.line(LineType::SoftOrSpace); + } + _ => { + // Default formatting when not in a specific context + e.space(); + } +} +``` + +#### When to Use Context Helpers + +**Use `is_within_group()` when:** +- Different SQL statement types need different formatting for the same AST node +- Sub-expressions should format differently based on their containing statement +- You need to apply specific indentation rules only in certain contexts + +**Use `parent_group()` when:** +- You need to know the immediate parent context (not just any ancestor) +- Making formatting decisions based on the direct containing statement +- Applying conditional formatting that depends on the parent statement type + +#### Important Notes + +- **Context helpers are read-only** - they don't modify the group stack +- **Check context before making formatting decisions** - don't assume a specific parent +- **Use sparingly** - most formatting should be consistent regardless of context +- **Prefer explicit context** over deep nesting checks + + +### CRITICAL RULES + +#### ❌ NEVER DO THESE: +1. **NEVER modify the renderer** - only change `nodes.rs` +2. **NEVER create random groups** - only use existing `GroupKind` variants +3. **NEVER use length-based formatting** - DO NOT change formatting based on number of items (e.g., `if items.len() > 3`). Always use consistent formatting that lets the renderer decide line breaks +4. **NEVER manually parse child nodes** - DO NOT use patterns like `if let Some(pgt_query::protobuf::node::Node::List(list)) = &node`. ALWAYS call `node.to_tokens(e)` and let the child node handle its own formatting using context from the EventEmitter + +#### ✅ ALWAYS DO THESE: +1. **Run pgFormatter** - leverage `pg_format file.sql` and try to achieve a similarly formatted output with our pretty printer +1. **Use existing group contexts** - leverage `GroupKind::SelectStmt`, `GroupKind::InsertStmt`, etc. +2. **Add breaks at clause boundaries** - before `WHERE`, `ORDER BY`, `GROUP BY`, etc. +3. **Use proper indentation** - wrap subordinate clauses with `indent_start()/indent_end()` + +### Manual Child Node Parsing - FORBIDDEN PATTERN + +**❌ NEVER DO THIS:** +```rust +// BAD: Parent node manually parsing child nodes +if let Some(pgt_query::protobuf::node::Node::List(list)) = &arg.node { + for (i, item) in list.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } +} else { + arg.to_tokens(e); +} +``` + +**✅ ALWAYS DO THIS:** +```rust +// GOOD: Let the child node handle its own formatting +arg.to_tokens(e); +``` + +The child node's `to_tokens` implementation should use the EventEmitter's context functions to determine how to format itself based on its parent context. + +### String Formatting Helpers + +Use the provided EventEmitter helper methods for common string formatting patterns: + +```rust +// Good: Use helpers for string formatting +e.emit_quoted_string_or_fallback(arg); // 'quoted string' or fallback +e.emit_string_as_ident_or_fallback(node); // identifier or fallback +e.emit_string_as_upper_ident(node); // UPPERCASE identifier +e.emit_quoted_string_if_string(node); // 'quoted' or nothing + +// Bad: Manual string node inspection +if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + e.token(TokenKind::STRING(format!("'{}'", s.sval))); +} else { + arg.to_tokens(e); +} +``` + +## Common Formatting Patterns + +### ALTER Statements - FOCUS ON INDENTATION +```rust +// Pattern: Main statement + indented optional clauses +e.token(TokenKind::ALTER_KW); +e.space(); +e.token(TokenKind::TABLE_KW); +e.space(); +table_name.to_tokens(e); + +// CRITICAL: Always indent optional clauses +if has_version_clause { + e.indent_start(); // START indentation + e.line(LineType::SoftOrSpace); // Break to new line + e.token(TokenKind::VERSION_KW); + e.space(); + version.to_tokens(e); + e.indent_end(); // END indentation +} + +if has_options_clause { + e.indent_start(); // START indentation for OPTIONS + e.line(LineType::SoftOrSpace); // Break to new line + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + // ... options content + e.token(TokenKind::R_PAREN); + e.indent_end(); // END indentation for OPTIONS +} +``` + +**Result:** +```sql +ALTER FOREIGN DATA WRAPPER fdw_name + VERSION '1.2' -- Indented optional clause + OPTIONS ( -- Indented optional clause + host 'example.com' + ); +``` + +### CREATE Statements +```rust +// Pattern: CREATE + main object + indented options +e.token(TokenKind::CREATE_KW); +e.space(); +e.token(TokenKind::FUNCTION_KW); +// ... + +if !parameters.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, param) in parameters.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); // Allow breaking between params + } + param.to_tokens(e); + } + e.token(TokenKind::R_PAREN); +} + +if has_returns { + e.line(LineType::SoftOrSpace); // Break before RETURNS when needed + e.token(TokenKind::RETURNS_KW); + // ... +} +``` + +### MERGE Statements - HIERARCHICAL INDENTATION +```rust +// Pattern: Multi-level hierarchical indentation +e.token(TokenKind::MERGE_KW); +e.space(); +e.token(TokenKind::INTO_KW); +// ... + +e.line(LineType::SoftOrSpace); +e.token(TokenKind::USING_KW); +e.space(); +source.to_tokens(e); +e.space(); // Keep ON on same line as USING when possible +e.token(TokenKind::ON_KW); +// ... + +for when_clause in when_clauses { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::WHEN_KW); + // ... + e.space(); + e.token(TokenKind::THEN_KW); + + // CRITICAL: Indent the action + e.indent_start(); // Level 1 indentation + e.line(LineType::SoftOrSpace); + + match action_type { + Update => { + e.token(TokenKind::UPDATE_KW); + e.space(); + e.token(TokenKind::SET_KW); + e.indent_start(); // Level 2 indentation for SET items + e.line(LineType::SoftOrSpace); + // SET assignments here + e.indent_end(); // End level 2 + } + Insert => { + e.token(TokenKind::INSERT_KW); + // columns... + e.indent_start(); // Level 2 indentation for VALUES + e.line(LineType::SoftOrSpace); + e.token(TokenKind::VALUES_KW); + // values... + e.indent_end(); // End level 2 + } + } + + e.indent_end(); // End level 1 +} +``` + +**Result:** +```sql +MERGE INTO target_table t +USING source_table s ON t.id = s.id +WHEN MATCHED THEN + UPDATE SET -- Level 1 indent + column = value -- Level 2 indent +WHEN NOT MATCHED THEN + INSERT (columns) -- Level 1 indent + VALUES (values); -- Level 2 indent +``` + +## Testing and Validation + +### Code Quality Checks +```bash +# Run clippy to catch warnings and potential issues +cargo clippy + +# Run clippy for specific package +cargo clippy -p pgt_pretty_print + +# Run clippy with additional checks +cargo clippy -- -W clippy::all +``` + +**CRITICAL**: Always run `cargo clippy` after making changes to catch: +- Unused code and imports +- Collapsible if/else blocks +- Performance improvements +- Code style issues +- Potential bugs + +### Running Tests +```bash +# Run all pretty printer tests +cargo test -p pgt_pretty_print + +# Run specific test with output +cargo test -p pgt_pretty_print test_formatter__merge_stmt_0_60 -- --show-output + +# Run tests and check failure count +cargo test -p pgt_pretty_print 2>&1 | grep -E "FAILED.*failed" | tail -1 +``` + +### Interpreting Test Results +Tests will fail with messages like: +``` +Line exceeds max length of 60: CREATE FUNCTION add (a pg_catalog.int4, b pg_catalog.int4) RETURNS pg_catalog.int4 AS 'SELECT $1 + $2' LANGUAGE sql ; +``` + +This means you need to add line breaks to keep lines under 60 characters. + +### Using pgFormatter for Inspiration +```bash +# Get formatting inspiration +pg_format crates/pgt_pretty_print/tests/data/create_function_stmt_0_60.sql + +# This will show you how pgFormatter would format the statement. Try to copy it! +``` + +### Snapshot Updates +When tests fail due to formatting changes: +```bash +# Review and accept snapshot changes +cargo insta review + +# Or run tests to see diffs +cargo insta test +``` + +## Step-by-Step Process + +1. **Identify failing tests**: + ```bash + cargo test -p pgt_pretty_print | grep FAILED + ``` + +2. **Examine a specific failure**: + ```bash + cargo test -p pgt_pretty_print test_formatter__create_function_stmt_0_60 -- --show-output + ``` + +3. **Use pgFormatter for inspiration**: + ```bash + pg_format crates/pgt_pretty_print/tests/data/create_function_stmt_0_60.sql + ``` + +4. **Find the ToTokens implementation** in `crates/pgt_pretty_print/src/nodes.rs`: + ```bash + grep -n "impl ToTokens.*CreateFunctionStmt" crates/pgt_pretty_print/src/nodes.rs + ``` + +5. **Apply formatting improvements**: + - Add `e.line(LineType::SoftOrSpace)` before major clauses + - Add `e.indent_start()/e.indent_end()` around subordinate clauses + - Use `e.space()` for required spaces + +6. **Test the changes**: + ```bash + cargo test -p pgt_pretty_print test_formatter__create_function_stmt_0_60 -- --show-output + ``` + +7. **Run code quality checks**: + ```bash + cargo clippy -p pgt_pretty_print + ``` + +8. **Iterate until the formatting is correct** + +## Examples of Good Formatting + +### CREATE RULE (Documentation Style) +```sql +CREATE RULE notify_me AS ON UPDATE + TO mytable + DO NOTIFY mytable_updated; +``` + +### ALTER FOREIGN SERVER (Indented Options) +```sql +ALTER SERVER myserver + VERSION '1.2' + OPTIONS (host 'new.example.com'); +``` + +### MERGE (Hierarchical Structure) +```sql +MERGE INTO target_table t +USING source_table s ON t.id = s.id +WHEN MATCHED THEN + UPDATE SET + value = s.value +WHEN NOT MATCHED THEN + INSERT (id, value) + VALUES (s.id, s.value); +``` + +## Success Criteria + +- All lines must be ≤ 60 characters (except JSON content) +- Indentation should show logical hierarchy +- Related clauses should stay together when possible +- Output should be readable and maintainable +- **JSON Content Rule**: Do not format JSON strings/objects - preserve them as-is even if they exceed line limits + +Remember: The goal is readable SQL formatting that respects line length constraints while maintaining semantic clarity. diff --git a/crates/pgt_pretty_print/Cargo.toml b/crates/pgt_pretty_print/Cargo.toml new file mode 100644 index 000000000..66e27d307 --- /dev/null +++ b/crates/pgt_pretty_print/Cargo.toml @@ -0,0 +1,22 @@ +[package] +authors.workspace = true +categories.workspace = true +description = "" +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +name = "pgt_pretty_print" +repository.workspace = true +version = "0.0.0" + + +[dependencies] +pgt_pretty_print_codegen.workspace = true +pgt_query.workspace = true + +[dev-dependencies] +camino.workspace = true +dir-test.workspace = true +insta.workspace = true +pgt_statement_splitter.workspace = true diff --git a/crates/pgt_pretty_print/src/codegen/group_kind.rs b/crates/pgt_pretty_print/src/codegen/group_kind.rs new file mode 100644 index 000000000..859fc4cb0 --- /dev/null +++ b/crates/pgt_pretty_print/src/codegen/group_kind.rs @@ -0,0 +1 @@ +pgt_pretty_print_codegen::group_kind_codegen!(); diff --git a/crates/pgt_pretty_print/src/codegen/mod.rs b/crates/pgt_pretty_print/src/codegen/mod.rs new file mode 100644 index 000000000..3746b4ac5 --- /dev/null +++ b/crates/pgt_pretty_print/src/codegen/mod.rs @@ -0,0 +1,2 @@ +pub mod group_kind; +pub mod token_kind; diff --git a/crates/pgt_pretty_print/src/codegen/token_kind.rs b/crates/pgt_pretty_print/src/codegen/token_kind.rs new file mode 100644 index 000000000..17aefbf57 --- /dev/null +++ b/crates/pgt_pretty_print/src/codegen/token_kind.rs @@ -0,0 +1 @@ +pgt_pretty_print_codegen::token_kind_codegen!(); diff --git a/crates/pgt_pretty_print/src/emitter.rs b/crates/pgt_pretty_print/src/emitter.rs new file mode 100644 index 000000000..222672caa --- /dev/null +++ b/crates/pgt_pretty_print/src/emitter.rs @@ -0,0 +1,116 @@ +pub use crate::codegen::group_kind::GroupKind; +pub use crate::codegen::token_kind::TokenKind; + +#[derive(Debug, Clone, PartialEq)] +pub enum LineType { + /// Must break (semicolon, etc.) + Hard, + /// Break if group doesn't fit + Soft, + /// Break if group doesn't fit, but collapse to space if it does + SoftOrSpace, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum LayoutEvent { + Token(TokenKind), + Space, + Line(LineType), + GroupStart { kind: GroupKind }, + GroupEnd, + IndentStart, + IndentEnd, +} + +#[derive(Debug, Default)] +pub struct EventEmitter { + pub events: Vec, +} + +impl EventEmitter { + pub fn new() -> Self { + Self::default() + } + + pub fn token(&mut self, token: TokenKind) { + self.events.push(LayoutEvent::Token(token)); + } + + pub fn space(&mut self) { + self.events.push(LayoutEvent::Space); + } + + pub fn line(&mut self, line_type: LineType) { + self.events.push(LayoutEvent::Line(line_type)); + } + + pub fn group_start(&mut self, kind: GroupKind) { + self.events.push(LayoutEvent::GroupStart { kind }); + } + + pub fn is_within_group(&self, target_kind: GroupKind) -> bool { + let mut depth = 0; + for event in self.events.iter().rev() { + match event { + LayoutEvent::GroupEnd => depth += 1, + LayoutEvent::GroupStart { kind, .. } => { + if depth == 0 && *kind == target_kind { + return true; + } + if depth > 0 { + depth -= 1; + } + } + _ => {} + } + } + false + } + + pub fn parent_group(&self) -> Option { + let mut depth = 0; + for event in self.events.iter().rev() { + match event { + LayoutEvent::GroupEnd => depth += 1, + LayoutEvent::GroupStart { kind, .. } => { + if depth == 1 { + return Some(kind.clone()); + } + if depth > 0 { + depth -= 1; + } + } + _ => {} + } + } + None + } + + pub fn is_top_level(&self) -> bool { + let mut depth = 0; + for event in &self.events { + match event { + LayoutEvent::GroupStart { .. } => depth += 1, + LayoutEvent::GroupEnd => depth -= 1, + _ => {} + } + } + depth == 1 + } + + pub fn group_end(&mut self) { + self.events.push(LayoutEvent::GroupEnd); + } + + pub fn indent_start(&mut self) { + self.events.push(LayoutEvent::IndentStart); + } + + pub fn indent_end(&mut self) { + self.events.push(LayoutEvent::IndentEnd); + } +} + +pub trait ToTokens { + fn to_tokens(&self, emitter: &mut EventEmitter); +} diff --git a/crates/pgt_pretty_print/src/lib.rs b/crates/pgt_pretty_print/src/lib.rs new file mode 100644 index 000000000..4ff6d3359 --- /dev/null +++ b/crates/pgt_pretty_print/src/lib.rs @@ -0,0 +1,6 @@ +mod codegen; +pub mod emitter; +mod nodes; +pub mod renderer; + +pub use crate::codegen::token_kind::TokenKind; diff --git a/crates/pgt_pretty_print/src/nodes.rs b/crates/pgt_pretty_print/src/nodes.rs new file mode 100644 index 000000000..edc11e688 --- /dev/null +++ b/crates/pgt_pretty_print/src/nodes.rs @@ -0,0 +1,11491 @@ +use crate::{ + TokenKind, + emitter::{EventEmitter, GroupKind, LineType, ToTokens}, +}; + +fn format_identifier_for_alias(name: &str) -> String { + if name.is_empty() { + return name.to_string(); + } + + let needs_quotes = name.chars().next().unwrap().is_numeric() + || name.contains('?') + || name + .chars() + .any(|c| c.is_uppercase() || (!c.is_alphanumeric() && c != '_')); + + if needs_quotes { + format!("\"{}\"", name) + } else { + name.to_string() + } +} + +/// Helper functions for common string formatting patterns +impl EventEmitter { + /// Emit a string node as a quoted string literal 'value' + fn emit_quoted_string_or_fallback(&mut self, node: &pgt_query::protobuf::Node) { + if let Some(pgt_query::protobuf::node::Node::String(s)) = &node.node { + self.token(TokenKind::STRING(format!("'{}'", s.sval))); + } else { + node.to_tokens(self); + } + } + + /// Emit a string node as an identifier, or fallback to default formatting + fn emit_string_as_ident_or_fallback(&mut self, node: &pgt_query::protobuf::Node) { + if let Some(pgt_query::protobuf::node::Node::String(s)) = &node.node { + self.token(TokenKind::IDENT(s.sval.clone())); + } else { + node.to_tokens(self); + } + } + + /// Emit a string node as an uppercase identifier + fn emit_string_as_upper_ident(&mut self, node: &pgt_query::protobuf::Node) { + if let Some(pgt_query::protobuf::node::Node::String(s)) = &node.node { + self.token(TokenKind::IDENT(s.sval.to_uppercase())); + } + } +} + +impl ToTokens for pgt_query::NodeEnum { + fn to_tokens(&self, e: &mut EventEmitter) { + match self { + pgt_query::protobuf::node::Node::SelectStmt(stmt) => stmt.as_ref().to_tokens(e), + pgt_query::protobuf::node::Node::ResTarget(target) => target.to_tokens(e), + pgt_query::protobuf::node::Node::MultiAssignRef(ref_) => ref_.to_tokens(e), + pgt_query::protobuf::node::Node::ColumnRef(col_ref) => col_ref.to_tokens(e), + pgt_query::protobuf::node::Node::String(string) => string.to_tokens(e), + pgt_query::protobuf::node::Node::RangeVar(string) => string.to_tokens(e), + pgt_query::protobuf::node::Node::RangeSubselect(subselect) => subselect.to_tokens(e), + pgt_query::protobuf::node::Node::RangeFunction(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTableSample(sample) => sample.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTableFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTableFuncCol(col) => col.to_tokens(e), + pgt_query::protobuf::node::Node::JoinExpr(join) => join.to_tokens(e), + pgt_query::protobuf::node::Node::FuncCall(func_call) => func_call.to_tokens(e), + pgt_query::protobuf::node::Node::Aggref(aggref) => aggref.to_tokens(e), + pgt_query::protobuf::node::Node::GroupingFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::WindowFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::SubscriptingRef(ref_node) => ref_node.to_tokens(e), + pgt_query::protobuf::node::Node::CurrentOfExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::OnConflictExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::Query(query) => query.to_tokens(e), + pgt_query::protobuf::node::Node::TargetEntry(entry) => entry.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTblRef(ref_node) => ref_node.to_tokens(e), + pgt_query::protobuf::node::Node::FromExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::Var(var) => var.to_tokens(e), + pgt_query::protobuf::node::Node::NextValueExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::InferenceElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::FuncExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::WindowDef(window_def) => window_def.to_tokens(e), + pgt_query::protobuf::node::Node::SortBy(sort_by) => sort_by.to_tokens(e), + pgt_query::protobuf::node::Node::InsertStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::List(list) => list.to_tokens(e), + pgt_query::protobuf::node::Node::AConst(const_val) => const_val.to_tokens(e), + pgt_query::protobuf::node::Node::DeleteStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::AIndirection(indirection) => indirection.to_tokens(e), + pgt_query::protobuf::node::Node::UpdateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ColumnDef(def) => def.to_tokens(e), + pgt_query::protobuf::node::Node::TypeName(type_name) => type_name.to_tokens(e), + pgt_query::protobuf::node::Node::DropStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::TruncateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTableStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTableCmd(cmd) => cmd.to_tokens(e), + pgt_query::protobuf::node::Node::ViewStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::MergeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::MergeWhenClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::Alias(alias) => alias.to_tokens(e), + pgt_query::protobuf::node::Node::CreateSchemaStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::RoleSpec(role) => role.to_tokens(e), + pgt_query::protobuf::node::Node::GrantStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AccessPriv(privilege) => privilege.to_tokens(e), + pgt_query::protobuf::node::Node::TransactionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::VariableSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::IndexStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::IndexElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::CopyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DefElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::Boolean(b) => b.to_tokens(e), + pgt_query::protobuf::node::Node::GrantRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDefaultPrivilegesStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::VariableShowStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTableSpaceStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropTableSpaceStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTableSpaceOptionsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::Float(f) => f.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTableMoveAllStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateExtensionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CommentStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterExtensionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterExtensionContentsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ObjectWithArgs(obj) => obj.to_tokens(e), + pgt_query::protobuf::node::Node::FunctionParameter(param) => param.to_tokens(e), + pgt_query::protobuf::node::Node::CreateFdwStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::SetOperationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateForeignServerStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterFdwStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterForeignServerStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateForeignTableStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateUserMappingStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterUserMappingStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropUserMappingStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ImportForeignSchemaStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreatePolicyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterPolicyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateAmStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateSeqStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterSeqStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::Integer(i) => i.to_tokens(e), + pgt_query::protobuf::node::Node::DefineStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateDomainStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CollateClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDomainStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::Constraint(constraint) => constraint.to_tokens(e), + pgt_query::protobuf::node::Node::CreateOpClassStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateOpClassItem(item) => item.to_tokens(e), + pgt_query::protobuf::node::Node::CreateOpFamilyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterOpFamilyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReplicaIdentityStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::SecLabelStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterCollationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DeclareCursorStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ClosePortalStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::FetchStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AStar(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReturnStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::PlassignStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateStatsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::StatsElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::AlterRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterRoleSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterStatsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateFunctionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTrigStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateEventTrigStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterEventTrigStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreatePlangStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterFunctionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DoStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::InlineCodeBlock(block) => block.to_tokens(e), + pgt_query::protobuf::node::Node::CallStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CallContext(ctx) => ctx.to_tokens(e), + pgt_query::protobuf::node::Node::RenameStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterObjectDependsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterObjectSchemaStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterOwnerStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterOperatorStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTypeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterEnumStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::RuleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::NotifyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ListenStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::UnlistenStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ExecuteStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::PrepareStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropOwnedStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReassignOwnedStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTsdictionaryStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTsconfigurationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreatePublicationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterPublicationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateSubscriptionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterSubscriptionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropSubscriptionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ParamRef(param) => param.to_tokens(e), + pgt_query::protobuf::node::Node::DeallocateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::LockStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CompositeTypeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateEnumStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateRangeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTableAsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::RefreshMatViewStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::LoadStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreatedbStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropdbStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ClusterStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::VacuumStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::VacuumRelation(rel) => rel.to_tokens(e), + pgt_query::protobuf::node::Node::ExplainStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDatabaseSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDatabaseRefreshCollStmt(stmt) => { + stmt.to_tokens(e) + } + pgt_query::protobuf::node::Node::CheckPointStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DiscardStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ConstraintsSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReindexStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateConversionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateCastStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTransformStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDatabaseStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterSystemStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::BitString(s) => s.to_tokens(e), + pgt_query::protobuf::node::Node::TypeCast(tc) => tc.to_tokens(e), + pgt_query::protobuf::node::Node::Param(p) => p.to_tokens(e), + pgt_query::protobuf::node::Node::OpExpr(op) => op.as_ref().to_tokens(e), + pgt_query::protobuf::node::Node::ScalarArrayOpExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::BoolExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::CaseExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::CaseWhen(when) => when.to_tokens(e), + pgt_query::protobuf::node::Node::ArrayExpr(arr) => arr.to_tokens(e), + pgt_query::protobuf::node::Node::RowExpr(row) => row.to_tokens(e), + pgt_query::protobuf::node::Node::AArrayExpr(arr) => arr.to_tokens(e), + pgt_query::protobuf::node::Node::SubLink(link) => link.to_tokens(e), + pgt_query::protobuf::node::Node::SubPlan(plan) => plan.to_tokens(e), + pgt_query::protobuf::node::Node::AlternativeSubPlan(plan) => plan.to_tokens(e), + pgt_query::protobuf::node::Node::CoalesceExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::MinMaxExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::XmlExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::XmlSerialize(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::NullTest(test) => test.to_tokens(e), + pgt_query::protobuf::node::Node::BooleanTest(test) => test.to_tokens(e), + pgt_query::protobuf::node::Node::PublicationObjSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::NamedArgExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::WithClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::CommonTableExpr(cte) => cte.to_tokens(e), + pgt_query::protobuf::node::Node::GroupingSet(gs) => gs.to_tokens(e), + pgt_query::protobuf::node::Node::AIndices(idx) => idx.to_tokens(e), + pgt_query::protobuf::node::Node::LockingClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::TableFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTable(table) => table.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTablePath(path) => path.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTablePathScan(scan) => scan.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTableSiblingJoin(join) => join.to_tokens(e), + pgt_query::protobuf::node::Node::JsonFormat(format) => format.to_tokens(e), + pgt_query::protobuf::node::Node::JsonIsPredicate(pred) => pred.to_tokens(e), + pgt_query::protobuf::node::Node::JsonReturning(ret) => ret.to_tokens(e), + pgt_query::protobuf::node::Node::JsonBehavior(beh) => beh.to_tokens(e), + pgt_query::protobuf::node::Node::JsonExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::JsonFuncExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::JsonValueExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::JsonOutput(output) => output.to_tokens(e), + pgt_query::protobuf::node::Node::JsonKeyValue(kv) => kv.to_tokens(e), + pgt_query::protobuf::node::Node::JsonObjectConstructor(ctor) => ctor.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArrayConstructor(ctor) => ctor.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTablePathSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTableColumn(col) => col.to_tokens(e), + pgt_query::protobuf::node::Node::DistinctExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::CollateExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::NullIfExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::SqlvalueFunction(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::IntoClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionBoundSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::SetToDefault(def) => def.to_tokens(e), + pgt_query::protobuf::node::Node::TableLikeClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::RelabelType(rt) => rt.to_tokens(e), + pgt_query::protobuf::node::Node::CoerceToDomain(ctd) => ctd.to_tokens(e), + pgt_query::protobuf::node::Node::FieldSelect(fs) => fs.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionRangeDatum(prd) => prd.to_tokens(e), + pgt_query::protobuf::node::Node::CtesearchClause(csc) => csc.to_tokens(e), + pgt_query::protobuf::node::Node::CtecycleClause(ccc) => ccc.to_tokens(e), + pgt_query::protobuf::node::Node::TriggerTransition(tt) => tt.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArgument(ja) => ja.to_tokens(e), + pgt_query::protobuf::node::Node::PublicationTable(pt) => pt.to_tokens(e), + pgt_query::protobuf::node::Node::CoerceViaIo(cvi) => cvi.to_tokens(e), + pgt_query::protobuf::node::Node::FieldStore(fs) => fs.to_tokens(e), + pgt_query::protobuf::node::Node::ArrayCoerceExpr(ace) => ace.to_tokens(e), + pgt_query::protobuf::node::Node::ConvertRowtypeExpr(cre) => cre.to_tokens(e), + pgt_query::protobuf::node::Node::CaseTestExpr(cte) => cte.to_tokens(e), + pgt_query::protobuf::node::Node::CoerceToDomainValue(cdv) => cdv.to_tokens(e), + pgt_query::protobuf::node::Node::MergeAction(ma) => ma.to_tokens(e), + pgt_query::protobuf::node::Node::MergeSupportFunc(msf) => msf.to_tokens(e), + pgt_query::protobuf::node::Node::SinglePartitionSpec(_) => {} + pgt_query::protobuf::node::Node::PartitionCmd(pc) => pc.to_tokens(e), + pgt_query::protobuf::node::Node::JsonConstructorExpr(jce) => jce.to_tokens(e), + pgt_query::protobuf::node::Node::JsonParseExpr(jpe) => jpe.to_tokens(e), + pgt_query::protobuf::node::Node::JsonScalarExpr(jse) => jse.to_tokens(e), + pgt_query::protobuf::node::Node::JsonSerializeExpr(jse) => jse.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArrayQueryConstructor(jaqc) => jaqc.to_tokens(e), + pgt_query::protobuf::node::Node::JsonAggConstructor(jac) => jac.to_tokens(e), + pgt_query::protobuf::node::Node::JsonObjectAgg(joa) => joa.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArrayAgg(jaa) => jaa.to_tokens(e), + pgt_query::protobuf::node::Node::WindowClause(wc) => wc.to_tokens(e), + pgt_query::protobuf::node::Node::WindowFuncRunCondition(wfrc) => wfrc.to_tokens(e), + pgt_query::protobuf::node::Node::SortGroupClause(sgc) => sgc.to_tokens(e), + pgt_query::protobuf::node::Node::RowMarkClause(rmc) => rmc.to_tokens(e), + pgt_query::protobuf::node::Node::WithCheckOption(wco) => wco.to_tokens(e), + pgt_query::protobuf::node::Node::TableSampleClause(tsc) => tsc.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTblEntry(rte) => rte.to_tokens(e), + pgt_query::protobuf::node::Node::RtepermissionInfo(rpi) => rpi.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTblFunction(rtf) => rtf.to_tokens(e), + _ => { + unimplemented!("Node type {:?} not implemented for to_tokens", self); + } + } + } +} + +impl ToTokens for pgt_query::Node { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(node) = &self.node { + match node { + pgt_query::protobuf::node::Node::SelectStmt(stmt) => stmt.as_ref().to_tokens(e), + pgt_query::protobuf::node::Node::ResTarget(target) => target.to_tokens(e), + pgt_query::protobuf::node::Node::MultiAssignRef(ref_) => ref_.to_tokens(e), + pgt_query::protobuf::node::Node::ColumnRef(col_ref) => col_ref.to_tokens(e), + pgt_query::protobuf::node::Node::String(string) => string.to_tokens(e), + pgt_query::protobuf::node::Node::RangeVar(string) => string.to_tokens(e), + pgt_query::protobuf::node::Node::RangeSubselect(subselect) => { + subselect.to_tokens(e) + } + pgt_query::protobuf::node::Node::RangeFunction(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTableSample(sample) => sample.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTableFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTableFuncCol(col) => col.to_tokens(e), + pgt_query::protobuf::node::Node::JoinExpr(join) => join.to_tokens(e), + pgt_query::protobuf::node::Node::FuncCall(func_call) => func_call.to_tokens(e), + pgt_query::protobuf::node::Node::Aggref(aggref) => aggref.to_tokens(e), + pgt_query::protobuf::node::Node::GroupingFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::WindowFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::SubscriptingRef(ref_node) => ref_node.to_tokens(e), + pgt_query::protobuf::node::Node::CurrentOfExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::OnConflictExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::Query(query) => query.to_tokens(e), + pgt_query::protobuf::node::Node::TargetEntry(entry) => entry.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTblRef(ref_node) => ref_node.to_tokens(e), + pgt_query::protobuf::node::Node::FromExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::Var(var) => var.to_tokens(e), + pgt_query::protobuf::node::Node::NextValueExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::InferenceElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::WindowDef(window_def) => window_def.to_tokens(e), + pgt_query::protobuf::node::Node::SortBy(sort_by) => sort_by.to_tokens(e), + pgt_query::protobuf::node::Node::InsertStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::List(list) => list.to_tokens(e), + pgt_query::protobuf::node::Node::AConst(const_val) => const_val.to_tokens(e), + pgt_query::protobuf::node::Node::DeleteStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::UpdateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ColumnDef(def) => def.to_tokens(e), + pgt_query::protobuf::node::Node::TypeName(type_name) => type_name.to_tokens(e), + pgt_query::protobuf::node::Node::DropStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::TruncateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTableStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTableCmd(cmd) => cmd.to_tokens(e), + pgt_query::protobuf::node::Node::ViewStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::MergeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::MergeWhenClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::Alias(alias) => alias.to_tokens(e), + pgt_query::protobuf::node::Node::CreateSchemaStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::RoleSpec(role) => role.to_tokens(e), + pgt_query::protobuf::node::Node::GrantStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AccessPriv(privilege) => privilege.to_tokens(e), + pgt_query::protobuf::node::Node::TransactionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::VariableSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::IndexStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::IndexElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::CopyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DefElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::Boolean(b) => b.to_tokens(e), + pgt_query::protobuf::node::Node::GrantRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDefaultPrivilegesStmt(stmt) => { + stmt.to_tokens(e) + } + pgt_query::protobuf::node::Node::VariableShowStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTableSpaceStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropTableSpaceStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::Float(f) => f.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTableMoveAllStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateExtensionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CommentStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterExtensionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterExtensionContentsStmt(stmt) => { + stmt.to_tokens(e) + } + pgt_query::protobuf::node::Node::ObjectWithArgs(obj) => obj.to_tokens(e), + pgt_query::protobuf::node::Node::FunctionParameter(param) => param.to_tokens(e), + pgt_query::protobuf::node::Node::CreateFdwStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::SetOperationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateForeignServerStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterFdwStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterForeignServerStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateForeignTableStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateUserMappingStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterUserMappingStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropUserMappingStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ImportForeignSchemaStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreatePolicyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterPolicyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateAmStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateSeqStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterSeqStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::Integer(i) => i.to_tokens(e), + pgt_query::protobuf::node::Node::DefineStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateDomainStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CollateClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDomainStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::Constraint(constraint) => constraint.to_tokens(e), + pgt_query::protobuf::node::Node::CreateOpClassStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateOpClassItem(item) => item.to_tokens(e), + pgt_query::protobuf::node::Node::CreateOpFamilyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterOpFamilyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReplicaIdentityStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::SecLabelStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterCollationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DeclareCursorStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ClosePortalStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::FetchStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AStar(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReturnStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::PlassignStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateStatsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::StatsElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::AlterRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterRoleSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropRoleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterStatsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateFunctionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTrigStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateEventTrigStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterEventTrigStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreatePlangStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterFunctionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DoStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::InlineCodeBlock(block) => block.to_tokens(e), + pgt_query::protobuf::node::Node::CallStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CallContext(ctx) => ctx.to_tokens(e), + pgt_query::protobuf::node::Node::RenameStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterObjectDependsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterObjectSchemaStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterOwnerStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterOperatorStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTypeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterEnumStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::RuleStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::NotifyStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ListenStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::UnlistenStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ExecuteStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::PrepareStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropOwnedStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReassignOwnedStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTsdictionaryStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterTsconfigurationStmt(stmt) => { + stmt.to_tokens(e) + } + pgt_query::protobuf::node::Node::CreatePublicationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterPublicationStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateSubscriptionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterSubscriptionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropSubscriptionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ParamRef(param) => param.to_tokens(e), + pgt_query::protobuf::node::Node::DeallocateStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::LockStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CompositeTypeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateEnumStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateRangeStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTableAsStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::RefreshMatViewStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::LoadStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreatedbStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DropdbStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ClusterStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::VacuumStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::VacuumRelation(rel) => rel.to_tokens(e), + pgt_query::protobuf::node::Node::ExplainStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDatabaseSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDatabaseRefreshCollStmt(stmt) => { + stmt.to_tokens(e) + } + pgt_query::protobuf::node::Node::CheckPointStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::DiscardStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ConstraintsSetStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::ReindexStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateConversionStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateCastStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::CreateTransformStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterDatabaseStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::AlterSystemStmt(stmt) => stmt.to_tokens(e), + pgt_query::protobuf::node::Node::BitString(s) => s.to_tokens(e), + pgt_query::protobuf::node::Node::TypeCast(tc) => tc.to_tokens(e), + pgt_query::protobuf::node::Node::Param(p) => p.to_tokens(e), + pgt_query::protobuf::node::Node::OpExpr(op) => op.to_tokens(e), + pgt_query::protobuf::node::Node::ScalarArrayOpExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::BoolExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::CaseExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::CaseWhen(when) => when.to_tokens(e), + pgt_query::protobuf::node::Node::ArrayExpr(arr) => arr.to_tokens(e), + pgt_query::protobuf::node::Node::RowExpr(row) => row.to_tokens(e), + pgt_query::protobuf::node::Node::AArrayExpr(arr) => arr.to_tokens(e), + pgt_query::protobuf::node::Node::SubLink(link) => link.to_tokens(e), + pgt_query::protobuf::node::Node::SubPlan(plan) => plan.to_tokens(e), + pgt_query::protobuf::node::Node::AlternativeSubPlan(plan) => plan.to_tokens(e), + pgt_query::protobuf::node::Node::CoalesceExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::MinMaxExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::XmlExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::XmlSerialize(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::NullTest(test) => test.to_tokens(e), + pgt_query::protobuf::node::Node::BooleanTest(test) => test.to_tokens(e), + pgt_query::protobuf::node::Node::PublicationObjSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::NamedArgExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::WithClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::CommonTableExpr(cte) => cte.to_tokens(e), + pgt_query::protobuf::node::Node::GroupingSet(gs) => gs.to_tokens(e), + pgt_query::protobuf::node::Node::AIndirection(ind) => ind.to_tokens(e), + pgt_query::protobuf::node::Node::AIndices(idx) => idx.to_tokens(e), + pgt_query::protobuf::node::Node::LockingClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::TableFunc(func) => func.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTable(table) => table.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTablePath(path) => path.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTablePathScan(scan) => scan.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTableSiblingJoin(join) => join.to_tokens(e), + pgt_query::protobuf::node::Node::JsonFormat(format) => format.to_tokens(e), + pgt_query::protobuf::node::Node::JsonIsPredicate(pred) => pred.to_tokens(e), + pgt_query::protobuf::node::Node::JsonReturning(ret) => ret.to_tokens(e), + pgt_query::protobuf::node::Node::JsonBehavior(beh) => beh.to_tokens(e), + pgt_query::protobuf::node::Node::JsonExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::JsonFuncExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::JsonValueExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::JsonOutput(output) => output.to_tokens(e), + pgt_query::protobuf::node::Node::JsonKeyValue(kv) => kv.to_tokens(e), + pgt_query::protobuf::node::Node::JsonObjectConstructor(ctor) => ctor.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArrayConstructor(ctor) => ctor.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTablePathSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::JsonTableColumn(col) => col.to_tokens(e), + pgt_query::protobuf::node::Node::DistinctExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::CollateExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::NullIfExpr(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::SqlvalueFunction(expr) => expr.to_tokens(e), + pgt_query::protobuf::node::Node::IntoClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionElem(elem) => elem.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionBoundSpec(spec) => spec.to_tokens(e), + pgt_query::protobuf::node::Node::SetToDefault(def) => def.to_tokens(e), + pgt_query::protobuf::node::Node::TableLikeClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::OidList(list) => list.to_tokens(e), + pgt_query::protobuf::node::Node::IntList(list) => list.to_tokens(e), + pgt_query::protobuf::node::Node::OnConflictClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::InferClause(clause) => clause.to_tokens(e), + pgt_query::protobuf::node::Node::RelabelType(rt) => rt.to_tokens(e), + pgt_query::protobuf::node::Node::CoerceToDomain(ctd) => ctd.to_tokens(e), + pgt_query::protobuf::node::Node::FieldSelect(fs) => fs.to_tokens(e), + pgt_query::protobuf::node::Node::PartitionRangeDatum(prd) => prd.to_tokens(e), + pgt_query::protobuf::node::Node::CtesearchClause(csc) => csc.to_tokens(e), + pgt_query::protobuf::node::Node::CtecycleClause(ccc) => ccc.to_tokens(e), + pgt_query::protobuf::node::Node::TriggerTransition(tt) => tt.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArgument(ja) => ja.to_tokens(e), + pgt_query::protobuf::node::Node::PublicationTable(pt) => pt.to_tokens(e), + pgt_query::protobuf::node::Node::CoerceViaIo(cvi) => cvi.to_tokens(e), + pgt_query::protobuf::node::Node::FieldStore(fs) => fs.to_tokens(e), + pgt_query::protobuf::node::Node::ArrayCoerceExpr(ace) => ace.to_tokens(e), + pgt_query::protobuf::node::Node::ConvertRowtypeExpr(cre) => cre.to_tokens(e), + pgt_query::protobuf::node::Node::CaseTestExpr(cte) => cte.to_tokens(e), + pgt_query::protobuf::node::Node::CoerceToDomainValue(cdv) => cdv.to_tokens(e), + pgt_query::protobuf::node::Node::MergeAction(ma) => ma.to_tokens(e), + pgt_query::protobuf::node::Node::MergeSupportFunc(msf) => msf.to_tokens(e), + pgt_query::protobuf::node::Node::SinglePartitionSpec(_) => {} + pgt_query::protobuf::node::Node::PartitionCmd(pc) => pc.to_tokens(e), + pgt_query::protobuf::node::Node::JsonConstructorExpr(jce) => jce.to_tokens(e), + pgt_query::protobuf::node::Node::JsonParseExpr(jpe) => jpe.to_tokens(e), + pgt_query::protobuf::node::Node::JsonScalarExpr(jse) => jse.to_tokens(e), + pgt_query::protobuf::node::Node::JsonSerializeExpr(jse) => jse.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArrayQueryConstructor(jaqc) => { + jaqc.to_tokens(e) + } + pgt_query::protobuf::node::Node::JsonAggConstructor(jac) => jac.to_tokens(e), + pgt_query::protobuf::node::Node::JsonObjectAgg(joa) => joa.to_tokens(e), + pgt_query::protobuf::node::Node::JsonArrayAgg(jaa) => jaa.to_tokens(e), + pgt_query::protobuf::node::Node::WindowClause(wc) => wc.to_tokens(e), + pgt_query::protobuf::node::Node::WindowFuncRunCondition(wfrc) => wfrc.to_tokens(e), + pgt_query::protobuf::node::Node::SortGroupClause(sgc) => sgc.to_tokens(e), + pgt_query::protobuf::node::Node::RowMarkClause(rmc) => rmc.to_tokens(e), + pgt_query::protobuf::node::Node::WithCheckOption(wco) => wco.to_tokens(e), + pgt_query::protobuf::node::Node::TableSampleClause(tsc) => tsc.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTblEntry(rte) => rte.to_tokens(e), + pgt_query::protobuf::node::Node::RtepermissionInfo(rpi) => rpi.to_tokens(e), + pgt_query::protobuf::node::Node::RangeTblFunction(rtf) => rtf.to_tokens(e), + _ => { + unimplemented!("Node type {:?} not implemented for to_tokens", node); + } + } + } + } +} + +impl ToTokens for pgt_query::protobuf::SelectStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::SelectStmt); + + if let Some(ref with_clause) = self.with_clause { + with_clause.to_tokens(e); + e.line(LineType::SoftOrSpace); + } + + use pgt_query::protobuf::SetOperation; + let is_set_operation = matches!( + self.op(), + SetOperation::SetopUnion | SetOperation::SetopIntersect | SetOperation::SetopExcept + ); + + if is_set_operation { + if let Some(ref larg) = self.larg { + larg.as_ref().to_tokens(e); + } + + match self.op() { + SetOperation::SetopUnion => { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::UNION_KW); + if self.all { + e.space(); + e.token(TokenKind::ALL_KW); + } + e.line(LineType::SoftOrSpace); + } + SetOperation::SetopIntersect => { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::INTERSECT_KW); + if self.all { + e.space(); + e.token(TokenKind::ALL_KW); + } + e.line(LineType::SoftOrSpace); + } + SetOperation::SetopExcept => { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::EXCEPT_KW); + if self.all { + e.space(); + e.token(TokenKind::ALL_KW); + } + e.line(LineType::SoftOrSpace); + } + _ => {} + } + + if let Some(ref rarg) = self.rarg { + rarg.as_ref().to_tokens(e); + } + } else if !self.values_lists.is_empty() { + e.token(TokenKind::VALUES_KW); + e.indent_start(); + e.line(LineType::SoftOrSpace); + for (i, values_list) in self.values_lists.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + values_list.to_tokens(e); + } + e.indent_end(); + } else { + e.token(TokenKind::SELECT_KW); + + if !self.distinct_clause.is_empty() { + e.space(); + e.token(TokenKind::DISTINCT_KW); + + if self.distinct_clause.len() > 1 + || (self.distinct_clause.len() == 1 && self.distinct_clause[0].node.is_some()) + { + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, node) in self.distinct_clause.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + if node.node.is_some() { + node.to_tokens(e); + } + } + e.token(TokenKind::R_PAREN); + } + } + + if !self.target_list.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + + for (i, target) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + target.to_tokens(e); + } + e.indent_end(); + } + + if let Some(ref into_clause) = self.into_clause { + into_clause.to_tokens(e); + } + + if !self.from_clause.is_empty() { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::FROM_KW); + e.line(LineType::SoftOrSpace); + + e.indent_start(); + for (i, from) in self.from_clause.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + from.to_tokens(e); + } + e.indent_end(); + } + + if let Some(ref where_clause) = self.where_clause { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + + if !self.group_clause.is_empty() { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::GROUP_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.indent_start(); + for (i, group) in self.group_clause.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + } + e.line(LineType::SoftOrSpace); + group.to_tokens(e); + } + e.indent_end(); + } + + if !self.locking_clause.is_empty() { + for clause in &self.locking_clause { + e.space(); + clause.to_tokens(e); + } + } + + if let Some(ref having) = self.having_clause { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::HAVING_KW); + e.space(); + having.to_tokens(e); + } + + if !self.sort_clause.is_empty() { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::ORDER_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.indent_start(); + for (i, sort_by) in self.sort_clause.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + } + e.line(LineType::SoftOrSpace); + sort_by.to_tokens(e); + } + e.indent_end(); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ResTarget { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ResTarget); + + if e.is_within_group(GroupKind::UpdateStmt) { + if !self.name.is_empty() { + e.token(TokenKind::IDENT(self.name.clone())); + for d in &self.indirection { + if !matches!(d.node, Some(pgt_query::protobuf::node::Node::AIndices(_))) { + e.token(TokenKind::DOT); + } + d.to_tokens(e); + } + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + } + if let Some(ref val) = self.val { + val.to_tokens(e); + } + } else if let Some(ref val) = self.val { + val.to_tokens(e); + if !self.name.is_empty() { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::IDENT(format_identifier_for_alias(&self.name))); + } + } else if !self.name.is_empty() { + e.token(TokenKind::IDENT(format_identifier_for_alias(&self.name))); + for d in &self.indirection { + d.to_tokens(e); + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::MultiAssignRef { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref source) = self.source { + source.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::ColumnRef { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ColumnRef); + + for (i, field) in self.fields.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + field.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::String { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.sval.clone())); + } +} + +impl ToTokens for pgt_query::protobuf::RangeVar { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RangeVar); + + if !self.inh + && !e.is_within_group(GroupKind::CompositeTypeStmt) + && !e.is_within_group(GroupKind::CreateStmt) + { + e.token(TokenKind::ONLY_KW); + e.space(); + } + + if !self.schemaname.is_empty() { + e.token(TokenKind::IDENT(self.schemaname.clone())); + e.token(TokenKind::DOT); + } + + e.token(TokenKind::IDENT(self.relname.clone())); + + if let Some(ref alias) = self.alias { + e.space(); + alias.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JoinExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::JoinType; + + e.group_start(GroupKind::JoinExpr); + + if let Some(ref larg) = self.larg { + larg.to_tokens(e); + } + + e.line(LineType::SoftOrSpace); + + if self.is_natural { + e.token(TokenKind::NATURAL_KW); + e.space(); + } + + match self.jointype() { + JoinType::JoinInner => { + e.token(TokenKind::INNER_KW); + e.space(); + e.token(TokenKind::JOIN_KW); + } + JoinType::JoinLeft => { + e.token(TokenKind::LEFT_KW); + e.space(); + e.token(TokenKind::JOIN_KW); + } + JoinType::JoinFull => { + e.token(TokenKind::FULL_KW); + e.space(); + e.token(TokenKind::JOIN_KW); + } + JoinType::JoinRight => { + e.token(TokenKind::RIGHT_KW); + e.space(); + e.token(TokenKind::JOIN_KW); + } + _ => { + e.token(TokenKind::JOIN_KW); + } + } + + e.indent_start(); + e.line(LineType::SoftOrSpace); + + if let Some(ref rarg) = self.rarg { + rarg.to_tokens(e); + } + + e.indent_end(); + + if !self.using_clause.is_empty() { + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, col) in self.using_clause.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } else if let Some(ref quals) = self.quals { + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + quals.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::FuncCall { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::FuncCall); + + for (i, name) in self.funcname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + name.to_tokens(e); + } + + e.token(TokenKind::L_PAREN); + + if self.agg_star { + e.token(TokenKind::IDENT("*".to_string())); + } else if !self.args.is_empty() || !self.agg_order.is_empty() { + e.group_start(GroupKind::FuncCall); + e.line(LineType::Soft); + + e.indent_start(); + + if self.agg_distinct { + e.token(TokenKind::DISTINCT_KW); + e.space(); + } + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + arg.to_tokens(e); + } + + if !self.agg_order.is_empty() && !self.agg_within_group { + e.space(); + e.token(TokenKind::ORDER_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + for (i, agg_order) in self.agg_order.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + agg_order.to_tokens(e); + } + } + + e.indent_end(); + e.line(LineType::Soft); + e.group_end(); + } + + e.token(TokenKind::R_PAREN); + + if self.agg_within_group && !self.agg_order.is_empty() { + e.space(); + e.token(TokenKind::WITHIN_KW); + e.space(); + e.token(TokenKind::GROUP_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.token(TokenKind::ORDER_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + for (i, agg_order) in self.agg_order.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + agg_order.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if let Some(ref agg_filter) = self.agg_filter { + e.space(); + e.token(TokenKind::FILTER_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.token(TokenKind::WHERE_KW); + e.space(); + agg_filter.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + + if let Some(ref over) = self.over { + e.space(); + e.token(TokenKind::OVER_KW); + e.space(); + over.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::WindowDef { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::WindowDef); + + e.token(TokenKind::L_PAREN); + + let mut need_space = false; + + if !self.partition_clause.is_empty() { + e.token(TokenKind::PARTITION_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + + for (i, partition) in self.partition_clause.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + partition.to_tokens(e); + } + need_space = true; + } + + if !self.order_clause.is_empty() { + if need_space { + e.space(); + } + e.token(TokenKind::ORDER_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + + for (i, order) in self.order_clause.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + order.to_tokens(e); + } + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::SortBy { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::{SortByDir, SortByNulls}; + + e.group_start(GroupKind::SortBy); + + if let Some(ref node) = self.node { + node.to_tokens(e); + } + + match self.sortby_dir() { + SortByDir::SortbyAsc => { + e.space(); + e.token(TokenKind::ASC_KW); + } + SortByDir::SortbyDesc => { + e.space(); + e.token(TokenKind::DESC_KW); + } + SortByDir::SortbyDefault | SortByDir::Undefined => {} + SortByDir::SortbyUsing => { + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + for (i, op) in self.use_op.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + op.to_tokens(e); + } + } + } + + match self.sortby_nulls() { + SortByNulls::SortbyNullsFirst => { + e.space(); + e.token(TokenKind::NULLS_KW); + e.space(); + e.token(TokenKind::FIRST_KW); + } + SortByNulls::SortbyNullsLast => { + e.space(); + e.token(TokenKind::NULLS_KW); + e.space(); + e.token(TokenKind::LAST_KW); + } + SortByNulls::SortbyNullsDefault | SortByNulls::Undefined => {} + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::InsertStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::InsertStmt); + + e.token(TokenKind::INSERT_KW); + e.space(); + e.token(TokenKind::INTO_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if !self.cols.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, col) in self.cols.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if let Some(ref select_stmt) = self.select_stmt { + e.space(); + select_stmt.to_tokens(e); + } + + if let Some(ref on_conflict_clause) = self.on_conflict_clause { + e.line(LineType::SoftOrSpace); + on_conflict_clause.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::List { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::List); + + if e.is_within_group(GroupKind::AlterTsconfigurationStmt) { + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + } else if e.is_within_group(GroupKind::DropStmt) + || e.is_within_group(GroupKind::RenameStmt) + || e.is_within_group(GroupKind::AlterObjectSchemaStmt) + || e.is_within_group(GroupKind::AlterOwnerStmt) + { + // For ObjectOpfamily/ObjectOpclass: 2 items = "name USING method", otherwise dot-separated + if self.items.len() == 2 { + // ObjectOpfamily/ObjectOpclass format: "name USING method" + if let Some(first) = self.items.first() { + first.to_tokens(e); // method + } + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + if let Some(second) = self.items.get(1) { + second.to_tokens(e); // name + } + } else { + // Standard dot-separated format + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + item.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::AExpr) { + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + } else if e.is_within_group(GroupKind::RangeFunction) { + // In RangeFunction context, only emit the first item (the function call) + if let Some(first_item) = self.items.first() { + first_item.to_tokens(e); + } + } else if e.is_within_group(GroupKind::DefElem) { + // DefElem context handling for different cases + if e.parent_group() == Some(GroupKind::CreateRoleStmt) { + // addroleto case: comma-separated list + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + } else if e.parent_group() == Some(GroupKind::CreateFunctionStmt) { + // AS clause: comma-separated quoted strings + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + e.emit_quoted_string_or_fallback(item); + } + } else if e.parent_group() == Some(GroupKind::DefineStmt) { + // Operator names: dot-separated + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + item.to_tokens(e); + } + } else { + // Default: comma-separated + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + } + } else { + e.token(TokenKind::L_PAREN); + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + item.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::OidList { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::OidList); + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::IntList { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::IntList); + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AConst { + fn to_tokens(&self, e: &mut EventEmitter) { + if self.isnull { + e.token(TokenKind::NULL_KW); + } else if let Some(ref val) = self.val { + match val { + pgt_query::protobuf::a_const::Val::Ival(ival) => { + e.token(TokenKind::IDENT(ival.ival.to_string())); + } + pgt_query::protobuf::a_const::Val::Fval(fval) => { + e.token(TokenKind::IDENT(fval.fval.clone())); + } + pgt_query::protobuf::a_const::Val::Boolval(boolval) => { + let val_str = if boolval.boolval { "TRUE" } else { "FALSE" }; + e.token(TokenKind::IDENT(val_str.to_string())); + } + pgt_query::protobuf::a_const::Val::Sval(sval) => { + e.token(TokenKind::STRING(format!("'{}'", sval.sval))); + } + pgt_query::protobuf::a_const::Val::Bsval(bsval) => { + bsval.to_tokens(e); + } + } + } + } +} + +impl ToTokens for pgt_query::protobuf::DeleteStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DeleteStmt); + + e.token(TokenKind::DELETE_KW); + e.space(); + e.token(TokenKind::FROM_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if let Some(ref where_clause) = self.where_clause { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::AExprKind; + + e.group_start(GroupKind::AExpr); + + if e.is_within_group(GroupKind::TypeCast) { + e.token(TokenKind::L_PAREN); + } + + match self.kind() { + AExprKind::AexprOpAny | AExprKind::AexprOpAll => { + if let Some(ref lexpr) = self.lexpr { + lexpr.to_tokens(e); + } + + if !self.name.is_empty() { + e.space(); + for name in &self.name { + name.to_tokens(e); + } + e.space(); + } + + if self.kind == AExprKind::AexprOpAny as i32 { + e.token(TokenKind::ANY_KW); + } else { + e.token(TokenKind::ALL_KW); + } + e.token(TokenKind::L_PAREN); + + if let Some(ref rexpr) = self.rexpr { + rexpr.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + AExprKind::AexprIn => { + if let Some(ref lexpr) = self.lexpr { + lexpr.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + if let Some(ref rexpr) = self.rexpr { + rexpr.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + AExprKind::AexprDistinct => { + if let Some(ref lexpr) = self.lexpr { + lexpr.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + e.token(TokenKind::DISTINCT_KW); + e.space(); + e.token(TokenKind::FROM_KW); + e.space(); + + if let Some(ref rexpr) = self.rexpr { + rexpr.to_tokens(e); + } + } + AExprKind::AexprNullif => { + e.token(TokenKind::NULLIF_KW); + e.token(TokenKind::L_PAREN); + + if let Some(ref lexpr) = self.lexpr { + lexpr.to_tokens(e); + } + + e.token(TokenKind::COMMA); + e.space(); + + if let Some(ref rexpr) = self.rexpr { + rexpr.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + AExprKind::AexprLike => { + if let Some(ref lexpr) = self.lexpr { + lexpr.to_tokens(e); + } + + e.space(); + e.token(TokenKind::LIKE_KW); + e.space(); + + if let Some(ref rexpr) = self.rexpr { + rexpr.to_tokens(e); + } + } + AExprKind::AexprIlike => { + if let Some(ref lexpr) = self.lexpr { + lexpr.to_tokens(e); + } + + e.space(); + e.token(TokenKind::ILIKE_KW); + e.space(); + + if let Some(ref rexpr) = self.rexpr { + rexpr.to_tokens(e); + } + } + _ => { + if let Some(ref lexpr) = self.lexpr { + lexpr.to_tokens(e); + } + + if !self.name.is_empty() { + e.space(); + for (i, name) in self.name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + match name.node { + Some(pgt_query::protobuf::node::Node::String(ref s)) => { + e.token(TokenKind::IDENT(s.sval.clone())); + } + _ => name.to_tokens(e), + } + } + e.space(); + } + + if let Some(ref rexpr) = self.rexpr { + rexpr.to_tokens(e); + } + } + } + + if e.is_within_group(GroupKind::TypeCast) { + e.token(TokenKind::R_PAREN); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::UpdateStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::UpdateStmt); + + e.token(TokenKind::UPDATE_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if !self.target_list.is_empty() { + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + for (i, target) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + target.to_tokens(e); + } + } + + if let Some(ref where_clause) = self.where_clause { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if let Some(ref relation) = self.relation { + if relation.relpersistence == "t" { + e.token(TokenKind::TEMP_KW); + e.space(); + } + } + + e.token(TokenKind::TABLE_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if let Some(ref partbound) = self.partbound { + e.space(); + e.token(TokenKind::PARTITION_KW); + e.space(); + e.token(TokenKind::OF_KW); + e.space(); + if !self.inh_relations.is_empty() { + if let Some(ref parent) = self.inh_relations.first() { + parent.to_tokens(e); + } + } + partbound.to_tokens(e); + } + + if !self.table_elts.is_empty() + || (!self.inh_relations.is_empty() && self.partbound.is_none()) + { + e.space(); + e.token(TokenKind::L_PAREN); + if !self.table_elts.is_empty() { + e.indent_start(); + e.line(LineType::Soft); + for (i, elt) in self.table_elts.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + elt.to_tokens(e); + } + e.indent_end(); + e.line(LineType::Soft); + } + e.token(TokenKind::R_PAREN); + } + + if let Some(ref partspec) = self.partspec { + partspec.to_tokens(e); + } + + if !self.inh_relations.is_empty() && self.partbound.is_none() { + e.space(); + e.token(TokenKind::INHERITS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, parent) in self.inh_relations.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + parent.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ColumnDef { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ColumnDef); + + e.token(TokenKind::IDENT(self.colname.clone())); + + if let Some(ref type_name) = self.type_name { + e.space(); + type_name.to_tokens(e); + } + + for constraint in &self.constraints { + e.space(); + constraint.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::TypeName { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::TypeName); + + for (i, name) in self.names.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + // Handle type modifiers (e.g., VARCHAR(10), NUMERIC(10,2)) + if !self.typmods.is_empty() { + e.token(TokenKind::L_PAREN); + for (i, typmod) in self.typmods.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + typmod.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + // Handle array types (e.g., INT[], TEXT[][]) + for bound in &self.array_bounds { + e.token(TokenKind::L_BRACK); + // PostgreSQL uses -1 for unbounded arrays, which renders as [] + if let Some(pgt_query::protobuf::node::Node::Integer(i)) = &bound.node { + if i.ival != -1 { + bound.to_tokens(e); + } + } + e.token(TokenKind::R_BRACK); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DropStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DropStmt); + + e.token(TokenKind::DROP_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.remove_type() { + ObjectType::ObjectTable => e.token(TokenKind::TABLE_KW), + ObjectType::ObjectIndex => e.token(TokenKind::INDEX_KW), + ObjectType::ObjectView => e.token(TokenKind::VIEW_KW), + ObjectType::ObjectSequence => e.token(TokenKind::SEQUENCE_KW), + ObjectType::ObjectFunction => e.token(TokenKind::FUNCTION_KW), + ObjectType::ObjectProcedure => e.token(TokenKind::PROCEDURE_KW), + ObjectType::ObjectTrigger => e.token(TokenKind::TRIGGER_KW), + ObjectType::ObjectDatabase => e.token(TokenKind::DATABASE_KW), + ObjectType::ObjectRole => e.token(TokenKind::ROLE_KW), + ObjectType::ObjectSchema => e.token(TokenKind::SCHEMA_KW), + ObjectType::ObjectType => e.token(TokenKind::TYPE_KW), + ObjectType::ObjectDomain => e.token(TokenKind::DOMAIN_KW), + ObjectType::ObjectForeignTable => { + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::TABLE_KW); + } + ObjectType::ObjectMatview => { + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + } + ObjectType::ObjectOperator => e.token(TokenKind::OPERATOR_KW), + ObjectType::ObjectAggregate => e.token(TokenKind::AGGREGATE_KW), + ObjectType::ObjectExtension => e.token(TokenKind::EXTENSION_KW), + ObjectType::ObjectLanguage => e.token(TokenKind::LANGUAGE_KW), + ObjectType::ObjectTablespace => e.token(TokenKind::TABLESPACE_KW), + ObjectType::ObjectOpfamily => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::FAMILY_KW); + } + ObjectType::ObjectOpclass => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::CLASS_KW); + } + _ => e.token(TokenKind::TABLE_KW), + } + + e.line(LineType::SoftOrSpace); + + for (i, obj) in self.objects.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + obj.to_tokens(e); + } + + use pgt_query::protobuf::DropBehavior; + match self.behavior() { + DropBehavior::DropCascade => { + e.space(); + e.token(TokenKind::CASCADE_KW); + } + DropBehavior::DropRestrict => {} + DropBehavior::Undefined => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RowCompareExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RowCompareExpr); + + e.token(TokenKind::L_PAREN); + for (i, arg) in self.largs.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + + e.space(); + + use pgt_query::protobuf::RowCompareType; + match self.rctype() { + RowCompareType::RowcompareLt => e.token(TokenKind::IDENT("<".to_string())), + RowCompareType::RowcompareLe => e.token(TokenKind::IDENT("<=".to_string())), + RowCompareType::RowcompareEq => e.token(TokenKind::IDENT("=".to_string())), + RowCompareType::RowcompareGe => e.token(TokenKind::IDENT(">=".to_string())), + RowCompareType::RowcompareGt => e.token(TokenKind::IDENT(">".to_string())), + RowCompareType::RowcompareNe => e.token(TokenKind::IDENT("<>".to_string())), + RowCompareType::Undefined => todo!(), + } + + e.space(); + + e.token(TokenKind::L_PAREN); + for (i, arg) in self.rargs.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::TruncateStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::TruncateStmt); + + e.token(TokenKind::TRUNCATE_KW); + e.space(); + e.token(TokenKind::TABLE_KW); + e.space(); + + for (i, rel) in self.relations.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + rel.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterTableStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterTableStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.objtype() { + ObjectType::ObjectTable => e.token(TokenKind::TABLE_KW), + ObjectType::ObjectIndex => e.token(TokenKind::INDEX_KW), + ObjectType::ObjectSequence => e.token(TokenKind::SEQUENCE_KW), + ObjectType::ObjectView => e.token(TokenKind::VIEW_KW), + ObjectType::ObjectMatview => { + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + } + ObjectType::ObjectForeignTable => { + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::TABLE_KW); + } + _ => e.token(TokenKind::TABLE_KW), + } + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + for (i, cmd) in self.cmds.iter().enumerate() { + if i == 0 { + e.space(); + } else { + e.token(TokenKind::COMMA); + e.space(); + } + cmd.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterTableCmd { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterTableCmd); + + use pgt_query::protobuf::AlterTableType; + + match self.subtype() { + AlterTableType::AtAddColumn => { + e.token(TokenKind::ADD_KW); + e.space(); + e.token(TokenKind::COLUMN_KW); + if let Some(ref def) = self.def { + e.space(); + def.to_tokens(e); + } + } + AlterTableType::AtDropColumn => { + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::COLUMN_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } + AlterTableType::AtReplicaIdentity => { + e.token(TokenKind::REPLICA_KW); + e.space(); + e.token(TokenKind::IDENTITY_KW); + e.space(); + if let Some(ref def) = self.def { + e.emit_string_as_ident_or_fallback(def); + } + } + AlterTableType::AtChangeOwner => { + e.token(TokenKind::OWNER_KW); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + if let Some(ref newowner) = self.newowner { + newowner.to_tokens(e); + } + } + AlterTableType::AtAlterColumnType => { + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::COLUMN_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + if let Some(ref def) = self.def { + e.space(); + def.to_tokens(e); + } + } + AlterTableType::AtSetNotNull => { + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::COLUMN_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + AlterTableType::AtDropNotNull => { + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::COLUMN_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + e.space(); + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + AlterTableType::AtSetOptions => { + e.token(TokenKind::SET_KW); + e.space(); + if let Some(ref def) = self.def { + def.to_tokens(e); + } + } + AlterTableType::AtSetStatistics => { + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::COLUMN_KW); + e.space(); + if self.num > 0 { + e.token(TokenKind::IDENT(self.num.to_string())); + } else { + e.token(TokenKind::IDENT(self.name.clone())); + } + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::STATISTICS_KW); + e.space(); + if let Some(ref def) = self.def { + def.to_tokens(e); + } + } + _ => {} + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ViewStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ViewStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if self.replace { + e.token(TokenKind::OR_KW); + e.space(); + e.token(TokenKind::REPLACE_KW); + e.space(); + } + + e.token(TokenKind::VIEW_KW); + e.space(); + + if let Some(ref view) = self.view { + view.to_tokens(e); + } + + if let Some(ref query) = self.query { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + query.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::MergeStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::MergeStmt); + + e.token(TokenKind::MERGE_KW); + e.space(); + e.token(TokenKind::INTO_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::USING_KW); + e.space(); + + if let Some(ref source_relation) = self.source_relation { + source_relation.to_tokens(e); + } + + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + if let Some(ref join_condition) = self.join_condition { + join_condition.to_tokens(e); + } + + for when_clause in &self.merge_when_clauses { + e.line(LineType::SoftOrSpace); + when_clause.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::MergeWhenClause { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::MergeWhenClause); + + e.token(TokenKind::WHEN_KW); + e.space(); + + use pgt_query::protobuf::{CmdType, MergeMatchKind}; + + match self.match_kind() { + MergeMatchKind::MergeWhenMatched => { + e.token(TokenKind::MATCHED_KW); + } + MergeMatchKind::MergeWhenNotMatchedByTarget => { + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::MATCHED_KW); + } + MergeMatchKind::MergeWhenNotMatchedBySource => { + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::MATCHED_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + e.token(TokenKind::SOURCE_KW); + } + _ => {} + } + + if let Some(ref condition) = self.condition { + e.space(); + e.token(TokenKind::AND_KW); + e.space(); + condition.to_tokens(e); + } + + e.space(); + e.token(TokenKind::THEN_KW); + e.indent_start(); + e.line(LineType::SoftOrSpace); + + match self.command_type() { + CmdType::CmdInsert => { + e.token(TokenKind::INSERT_KW); + if !self.target_list.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, target) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + target.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + if !self.values.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::VALUES_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, val) in self.values.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + val.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + e.indent_end(); + } + } + CmdType::CmdUpdate => { + e.group_start(GroupKind::UpdateStmt); + e.token(TokenKind::UPDATE_KW); + if !self.target_list.is_empty() { + e.space(); + e.token(TokenKind::SET_KW); + e.indent_start(); + e.line(LineType::SoftOrSpace); + for (i, target) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + target.to_tokens(e); + } + e.indent_end(); + } + e.group_end(); + } + CmdType::CmdDelete => { + e.token(TokenKind::DELETE_KW); + } + CmdType::CmdNothing => { + e.token(TokenKind::DO_KW); + e.space(); + e.token(TokenKind::NOTHING_KW); + } + _ => {} + } + + e.indent_end(); + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RangeSubselect { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RangeSubselect); + + if self.lateral { + e.token(TokenKind::LATERAL_KW); + e.space(); + } + + e.token(TokenKind::L_PAREN); + if let Some(ref subquery) = self.subquery { + subquery.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + + if let Some(ref alias) = self.alias { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + alias.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RangeFunction { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RangeFunction); + + if self.lateral { + e.token(TokenKind::LATERAL_KW); + e.space(); + } + + if self.is_rowsfrom { + e.token(TokenKind::ROWS_KW); + e.space(); + e.token(TokenKind::FROM_KW); + e.token(TokenKind::L_PAREN); + } + + for (i, func) in self.functions.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + func.to_tokens(e); + } + + if self.is_rowsfrom { + e.token(TokenKind::R_PAREN); + } + + if self.ordinality { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::ORDINALITY_KW); + } + + if let Some(ref alias) = self.alias { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + alias.to_tokens(e); + + if !self.coldeflist.is_empty() { + e.token(TokenKind::L_PAREN); + for (i, col) in self.coldeflist.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::Alias { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.aliasname.clone())); + if !self.colnames.is_empty() { + e.token(TokenKind::L_PAREN); + for (i, col) in self.colnames.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } +} + +impl ToTokens for pgt_query::protobuf::CreateSchemaStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateSchemaStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::SCHEMA_KW); + + if self.if_not_exists { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + if !self.schemaname.is_empty() { + e.space(); + e.token(TokenKind::IDENT(self.schemaname.clone())); + } + + if let Some(ref authrole) = self.authrole { + e.space(); + e.token(TokenKind::AUTHORIZATION_KW); + e.space(); + authrole.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RoleSpec { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::RoleSpecType; + match self.roletype() { + RoleSpecType::RolespecCstring => { + if !self.rolename.is_empty() { + e.token(TokenKind::IDENT(self.rolename.clone())); + } + } + RoleSpecType::RolespecCurrentRole => { + e.token(TokenKind::CURRENT_ROLE_KW); + } + RoleSpecType::RolespecCurrentUser => { + e.token(TokenKind::CURRENT_USER_KW); + } + RoleSpecType::RolespecSessionUser => { + e.token(TokenKind::SESSION_USER_KW); + } + RoleSpecType::RolespecPublic => { + e.token(TokenKind::IDENT("PUBLIC".to_string())); + } + _ => { + if !self.rolename.is_empty() { + e.token(TokenKind::IDENT(self.rolename.clone())); + } + } + } + } +} + +impl ToTokens for pgt_query::protobuf::GrantStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::GrantStmt); + + if self.is_grant { + e.token(TokenKind::GRANT_KW); + } else { + e.token(TokenKind::REVOKE_KW); + } + e.space(); + + if !self.privileges.is_empty() { + for (i, privilege) in self.privileges.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + privilege.to_tokens(e); + } + } else { + e.token(TokenKind::ALL_KW); + } + + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.objtype() { + ObjectType::ObjectTable => { + if e.is_within_group(GroupKind::AlterDefaultPrivilegesStmt) { + e.token(TokenKind::TABLES_KW); + } else { + e.token(TokenKind::TABLE_KW); + } + if !self.objects.is_empty() { + e.space(); + } + } + ObjectType::ObjectSchema => { + e.token(TokenKind::SCHEMA_KW); + if !self.objects.is_empty() { + e.space(); + } + } + ObjectType::ObjectDatabase => { + e.token(TokenKind::DATABASE_KW); + if !self.objects.is_empty() { + e.space(); + } + } + ObjectType::ObjectFunction => { + if e.is_within_group(GroupKind::AlterDefaultPrivilegesStmt) { + e.token(TokenKind::FUNCTIONS_KW); + } else { + e.token(TokenKind::FUNCTION_KW); + } + if !self.objects.is_empty() { + e.space(); + } + } + ObjectType::ObjectProcedure => { + e.token(TokenKind::PROCEDURE_KW); + if !self.objects.is_empty() { + e.space(); + } + } + ObjectType::ObjectSequence => { + if e.is_within_group(GroupKind::AlterDefaultPrivilegesStmt) { + e.token(TokenKind::SEQUENCES_KW); + } else { + e.token(TokenKind::SEQUENCE_KW); + } + if !self.objects.is_empty() { + e.space(); + } + } + _ => {} + } + + for (i, obj) in self.objects.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + obj.to_tokens(e); + } + + if self.is_grant { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::TO_KW); + } else { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::FROM_KW); + } + e.space(); + + for (i, grantee) in self.grantees.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + grantee.to_tokens(e); + } + + if self.grant_option && self.is_grant { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::GRANT_KW); + e.space(); + e.token(TokenKind::OPTION_KW); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AccessPriv { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.priv_name.to_uppercase())); + + if !self.cols.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, col) in self.cols.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } +} + +impl ToTokens for pgt_query::protobuf::TransactionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::TransactionStmt); + + use pgt_query::protobuf::TransactionStmtKind; + match self.kind() { + TransactionStmtKind::TransStmtBegin => { + e.token(TokenKind::BEGIN_KW); + } + TransactionStmtKind::TransStmtStart => { + e.token(TokenKind::START_KW); + e.space(); + e.token(TokenKind::TRANSACTION_KW); + } + TransactionStmtKind::TransStmtCommit => { + e.token(TokenKind::COMMIT_KW); + } + TransactionStmtKind::TransStmtRollback => { + e.token(TokenKind::ROLLBACK_KW); + } + TransactionStmtKind::TransStmtSavepoint => { + e.token(TokenKind::SAVEPOINT_KW); + if !self.savepoint_name.is_empty() { + e.space(); + e.token(TokenKind::IDENT(self.savepoint_name.clone())); + } + } + TransactionStmtKind::TransStmtRelease => { + e.token(TokenKind::RELEASE_KW); + if !self.savepoint_name.is_empty() { + e.space(); + e.token(TokenKind::SAVEPOINT_KW); + e.space(); + e.token(TokenKind::IDENT(self.savepoint_name.clone())); + } + } + TransactionStmtKind::TransStmtRollbackTo => { + e.token(TokenKind::ROLLBACK_KW); + e.space(); + e.token(TokenKind::TO_KW); + if !self.savepoint_name.is_empty() { + e.space(); + e.token(TokenKind::SAVEPOINT_KW); + e.space(); + e.token(TokenKind::IDENT(self.savepoint_name.clone())); + } + } + TransactionStmtKind::TransStmtPrepare => { + e.token(TokenKind::PREPARE_KW); + e.space(); + e.token(TokenKind::TRANSACTION_KW); + if !self.gid.is_empty() { + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.gid))); + } + } + TransactionStmtKind::TransStmtCommitPrepared => { + e.token(TokenKind::COMMIT_KW); + e.space(); + e.token(TokenKind::PREPARED_KW); + if !self.gid.is_empty() { + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.gid))); + } + } + TransactionStmtKind::TransStmtRollbackPrepared => { + e.token(TokenKind::ROLLBACK_KW); + e.space(); + e.token(TokenKind::PREPARED_KW); + if !self.gid.is_empty() { + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.gid))); + } + } + _ => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::VariableSetStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::VariableSetStmt); + + use pgt_query::protobuf::VariableSetKind; + match self.kind() { + VariableSetKind::VarSetValue => { + e.token(TokenKind::SET_KW); + e.space(); + + if self.is_local { + e.token(TokenKind::LOCAL_KW); + e.space(); + } + + e.token(TokenKind::IDENT(self.name.clone())); + + if !self.args.is_empty() { + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + } + } + VariableSetKind::VarSetDefault => { + e.token(TokenKind::SET_KW); + e.space(); + + if self.is_local { + e.token(TokenKind::LOCAL_KW); + e.space(); + } + + e.token(TokenKind::IDENT(self.name.clone())); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::DEFAULT_KW); + } + VariableSetKind::VarSetCurrent => { + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + e.space(); + e.token(TokenKind::FROM_KW); + e.space(); + e.token(TokenKind::CURRENT_KW); + } + VariableSetKind::VarSetMulti => { + e.token(TokenKind::SET_KW); + e.space(); + + if self.is_local { + e.token(TokenKind::LOCAL_KW); + e.space(); + } + + e.token(TokenKind::IDENT(self.name.clone())); + } + VariableSetKind::VarReset => { + e.token(TokenKind::RESET_KW); + e.space(); + + if self.is_local { + e.token(TokenKind::LOCAL_KW); + e.space(); + } + + e.token(TokenKind::IDENT(self.name.clone())); + } + VariableSetKind::VarResetAll => { + e.token(TokenKind::RESET_KW); + e.space(); + e.token(TokenKind::ALL_KW); + } + _ => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::IndexStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::IndexStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if self.unique { + e.token(TokenKind::UNIQUE_KW); + e.space(); + } + + if self.concurrent { + e.token(TokenKind::CONCURRENTLY_KW); + e.space(); + } + + e.token(TokenKind::INDEX_KW); + e.space(); + + if self.if_not_exists { + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + e.space(); + } + + if !self.idxname.is_empty() { + e.token(TokenKind::IDENT(self.idxname.clone())); + e.space(); + } + + e.token(TokenKind::ON_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if !self.index_params.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + e.indent_start(); + for (i, param) in self.index_params.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + param.to_tokens(e); + } + e.indent_end(); + e.token(TokenKind::R_PAREN); + } + + if self.nulls_not_distinct { + e.space(); + e.token(TokenKind::NULLS_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::DISTINCT_KW); + } + + if !self.index_including_params.is_empty() { + e.space(); + e.token(TokenKind::IDENT("INCLUDE".to_string())); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, param) in self.index_including_params.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + param.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if let Some(ref where_clause) = self.where_clause { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::IndexElem { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::IndexElem); + + if let Some(ref expr) = self.expr { + e.token(TokenKind::L_PAREN); + expr.to_tokens(e); + e.token(TokenKind::R_PAREN); + } else if !self.name.is_empty() { + e.token(TokenKind::IDENT(self.name.clone())); + } + + if !self.opclass.is_empty() { + e.space(); + for (i, opclass) in self.opclass.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + opclass.to_tokens(e); + } + } + + use pgt_query::protobuf::SortByDir; + if self.ordering != SortByDir::SortbyDefault as i32 { + e.space(); + match self.ordering() { + SortByDir::SortbyAsc => e.token(TokenKind::ASC_KW), + SortByDir::SortbyDesc => e.token(TokenKind::DESC_KW), + _ => {} + } + } + + use pgt_query::protobuf::SortByNulls; + if self.nulls_ordering != SortByNulls::SortbyNullsDefault as i32 { + e.space(); + e.token(TokenKind::NULLS_KW); + e.space(); + match self.nulls_ordering() { + SortByNulls::SortbyNullsFirst => e.token(TokenKind::FIRST_KW), + SortByNulls::SortbyNullsLast => e.token(TokenKind::LAST_KW), + _ => {} + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CopyStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CopyStmt); + + e.token(TokenKind::COPY_KW); + + if self.is_from { + e.space(); + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + e.space(); + e.token(TokenKind::FROM_KW); + e.space(); + + if !self.filename.is_empty() { + e.token(TokenKind::STRING(format!("'{}'", self.filename))); + } else { + e.token(TokenKind::STDIN_KW); + } + } else { + if let Some(ref relation) = self.relation { + e.space(); + relation.to_tokens(e); + } + + if !self.attlist.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, attr) in self.attlist.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + attr.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if let Some(ref query) = self.query { + e.space(); + e.token(TokenKind::L_PAREN); + query.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + + if !self.filename.is_empty() { + e.token(TokenKind::STRING(format!("'{}'", self.filename))); + } else { + e.token(TokenKind::STDOUT_KW); + } + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.space(); + } + option.to_tokens(e); + } + } + + if let Some(ref where_clause) = self.where_clause { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DefElem { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DefElem); + + if self.defname == "format" { + if let Some(ref arg) = self.arg { + e.emit_string_as_upper_ident(arg); + } + } else if self.defname == "header" { + e.token(TokenKind::HEADER_KW); + } else if self.defname == "delimiter" { + e.token(TokenKind::DELIMITER_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "quote" { + e.token(TokenKind::QUOTE_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "escape" { + e.token(TokenKind::ESCAPE_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "null" { + e.token(TokenKind::NULL_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "encoding" { + e.token(TokenKind::ENCODING_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if e.is_within_group(GroupKind::AlterTableSpaceOptionsStmt) { + e.token(TokenKind::IDENT(self.defname.clone())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if e.is_within_group(GroupKind::AlterExtensionStmt) && self.defname == "new_version" + { + e.token(TokenKind::UPDATE_KW); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + e.token(TokenKind::STRING(format!("'{}'", s.sval))); + } else { + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::CreateRoleStmt) + || e.is_within_group(GroupKind::AlterRoleStmt) + { + if self.defname == "canlogin" { + if let Some(ref arg) = self.arg { + if let Some(pgt_query::protobuf::node::Node::Boolean(b)) = &arg.node { + if b.boolval { + e.token(TokenKind::IDENT("LOGIN".to_string())); + } else { + e.token(TokenKind::IDENT("NOLOGIN".to_string())); + } + } else { + e.token(TokenKind::IDENT("LOGIN".to_string())); + } + } else { + e.token(TokenKind::IDENT("LOGIN".to_string())); + } + } else if self.defname == "password" { + e.token(TokenKind::PASSWORD_KW); + if let Some(ref arg) = self.arg { + e.space(); + if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + e.token(TokenKind::STRING(format!("'{}'", s.sval))); + } else { + arg.to_tokens(e); + } + } + } else if self.defname == "superuser" { + if let Some(ref arg) = self.arg { + if let Some(pgt_query::protobuf::node::Node::Boolean(b)) = &arg.node { + if b.boolval { + e.token(TokenKind::IDENT("SUPERUSER".to_string())); + } else { + e.token(TokenKind::IDENT("NOSUPERUSER".to_string())); + } + } else { + e.token(TokenKind::IDENT("SUPERUSER".to_string())); + } + } else { + e.token(TokenKind::IDENT("SUPERUSER".to_string())); + } + } else if self.defname == "createdb" { + e.token(TokenKind::IDENT("CREATEDB".to_string())); + } else if self.defname == "createrole" { + e.token(TokenKind::IDENT("CREATEROLE".to_string())); + } else if self.defname == "inherit" { + e.token(TokenKind::INHERIT_KW); + } else if self.defname == "replication" { + e.token(TokenKind::IDENT("REPLICATION".to_string())); + } else if self.defname == "addroleto" { + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::ROLE_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else { + e.token(TokenKind::IDENT(self.defname.to_uppercase())); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::AlterSeqStmt) { + if self.defname == "restart" { + e.token(TokenKind::RESTART_KW); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + arg.to_tokens(e); + } + } else { + e.token(TokenKind::IDENT(self.defname.to_uppercase())); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::CreateForeignTableStmt) + || e.is_within_group(GroupKind::CreateForeignServerStmt) + || e.is_within_group(GroupKind::AlterForeignServerStmt) + || e.is_within_group(GroupKind::CreateUserMappingStmt) + || e.is_within_group(GroupKind::AlterUserMappingStmt) + || e.is_within_group(GroupKind::AlterFdwStmt) + { + use pgt_query::protobuf::DefElemAction; + + match self.defaction() { + DefElemAction::DefelemAdd => { + e.token(TokenKind::ADD_KW); + e.space(); + } + DefElemAction::DefelemSet => { + e.token(TokenKind::SET_KW); + e.space(); + } + DefElemAction::DefelemDrop => { + e.token(TokenKind::DROP_KW); + e.space(); + } + _ => {} + } + + e.token(TokenKind::IDENT(self.defname.clone())); + if let Some(ref arg) = self.arg { + e.space(); + if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + e.token(TokenKind::STRING(format!("'{}'", s.sval))); + } else { + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::DoStmt) { + if self.defname == "language" { + e.token(TokenKind::LANGUAGE_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "as" { + if let Some(ref arg) = self.arg { + e.space(); + if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + e.token(TokenKind::STRING(format!("'{}'", s.sval))); + } else { + arg.to_tokens(e); + } + } + } + } else if e.is_within_group(GroupKind::CreateFunctionStmt) { + if self.defname == "as" { + e.token(TokenKind::AS_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "language" { + e.token(TokenKind::LANGUAGE_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "volatility" && self.arg.is_some() { + if let Some(ref arg) = self.arg { + if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + match s.sval.as_str() { + "i" => e.token(TokenKind::IMMUTABLE_KW), + "s" => e.token(TokenKind::STABLE_KW), + "v" => e.token(TokenKind::VOLATILE_KW), + _ => e.token(TokenKind::IDENT(s.sval.to_uppercase())), + } + } + } + } else if self.defname == "strict" && self.arg.is_some() { + e.token(TokenKind::STRICT_KW); + } else { + e.token(TokenKind::IDENT(self.defname.to_uppercase())); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::AlterFunctionStmt) { + if self.defname == "volatility" && self.arg.is_some() { + if let Some(ref arg) = self.arg { + if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + match s.sval.as_str() { + "i" => e.token(TokenKind::IMMUTABLE_KW), + "s" => e.token(TokenKind::STABLE_KW), + "v" => e.token(TokenKind::VOLATILE_KW), + _ => e.token(TokenKind::IDENT(s.sval.to_uppercase())), + } + } + } + } else { + e.token(TokenKind::IDENT(self.defname.to_uppercase())); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::CreateRangeStmt) { + e.token(TokenKind::IDENT(self.defname.clone())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if e.is_within_group(GroupKind::AlterTsdictionaryStmt) { + e.token(TokenKind::IDENT(self.defname.clone())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + if let Some(pgt_query::protobuf::node::Node::String(s)) = &arg.node { + e.token(TokenKind::STRING(format!("'{}'", s.sval))); + } else { + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::DefineStmt) { + if self.defname == "from" { + e.token(TokenKind::FROM_KW); + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "leftarg" { + e.token(TokenKind::IDENT("LEFTARG".to_string())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "rightarg" { + e.token(TokenKind::IDENT("RIGHTARG".to_string())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "procedure" { + e.token(TokenKind::PROCEDURE_KW); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "commutator" { + e.token(TokenKind::IDENT("COMMUTATOR".to_string())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "negator" { + e.token(TokenKind::IDENT("NEGATOR".to_string())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "restrict" { + e.token(TokenKind::RESTRICT_KW); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "join" { + e.token(TokenKind::JOIN_KW); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else if self.defname == "hashes" { + e.token(TokenKind::IDENT("HASHES".to_string())); + } else if self.defname == "merges" { + e.token(TokenKind::IDENT("MERGES".to_string())); + } else { + e.token(TokenKind::IDENT(self.defname.clone())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } + } else if e.is_within_group(GroupKind::AlterOperatorStmt) { + // Handle both quoted and unquoted parameter names + let defname_lower = self.defname.to_lowercase(); + if defname_lower == "restrict" + || defname_lower == "join" + || defname_lower == "commutator" + || defname_lower == "negator" + || defname_lower == "leftarg" + || defname_lower == "rightarg" + { + // Check if defname needs quoting (contains mixed case or special chars) + if self.defname == self.defname.to_uppercase() { + e.token(TokenKind::IDENT(self.defname.clone())); + } else { + e.token(TokenKind::IDENT(format!("\"{}\"", self.defname))); + } + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } else { + e.token(TokenKind::IDENT(self.defname.to_lowercase())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } + } else { + e.token(TokenKind::IDENT(self.defname.to_uppercase())); + if let Some(ref arg) = self.arg { + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + arg.to_tokens(e); + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::Boolean { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::Boolean); + + if self.boolval { + e.token(TokenKind::TRUE_KW); + } else { + e.token(TokenKind::FALSE_KW); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::GrantRoleStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::GrantRoleStmt); + + if self.is_grant { + e.token(TokenKind::GRANT_KW); + } else { + e.token(TokenKind::REVOKE_KW); + } + e.space(); + + for (i, role) in self.granted_roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + role.to_tokens(e); + } + + e.space(); + if self.is_grant { + e.token(TokenKind::TO_KW); + } else { + e.token(TokenKind::FROM_KW); + } + e.space(); + + for (i, grantee) in self.grantee_roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + grantee.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterDefaultPrivilegesStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterDefaultPrivilegesStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::DEFAULT_KW); + e.space(); + e.token(TokenKind::PRIVILEGES_KW); + + if let Some(ref action) = self.action { + e.space(); + action.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::VariableShowStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::VariableShowStmt); + + e.token(TokenKind::SHOW_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateTableSpaceStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateTableSpaceStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::TABLESPACE_KW); + e.space(); + e.token(TokenKind::IDENT(self.tablespacename.clone())); + + if let Some(ref owner) = self.owner { + e.space(); + e.token(TokenKind::OWNER_KW); + e.space(); + owner.to_tokens(e); + } + + if !self.location.is_empty() { + e.space(); + e.token(TokenKind::LOCATION_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.location))); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DropTableSpaceStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DropTableSpaceStmt); + + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::TABLESPACE_KW); + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + e.token(TokenKind::IDENT(self.tablespacename.clone())); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterTableSpaceOptionsStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterTableSpaceOptionsStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::TABLESPACE_KW); + e.space(); + e.token(TokenKind::IDENT(self.tablespacename.clone())); + + if self.is_reset { + e.space(); + e.token(TokenKind::RESET_KW); + } else { + e.space(); + e.token(TokenKind::SET_KW); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::Float { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.fval.clone())); + } +} + +impl ToTokens for pgt_query::protobuf::AlterTableMoveAllStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterTableMoveAllStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + + match self.objtype { + x if x == pgt_query::protobuf::ObjectType::ObjectTable as i32 => { + e.token(TokenKind::TABLE_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectIndex as i32 => { + e.token(TokenKind::INDEX_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectMatview as i32 => { + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + } + _ => {} + } + + e.space(); + e.token(TokenKind::ALL_KW); + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::TABLESPACE_KW); + e.space(); + e.token(TokenKind::IDENT(self.orig_tablespacename.clone())); + + if !self.roles.is_empty() { + e.space(); + e.token(TokenKind::OWNED_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + for (i, role) in self.roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + role.to_tokens(e); + } + } + + // Indent the SET TABLESPACE clause + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::TABLESPACE_KW); + e.space(); + e.token(TokenKind::IDENT(self.new_tablespacename.clone())); + + if self.nowait { + e.space(); + e.token(TokenKind::NOWAIT_KW); + } + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateExtensionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateExtensionStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::EXTENSION_KW); + + if self.if_not_exists { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + e.token(TokenKind::IDENT(self.extname.clone())); + + if !self.options.is_empty() { + for option in &self.options { + e.space(); + option.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CommentStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CommentStmt); + + e.token(TokenKind::COMMENT_KW); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + match self.objtype { + x if x == pgt_query::protobuf::ObjectType::ObjectTable as i32 => { + e.token(TokenKind::TABLE_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectColumn as i32 => { + e.token(TokenKind::COLUMN_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectFunction as i32 => { + e.token(TokenKind::FUNCTION_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectIndex as i32 => { + e.token(TokenKind::INDEX_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectView as i32 => { + e.token(TokenKind::VIEW_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectSequence as i32 => { + e.token(TokenKind::SEQUENCE_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectSchema as i32 => { + e.token(TokenKind::SCHEMA_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectDatabase as i32 => { + e.token(TokenKind::DATABASE_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectRole as i32 => { + e.token(TokenKind::ROLE_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectType as i32 => { + e.token(TokenKind::TYPE_KW); + } + _ => {} + } + + e.space(); + if let Some(ref object) = self.object { + object.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + + if self.comment.is_empty() { + e.token(TokenKind::NULL_KW); + } else { + e.token(TokenKind::STRING(format!("'{}'", self.comment))); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterExtensionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterExtensionStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::EXTENSION_KW); + e.space(); + e.token(TokenKind::IDENT(self.extname.clone())); + + if !self.options.is_empty() { + for option in &self.options { + e.space(); + option.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterExtensionContentsStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterExtensionContentsStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::EXTENSION_KW); + e.space(); + e.token(TokenKind::IDENT(self.extname.clone())); + e.space(); + + if self.action > 0 { + e.token(TokenKind::ADD_KW); + } else { + e.token(TokenKind::DROP_KW); + } + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.objtype() { + ObjectType::ObjectFunction => { + e.token(TokenKind::FUNCTION_KW); + } + ObjectType::ObjectTable => { + e.token(TokenKind::TABLE_KW); + } + ObjectType::ObjectType => { + e.token(TokenKind::TYPE_KW); + } + ObjectType::ObjectOperator => { + e.token(TokenKind::OPERATOR_KW); + } + _ => {} + } + + if let Some(ref object) = self.object { + e.space(); + object.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ObjectWithArgs { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ObjectWithArgs); + + for (i, name) in self.objname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + if !self.objargs.is_empty() || !self.objfuncargs.is_empty() || self.args_unspecified { + e.token(TokenKind::L_PAREN); + + let args_to_print = if !self.objfuncargs.is_empty() { + &self.objfuncargs + } else { + &self.objargs + }; + + if args_to_print.len() > 2 { + e.line(LineType::Soft); + e.indent_start(); + for (i, arg) in args_to_print.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + arg.to_tokens(e); + } + e.indent_end(); + e.line(LineType::Soft); + } else { + for (i, arg) in args_to_print.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + } + + e.token(TokenKind::R_PAREN); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::FunctionParameter { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::FunctionParameter); + + if !self.name.is_empty() { + e.token(TokenKind::IDENT(self.name.clone())); + e.space(); + } + + if let Some(ref arg_type) = self.arg_type { + arg_type.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateFdwStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateFdwStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::DATA_KW); + e.space(); + e.token(TokenKind::WRAPPER_KW); + e.space(); + e.token(TokenKind::IDENT(self.fdwname.clone())); + + if !self.func_options.is_empty() { + e.space(); + e.token(TokenKind::HANDLER_KW); + e.space(); + for (i, option) in self.func_options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateRoleStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateRoleStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + use pgt_query::protobuf::RoleStmtType; + match self.stmt_type() { + RoleStmtType::RolestmtRole => e.token(TokenKind::ROLE_KW), + RoleStmtType::RolestmtUser => e.token(TokenKind::USER_KW), + RoleStmtType::RolestmtGroup => e.token(TokenKind::GROUP_KW), + _ => e.token(TokenKind::ROLE_KW), + } + + e.space(); + e.token(TokenKind::IDENT(self.role.clone())); + + if !self.options.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::WITH_KW); + for option in &self.options { + e.space(); + option.to_tokens(e); + } + e.indent_end(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::SetOperationStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::SetOperationStmt); + + if let Some(ref larg) = self.larg { + larg.to_tokens(e); + } + + use pgt_query::protobuf::SetOperation; + match self.op() { + SetOperation::SetopUnion => { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::UNION_KW); + if self.all { + e.space(); + e.token(TokenKind::ALL_KW); + } + e.line(LineType::SoftOrSpace); + } + SetOperation::SetopIntersect => { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::INTERSECT_KW); + if self.all { + e.space(); + e.token(TokenKind::ALL_KW); + } + e.line(LineType::SoftOrSpace); + } + SetOperation::SetopExcept => { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::EXCEPT_KW); + if self.all { + e.space(); + e.token(TokenKind::ALL_KW); + } + e.line(LineType::SoftOrSpace); + } + _ => {} + } + + if let Some(ref rarg) = self.rarg { + rarg.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateForeignServerStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateForeignServerStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::SERVER_KW); + + if self.if_not_exists { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + e.token(TokenKind::IDENT(self.servername.clone())); + + if !self.servertype.is_empty() { + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.servertype))); + } + + if !self.version.is_empty() { + e.space(); + e.token(TokenKind::VERSION_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.version))); + } + + e.space(); + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::DATA_KW); + e.space(); + e.token(TokenKind::WRAPPER_KW); + e.space(); + e.token(TokenKind::IDENT(self.fdwname.clone())); + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterFdwStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterFdwStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::DATA_KW); + e.space(); + e.token(TokenKind::WRAPPER_KW); + e.space(); + e.token(TokenKind::IDENT(self.fdwname.clone())); + + if !self.func_options.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::HANDLER_KW); + e.space(); + for (i, option) in self.func_options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.indent_end(); + } + + if !self.options.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + e.indent_end(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterForeignServerStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterForeignServerStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::SERVER_KW); + e.space(); + e.token(TokenKind::IDENT(self.servername.clone())); + + if self.has_version { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::VERSION_KW); + e.space(); + if !self.version.is_empty() { + e.token(TokenKind::STRING(format!("'{}'", self.version))); + } else { + e.token(TokenKind::NULL_KW); + } + e.indent_end(); + } + + if !self.options.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + e.indent_end(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateForeignTableStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateForeignTableStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::TABLE_KW); + e.space(); + + if let Some(ref base_stmt) = self.base_stmt { + if let Some(ref relation) = base_stmt.relation { + relation.to_tokens(e); + } + + if !base_stmt.table_elts.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + e.indent_start(); + e.line(LineType::SoftOrSpace); + for (i, elt) in base_stmt.table_elts.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + elt.to_tokens(e); + } + e.indent_end(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::R_PAREN); + } + } + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::SERVER_KW); + e.space(); + e.token(TokenKind::IDENT(self.servername.clone())); + + if !self.options.is_empty() { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateUserMappingStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateUserMappingStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::USER_KW); + e.space(); + e.token(TokenKind::MAPPING_KW); + + if self.if_not_exists { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + if let Some(ref user) = self.user { + user.to_tokens(e); + } else { + e.token(TokenKind::CURRENT_USER_KW); + } + + e.space(); + e.token(TokenKind::SERVER_KW); + e.space(); + e.token(TokenKind::IDENT(self.servername.clone())); + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterUserMappingStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterUserMappingStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::USER_KW); + e.space(); + e.token(TokenKind::MAPPING_KW); + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + if let Some(ref user) = self.user { + user.to_tokens(e); + } else { + e.token(TokenKind::CURRENT_USER_KW); + } + + e.space(); + e.token(TokenKind::SERVER_KW); + e.space(); + e.token(TokenKind::IDENT(self.servername.clone())); + + if !self.options.is_empty() { + // Indent the OPTIONS clause + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + e.indent_end(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DropUserMappingStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DropUserMappingStmt); + + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::USER_KW); + e.space(); + e.token(TokenKind::MAPPING_KW); + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + if let Some(ref user) = self.user { + user.to_tokens(e); + } + + e.space(); + e.token(TokenKind::SERVER_KW); + e.space(); + e.token(TokenKind::IDENT(self.servername.clone())); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ImportForeignSchemaStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ImportForeignSchemaStmt); + + e.token(TokenKind::IMPORT_KW); + e.space(); + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::SCHEMA_KW); + e.space(); + e.token(TokenKind::IDENT(self.remote_schema.clone())); + + use pgt_query::protobuf::ImportForeignSchemaType; + match self.list_type() { + ImportForeignSchemaType::FdwImportSchemaLimitTo => { + e.space(); + e.token(TokenKind::LIMIT_KW); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, table) in self.table_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + table.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + ImportForeignSchemaType::FdwImportSchemaExcept => { + e.space(); + e.token(TokenKind::EXCEPT_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, table) in self.table_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + table.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + _ => {} + } + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::FROM_KW); + e.space(); + e.token(TokenKind::SERVER_KW); + e.space(); + e.token(TokenKind::IDENT(self.server_name.clone())); + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::INTO_KW); + e.space(); + e.token(TokenKind::IDENT(self.local_schema.clone())); + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::OPTIONS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreatePolicyStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreatePolicyStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::POLICY_KW); + e.space(); + e.token(TokenKind::IDENT(self.policy_name.clone())); + + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + if let Some(ref table) = self.table { + table.to_tokens(e); + } + + if !self.permissive { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::IDENT("RESTRICTIVE".to_string())); + } + + if !self.cmd_name.is_empty() && self.cmd_name != "all" { + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + match self.cmd_name.as_str() { + "select" => e.token(TokenKind::SELECT_KW), + "insert" => e.token(TokenKind::INSERT_KW), + "update" => e.token(TokenKind::UPDATE_KW), + "delete" => e.token(TokenKind::DELETE_KW), + _ => e.token(TokenKind::IDENT(self.cmd_name.clone())), + } + } else if self.cmd_name == "all" { + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::ALL_KW); + } + + if !self.roles.is_empty() { + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + for (i, role) in self.roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + role.to_tokens(e); + } + } + + if let Some(ref qual) = self.qual { + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::L_PAREN); + qual.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + + if let Some(ref with_check) = self.with_check { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::CHECK_KW); + e.space(); + e.token(TokenKind::L_PAREN); + with_check.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterPolicyStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterPolicyStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::POLICY_KW); + e.space(); + e.token(TokenKind::IDENT(self.policy_name.clone())); + + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + if let Some(ref table) = self.table { + table.to_tokens(e); + } + + if !self.roles.is_empty() { + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + for (i, role) in self.roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + role.to_tokens(e); + } + } + + if let Some(ref qual) = self.qual { + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::L_PAREN); + qual.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + + if let Some(ref with_check) = self.with_check { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::CHECK_KW); + e.space(); + e.token(TokenKind::L_PAREN); + with_check.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateAmStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateAmStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::ACCESS_KW); + e.space(); + e.token(TokenKind::METHOD_KW); + e.space(); + e.token(TokenKind::IDENT(self.amname.clone())); + + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + match self.amtype.as_str() { + "t" => e.token(TokenKind::TABLE_KW), + "i" => e.token(TokenKind::INDEX_KW), + _ => e.token(TokenKind::IDENT(self.amtype.clone())), + } + + e.space(); + e.token(TokenKind::HANDLER_KW); + e.space(); + for (i, handler) in self.handler_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + handler.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateSeqStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateSeqStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::SEQUENCE_KW); + + if self.if_not_exists { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + if let Some(ref sequence) = self.sequence { + e.space(); + sequence.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + for option in &self.options { + option.to_tokens(e); + e.space(); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterSeqStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterSeqStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::SEQUENCE_KW); + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + if let Some(ref sequence) = self.sequence { + e.space(); + sequence.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.space(); + } + option.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::Integer { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.ival.to_string())); + } +} + +impl ToTokens for pgt_query::protobuf::DefineStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DefineStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.kind() { + ObjectType::ObjectAggregate => { + e.token(TokenKind::AGGREGATE_KW); + } + ObjectType::ObjectOperator => { + e.token(TokenKind::OPERATOR_KW); + } + ObjectType::ObjectType => { + e.token(TokenKind::TYPE_KW); + } + ObjectType::ObjectCollation => { + e.token(TokenKind::COLLATION_KW); + } + ObjectType::ObjectTsdictionary => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::DICTIONARY_KW); + } + ObjectType::ObjectTsconfiguration => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::CONFIGURATION_KW); + } + ObjectType::ObjectTstemplate => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::TEMPLATE_KW); + } + ObjectType::ObjectTsparser => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::PARSER_KW); + } + _ => {} + } + + if !self.defnames.is_empty() { + e.space(); + for (i, name) in self.defnames.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + if !self.args.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if !self.definition.is_empty() { + e.space(); + + // Special handling for CREATE COLLATION ... FROM + if self.kind() == ObjectType::ObjectCollation + && self.definition.len() == 1 + && self.definition[0].node.as_ref().map_or(false, |n| { + matches!(n, pgt_query::protobuf::node::Node::DefElem(elem) if elem.defname == "from") + }) + { + // For CREATE COLLATION ... FROM, don't use parentheses + self.definition[0].to_tokens(e); + } else { + e.token(TokenKind::L_PAREN); + e.indent_start(); + for (i, def) in self.definition.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + } + e.line(LineType::SoftOrSpace); + def.to_tokens(e); + } + e.indent_end(); + e.line(LineType::Soft); + e.token(TokenKind::R_PAREN); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateDomainStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateDomainStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::DOMAIN_KW); + e.space(); + + for (i, name) in self.domainname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + if let Some(ref type_name) = self.type_name { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + type_name.to_tokens(e); + } + + if let Some(ref coll_clause) = self.coll_clause { + e.space(); + coll_clause.to_tokens(e); + } + + for constraint in &self.constraints { + e.space(); + constraint.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CollateClause { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(arg) = &self.arg { + arg.to_tokens(e); + e.space(); + } + + e.token(TokenKind::COLLATE_KW); + e.space(); + + for (i, name) in self.collname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + e.token(TokenKind::IDENT('"'.to_string())); + name.to_tokens(e); + e.token(TokenKind::IDENT('"'.to_string())); + } + } +} + +impl ToTokens for pgt_query::protobuf::AlterDomainStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterDomainStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::DOMAIN_KW); + + if self.missing_ok && self.subtype == "T" { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + for (i, name) in self.type_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + match self.subtype.as_str() { + "T" => { + e.space(); + e.token(TokenKind::TYPE_KW); + } + "N" => { + e.space(); + if let Some(ref def) = self.def { + if let Some(pgt_query::protobuf::node::Node::String(s)) = &def.node { + if s.sval == "NOT NULL" { + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } else if s.sval == "NULL" { + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + } + } + } + "O" => { + e.space(); + e.token(TokenKind::OWNER_KW); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + if let Some(ref def) = self.def { + def.to_tokens(e); + } + } + "R" => { + e.space(); + e.token(TokenKind::RENAME_KW); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } + "S" => { + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::SCHEMA_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } + "A" => { + e.space(); + e.token(TokenKind::ADD_KW); + e.space(); + if let Some(ref def) = self.def { + def.to_tokens(e); + } + } + "D" | "X" => { + e.space(); + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::CONSTRAINT_KW); + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } + "V" => { + e.space(); + e.token(TokenKind::VALIDATE_KW); + e.space(); + e.token(TokenKind::CONSTRAINT_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } + _ => panic!("Unknown ALTER DOMAIN subtype: {}", self.subtype), + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::Constraint { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::Constraint); + + if !self.conname.is_empty() { + e.token(TokenKind::CONSTRAINT_KW); + e.space(); + e.token(TokenKind::IDENT(self.conname.clone())); + e.space(); + } + + use pgt_query::protobuf::ConstrType; + match self.contype() { + ConstrType::ConstrCheck => { + e.token(TokenKind::CHECK_KW); + e.space(); + e.token(TokenKind::L_PAREN); + if let Some(ref raw_expr) = self.raw_expr { + raw_expr.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + ConstrType::ConstrPrimary => { + e.token(TokenKind::PRIMARY_KW); + e.space(); + e.token(TokenKind::KEY_KW); + + if !self.keys.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, key) in self.keys.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + key.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } + ConstrType::ConstrUnique => { + e.token(TokenKind::UNIQUE_KW); + + if !self.keys.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, key) in self.keys.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + key.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } + ConstrType::ConstrForeign => { + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::KEY_KW); + } + ConstrType::ConstrNotnull => { + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + ConstrType::ConstrDefault => { + e.token(TokenKind::DEFAULT_KW); + e.space(); + if let Some(ref raw_expr) = self.raw_expr { + raw_expr.to_tokens(e); + } + } + _ => {} + } + + if self.is_no_inherit { + e.space(); + e.token(TokenKind::NO_KW); + e.space(); + e.token(TokenKind::INHERIT_KW); + } + + if self.deferrable { + e.space(); + e.token(TokenKind::DEFERRABLE_KW); + + if self.initdeferred { + e.space(); + e.token(TokenKind::INITIALLY_KW); + e.space(); + e.token(TokenKind::DEFERRED_KW); + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateOpClassStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateOpClassStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::CLASS_KW); + e.space(); + + for (i, name) in self.opclassname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + if self.is_default { + e.space(); + e.token(TokenKind::DEFAULT_KW); + } + + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + + if let Some(ref datatype) = self.datatype { + datatype.to_tokens(e); + } + + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::IDENT(self.amname.clone())); + + if !self.opfamilyname.is_empty() { + e.space(); + e.token(TokenKind::FAMILY_KW); + e.space(); + for (i, name) in self.opfamilyname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + if !self.items.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::AS_KW); + e.space(); + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + e.indent_end(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateOpClassItem { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateOpClassItem); + + match self.itemtype { + 1 => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::IDENT(self.number.to_string())); + e.space(); + if let Some(ref name) = self.name { + name.to_tokens(e); + } + if !self.class_args.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, arg) in self.class_args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } + 2 => { + e.token(TokenKind::FUNCTION_KW); + e.space(); + e.token(TokenKind::IDENT(self.number.to_string())); + if !self.class_args.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, arg) in self.class_args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + if let Some(ref name) = self.name { + e.space(); + name.to_tokens(e); + } + } + 3 => { + e.token(TokenKind::STORAGE_KW); + e.space(); + if let Some(ref storedtype) = self.storedtype { + storedtype.to_tokens(e); + } + } + _ => {} + } + + if !self.order_family.is_empty() { + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::ORDER_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + for (i, name) in self.order_family.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateOpFamilyStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateOpFamilyStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::FAMILY_KW); + e.space(); + + for (i, name) in self.opfamilyname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::IDENT(self.amname.clone())); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterOpFamilyStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterOpFamilyStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::FAMILY_KW); + e.space(); + + for (i, name) in self.opfamilyname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::IDENT(self.amname.clone())); + + // Indent the ADD/DROP operations + e.indent_start(); + e.line(LineType::SoftOrSpace); + + if self.is_drop { + e.token(TokenKind::DROP_KW); + } else { + e.token(TokenKind::ADD_KW); + } + e.space(); + + for (i, item) in self.items.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + item.to_tokens(e); + } + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ReplicaIdentityStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + match self.identity_type.as_str() { + "d" => e.token(TokenKind::DEFAULT_KW), + "n" => e.token(TokenKind::NOTHING_KW), + "f" => e.token(TokenKind::FULL_KW), + "i" => { + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::INDEX_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } + _ => panic!("Unknown replica identity type: {}", self.identity_type), + } + } +} + +impl ToTokens for pgt_query::protobuf::AlterCollationStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterCollationStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::COLLATION_KW); + e.space(); + + for (i, name) in self.collname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.space(); + e.token(TokenKind::REFRESH_KW); + e.space(); + e.token(TokenKind::VERSION_KW); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DeclareCursorStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DeclareCursorStmt); + + e.token(TokenKind::DECLARE_KW); + e.space(); + e.token(TokenKind::IDENT(self.portalname.clone())); + e.space(); + e.token(TokenKind::CURSOR_KW); + + // TODO: Handle cursor options (options field) + + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + if let Some(ref query) = self.query { + query.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ClosePortalStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ClosePortalStmt); + + e.token(TokenKind::CLOSE_KW); + e.space(); + e.token(TokenKind::IDENT(self.portalname.clone())); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::SecLabelStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::SecLabelStmt); + + e.token(TokenKind::SECURITY_KW); + e.space(); + e.token(TokenKind::LABEL_KW); + + if !self.provider.is_empty() { + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::IDENT(self.provider.clone())); + } + + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.objtype() { + ObjectType::ObjectTable => e.token(TokenKind::TABLE_KW), + ObjectType::ObjectColumn => e.token(TokenKind::COLUMN_KW), + ObjectType::ObjectFunction => e.token(TokenKind::FUNCTION_KW), + ObjectType::ObjectRole => e.token(TokenKind::ROLE_KW), + ObjectType::ObjectDatabase => e.token(TokenKind::DATABASE_KW), + ObjectType::ObjectTablespace => e.token(TokenKind::TABLESPACE_KW), + ObjectType::ObjectSchema => e.token(TokenKind::SCHEMA_KW), + ObjectType::ObjectType => e.token(TokenKind::TYPE_KW), + ObjectType::ObjectDomain => e.token(TokenKind::DOMAIN_KW), + ObjectType::ObjectSequence => e.token(TokenKind::SEQUENCE_KW), + ObjectType::ObjectLanguage => e.token(TokenKind::LANGUAGE_KW), + ObjectType::ObjectLargeobject => { + e.token(TokenKind::LARGE_KW); + e.space(); + e.token(TokenKind::OBJECT_KW); + } + ObjectType::ObjectProcedure => e.token(TokenKind::PROCEDURE_KW), + ObjectType::ObjectRoutine => e.token(TokenKind::ROUTINE_KW), + _ => {} + } + + if let Some(ref object) = self.object { + e.space(); + object.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.label))); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AStar { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT("*".to_string())); + } +} + +impl ToTokens for pgt_query::protobuf::ReturnStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ReturnStmt); + + e.token(TokenKind::RETURN_KW); + + if let Some(ref returnval) = self.returnval { + e.space(); + returnval.as_ref().to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::FetchStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::FetchDirection; + + e.group_start(GroupKind::FetchStmt); + + if self.ismove { + e.token(TokenKind::MOVE_KW); + } else { + e.token(TokenKind::FETCH_KW); + } + + match self.direction() { + FetchDirection::FetchForward => { + if self.how_many == 0 { + e.space(); + e.token(TokenKind::ALL_KW); + } else if self.how_many > 1 { + e.space(); + e.token(TokenKind::FORWARD_KW); + e.space(); + e.token(TokenKind::IDENT(self.how_many.to_string())); + } else { + e.space(); + e.token(TokenKind::NEXT_KW); + } + } + FetchDirection::FetchBackward => { + if self.how_many == 0 { + e.space(); + e.token(TokenKind::BACKWARD_KW); + e.space(); + e.token(TokenKind::ALL_KW); + } else if self.how_many > 1 { + e.space(); + e.token(TokenKind::BACKWARD_KW); + e.space(); + e.token(TokenKind::IDENT(self.how_many.to_string())); + } else { + e.space(); + e.token(TokenKind::PRIOR_KW); + } + } + FetchDirection::FetchAbsolute => { + e.space(); + e.token(TokenKind::ABSOLUTE_KW); + e.space(); + e.token(TokenKind::IDENT(self.how_many.to_string())); + } + FetchDirection::FetchRelative => { + e.space(); + e.token(TokenKind::RELATIVE_KW); + e.space(); + e.token(TokenKind::IDENT(self.how_many.to_string())); + } + _ => {} + } + + if !self.portalname.is_empty() { + e.space(); + e.token(TokenKind::FROM_KW); + e.space(); + e.token(TokenKind::IDENT(self.portalname.clone())); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateStatsStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateStatsStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::STATISTICS_KW); + + if self.if_not_exists { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + if !self.defnames.is_empty() { + e.space(); + for (i, name) in self.defnames.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + if !self.stat_types.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, stat_type) in self.stat_types.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + stat_type.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if !self.exprs.is_empty() { + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + for (i, expr) in self.exprs.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + expr.to_tokens(e); + } + } + + if !self.relations.is_empty() { + e.space(); + e.token(TokenKind::FROM_KW); + e.space(); + for (i, relation) in self.relations.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + relation.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::StatsElem { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } else { + e.token(TokenKind::IDENT(self.name.clone())); + } + } +} + +impl ToTokens for pgt_query::protobuf::AlterRoleStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterRoleStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::ROLE_KW); + + if let Some(ref role) = self.role { + e.space(); + role.to_tokens(e); + } + + if self.action == 1 { + e.space(); + e.token(TokenKind::SET_KW); + } else if self.action == -1 { + e.space(); + e.token(TokenKind::RESET_KW); + } else if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.space(); + } + option.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterRoleSetStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterRoleSetStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::ROLE_KW); + + if let Some(ref role) = self.role { + e.space(); + role.to_tokens(e); + } + + if !self.database.is_empty() { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::DATABASE_KW); + e.space(); + e.token(TokenKind::IDENT(self.database.clone())); + } + + if let Some(ref setstmt) = self.setstmt { + e.space(); + setstmt.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DropRoleStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DropRoleStmt); + + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::ROLE_KW); + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + if !self.roles.is_empty() { + e.space(); + for (i, role) in self.roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + role.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterStatsStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterStatsStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::STATISTICS_KW); + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + if !self.defnames.is_empty() { + e.space(); + for (i, name) in self.defnames.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + if let Some(ref target) = self.stxstattarget { + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::STATISTICS_KW); + e.space(); + target.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateFunctionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateFunctionStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if self.replace { + e.token(TokenKind::OR_KW); + e.space(); + e.token(TokenKind::REPLACE_KW); + e.space(); + } + + if self.is_procedure { + e.token(TokenKind::PROCEDURE_KW); + } else { + e.token(TokenKind::FUNCTION_KW); + } + + if !self.funcname.is_empty() { + e.space(); + for (i, name) in self.funcname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + e.space(); + e.token(TokenKind::L_PAREN); + if !self.parameters.is_empty() { + e.line(LineType::Soft); + e.indent_start(); + for (i, param) in self.parameters.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + param.to_tokens(e); + } + + e.line(LineType::Soft); + e.indent_end(); + } + + e.token(TokenKind::R_PAREN); + + if let Some(ref return_type) = self.return_type { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::RETURNS_KW); + e.space(); + return_type.to_tokens(e); + } + + if !self.options.is_empty() { + e.line(LineType::SoftOrSpace); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.line(LineType::SoftOrSpace); + } + option.to_tokens(e); + } + } + + if let Some(ref sql_body) = self.sql_body { + e.space(); + sql_body.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateTrigStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateTrigStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if self.replace { + e.token(TokenKind::OR_KW); + e.space(); + e.token(TokenKind::REPLACE_KW); + e.space(); + } + + e.token(TokenKind::TRIGGER_KW); + e.space(); + e.token(TokenKind::IDENT(self.trigname.clone())); + e.line(LineType::SoftOrSpace); + + e.token(TokenKind::AFTER_KW); + e.space(); + e.token(TokenKind::INSERT_KW); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + e.line(LineType::SoftOrSpace); + + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::EACH_KW); + e.space(); + e.token(TokenKind::ROW_KW); + e.line(LineType::SoftOrSpace); + + e.token(TokenKind::EXECUTE_KW); + e.space(); + e.token(TokenKind::FUNCTION_KW); + e.space(); + + if !self.funcname.is_empty() { + for (i, name) in self.funcname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + e.token(TokenKind::L_PAREN); + e.token(TokenKind::R_PAREN); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateEventTrigStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateEventTrigStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::EVENT_KW); + e.space(); + e.token(TokenKind::TRIGGER_KW); + e.space(); + e.token(TokenKind::IDENT(self.trigname.clone())); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::IDENT(self.eventname.clone())); + e.line(LineType::SoftOrSpace); + + if !self.whenclause.is_empty() { + e.token(TokenKind::WHEN_KW); + e.space(); + for (i, clause) in self.whenclause.iter().enumerate() { + if i > 0 { + e.space(); + e.token(TokenKind::AND_KW); + e.space(); + } + clause.to_tokens(e); + } + e.line(LineType::SoftOrSpace); + } + + e.token(TokenKind::EXECUTE_KW); + e.space(); + e.token(TokenKind::FUNCTION_KW); + e.space(); + + if !self.funcname.is_empty() { + for (i, name) in self.funcname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + } + + e.token(TokenKind::L_PAREN); + e.token(TokenKind::R_PAREN); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterEventTrigStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterEventTrigStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::EVENT_KW); + e.space(); + e.token(TokenKind::TRIGGER_KW); + e.space(); + e.token(TokenKind::IDENT(self.trigname.clone())); + e.space(); + + match self.tgenabled.as_str() { + "O" => e.token(TokenKind::ENABLE_KW), + "D" => e.token(TokenKind::DISABLE_KW), + "R" => { + e.token(TokenKind::ENABLE_KW); + e.space(); + e.token(TokenKind::REPLICA_KW); + } + "A" => { + e.token(TokenKind::ENABLE_KW); + e.space(); + e.token(TokenKind::ALWAYS_KW); + } + _ => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreatePLangStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreatePlangStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if self.replace { + e.token(TokenKind::OR_KW); + e.space(); + e.token(TokenKind::REPLACE_KW); + e.space(); + } + + if self.pltrusted { + e.token(TokenKind::TRUSTED_KW); + e.space(); + } + + e.token(TokenKind::LANGUAGE_KW); + e.space(); + e.token(TokenKind::IDENT(self.plname.clone())); + + if !self.plhandler.is_empty() { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::HANDLER_KW); + e.space(); + for (i, handler) in self.plhandler.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + handler.to_tokens(e); + } + } + + if !self.plinline.is_empty() { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::INLINE_KW); + e.space(); + for (i, inline) in self.plinline.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + inline.to_tokens(e); + } + } + + if !self.plvalidator.is_empty() { + e.line(LineType::SoftOrSpace); + e.token(TokenKind::VALIDATOR_KW); + e.space(); + for (i, validator) in self.plvalidator.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + validator.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterFunctionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterFunctionStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + + match self.objtype { + x if x == pgt_query::protobuf::ObjectType::ObjectFunction as i32 => { + e.token(TokenKind::FUNCTION_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectProcedure as i32 => { + e.token(TokenKind::PROCEDURE_KW); + } + x if x == pgt_query::protobuf::ObjectType::ObjectRoutine as i32 => { + e.token(TokenKind::ROUTINE_KW); + } + _ => { + e.token(TokenKind::FUNCTION_KW); + } + } + e.space(); + + if let Some(ref func) = self.func { + func.to_tokens(e); + } + + for action in &self.actions { + e.line(LineType::SoftOrSpace); + action.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::InlineCodeBlock { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::InlineCodeBlock); + + e.token(TokenKind::STRING(self.source_text.clone())); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DoStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DoStmt); + e.token(TokenKind::DO_KW); + + if !self.args.is_empty() { + e.space(); + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.line(LineType::SoftOrSpace); + } + arg.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CallStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CallStmt); + + e.token(TokenKind::CALL_KW); + e.space(); + + if let Some(ref funccall) = self.funccall { + funccall.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RenameStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RenameStmt); + e.token(TokenKind::ALTER_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.rename_type() { + ObjectType::ObjectTable => e.token(TokenKind::TABLE_KW), + ObjectType::ObjectSequence => e.token(TokenKind::SEQUENCE_KW), + ObjectType::ObjectView => e.token(TokenKind::VIEW_KW), + ObjectType::ObjectIndex => e.token(TokenKind::INDEX_KW), + ObjectType::ObjectAggregate => e.token(TokenKind::AGGREGATE_KW), + ObjectType::ObjectFunction => e.token(TokenKind::FUNCTION_KW), + ObjectType::ObjectOperator => e.token(TokenKind::OPERATOR_KW), + ObjectType::ObjectType => e.token(TokenKind::TYPE_KW), + ObjectType::ObjectColumn => e.token(TokenKind::COLUMN_KW), + ObjectType::ObjectOpfamily => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::FAMILY_KW); + } + ObjectType::ObjectOpclass => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::CLASS_KW); + } + ObjectType::ObjectConversion => e.token(TokenKind::CONVERSION_KW), + ObjectType::ObjectFdw => { + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::DATA_KW); + e.space(); + e.token(TokenKind::WRAPPER_KW); + } + ObjectType::ObjectForeignServer => e.token(TokenKind::SERVER_KW), + ObjectType::ObjectLanguage => e.token(TokenKind::LANGUAGE_KW), + ObjectType::ObjectPublication => e.token(TokenKind::PUBLICATION_KW), + ObjectType::ObjectSubscription => e.token(TokenKind::SUBSCRIPTION_KW), + ObjectType::ObjectDatabase => e.token(TokenKind::DATABASE_KW), + ObjectType::ObjectRole => e.token(TokenKind::ROLE_KW), + ObjectType::ObjectSchema => e.token(TokenKind::SCHEMA_KW), + ObjectType::ObjectEventTrigger => { + e.token(TokenKind::EVENT_KW); + e.space(); + e.token(TokenKind::TRIGGER_KW); + } + ObjectType::ObjectTablespace => e.token(TokenKind::TABLESPACE_KW), + ObjectType::ObjectCollation => e.token(TokenKind::COLLATION_KW), + ObjectType::ObjectDomain => e.token(TokenKind::DOMAIN_KW), + ObjectType::ObjectPolicy => e.token(TokenKind::POLICY_KW), + ObjectType::ObjectRule => e.token(TokenKind::RULE_KW), + ObjectType::ObjectTrigger => e.token(TokenKind::TRIGGER_KW), + ObjectType::ObjectStatisticExt => e.token(TokenKind::STATISTICS_KW), + ObjectType::ObjectTsparser => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::PARSER_KW); + } + ObjectType::ObjectTsdictionary => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::DICTIONARY_KW); + } + ObjectType::ObjectTstemplate => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::TEMPLATE_KW); + } + ObjectType::ObjectTsconfiguration => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::CONFIGURATION_KW); + } + ObjectType::ObjectMatview => { + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + } + ObjectType::ObjectExtension => e.token(TokenKind::EXTENSION_KW), + ObjectType::ObjectProcedure => e.token(TokenKind::PROCEDURE_KW), + _ => {} + } + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } else if let Some(ref object) = self.object { + object.to_tokens(e); + } + + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::RENAME_KW); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::IDENT(self.newname.clone())); + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterObjectDependsStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterObjectDependsStmt); + e.token(TokenKind::ALTER_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.object_type() { + ObjectType::ObjectFunction => e.token(TokenKind::FUNCTION_KW), + ObjectType::ObjectProcedure => e.token(TokenKind::PROCEDURE_KW), + ObjectType::ObjectRoutine => e.token(TokenKind::ROUTINE_KW), + ObjectType::ObjectIndex => e.token(TokenKind::INDEX_KW), + _ => {} + } + e.space(); + + if let Some(ref object) = self.object { + object.to_tokens(e); + } + + // Indent the DEPENDS ON EXTENSION clause + e.indent_start(); + e.line(LineType::SoftOrSpace); + if self.remove { + e.token(TokenKind::NO_KW); + e.space(); + } + e.token(TokenKind::DEPENDS_KW); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::EXTENSION_KW); + e.space(); + + if let Some(ref extname) = self.extname { + extname.to_tokens(e); + } + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterObjectSchemaStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterObjectSchemaStmt); + e.token(TokenKind::ALTER_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.object_type() { + ObjectType::ObjectTable => e.token(TokenKind::TABLE_KW), + ObjectType::ObjectSequence => e.token(TokenKind::SEQUENCE_KW), + ObjectType::ObjectView => e.token(TokenKind::VIEW_KW), + ObjectType::ObjectMatview => { + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + } + ObjectType::ObjectForeignTable => { + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::TABLE_KW); + } + ObjectType::ObjectAggregate => e.token(TokenKind::AGGREGATE_KW), + ObjectType::ObjectFunction => e.token(TokenKind::FUNCTION_KW), + ObjectType::ObjectOperator => e.token(TokenKind::OPERATOR_KW), + ObjectType::ObjectType => e.token(TokenKind::TYPE_KW), + ObjectType::ObjectOpfamily => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::FAMILY_KW); + } + ObjectType::ObjectOpclass => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::CLASS_KW); + } + ObjectType::ObjectConversion => e.token(TokenKind::CONVERSION_KW), + ObjectType::ObjectCollation => e.token(TokenKind::COLLATION_KW), + ObjectType::ObjectDomain => e.token(TokenKind::DOMAIN_KW), + ObjectType::ObjectExtension => e.token(TokenKind::EXTENSION_KW), + ObjectType::ObjectLanguage => e.token(TokenKind::LANGUAGE_KW), + ObjectType::ObjectPublication => e.token(TokenKind::PUBLICATION_KW), + ObjectType::ObjectSchema => e.token(TokenKind::SCHEMA_KW), + ObjectType::ObjectStatisticExt => e.token(TokenKind::STATISTICS_KW), + ObjectType::ObjectTsparser => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::PARSER_KW); + } + ObjectType::ObjectTsdictionary => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::DICTIONARY_KW); + } + ObjectType::ObjectTstemplate => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::TEMPLATE_KW); + } + ObjectType::ObjectTsconfiguration => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::CONFIGURATION_KW); + } + _ => {} + } + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } else if let Some(ref object) = self.object { + object.to_tokens(e); + } + + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::SCHEMA_KW); + e.space(); + e.token(TokenKind::IDENT(self.newschema.clone())); + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterOwnerStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterOwnerStmt); + e.token(TokenKind::ALTER_KW); + e.space(); + + use pgt_query::protobuf::ObjectType; + match self.object_type() { + ObjectType::ObjectTable => e.token(TokenKind::TABLE_KW), + ObjectType::ObjectSequence => e.token(TokenKind::SEQUENCE_KW), + ObjectType::ObjectView => e.token(TokenKind::VIEW_KW), + ObjectType::ObjectMatview => { + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + } + ObjectType::ObjectForeignTable => { + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::TABLE_KW); + } + ObjectType::ObjectDatabase => e.token(TokenKind::DATABASE_KW), + ObjectType::ObjectFunction => e.token(TokenKind::FUNCTION_KW), + ObjectType::ObjectProcedure => e.token(TokenKind::PROCEDURE_KW), + ObjectType::ObjectRoutine => e.token(TokenKind::ROUTINE_KW), + ObjectType::ObjectSchema => e.token(TokenKind::SCHEMA_KW), + ObjectType::ObjectType => e.token(TokenKind::TYPE_KW), + ObjectType::ObjectOperator => e.token(TokenKind::OPERATOR_KW), + ObjectType::ObjectAggregate => e.token(TokenKind::AGGREGATE_KW), + ObjectType::ObjectOpfamily => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::FAMILY_KW); + } + ObjectType::ObjectOpclass => { + e.token(TokenKind::OPERATOR_KW); + e.space(); + e.token(TokenKind::CLASS_KW); + } + ObjectType::ObjectConversion => e.token(TokenKind::CONVERSION_KW), + ObjectType::ObjectLanguage => e.token(TokenKind::LANGUAGE_KW), + ObjectType::ObjectLargeobject => { + e.token(TokenKind::LARGE_KW); + e.space(); + e.token(TokenKind::OBJECT_KW); + } + ObjectType::ObjectTsparser => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::PARSER_KW); + } + ObjectType::ObjectTstemplate => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::TEMPLATE_KW); + } + ObjectType::ObjectTsdictionary => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::DICTIONARY_KW); + } + ObjectType::ObjectTsconfiguration => { + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::CONFIGURATION_KW); + } + ObjectType::ObjectStatisticExt => e.token(TokenKind::STATISTICS_KW), + ObjectType::ObjectEventTrigger => { + e.token(TokenKind::EVENT_KW); + e.space(); + e.token(TokenKind::TRIGGER_KW); + } + ObjectType::ObjectCollation => e.token(TokenKind::COLLATION_KW), + ObjectType::ObjectFdw => { + e.token(TokenKind::FOREIGN_KW); + e.space(); + e.token(TokenKind::DATA_KW); + e.space(); + e.token(TokenKind::WRAPPER_KW); + } + ObjectType::ObjectPublication => e.token(TokenKind::PUBLICATION_KW), + ObjectType::ObjectSubscription => e.token(TokenKind::SUBSCRIPTION_KW), + ObjectType::ObjectDomain => e.token(TokenKind::DOMAIN_KW), + _ => {} + } + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } else if let Some(ref object) = self.object { + object.to_tokens(e); + } + + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::OWNER_KW); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + + if let Some(ref newowner) = self.newowner { + newowner.to_tokens(e); + } + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterOperatorStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterOperatorStmt); + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::OPERATOR_KW); + e.space(); + + if let Some(ref opername) = self.opername { + opername.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.indent_start(); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + } + e.line(LineType::SoftOrSpace); + option.to_tokens(e); + } + e.indent_end(); + e.line(LineType::Soft); + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterTypeStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterTypeStmt); + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + + for (i, type_name) in self.type_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + type_name.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.space(); + } + option.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterEnumStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterEnumStmt); + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + + for (i, type_name) in self.type_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + type_name.to_tokens(e); + } + + e.space(); + if !self.old_val.is_empty() { + e.token(TokenKind::RENAME_KW); + e.space(); + e.token(TokenKind::VALUE_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.old_val))); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.new_val))); + } else { + e.token(TokenKind::ADD_KW); + e.space(); + e.token(TokenKind::VALUE_KW); + if self.skip_if_new_val_exists { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.new_val))); + if !self.new_val_neighbor.is_empty() { + e.space(); + if self.new_val_is_after { + e.token(TokenKind::AFTER_KW); + } else { + e.token(TokenKind::BEFORE_KW); + } + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.new_val_neighbor))); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RuleStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RuleStmt); + e.token(TokenKind::CREATE_KW); + if self.replace { + e.space(); + e.token(TokenKind::OR_KW); + e.space(); + e.token(TokenKind::REPLACE_KW); + } + e.space(); + e.token(TokenKind::RULE_KW); + e.space(); + e.token(TokenKind::IDENT(self.rulename.clone())); + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + + use pgt_query::protobuf::CmdType; + match self.event() { + CmdType::CmdSelect => e.token(TokenKind::SELECT_KW), + CmdType::CmdInsert => e.token(TokenKind::INSERT_KW), + CmdType::CmdUpdate => e.token(TokenKind::UPDATE_KW), + CmdType::CmdDelete => e.token(TokenKind::DELETE_KW), + _ => {} + } + + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::TO_KW); + e.space(); + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if let Some(ref where_clause) = self.where_clause { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::DO_KW); + e.space(); + + if self.instead { + e.token(TokenKind::INSTEAD_KW); + e.space(); + } + + if self.actions.len() == 1 && !self.actions[0].node.is_none() { + self.actions[0].to_tokens(e); + } else if self.actions.len() > 1 { + e.token(TokenKind::L_PAREN); + for (i, action) in self.actions.iter().enumerate() { + if i > 0 { + e.token(TokenKind::SEMICOLON); + e.space(); + } + action.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } else { + e.token(TokenKind::NOTHING_KW); + } + + e.indent_end(); + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::NotifyStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::NotifyStmt); + e.token(TokenKind::NOTIFY_KW); + e.space(); + e.token(TokenKind::IDENT(self.conditionname.clone())); + + if !self.payload.is_empty() { + e.token(TokenKind::COMMA); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.payload))); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ListenStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ListenStmt); + e.token(TokenKind::LISTEN_KW); + e.space(); + e.token(TokenKind::IDENT(self.conditionname.clone())); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::UnlistenStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::UnlistenStmt); + e.token(TokenKind::UNLISTEN_KW); + e.space(); + e.token(TokenKind::IDENT(self.conditionname.clone())); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ExecuteStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ExecuteStmt); + e.token(TokenKind::EXECUTE_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + + if !self.params.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, param) in self.params.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + param.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::PrepareStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::PrepareStmt); + e.token(TokenKind::PREPARE_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + + if !self.argtypes.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, argtype) in self.argtypes.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + argtype.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + e.space(); + e.token(TokenKind::AS_KW); + e.line(LineType::SoftOrSpace); + e.indent_start(); + + if let Some(query) = &self.query { + query.to_tokens(e); + } + + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ParamRef { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ParamRef); + e.token(TokenKind::IDENT(format!("${}", self.number))); + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DeallocateStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DeallocateStmt); + e.token(TokenKind::DEALLOCATE_KW); + e.space(); + + if self.isall { + e.token(TokenKind::ALL_KW); + } else { + e.token(TokenKind::IDENT(self.name.clone())); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::LockStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::LockStmt); + e.token(TokenKind::LOCK_KW); + e.space(); + + if !self.relations.is_empty() { + e.token(TokenKind::TABLE_KW); + e.space(); + + for (i, relation) in self.relations.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + relation.to_tokens(e); + } + } + + match self.mode { + 1 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::ACCESS_KW); + e.space(); + e.token(TokenKind::SHARE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + 2 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::ROW_KW); + e.space(); + e.token(TokenKind::SHARE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + 3 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::ROW_KW); + e.space(); + e.token(TokenKind::EXCLUSIVE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + 4 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::SHARE_KW); + e.space(); + e.token(TokenKind::UPDATE_KW); + e.space(); + e.token(TokenKind::EXCLUSIVE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + 5 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::SHARE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + 6 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::SHARE_KW); + e.space(); + e.token(TokenKind::ROW_KW); + e.space(); + e.token(TokenKind::EXCLUSIVE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + 7 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::EXCLUSIVE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + 8 => { + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::ACCESS_KW); + e.space(); + e.token(TokenKind::EXCLUSIVE_KW); + e.space(); + e.token(TokenKind::MODE_KW); + } + _ => {} + } + + if self.nowait { + e.space(); + e.token(TokenKind::NOWAIT_KW); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CompositeTypeStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CompositeTypeStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + + if let Some(ref typevar) = self.typevar { + typevar.to_tokens(e); + } + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.indent_start(); + e.line(LineType::SoftOrSpace); + + for (i, col) in self.coldeflist.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + col.to_tokens(e); + } + + e.indent_end(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::R_PAREN); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateEnumStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateEnumStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + + for (i, name) in self.type_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::ENUM_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, val) in self.vals.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + e.emit_quoted_string_or_fallback(val); + } + + e.token(TokenKind::R_PAREN); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::PlAssignStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::PlassignStmt); + + e.token(TokenKind::IDENT(self.name.clone())); + + for indirection in &self.indirection { + indirection.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IDENT(":=".to_string())); + e.space(); + + if let Some(ref val) = self.val { + val.as_ref().to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateRangeStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateRangeStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::TYPE_KW); + e.space(); + + for (i, name) in self.type_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::RANGE_KW); + + if !self.params.is_empty() { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::L_PAREN); + + for (i, param) in self.params.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + param.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + e.indent_end(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateTableAsStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateTableAsStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if let Some(ref into) = self.into { + if self.objtype == pgt_query::protobuf::ObjectType::Undefined as i32 { + if into.on_commit != pgt_query::protobuf::OnCommitAction::OncommitNoop as i32 { + e.token(TokenKind::TEMP_KW); + e.space(); + } + } else if self.objtype == pgt_query::protobuf::ObjectType::ObjectTable as i32 { + e.token(TokenKind::TABLE_KW); + e.space(); + } else if self.objtype == pgt_query::protobuf::ObjectType::ObjectMatview as i32 { + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + e.space(); + } + + if self.if_not_exists { + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + e.space(); + } + + if let Some(ref rel) = into.rel { + rel.to_tokens(e); + } + + if !into.col_names.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, col) in into.col_names.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } else { + e.token(TokenKind::TABLE_KW); + e.space(); + } + + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + + if let Some(ref query) = self.query { + query.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RefreshMatViewStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RefreshMatViewStmt); + + e.token(TokenKind::REFRESH_KW); + e.space(); + e.token(TokenKind::MATERIALIZED_KW); + e.space(); + e.token(TokenKind::VIEW_KW); + e.space(); + + if self.concurrent { + e.token(TokenKind::CONCURRENTLY_KW); + e.space(); + } + + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if self.skip_data { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::NO_KW); + e.space(); + e.token(TokenKind::DATA_KW); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::LoadStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::LoadStmt); + + e.token(TokenKind::LOAD_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.filename))); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreatedbStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreatedbStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::DATABASE_KW); + e.space(); + e.token(TokenKind::IDENT(self.dbname.clone())); + + if !self.options.is_empty() { + todo!(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DropdbStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DropdbStmt); + + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::DATABASE_KW); + e.space(); + + if self.missing_ok { + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + e.space(); + } + + e.token(TokenKind::IDENT(self.dbname.clone())); + + if !self.options.is_empty() { + todo!(); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ClusterStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ClusterStmt); + + e.token(TokenKind::CLUSTER_KW); + + if !self.params.is_empty() { + todo!(); + } + + if let Some(ref relation) = self.relation { + e.space(); + relation.to_tokens(e); + } + + if !self.indexname.is_empty() { + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::IDENT(self.indexname.clone())); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::VacuumStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::VacuumStmt); + + if self.is_vacuumcmd { + e.token(TokenKind::VACUUM_KW); + } else { + e.token(TokenKind::ANALYZE_KW); + } + + if !self.options.is_empty() { + todo!(); + } + + if !self.rels.is_empty() { + e.space(); + let mut first = true; + for rel in &self.rels { + if !first { + e.token(TokenKind::COMMA); + e.space(); + } + first = false; + rel.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::VacuumRelation { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if !self.va_cols.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + let mut first = true; + for col in &self.va_cols { + if !first { + e.token(TokenKind::COMMA); + e.space(); + } + first = false; + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } +} + +impl ToTokens for pgt_query::protobuf::ExplainStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ExplainStmt); + + e.token(TokenKind::EXPLAIN_KW); + + if !self.options.is_empty() { + todo!(); + } + + if let Some(ref query) = self.query { + e.space(); + query.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterDatabaseSetStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterDatabaseSetStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::DATABASE_KW); + e.space(); + e.token(TokenKind::IDENT(self.dbname.clone())); + e.space(); + + if let Some(ref setstmt) = self.setstmt { + setstmt.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterDatabaseRefreshCollStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterDatabaseRefreshCollStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::DATABASE_KW); + e.space(); + e.token(TokenKind::IDENT(self.dbname.clone())); + e.space(); + e.token(TokenKind::REFRESH_KW); + e.space(); + e.token(TokenKind::COLLATION_KW); + e.space(); + e.token(TokenKind::VERSION_KW); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CheckPointStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CheckPointStmt); + + e.token(TokenKind::CHECKPOINT_KW); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DiscardStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::DiscardMode; + + e.group_start(GroupKind::DiscardStmt); + + e.token(TokenKind::DISCARD_KW); + e.space(); + + match self.target() { + DiscardMode::DiscardAll => e.token(TokenKind::ALL_KW), + DiscardMode::DiscardPlans => e.token(TokenKind::PLANS_KW), + DiscardMode::DiscardSequences => e.token(TokenKind::SEQUENCES_KW), + DiscardMode::DiscardTemp => e.token(TokenKind::TEMP_KW), + _ => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ConstraintsSetStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ConstraintsSetStmt); + + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::CONSTRAINTS_KW); + e.space(); + + if self.constraints.is_empty() { + e.token(TokenKind::ALL_KW); + } else { + let mut first = true; + for constraint in &self.constraints { + if !first { + e.token(TokenKind::COMMA); + e.space(); + } + first = false; + constraint.to_tokens(e); + } + } + + e.space(); + if self.deferred { + e.token(TokenKind::DEFERRED_KW); + } else { + e.token(TokenKind::IMMEDIATE_KW); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ReindexStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::ReindexObjectType; + + e.group_start(GroupKind::ReindexStmt); + + e.token(TokenKind::REINDEX_KW); + + if !self.params.is_empty() { + todo!(); + } + + e.space(); + match self.kind() { + ReindexObjectType::ReindexObjectIndex => e.token(TokenKind::INDEX_KW), + ReindexObjectType::ReindexObjectTable => e.token(TokenKind::TABLE_KW), + ReindexObjectType::ReindexObjectSchema => e.token(TokenKind::SCHEMA_KW), + ReindexObjectType::ReindexObjectSystem => e.token(TokenKind::SYSTEM_KW), + ReindexObjectType::ReindexObjectDatabase => e.token(TokenKind::DATABASE_KW), + _ => {} + } + + e.space(); + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } else if !self.name.is_empty() { + e.token(TokenKind::IDENT(self.name.clone())); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterDatabaseStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterDatabaseStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::DATABASE_KW); + e.space(); + e.token(TokenKind::IDENT(self.dbname.clone())); + + if !self.options.is_empty() { + e.space(); + let mut first = true; + for option in &self.options { + if !first { + e.space(); + } + first = false; + option.to_tokens(e); + } + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterSystemStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterSystemStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::SYSTEM_KW); + e.space(); + + if let Some(ref setstmt) = self.setstmt { + setstmt.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::BitString { + fn to_tokens(&self, e: &mut EventEmitter) { + // The bsval contains the bit string value including any prefix + // For binary strings: "b..." or "B..." + // For hex strings: "x..." or "X..." + if self.bsval.starts_with("b'") || self.bsval.starts_with("B'") { + e.token(TokenKind::STRING(self.bsval.to_uppercase())); + } else if self.bsval.starts_with("x'") || self.bsval.starts_with("X'") { + e.token(TokenKind::STRING(self.bsval.to_uppercase())); + } else if self.bsval.starts_with('b') || self.bsval.starts_with('B') { + // Handle binary without quotes + let digits = &self.bsval[1..]; + e.token(TokenKind::STRING(format!("B'{}'", digits))); + } else if self.bsval.starts_with('x') || self.bsval.starts_with('X') { + // Handle hex without quotes + let digits = &self.bsval[1..]; + e.token(TokenKind::STRING(format!("X'{}'", digits))); + } else { + // Default to binary if no prefix + e.token(TokenKind::STRING(format!("B'{}'", self.bsval))); + } + } +} + +impl ToTokens for pgt_query::protobuf::TypeCast { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::TypeCast); + + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + + e.token(TokenKind::DOUBLE_COLON); + + if let Some(ref type_name) = self.type_name { + type_name.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::Param { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::DOLLAR); + e.token(TokenKind::IDENT(self.paramid.to_string())); + } +} + +impl ToTokens for pgt_query::protobuf::OpExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + // OpExpr is handled by delegating to its arguments + // The operator information is stored in opno/opresulttype but we + // reconstruct from the AST context + if self.args.len() >= 2 { + // Binary operator + self.args[0].to_tokens(e); + e.space(); + e.token(TokenKind::IDENT("+".to_string())); // Default to +, actual op would need lookup + e.space(); + self.args[1].to_tokens(e); + } else if self.args.len() == 1 { + // Unary operator + e.token(TokenKind::IDENT("-".to_string())); // Default to -, actual op would need lookup + self.args[0].to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::ScalarArrayOpExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ScalarArrayOpExpr); + + if self.args.len() >= 2 { + self.args[0].to_tokens(e); + e.space(); + e.token(TokenKind::IDENT("=".to_string())); + e.space(); + if self.use_or { + e.token(TokenKind::ANY_KW); + } else { + e.token(TokenKind::ALL_KW); + } + e.token(TokenKind::L_PAREN); + self.args[1].to_tokens(e); + e.token(TokenKind::R_PAREN); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::BoolExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::BoolExprType; + + match self.boolop() { + BoolExprType::AndExpr => { + // Add indentation for multi-line AND expressions in JOIN ON clauses + let needs_indent = e.is_within_group(GroupKind::JoinExpr); + if needs_indent && self.args.len() > 1 { + e.indent_start(); + } + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::AND_KW); + e.space(); + arg.to_tokens(e); + e.indent_end(); + } else { + arg.to_tokens(e); + } + } + + if needs_indent && self.args.len() > 1 { + e.indent_end(); + } + } + BoolExprType::OrExpr => { + // Add indentation for multi-line OR expressions in JOIN ON clauses + let needs_indent = e.is_within_group(GroupKind::JoinExpr); + if needs_indent && self.args.len() > 1 { + e.indent_start(); + } + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::OR_KW); + e.space(); + arg.to_tokens(e); + e.indent_end(); + } else { + arg.to_tokens(e); + } + } + + if needs_indent && self.args.len() > 1 { + e.indent_end(); + } + } + BoolExprType::NotExpr => { + e.token(TokenKind::NOT_KW); + e.space(); + if let Some(arg) = self.args.first() { + arg.to_tokens(e); + } + } + BoolExprType::Undefined => {} + } + } +} + +impl ToTokens for pgt_query::protobuf::CaseExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::CASE_KW); + + // arg is the test expression in CASE expr WHEN ... + if let Some(ref arg) = self.arg { + e.space(); + arg.to_tokens(e); + } + + // args contains CaseWhen nodes + for when_clause in &self.args { + e.space(); + when_clause.to_tokens(e); + } + + // defresult is the ELSE clause + if let Some(ref defresult) = self.defresult { + e.space(); + e.token(TokenKind::ELSE_KW); + e.space(); + defresult.to_tokens(e); + } + + e.space(); + e.token(TokenKind::END_KW); + } +} + +impl ToTokens for pgt_query::protobuf::CaseWhen { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::WHEN_KW); + e.space(); + + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + + e.space(); + e.token(TokenKind::THEN_KW); + e.space(); + + if let Some(ref result) = self.result { + result.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::ArrayExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ArrayExpr); + + e.token(TokenKind::ARRAY_KW); + e.token(TokenKind::L_BRACK); + + if !self.elements.is_empty() { + e.indent_start(); + for (i, element) in self.elements.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + element.to_tokens(e); + } + e.indent_end(); + } + + e.token(TokenKind::R_BRACK); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AArrayExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AArrayExpr); + + e.token(TokenKind::ARRAY_KW); + e.token(TokenKind::L_BRACK); + + if !self.elements.is_empty() { + e.indent_start(); + for (i, element) in self.elements.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + element.to_tokens(e); + } + e.indent_end(); + } + + e.token(TokenKind::R_BRACK); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::RowExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RowExpr); + + e.token(TokenKind::ROW_KW); + e.token(TokenKind::L_PAREN); + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::SubLink { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::SubLinkType; + + match self.sub_link_type() { + SubLinkType::ExistsSublink => { + e.token(TokenKind::EXISTS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + if let Some(ref subselect) = self.subselect { + subselect.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + SubLinkType::ArraySublink => { + e.token(TokenKind::ARRAY_KW); + e.token(TokenKind::L_PAREN); + if let Some(ref subselect) = self.subselect { + subselect.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + SubLinkType::AnySublink => { + if let Some(ref testexpr) = self.testexpr { + testexpr.to_tokens(e); + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + } + e.token(TokenKind::L_PAREN); + if let Some(ref subselect) = self.subselect { + subselect.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + SubLinkType::AllSublink => { + if let Some(ref testexpr) = self.testexpr { + testexpr.to_tokens(e); + e.space(); + if !self.oper_name.is_empty() { + for oper in &self.oper_name { + if let Some(pgt_query::protobuf::node::Node::String(s)) = &oper.node { + e.token(TokenKind::IDENT(s.sval.clone())); + e.space(); + } + } + } + e.token(TokenKind::ALL_KW); + e.space(); + } + e.token(TokenKind::L_PAREN); + if let Some(ref subselect) = self.subselect { + subselect.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + _ => { + e.token(TokenKind::L_PAREN); + if let Some(ref subselect) = self.subselect { + subselect.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + } + } +} + +impl ToTokens for pgt_query::protobuf::CoalesceExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::COALESCE_KW); + e.token(TokenKind::L_PAREN); + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::MinMaxExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::MinMaxOp; + + e.group_start(GroupKind::MinMaxExpr); + + match self.op() { + MinMaxOp::IsGreatest => e.token(TokenKind::GREATEST_KW), + MinMaxOp::IsLeast => e.token(TokenKind::LEAST_KW), + MinMaxOp::Undefined => todo!(), + } + + e.token(TokenKind::L_PAREN); + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::XmlExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::XmlExprOp; + + e.group_start(GroupKind::XmlExpr); + + match self.op() { + XmlExprOp::IsXmlelement => { + e.token(TokenKind::XMLELEMENT_KW); + e.token(TokenKind::L_PAREN); + + if !self.name.is_empty() { + e.token(TokenKind::NAME_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + + if !self.args.is_empty() { + e.token(TokenKind::COMMA); + e.space(); + } + } + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + XmlExprOp::IsXmlconcat => { + e.token(TokenKind::XMLCONCAT_KW); + e.token(TokenKind::L_PAREN); + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + XmlExprOp::IsXmlforest => { + e.token(TokenKind::XMLFOREST_KW); + e.token(TokenKind::L_PAREN); + + for (i, (arg, name)) in self.args.iter().zip(self.arg_names.iter()).enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + if let Some(pgt_query::protobuf::node::Node::String(s)) = &name.node { + if !s.sval.is_empty() { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::IDENT(s.sval.clone())); + } + } + } + + e.token(TokenKind::R_PAREN); + } + XmlExprOp::IsXmlparse => { + e.token(TokenKind::XMLPARSE_KW); + e.token(TokenKind::L_PAREN); + e.token(TokenKind::DOCUMENT_KW); + e.space(); + + if let Some(first_arg) = self.args.first() { + first_arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + XmlExprOp::IsXmlpi => { + e.token(TokenKind::XMLPI_KW); + e.token(TokenKind::L_PAREN); + e.token(TokenKind::NAME_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + + if let Some(first_arg) = self.args.first() { + e.token(TokenKind::COMMA); + e.space(); + first_arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + XmlExprOp::IsXmlroot => { + e.token(TokenKind::XMLROOT_KW); + e.token(TokenKind::L_PAREN); + + if let Some(xml_expr) = self.args.first() { + xml_expr.to_tokens(e); + } + + if self.args.len() > 1 { + e.token(TokenKind::COMMA); + e.space(); + e.token(TokenKind::VERSION_KW); + e.space(); + if let Some(version) = self.args.get(1) { + version.to_tokens(e); + } + } + + e.token(TokenKind::R_PAREN); + } + XmlExprOp::IsDocument => { + if let Some(arg) = self.args.first() { + arg.to_tokens(e); + } + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + e.token(TokenKind::DOCUMENT_KW); + } + _ => {} + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::NullTest { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::NullTestType; + + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + + match self.nulltesttype() { + NullTestType::IsNull => { + e.token(TokenKind::NULL_KW); + } + NullTestType::IsNotNull => { + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + NullTestType::Undefined => {} + } + } +} + +impl ToTokens for pgt_query::protobuf::BooleanTest { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::BoolTestType; + + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + + match self.booltesttype() { + BoolTestType::IsTrue => { + e.token(TokenKind::TRUE_KW); + } + BoolTestType::IsNotTrue => { + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::TRUE_KW); + } + BoolTestType::IsFalse => { + e.token(TokenKind::FALSE_KW); + } + BoolTestType::IsNotFalse => { + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::FALSE_KW); + } + BoolTestType::IsUnknown => { + e.token(TokenKind::UNKNOWN_KW); + } + BoolTestType::IsNotUnknown => { + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::UNKNOWN_KW); + } + BoolTestType::Undefined => {} + } + } +} + +impl ToTokens for pgt_query::protobuf::CreateConversionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateConversionStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if self.def { + e.token(TokenKind::DEFAULT_KW); + e.space(); + } + + e.token(TokenKind::CONVERSION_KW); + e.space(); + + for (i, name) in self.conversion_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.for_encoding_name))); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.to_encoding_name))); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::FROM_KW); + e.space(); + + for (i, func) in self.func_name.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + func.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateCastStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateCastStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::CAST_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + if let Some(ref sourcetype) = self.sourcetype { + sourcetype.to_tokens(e); + } + + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + + if let Some(ref targettype) = self.targettype { + targettype.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.line(LineType::SoftOrSpace); + + if self.inout { + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::INOUT_KW); + } else if let Some(ref func) = self.func { + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::FUNCTION_KW); + e.space(); + func.to_tokens(e); + } else { + e.token(TokenKind::WITHOUT_KW); + e.space(); + e.token(TokenKind::FUNCTION_KW); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateTransformStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateTransformStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + + if self.replace { + e.token(TokenKind::OR_KW); + e.space(); + e.token(TokenKind::REPLACE_KW); + e.space(); + } + + e.token(TokenKind::TRANSFORM_KW); + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + if let Some(ref type_name) = self.type_name { + type_name.to_tokens(e); + } + + e.space(); + e.token(TokenKind::LANGUAGE_KW); + e.space(); + e.token(TokenKind::IDENT(self.lang.clone())); + + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::L_PAREN); + + let mut needs_comma = false; + + if let Some(ref fromsql) = self.fromsql { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::FROM_KW); + e.space(); + e.token(TokenKind::SQL_KW); + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::FUNCTION_KW); + e.space(); + fromsql.to_tokens(e); + e.indent_end(); + needs_comma = true; + } + + if let Some(ref tosql) = self.tosql { + if needs_comma { + e.token(TokenKind::COMMA); + } + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::SQL_KW); + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::FUNCTION_KW); + e.space(); + tosql.to_tokens(e); + e.indent_end(); + } + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::R_PAREN); + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DropOwnedStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DropOwnedStmt); + + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::OWNED_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + + for (i, role) in self.roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + role.to_tokens(e); + } + + use pgt_query::protobuf::DropBehavior; + match self.behavior() { + DropBehavior::DropRestrict => { + e.space(); + e.token(TokenKind::RESTRICT_KW); + } + DropBehavior::DropCascade => { + e.space(); + e.token(TokenKind::CASCADE_KW); + } + _ => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::ReassignOwnedStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::ReassignOwnedStmt); + + e.token(TokenKind::REASSIGN_KW); + e.space(); + e.token(TokenKind::OWNED_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + + for (i, role) in self.roles.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + role.to_tokens(e); + } + + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + + if let Some(ref newrole) = self.newrole { + newrole.to_tokens(e); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterTsDictionaryStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterTsdictionaryStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::DICTIONARY_KW); + e.space(); + + for (i, name) in self.dictname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + e.indent_end(); + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterTsConfigurationStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterTsconfigurationStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::TEXT_KW); + e.space(); + e.token(TokenKind::SEARCH_KW); + e.space(); + e.token(TokenKind::CONFIGURATION_KW); + e.space(); + + for (i, name) in self.cfgname.iter().enumerate() { + if i > 0 { + e.token(TokenKind::DOT); + } + name.to_tokens(e); + } + + e.space(); + + use pgt_query::protobuf::AlterTsConfigType; + match self.kind() { + AlterTsConfigType::AlterTsconfigAddMapping => { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::ADD_KW); + e.space(); + e.token(TokenKind::MAPPING_KW); + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + for (i, token) in self.tokentype.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + token.to_tokens(e); + } + + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + + for (i, dict) in self.dicts.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + dict.to_tokens(e); + } + e.indent_end(); + } + AlterTsConfigType::AlterTsconfigAlterMappingForToken => { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::MAPPING_KW); + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + for (i, token) in self.tokentype.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + token.to_tokens(e); + } + + if self.replace { + e.space(); + e.token(TokenKind::REPLACE_KW); + e.space(); + } + + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + + for (i, dict) in self.dicts.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + dict.to_tokens(e); + } + e.indent_end(); + } + AlterTsConfigType::AlterTsconfigDropMapping => { + e.indent_start(); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::MAPPING_KW); + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + for (i, token) in self.tokentype.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + token.to_tokens(e); + } + e.indent_end(); + } + _ => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreatePublicationStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreatePublicationStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::PUBLICATION_KW); + e.space(); + e.token(TokenKind::IDENT(self.pubname.clone())); + + if self.for_all_tables { + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::ALL_KW); + e.space(); + e.token(TokenKind::TABLES_KW); + } else if !self.pubobjects.is_empty() { + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + + todo!() + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterPublicationStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlterPublicationStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::PUBLICATION_KW); + e.space(); + e.token(TokenKind::IDENT(self.pubname.clone())); + e.space(); + + use pgt_query::protobuf::AlterPublicationAction; + match self.action() { + AlterPublicationAction::ApAddObjects => { + e.token(TokenKind::ADD_KW); + e.space(); + + if self.for_all_tables { + e.token(TokenKind::ALL_KW); + e.space(); + e.token(TokenKind::TABLES_KW); + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::SCHEMA_KW); + } else { + todo!() + } + } + AlterPublicationAction::ApDropObjects => { + e.token(TokenKind::DROP_KW); + e.space(); + + if self.for_all_tables { + e.token(TokenKind::ALL_KW); + e.space(); + e.token(TokenKind::TABLES_KW); + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::SCHEMA_KW); + } else { + todo!() + } + } + AlterPublicationAction::ApSetObjects => { + e.token(TokenKind::SET_KW); + e.space(); + + if self.for_all_tables { + e.token(TokenKind::ALL_KW); + e.space(); + e.token(TokenKind::TABLES_KW); + e.space(); + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::SCHEMA_KW); + } else { + e.token(TokenKind::TABLE_KW); + e.space(); + + for (i, obj) in self.pubobjects.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + obj.to_tokens(e); + } + } + } + _ => {} + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::PublicationObjSpec { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::PublicationObjSpec); + + use pgt_query::protobuf::PublicationObjSpecType; + match self.pubobjtype() { + PublicationObjSpecType::PublicationobjTable => { + if let Some(ref pubtable) = self.pubtable { + if let Some(ref relation) = pubtable.relation { + relation.to_tokens(e); + } + } + } + _ => {} + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CreateSubscriptionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CreateSubscriptionStmt); + + e.token(TokenKind::CREATE_KW); + e.space(); + e.token(TokenKind::SUBSCRIPTION_KW); + e.space(); + e.token(TokenKind::IDENT(self.subname.clone())); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::CONNECTION_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.conninfo))); + e.line(LineType::SoftOrSpace); + e.token(TokenKind::PUBLICATION_KW); + e.space(); + + for (i, pub_name) in self.publication.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + pub_name.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AlterSubscriptionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::AlterSubscriptionType; + + e.group_start(GroupKind::AlterSubscriptionStmt); + + e.token(TokenKind::ALTER_KW); + e.space(); + e.token(TokenKind::SUBSCRIPTION_KW); + e.space(); + e.token(TokenKind::IDENT(self.subname.clone())); + e.space(); + + match self.kind { + x if x == AlterSubscriptionType::AlterSubscriptionOptions as i32 => { + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + x if x == AlterSubscriptionType::AlterSubscriptionConnection as i32 => { + e.token(TokenKind::CONNECTION_KW); + e.space(); + e.token(TokenKind::STRING(format!("'{}'", self.conninfo))); + } + x if x == AlterSubscriptionType::AlterSubscriptionSetPublication as i32 => { + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::PUBLICATION_KW); + e.space(); + + for (i, pub_name) in self.publication.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + pub_name.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + } + x if x == AlterSubscriptionType::AlterSubscriptionAddPublication as i32 => { + e.token(TokenKind::ADD_KW); + e.space(); + e.token(TokenKind::PUBLICATION_KW); + e.space(); + + for (i, pub_name) in self.publication.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + pub_name.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + } + x if x == AlterSubscriptionType::AlterSubscriptionDropPublication as i32 => { + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::PUBLICATION_KW); + e.space(); + + for (i, pub_name) in self.publication.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + pub_name.to_tokens(e); + } + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + } + x if x == AlterSubscriptionType::AlterSubscriptionRefresh as i32 => { + e.token(TokenKind::REFRESH_KW); + e.space(); + e.token(TokenKind::PUBLICATION_KW); + + if !self.options.is_empty() { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + } + x if x == AlterSubscriptionType::AlterSubscriptionEnabled as i32 => { + match self.options.first() { + Some(option) => { + option.to_tokens(e); + } + None => {} + } + } + x if x == AlterSubscriptionType::AlterSubscriptionSkip as i32 => { + e.token(TokenKind::SKIP_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, option) in self.options.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + option.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } + _ => {} + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::NamedArgExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::NamedArgExpr); + + e.token(TokenKind::IDENT(self.name.clone())); + e.space(); + e.token(TokenKind::IDENT("=>".to_string())); + e.space(); + + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::DropSubscriptionStmt { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DropSubscriptionStmt); + + e.token(TokenKind::DROP_KW); + e.space(); + e.token(TokenKind::SUBSCRIPTION_KW); + + if self.missing_ok { + e.space(); + e.token(TokenKind::IF_KW); + e.space(); + e.token(TokenKind::EXISTS_KW); + } + + e.space(); + e.token(TokenKind::IDENT(self.subname.clone())); + + if self.behavior == pgt_query::protobuf::DropBehavior::DropCascade as i32 { + e.space(); + e.token(TokenKind::CASCADE_KW); + } + + if e.is_top_level() { + e.token(TokenKind::SEMICOLON); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::WithClause { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::WithClause); + + e.token(TokenKind::WITH_KW); + if self.recursive { + e.space(); + e.token(TokenKind::RECURSIVE_KW); + } + e.space(); + + for (i, cte) in self.ctes.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + cte.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CommonTableExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::CommonTableExpr); + + e.token(TokenKind::IDENT(self.ctename.clone())); + + if !self.aliascolnames.is_empty() { + e.token(TokenKind::L_PAREN); + // Allow breaking between columns if the list is long + for (i, col) in self.aliascolnames.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + if let Some(ref query) = self.ctequery { + query.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::GroupingSet { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::GroupingSetKind; + + e.group_start(GroupKind::GroupingSet); + + match self.kind() { + GroupingSetKind::GroupingSetEmpty => { + e.token(TokenKind::L_PAREN); + e.token(TokenKind::R_PAREN); + } + GroupingSetKind::GroupingSetSimple => { + for (i, item) in self.content.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + } + GroupingSetKind::GroupingSetSets => { + e.token(TokenKind::GROUPING_KW); + e.space(); + e.token(TokenKind::SETS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, item) in self.content.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + if let Some(pgt_query::protobuf::node::Node::GroupingSet(inner)) = &item.node { + if matches!(inner.kind(), GroupingSetKind::GroupingSetEmpty) { + e.token(TokenKind::L_PAREN); + e.token(TokenKind::R_PAREN); + } else { + item.to_tokens(e); + } + } else { + e.token(TokenKind::L_PAREN); + item.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + } + e.token(TokenKind::R_PAREN); + } + GroupingSetKind::GroupingSetRollup => { + e.token(TokenKind::ROLLUP_KW); + e.token(TokenKind::L_PAREN); + for (i, item) in self.content.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + GroupingSetKind::GroupingSetCube => { + e.token(TokenKind::CUBE_KW); + e.token(TokenKind::L_PAREN); + for (i, item) in self.content.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + GroupingSetKind::Undefined => { + for (i, item) in self.content.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + item.to_tokens(e); + } + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AIndirection { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AIndirection); + + if let Some(ref arg) = self.arg { + // Check if we need parentheses around the arg + let needs_parens = + matches!(&arg.node, Some(pgt_query::protobuf::node::Node::RowExpr(_))); + + if needs_parens { + e.token(TokenKind::L_PAREN); + } + arg.to_tokens(e); + if needs_parens { + e.token(TokenKind::R_PAREN); + } + } + + for ind in &self.indirection { + match &ind.node { + Some(pgt_query::protobuf::node::Node::String(s)) => { + e.token(TokenKind::DOT); + e.token(TokenKind::IDENT(s.sval.clone())); + } + Some(pgt_query::protobuf::node::Node::AIndices(indices)) => { + e.token(TokenKind::L_BRACK); + if let Some(ref lidx) = indices.lidx { + lidx.to_tokens(e); + } + if indices.is_slice { + e.token(TokenKind::IDENT(":".to_string())); + if let Some(ref uidx) = indices.uidx { + uidx.to_tokens(e); + } + } + e.token(TokenKind::R_BRACK); + } + Some(pgt_query::protobuf::node::Node::AStar(_)) => { + e.token(TokenKind::DOT); + e.token(TokenKind::IDENT("*".to_string())); + } + _ => ind.to_tokens(e), + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::AIndices { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::L_BRACK); + + if self.is_slice { + if let Some(ref lidx) = self.lidx { + lidx.to_tokens(e); + } + e.token(TokenKind::IDENT(":".to_string())); + if let Some(ref uidx) = self.uidx { + uidx.to_tokens(e); + } + } else if let Some(ref uidx) = self.uidx { + uidx.to_tokens(e); + } else if let Some(ref lidx) = self.lidx { + lidx.to_tokens(e); + } + + e.token(TokenKind::R_BRACK); + } +} + +impl ToTokens for pgt_query::protobuf::LockingClause { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::{LockClauseStrength, LockWaitPolicy}; + + e.group_start(GroupKind::LockingClause); + + e.token(TokenKind::FOR_KW); + e.space(); + + match self.strength() { + LockClauseStrength::LcsNone | LockClauseStrength::Undefined => {} + LockClauseStrength::LcsForupdate => e.token(TokenKind::UPDATE_KW), + LockClauseStrength::LcsFornokeyupdate => { + e.token(TokenKind::NO_KW); + e.space(); + e.token(TokenKind::KEY_KW); + e.space(); + e.token(TokenKind::UPDATE_KW); + } + LockClauseStrength::LcsForshare => e.token(TokenKind::SHARE_KW), + LockClauseStrength::LcsForkeyshare => { + e.token(TokenKind::KEY_KW); + e.space(); + e.token(TokenKind::SHARE_KW); + } + } + + if !self.locked_rels.is_empty() { + e.space(); + e.token(TokenKind::OF_KW); + e.space(); + for (i, rel) in self.locked_rels.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + rel.to_tokens(e); + } + } + + match self.wait_policy() { + LockWaitPolicy::LockWaitBlock | LockWaitPolicy::Undefined => {} + LockWaitPolicy::LockWaitSkip => { + e.space(); + e.token(TokenKind::SKIP_KW); + e.space(); + e.token(TokenKind::LOCKED_KW); + } + LockWaitPolicy::LockWaitError => { + e.space(); + e.token(TokenKind::NOWAIT_KW); + } + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::TableFunc { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::TableFunc); + + match self.functype() { + pgt_query::protobuf::TableFuncType::TftJsonTable => { + e.token(TokenKind::IDENT("JSON_TABLE".to_string())); + } + pgt_query::protobuf::TableFuncType::TftXmltable => { + e.token(TokenKind::IDENT("XMLTABLE".to_string())); + } + _ => todo!("Unknown table function type"), + } + + e.token(TokenKind::L_PAREN); + + if let Some(ref docexpr) = self.docexpr { + docexpr.to_tokens(e); + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + + if let Some(ref rowexpr) = self.rowexpr { + rowexpr.to_tokens(e); + e.line(LineType::SoftOrSpace); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonTable { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonTable); + + e.token(TokenKind::IDENT("JSON_TABLE".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref context_item) = self.context_item { + // Add a hard break after JSON_TABLE( if we have a long JSON string + e.line(LineType::Hard); + e.indent_start(); + context_item.to_tokens(e); + e.token(TokenKind::COMMA); + e.line(LineType::Hard); + e.indent_end(); + } + + if let Some(ref pathspec) = self.pathspec { + e.indent_start(); + pathspec.to_tokens(e); + e.indent_end(); + } + + if !self.columns.is_empty() { + e.line(LineType::Hard); + e.indent_start(); + e.token(TokenKind::COLUMNS_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.line(LineType::Hard); + e.indent_start(); + + for (i, col) in self.columns.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::Hard); + } + col.to_tokens(e); + } + + e.indent_end(); + e.line(LineType::Hard); + e.token(TokenKind::R_PAREN); + e.indent_end(); + } + + e.token(TokenKind::R_PAREN); + + if let Some(ref alias) = self.alias { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + alias.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonValueExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref raw_expr) = self.raw_expr { + raw_expr.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonTablePathSpec { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref string) = self.string { + string.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonTableColumn { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.name.clone())); + e.space(); + + if let Some(ref type_name) = self.type_name { + type_name.to_tokens(e); + } + + if let Some(ref pathspec) = self.pathspec { + e.space(); + e.token(TokenKind::PATH_KW); + e.space(); + pathspec.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::DistinctExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::DistinctExpr); + + if !self.args.is_empty() && self.args.len() >= 2 { + self.args[0].to_tokens(e); + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + e.token(TokenKind::DISTINCT_KW); + e.space(); + e.token(TokenKind::FROM_KW); + e.space(); + self.args[1].to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::NullIfExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::NullIfExpr); + + e.token(TokenKind::NULLIF_KW); + e.token(TokenKind::L_PAREN); + + if self.args.len() >= 2 { + self.args[0].to_tokens(e); + e.token(TokenKind::COMMA); + e.space(); + self.args[1].to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::SqlValueFunction { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::SqlValueFunctionOp; + + match self.op() { + SqlValueFunctionOp::SvfopCurrentDate => e.token(TokenKind::CURRENT_DATE_KW), + SqlValueFunctionOp::SvfopCurrentTime => e.token(TokenKind::CURRENT_TIME_KW), + SqlValueFunctionOp::SvfopCurrentTimeN => e.token(TokenKind::CURRENT_TIME_KW), + SqlValueFunctionOp::SvfopCurrentTimestamp => e.token(TokenKind::CURRENT_TIMESTAMP_KW), + SqlValueFunctionOp::SvfopCurrentTimestampN => e.token(TokenKind::CURRENT_TIMESTAMP_KW), + SqlValueFunctionOp::SvfopLocaltime => e.token(TokenKind::LOCALTIME_KW), + SqlValueFunctionOp::SvfopLocaltimeN => e.token(TokenKind::LOCALTIME_KW), + SqlValueFunctionOp::SvfopLocaltimestamp => e.token(TokenKind::LOCALTIMESTAMP_KW), + SqlValueFunctionOp::SvfopLocaltimestampN => e.token(TokenKind::LOCALTIMESTAMP_KW), + SqlValueFunctionOp::SvfopCurrentRole => e.token(TokenKind::CURRENT_ROLE_KW), + SqlValueFunctionOp::SvfopCurrentUser => e.token(TokenKind::CURRENT_USER_KW), + SqlValueFunctionOp::SvfopUser => e.token(TokenKind::USER_KW), + SqlValueFunctionOp::SvfopSessionUser => e.token(TokenKind::SESSION_USER_KW), + SqlValueFunctionOp::SvfopCurrentCatalog => e.token(TokenKind::CURRENT_CATALOG_KW), + SqlValueFunctionOp::SvfopCurrentSchema => e.token(TokenKind::CURRENT_SCHEMA_KW), + SqlValueFunctionOp::SqlvalueFunctionOpUndefined => todo!(), + } + } +} + +impl ToTokens for pgt_query::protobuf::CollateExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + e.space(); + e.token(TokenKind::COLLATE_KW); + e.space(); + e.token(TokenKind::STRING("en_US".to_string())); + } +} + +impl ToTokens for pgt_query::protobuf::IntoClause { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::IntoClause); + + e.space(); + e.token(TokenKind::INTO_KW); + e.space(); + + if let Some(ref rel) = self.rel { + rel.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::PartitionElem { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::PartitionElem); + + if !self.name.is_empty() { + e.token(TokenKind::IDENT(self.name.clone())); + } else if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::PartitionSpec { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::PartitionSpec); + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::PARTITION_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + + use pgt_query::protobuf::PartitionStrategy; + match self.strategy() { + PartitionStrategy::List => e.token(TokenKind::IDENT("LIST".to_string())), + PartitionStrategy::Range => e.token(TokenKind::RANGE_KW), + PartitionStrategy::Hash => e.token(TokenKind::IDENT("HASH".to_string())), + _ => {} + } + + e.space(); + e.token(TokenKind::L_PAREN); + + for (i, param) in self.part_params.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + param.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::PartitionBoundSpec { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::PartitionBoundSpec); + + e.line(LineType::SoftOrSpace); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::VALUES_KW); + e.space(); + + if self.is_default { + e.token(TokenKind::DEFAULT_KW); + } else if !self.listdatums.is_empty() { + e.token(TokenKind::IN_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, datum) in self.listdatums.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + datum.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } else if !self.lowerdatums.is_empty() && !self.upperdatums.is_empty() { + e.token(TokenKind::FROM_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, datum) in self.lowerdatums.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + datum.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, datum) in self.upperdatums.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + datum.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } else if self.modulus > 0 { + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.token(TokenKind::IDENT("MODULUS".to_string())); + e.space(); + e.token(TokenKind::IDENT(self.modulus.to_string())); + e.token(TokenKind::COMMA); + e.space(); + e.token(TokenKind::IDENT("REMAINDER".to_string())); + e.space(); + e.token(TokenKind::IDENT(self.remainder.to_string())); + e.token(TokenKind::R_PAREN); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::SetToDefault { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::DEFAULT_KW); + } +} + +impl ToTokens for pgt_query::protobuf::TableLikeClause { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::LIKE_KW); + e.space(); + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + let options = self.options; + if options == 2147483647 { + e.space(); + e.token(TokenKind::INCLUDING_KW); + e.space(); + e.token(TokenKind::ALL_KW); + } else { + if options & 1 != 0 { + e.space(); + e.token(TokenKind::INCLUDING_KW); + e.space(); + e.token(TokenKind::IDENT("DEFAULTS".to_string())); + } + if options & 2 != 0 { + e.space(); + e.token(TokenKind::INCLUDING_KW); + e.space(); + e.token(TokenKind::IDENT("IDENTITY".to_string())); + } + if options & 4 != 0 { + e.space(); + e.token(TokenKind::INCLUDING_KW); + e.space(); + e.token(TokenKind::IDENT("INDEXES".to_string())); + } + if options & 8 != 0 { + e.space(); + e.token(TokenKind::INCLUDING_KW); + e.space(); + e.token(TokenKind::IDENT("STORAGE".to_string())); + } + if options & 16 != 0 { + e.space(); + e.token(TokenKind::INCLUDING_KW); + e.space(); + e.token(TokenKind::IDENT("COMMENTS".to_string())); + } + if options & 32 != 0 { + e.space(); + e.token(TokenKind::INCLUDING_KW); + e.space(); + e.token(TokenKind::IDENT("STATISTICS".to_string())); + } + } + } +} + +impl ToTokens for pgt_query::protobuf::InferClause { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::InferClause); + + e.token(TokenKind::L_PAREN); + for (i, elem) in self.index_elems.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + elem.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + + if let Some(ref where_clause) = self.where_clause { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.as_ref().to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::OnConflictClause { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::OnConflictAction; + + e.group_start(GroupKind::OnConflictClause); + + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::CONFLICT_KW); + + if let Some(ref infer) = self.infer { + e.space(); + infer.to_tokens(e); + } + + e.space(); + + match self.action() { + OnConflictAction::OnconflictNothing => { + e.token(TokenKind::DO_KW); + e.space(); + e.token(TokenKind::NOTHING_KW); + } + OnConflictAction::OnconflictUpdate => { + e.token(TokenKind::DO_KW); + e.space(); + e.token(TokenKind::UPDATE_KW); + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + + for (i, target) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + target.to_tokens(e); + } + + if let Some(ref where_clause) = self.where_clause { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.as_ref().to_tokens(e); + } + } + _ => {} + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::Var { + fn to_tokens(&self, _e: &mut EventEmitter) { + todo!() + } +} + +impl ToTokens for pgt_query::protobuf::NextValueExpr { + fn to_tokens(&self, _e: &mut EventEmitter) { + todo!() + } +} + +impl ToTokens for pgt_query::protobuf::InferenceElem { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::FromExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + for (i, from_item) in self.fromlist.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + from_item.to_tokens(e); + } + + if let Some(ref quals) = self.quals { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + quals.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::RangeTblRef { + fn to_tokens(&self, _e: &mut EventEmitter) { + todo!() + } +} + +impl ToTokens for pgt_query::protobuf::TargetEntry { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + + if !self.resname.is_empty() { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::IDENT(self.resname.clone())); + } + } +} + +impl ToTokens for pgt_query::protobuf::Query { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::Query); + + use pgt_query::protobuf::CmdType; + + match self.command_type() { + CmdType::CmdSelect => { + if let Some(ref utility_stmt) = self.utility_stmt { + utility_stmt.to_tokens(e); + } else { + e.token(TokenKind::SELECT_KW); + e.space(); + + for (i, target) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + target.to_tokens(e); + } + } + } + CmdType::CmdInsert => { + if let Some(ref utility_stmt) = self.utility_stmt { + utility_stmt.to_tokens(e); + } + } + CmdType::CmdUpdate => { + if let Some(ref utility_stmt) = self.utility_stmt { + utility_stmt.to_tokens(e); + } + } + CmdType::CmdDelete => { + if let Some(ref utility_stmt) = self.utility_stmt { + utility_stmt.to_tokens(e); + } + } + CmdType::CmdMerge => { + if let Some(ref utility_stmt) = self.utility_stmt { + utility_stmt.to_tokens(e); + } + } + CmdType::CmdUtility => { + if let Some(ref utility_stmt) = self.utility_stmt { + utility_stmt.to_tokens(e); + } + } + _ => {} + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::OnConflictExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::OnConflictExpr); + + use pgt_query::protobuf::OnConflictAction; + + match self.action() { + OnConflictAction::OnconflictNothing => { + e.token(TokenKind::NOTHING_KW); + } + OnConflictAction::OnconflictUpdate => { + e.token(TokenKind::UPDATE_KW); + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + + for (i, set_item) in self.on_conflict_set.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + set_item.to_tokens(e); + } + + if let Some(ref where_clause) = self.on_conflict_where { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + } + _ => {} + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CurrentOfExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::CURRENT_KW); + e.space(); + e.token(TokenKind::OF_KW); + e.space(); + if !self.cursor_name.is_empty() { + e.token(TokenKind::IDENT(self.cursor_name.clone())); + } else if self.cursor_param != 0 { + e.token(TokenKind::IDENT(format!("${}", self.cursor_param))); + } + } +} + +impl ToTokens for pgt_query::protobuf::SubscriptingRef { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref expr) = self.refexpr { + expr.to_tokens(e); + } + + e.token(TokenKind::L_BRACK); + + if !self.refupperindexpr.is_empty() { + for (i, idx) in self.refupperindexpr.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + idx.to_tokens(e); + } + } + + if !self.reflowerindexpr.is_empty() { + e.token(TokenKind::IDENT(":".to_string())); + for (i, idx) in self.reflowerindexpr.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + idx.to_tokens(e); + } + } + + e.token(TokenKind::R_BRACK); + } +} + +impl ToTokens for pgt_query::protobuf::WindowFunc { + fn to_tokens(&self, e: &mut EventEmitter) { + if self.winfnoid == 0 { + return; + } + + e.token(TokenKind::IDENT("row_number".to_string())); + e.token(TokenKind::L_PAREN); + + if self.winstar { + e.token(TokenKind::IDENT("*".to_string())); + } else if !self.args.is_empty() { + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + } + + e.token(TokenKind::R_PAREN); + + e.space(); + e.token(TokenKind::OVER_KW); + e.space(); + e.token(TokenKind::L_PAREN); + + if self.winref > 0 { + e.token(TokenKind::ORDER_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + e.token(TokenKind::IDENT("id".to_string())); + } + + e.token(TokenKind::R_PAREN); + + if let Some(ref filter) = self.aggfilter { + e.space(); + e.token(TokenKind::FILTER_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.token(TokenKind::WHERE_KW); + e.space(); + filter.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + } +} + +impl ToTokens for pgt_query::protobuf::GroupingFunc { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT("grouping".to_string())); + e.token(TokenKind::L_PAREN); + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::Aggref { + fn to_tokens(&self, e: &mut EventEmitter) { + if self.aggfnoid == 0 { + return; + } + + e.token(TokenKind::IDENT("count".to_string())); + e.token(TokenKind::L_PAREN); + + if self.aggstar { + e.token(TokenKind::IDENT("*".to_string())); + } else if !self.args.is_empty() { + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + } + + e.token(TokenKind::R_PAREN); + + if let Some(ref filter) = self.aggfilter { + e.space(); + e.token(TokenKind::FILTER_KW); + e.space(); + e.token(TokenKind::L_PAREN); + e.token(TokenKind::WHERE_KW); + e.space(); + filter.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + } +} + +impl ToTokens for pgt_query::protobuf::FuncExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + // TODO: Implement proper function name resolution using funcid + // For now, just emit the arguments + if !self.args.is_empty() { + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonArrayConstructor { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT("JSON_ARRAY".to_string())); + e.token(TokenKind::L_PAREN); + + for (i, expr) in self.exprs.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + expr.to_tokens(e); + } + + if self.absent_on_null { + if !self.exprs.is_empty() { + e.space(); + } + e.token(TokenKind::IDENT("ABSENT".to_string())); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + + if let Some(ref output) = self.output { + e.space(); + output.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::JsonObjectConstructor { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT("JSON_OBJECT".to_string())); + e.token(TokenKind::L_PAREN); + + for (i, expr) in self.exprs.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + expr.to_tokens(e); + } + + if self.absent_on_null { + if !self.exprs.is_empty() { + e.space(); + } + e.token(TokenKind::IDENT("ABSENT".to_string())); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + + if self.unique { + if !self.exprs.is_empty() || self.absent_on_null { + e.space(); + } + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::UNIQUE_KW); + e.space(); + e.token(TokenKind::IDENT("KEYS".to_string())); + } + + if let Some(ref output) = self.output { + e.space(); + output.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::JsonKeyValue { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref key) = self.key { + key.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IDENT(":".to_string())); + e.space(); + + if let Some(ref value) = self.value { + value.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonOutput { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref returning) = self.returning { + returning.to_tokens(e); + } + + if let Some(ref type_name) = self.type_name { + e.space(); + type_name.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonFuncExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::JsonExprOp; + + match self.op() { + JsonExprOp::JsonExistsOp => { + e.token(TokenKind::IDENT("JSON_EXISTS".to_string())); + } + JsonExprOp::JsonQueryOp => { + e.token(TokenKind::IDENT("JSON_QUERY".to_string())); + } + JsonExprOp::JsonValueOp => { + e.token(TokenKind::IDENT("JSON_VALUE".to_string())); + } + _ => {} + } + + e.token(TokenKind::L_PAREN); + + if let Some(ref context_item) = self.context_item { + context_item.to_tokens(e); + } + + if let Some(ref pathspec) = self.pathspec { + e.token(TokenKind::COMMA); + e.space(); + pathspec.to_tokens(e); + } + + if !self.passing.is_empty() { + e.space(); + e.token(TokenKind::IDENT("PASSING".to_string())); + e.space(); + + for (i, pass) in self.passing.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + pass.to_tokens(e); + } + } + + if let Some(ref output) = self.output { + e.space(); + output.to_tokens(e); + } + + if let Some(ref on_empty) = self.on_empty { + e.space(); + on_empty.to_tokens(e); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::IDENT("EMPTY".to_string())); + } + + if let Some(ref on_error) = self.on_error { + e.space(); + on_error.to_tokens(e); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::ERROR_KW); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::JsonExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::JsonExprOp; + + match self.op() { + JsonExprOp::JsonExistsOp => { + e.token(TokenKind::IDENT("JSON_EXISTS".to_string())); + } + JsonExprOp::JsonQueryOp => { + e.token(TokenKind::IDENT("JSON_QUERY".to_string())); + } + JsonExprOp::JsonValueOp => { + e.token(TokenKind::IDENT("JSON_VALUE".to_string())); + } + _ => {} + } + + e.token(TokenKind::L_PAREN); + + if let Some(ref formatted_expr) = self.formatted_expr { + formatted_expr.to_tokens(e); + } + + if let Some(ref path_spec) = self.path_spec { + e.token(TokenKind::COMMA); + e.space(); + path_spec.to_tokens(e); + } + + if !self.passing_names.is_empty() && !self.passing_values.is_empty() { + e.space(); + e.token(TokenKind::IDENT("PASSING".to_string())); + e.space(); + + for (i, (name, value)) in self + .passing_names + .iter() + .zip(self.passing_values.iter()) + .enumerate() + { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + value.to_tokens(e); + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + name.to_tokens(e); + } + } + + if let Some(ref returning) = self.returning { + e.space(); + returning.to_tokens(e); + } + + if let Some(ref on_empty) = self.on_empty { + e.space(); + on_empty.to_tokens(e); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::IDENT("EMPTY".to_string())); + } + + if let Some(ref on_error) = self.on_error { + e.space(); + on_error.to_tokens(e); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::ERROR_KW); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::RangeTableFunc { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::RangeTableFunc); + + if self.lateral { + e.token(TokenKind::LATERAL_KW); + e.space(); + } + + e.token(TokenKind::IDENT("xmltable".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref rowexpr) = self.rowexpr { + rowexpr.to_tokens(e); + } + + if let Some(ref docexpr) = self.docexpr { + e.line(LineType::SoftOrSpace); + e.indent_start(); + e.token(TokenKind::IDENT("passing".to_string())); + e.space(); + docexpr.to_tokens(e); + e.indent_end(); + } + + if !self.columns.is_empty() { + e.line(LineType::SoftOrSpace); + e.indent_start(); + e.token(TokenKind::IDENT("columns".to_string())); + e.space(); + for (i, col) in self.columns.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.line(LineType::SoftOrSpace); + } + col.to_tokens(e); + } + e.indent_end(); + } + + e.token(TokenKind::R_PAREN); + + if let Some(ref alias) = self.alias { + e.space(); + alias.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonBehavior { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::JsonBehaviorType; + + match self.btype() { + JsonBehaviorType::JsonBehaviorNull => { + e.token(TokenKind::NULL_KW); + } + JsonBehaviorType::JsonBehaviorError => { + e.token(TokenKind::ERROR_KW); + } + JsonBehaviorType::JsonBehaviorEmpty => { + e.token(TokenKind::IDENT("EMPTY".to_string())); + } + JsonBehaviorType::JsonBehaviorEmptyArray => { + e.token(TokenKind::IDENT("EMPTY".to_string())); + e.space(); + e.token(TokenKind::ARRAY_KW); + } + JsonBehaviorType::JsonBehaviorEmptyObject => { + e.token(TokenKind::IDENT("EMPTY".to_string())); + e.space(); + e.token(TokenKind::IDENT("OBJECT".to_string())); + } + JsonBehaviorType::JsonBehaviorDefault => { + e.token(TokenKind::DEFAULT_KW); + if let Some(ref expr) = self.expr { + e.space(); + expr.to_tokens(e); + } + } + _ => {} + } + + if self.coerce { + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::IDENT("EMPTY".to_string())); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonReturning { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::RETURNING_KW); + e.space(); + + if let Some(ref format) = self.format { + format.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonIsPredicate { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IS_KW); + e.space(); + + use pgt_query::protobuf::JsonValueType; + match self.item_type() { + JsonValueType::JsTypeObject => { + e.token(TokenKind::JSON_KW); + e.space(); + e.token(TokenKind::IDENT("OBJECT".to_string())); + } + JsonValueType::JsTypeArray => { + e.token(TokenKind::JSON_KW); + e.space(); + e.token(TokenKind::ARRAY_KW); + } + JsonValueType::JsTypeScalar => { + e.token(TokenKind::JSON_KW); + e.space(); + e.token(TokenKind::IDENT("SCALAR".to_string())); + } + _ => { + e.token(TokenKind::JSON_KW); + } + } + + if self.unique_keys { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::UNIQUE_KW); + e.space(); + e.token(TokenKind::IDENT("KEYS".to_string())); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonFormat { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::{JsonEncoding, JsonFormatType}; + + e.token(TokenKind::FORMAT_KW); + e.space(); + + match self.format_type() { + JsonFormatType::JsFormatJson => { + e.token(TokenKind::JSON_KW); + } + JsonFormatType::JsFormatJsonb => { + e.token(TokenKind::IDENT("JSONB".to_string())); + } + _ => {} + } + + match self.encoding() { + JsonEncoding::JsEncUtf8 => { + e.space(); + e.token(TokenKind::IDENT("ENCODING".to_string())); + e.space(); + e.token(TokenKind::IDENT("UTF8".to_string())); + } + JsonEncoding::JsEncUtf16 => { + e.space(); + e.token(TokenKind::IDENT("ENCODING".to_string())); + e.space(); + e.token(TokenKind::IDENT("UTF16".to_string())); + } + JsonEncoding::JsEncUtf32 => { + e.space(); + e.token(TokenKind::IDENT("ENCODING".to_string())); + e.space(); + e.token(TokenKind::IDENT("UTF32".to_string())); + } + _ => {} + } + } +} + +impl ToTokens for pgt_query::protobuf::XmlSerialize { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT("XMLSERIALIZE".to_string())); + e.token(TokenKind::L_PAREN); + + use pgt_query::protobuf::XmlOptionType; + match self.xmloption() { + XmlOptionType::XmloptionDocument => { + e.token(TokenKind::IDENT("DOCUMENT".to_string())); + } + XmlOptionType::XmloptionContent => { + e.token(TokenKind::IDENT("CONTENT".to_string())); + } + _ => {} + } + + if let Some(ref expr) = self.expr { + e.space(); + expr.to_tokens(e); + } + + if let Some(ref type_name) = self.type_name { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + type_name.to_tokens(e); + } + + if self.indent { + e.space(); + e.token(TokenKind::IDENT("INDENT".to_string())); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::RangeTableFuncCol { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.colname.clone())); + + if let Some(ref type_name) = self.type_name { + e.space(); + type_name.to_tokens(e); + } + + if self.for_ordinality { + e.space(); + e.token(TokenKind::FOR_KW); + e.space(); + e.token(TokenKind::IDENT("ordinality".to_string())); + } + + if let Some(ref colexpr) = self.colexpr { + e.space(); + e.token(TokenKind::IDENT("path".to_string())); + e.space(); + colexpr.to_tokens(e); + } + + if let Some(ref coldefexpr) = self.coldefexpr { + e.space(); + e.token(TokenKind::DEFAULT_KW); + e.space(); + coldefexpr.to_tokens(e); + } + + if self.is_not_null { + e.space(); + e.token(TokenKind::NOT_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + } +} + +impl ToTokens for pgt_query::protobuf::RangeTableSample { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + e.space(); + e.token(TokenKind::IDENT("TABLESAMPLE".to_string())); + e.space(); + + for (i, method) in self.method.iter().enumerate() { + if i > 0 { + e.space(); + } + method.to_tokens(e); + } + + if !self.args.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if let Some(ref repeatable) = self.repeatable { + e.space(); + e.token(TokenKind::IDENT("REPEATABLE".to_string())); + e.space(); + e.token(TokenKind::L_PAREN); + repeatable.to_tokens(e); + e.token(TokenKind::R_PAREN); + } + } +} + +impl ToTokens for pgt_query::protobuf::RelabelType { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::CoerceToDomain { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::FieldSelect { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::PartitionRangeDatum { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::PartitionRangeDatumKind; + + match self.kind() { + PartitionRangeDatumKind::PartitionRangeDatumMinvalue => { + e.token(TokenKind::IDENT("MINVALUE".to_string())); + } + PartitionRangeDatumKind::PartitionRangeDatumMaxvalue => { + e.token(TokenKind::IDENT("MAXVALUE".to_string())); + } + PartitionRangeDatumKind::PartitionRangeDatumValue => { + if let Some(ref value) = self.value { + value.to_tokens(e); + } + } + _ => {} + } + } +} + +impl ToTokens for pgt_query::protobuf::CteSearchClause { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::SEARCH_KW); + e.space(); + + if self.search_breadth_first { + e.token(TokenKind::IDENT("BREADTH".to_string())); + } else { + e.token(TokenKind::IDENT("DEPTH".to_string())); + } + e.space(); + e.token(TokenKind::FIRST_KW); + e.space(); + e.token(TokenKind::BY_KW); + e.space(); + + for (i, col) in self.search_col_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::IDENT(self.search_seq_column.clone())); + } +} + +impl ToTokens for pgt_query::protobuf::CteCycleClause { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::CYCLE_KW); + e.space(); + + for (i, col) in self.cycle_col_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + e.token(TokenKind::IDENT(self.cycle_mark_column.clone())); + + if let Some(ref value) = self.cycle_mark_value { + e.space(); + e.token(TokenKind::TO_KW); + e.space(); + value.to_tokens(e); + } + + if let Some(ref default) = self.cycle_mark_default { + e.space(); + e.token(TokenKind::DEFAULT_KW); + e.space(); + default.to_tokens(e); + } + + e.space(); + e.token(TokenKind::USING_KW); + e.space(); + e.token(TokenKind::IDENT(self.cycle_path_column.clone())); + } +} + +impl ToTokens for pgt_query::protobuf::TriggerTransition { + fn to_tokens(&self, e: &mut EventEmitter) { + if self.is_new { + e.token(TokenKind::NEW_KW); + } else { + e.token(TokenKind::OLD_KW); + } + + if self.is_table { + e.space(); + e.token(TokenKind::TABLE_KW); + } + + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } +} + +impl ToTokens for pgt_query::protobuf::JsonArgument { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref val) = self.val { + val.to_tokens(e); + } + + if !self.name.is_empty() { + e.space(); + e.token(TokenKind::AS_KW); + e.space(); + e.token(TokenKind::IDENT(self.name.clone())); + } + } +} + +impl ToTokens for pgt_query::protobuf::PublicationTable { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref relation) = self.relation { + relation.to_tokens(e); + } + + if !self.columns.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, col) in self.columns.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + } + + if let Some(ref where_clause) = self.where_clause { + e.space(); + e.token(TokenKind::WHERE_KW); + e.space(); + where_clause.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::CoerceViaIo { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::FieldStore { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::ArrayCoerceExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::ConvertRowtypeExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + } +} + +impl ToTokens for pgt_query::protobuf::CaseTestExpr { + fn to_tokens(&self, _e: &mut EventEmitter) { + todo!() + } +} + +impl ToTokens for pgt_query::protobuf::CoerceToDomainValue { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::VALUE_KW); + } +} + +impl ToTokens for pgt_query::protobuf::MergeAction { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::CmdType; + + match self.command_type() { + CmdType::CmdInsert => { + e.token(TokenKind::INSERT_KW); + + if !self.target_list.is_empty() { + e.space(); + e.token(TokenKind::L_PAREN); + for (i, col) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + e.token(TokenKind::R_PAREN); + e.space(); + e.token(TokenKind::VALUES_KW); + e.space(); + e.token(TokenKind::L_PAREN); + for (i, _) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + e.token(TokenKind::DEFAULT_KW); + } + e.token(TokenKind::R_PAREN); + } else { + e.space(); + e.token(TokenKind::DEFAULT_KW); + e.space(); + e.token(TokenKind::VALUES_KW); + } + } + CmdType::CmdUpdate => { + e.token(TokenKind::UPDATE_KW); + e.space(); + e.token(TokenKind::SET_KW); + e.space(); + + for (i, col) in self.target_list.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + col.to_tokens(e); + } + } + CmdType::CmdDelete => { + e.token(TokenKind::DELETE_KW); + } + CmdType::CmdNothing => { + e.token(TokenKind::IDENT("DO".to_string())); + e.space(); + e.token(TokenKind::NOTHING_KW); + } + _ => {} + } + } +} + +impl ToTokens for pgt_query::protobuf::PartitionCmd { + fn to_tokens(&self, e: &mut EventEmitter) { + if let Some(ref name) = self.name { + name.to_tokens(e); + } + + if let Some(ref bound) = self.bound { + e.space(); + bound.to_tokens(e); + } + + if self.concurrent { + e.space(); + e.token(TokenKind::IDENT("CONCURRENTLY".to_string())); + } + } +} + +impl ToTokens for pgt_query::protobuf::JsonConstructorExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + use pgt_query::protobuf::JsonConstructorType; + + match self.r#type() { + JsonConstructorType::JsctorJsonObject => { + e.token(TokenKind::IDENT("JSON_OBJECT".to_string())); + } + JsonConstructorType::JsctorJsonArray => { + e.token(TokenKind::IDENT("JSON_ARRAY".to_string())); + } + _ => {} + } + + e.token(TokenKind::L_PAREN); + + for (i, arg) in self.args.iter().enumerate() { + if i > 0 { + e.token(TokenKind::COMMA); + e.space(); + } + arg.to_tokens(e); + } + + if self.absent_on_null { + if !self.args.is_empty() { + e.space(); + } + e.token(TokenKind::IDENT("ABSENT".to_string())); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + + if self.unique { + if !self.args.is_empty() || self.absent_on_null { + e.space(); + } + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::UNIQUE_KW); + e.space(); + e.token(TokenKind::IDENT("KEYS".to_string())); + } + + if let Some(ref returning) = self.returning { + e.space(); + e.token(TokenKind::IDENT("RETURNING".to_string())); + e.space(); + returning.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } +} + +impl ToTokens for pgt_query::protobuf::JsonParseExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT("JSON_PARSE".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + + if self.unique_keys { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::UNIQUE_KW); + e.space(); + e.token(TokenKind::IDENT("KEYS".to_string())); + } + + if let Some(ref output) = self.output { + e.space(); + e.token(TokenKind::IDENT("RETURNING".to_string())); + e.space(); + output.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + } +} + +#[cfg(test)] +mod test { + use crate::emitter::{EventEmitter, ToTokens}; + + use insta::assert_debug_snapshot; + + #[test] + fn simple_select() { + let input = "select public.t.a as y, b as z, c from t where id = @id;"; + + let parsed = pgt_query::parse(input).expect("Failed to parse SQL"); + + let ast = parsed.root().expect("No root node found"); + + let mut emitter = EventEmitter::new(); + ast.to_tokens(&mut emitter); + + assert_debug_snapshot!(emitter.events); + } +} + +impl ToTokens for pgt_query::protobuf::SinglePartitionSpec { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::AlternativeSubPlan { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::AlternativeSubPlan); + + if let Some(ref first_plan) = self.subplans.first() { + first_plan.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::CallContext { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::MergeSupportFunc { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::SubPlan { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::SubPlan); + + if let Some(ref _param_id) = self.param_ids.first() { + e.token(TokenKind::IDENT(format!("$SUBPLAN{}", self.plan_id))); + } else if !self.plan_name.is_empty() { + e.token(TokenKind::IDENT(self.plan_name.clone())); + } else { + e.token(TokenKind::IDENT(format!("SubPlan {}", self.plan_id))); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonTablePath { + fn to_tokens(&self, e: &mut EventEmitter) { + e.token(TokenKind::IDENT(self.name.clone())); + } +} + +impl ToTokens for pgt_query::protobuf::JsonTablePathScan { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonTablePathScan); + + if let Some(ref plan) = self.plan { + plan.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonTableSiblingJoin { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonTableSiblingJoin); + + if let Some(ref lplan) = self.lplan { + lplan.to_tokens(e); + } + + if let Some(ref rplan) = self.rplan { + e.space(); + e.token(TokenKind::COMMA); + e.space(); + rplan.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonScalarExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonScalarExpr); + + e.token(TokenKind::IDENT("JSON_SCALAR".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + + if let Some(ref output) = self.output { + e.space(); + output.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonSerializeExpr { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonSerializeExpr); + + e.token(TokenKind::IDENT("JSON_SERIALIZE".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref expr) = self.expr { + expr.to_tokens(e); + } + + if let Some(ref output) = self.output { + e.space(); + output.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonArrayQueryConstructor { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonArrayQueryConstructor); + + e.token(TokenKind::IDENT("JSON_ARRAY".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref query) = self.query { + query.to_tokens(e); + } + + if let Some(ref format) = self.format { + e.space(); + format.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonAggConstructor { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonAggConstructor); + + if let Some(ref output) = self.output { + output.to_tokens(e); + } + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonObjectAgg { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonObjectAgg); + + e.token(TokenKind::IDENT("JSON_OBJECTAGG".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + + if self.absent_on_null { + e.space(); + e.token(TokenKind::ABSENT_KW); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + + if self.unique { + e.space(); + e.token(TokenKind::WITH_KW); + e.space(); + e.token(TokenKind::UNIQUE_KW); + e.space(); + e.token(TokenKind::KEYS_KW); + } + + if let Some(ref constructor) = self.constructor { + e.space(); + constructor.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::JsonArrayAgg { + fn to_tokens(&self, e: &mut EventEmitter) { + e.group_start(GroupKind::JsonArrayAgg); + + e.token(TokenKind::IDENT("JSON_ARRAYAGG".to_string())); + e.token(TokenKind::L_PAREN); + + if let Some(ref arg) = self.arg { + arg.to_tokens(e); + } + + if self.absent_on_null { + e.space(); + e.token(TokenKind::ABSENT_KW); + e.space(); + e.token(TokenKind::ON_KW); + e.space(); + e.token(TokenKind::NULL_KW); + } + + if let Some(ref constructor) = self.constructor { + e.space(); + constructor.to_tokens(e); + } + + e.token(TokenKind::R_PAREN); + + e.group_end(); + } +} + +impl ToTokens for pgt_query::protobuf::WindowClause { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::WindowFuncRunCondition { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::SortGroupClause { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::RowMarkClause { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::WithCheckOption { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::TableSampleClause { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::RangeTblEntry { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::RtePermissionInfo { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} + +impl ToTokens for pgt_query::protobuf::RangeTblFunction { + fn to_tokens(&self, _e: &mut EventEmitter) {} +} diff --git a/crates/pgt_pretty_print/src/renderer.rs b/crates/pgt_pretty_print/src/renderer.rs new file mode 100644 index 000000000..52da18668 --- /dev/null +++ b/crates/pgt_pretty_print/src/renderer.rs @@ -0,0 +1,248 @@ +use crate::emitter::{LayoutEvent, LineType}; +use std::fmt::Write; + +#[derive(Debug, Clone)] +pub enum IndentStyle { + Spaces, + Tabs, +} + +#[derive(Debug, Clone)] +pub struct RenderConfig { + pub max_line_length: usize, + pub indent_size: usize, + pub indent_style: IndentStyle, +} + +impl Default for RenderConfig { + fn default() -> Self { + Self { + max_line_length: 80, + indent_size: 2, + indent_style: IndentStyle::Spaces, + } + } +} + +pub struct Renderer { + config: RenderConfig, + writer: W, + current_line_length: usize, + indent_level: usize, + at_line_start: bool, +} + +impl Renderer { + pub fn new(writer: W, config: RenderConfig) -> Self { + Self { + config, + writer, + current_line_length: 0, + indent_level: 0, + at_line_start: true, + } + } + + pub fn render(&mut self, events: Vec) -> Result<(), std::fmt::Error> { + self.render_events(&events) + } + + fn render_events(&mut self, events: &[LayoutEvent]) -> Result<(), std::fmt::Error> { + let mut i = 0; + while i < events.len() { + match &events[i] { + LayoutEvent::Token(token) => { + let token_text = token.render(); + self.write_text(&token_text)?; + i += 1; + } + LayoutEvent::Space => { + self.write_space()?; + i += 1; + } + LayoutEvent::Line(line_type) => { + self.handle_line(&line_type)?; + i += 1; + } + LayoutEvent::GroupStart { .. } => { + let group_end = self.find_group_end(events, i); + let group_slice = &events[i..=group_end]; + self.render_group(group_slice)?; + i = group_end + 1; + } + LayoutEvent::GroupEnd => { + assert!(false, "Unmatched group end"); + } + LayoutEvent::IndentStart => { + self.indent_level += 1; + i += 1; + } + LayoutEvent::IndentEnd => { + self.indent_level = self.indent_level.saturating_sub(1); + i += 1; + } + } + } + Ok(()) + } + + fn render_group(&mut self, group_events: &[LayoutEvent]) -> Result<(), std::fmt::Error> { + if let Some(single_line) = self.try_single_line(group_events) { + let would_fit = + self.current_line_length + single_line.len() <= self.config.max_line_length; + if would_fit { + self.write_text(&single_line)?; + return Ok(()); + } + } + + self.render_events_with_breaks(group_events) + } + + fn render_events_with_breaks(&mut self, events: &[LayoutEvent]) -> Result<(), std::fmt::Error> { + let mut i = 0; + while i < events.len() { + match &events[i] { + LayoutEvent::Token(token) => { + let text = token.render(); + self.write_text(&text)?; + i += 1; + } + LayoutEvent::Space => { + self.write_space()?; + i += 1; + } + LayoutEvent::Line(_) => { + self.write_line_break()?; + i += 1; + } + LayoutEvent::GroupStart { .. } => { + let group_end = self.find_group_end(events, i); + let inner_events = &events[i + 1..group_end]; // skip GroupStart/GroupEnd + self.render_events_with_breaks(inner_events)?; + i = group_end + 1; + } + LayoutEvent::GroupEnd => { + assert!(false, "Unmatched group end"); + } + LayoutEvent::IndentStart => { + self.indent_level += 1; + i += 1; + } + LayoutEvent::IndentEnd => { + self.indent_level = self.indent_level.saturating_sub(1); + i += 1; + } + } + } + Ok(()) + } + + fn try_single_line(&self, group_events: &[LayoutEvent]) -> Option { + let mut buffer = String::new(); + let mut has_hard_breaks = false; + + for event in group_events { + match event { + LayoutEvent::Token(token) => { + let text = token.render(); + buffer.push_str(&text); + } + LayoutEvent::Space => { + buffer.push(' '); + } + LayoutEvent::Line(LineType::Hard) => { + has_hard_breaks = true; + break; + } + LayoutEvent::Line(LineType::Soft) => { + // soft lines disappear in single-line mode (no space) + } + LayoutEvent::Line(LineType::SoftOrSpace) => { + buffer.push(' '); // Becomes space in single-line mode + } + LayoutEvent::GroupStart { .. } | LayoutEvent::GroupEnd => { + // skip group markers for single line test + } + LayoutEvent::IndentStart | LayoutEvent::IndentEnd => { + // skip indent changes for single line test + } + } + } + + if has_hard_breaks { None } else { Some(buffer) } + } + + fn handle_line(&mut self, line_type: &LineType) -> Result<(), std::fmt::Error> { + match line_type { + LineType::Hard => { + self.write_line_break()?; + } + LineType::Soft | LineType::SoftOrSpace => { + // For now, just treat as space outside groups + self.write_space()?; + } + } + Ok(()) + } + + fn find_group_end(&self, events: &[LayoutEvent], start: usize) -> usize { + let mut depth = 0; + for i in start..events.len() { + match &events[i] { + LayoutEvent::GroupStart { .. } => depth += 1, + LayoutEvent::GroupEnd => { + depth -= 1; + if depth == 0 { + return i; + } + } + _ => {} + } + } + panic!("Unmatched group start"); + } + + fn write_text(&mut self, text: &str) -> Result<(), std::fmt::Error> { + if self.at_line_start { + self.write_indentation()?; + self.at_line_start = false; + } + + write!(self.writer, "{}", text)?; + self.current_line_length += text.len(); + Ok(()) + } + + fn write_space(&mut self) -> Result<(), std::fmt::Error> { + if !self.at_line_start { + write!(self.writer, " ")?; + self.current_line_length += 1; + } + Ok(()) + } + + fn write_line_break(&mut self) -> Result<(), std::fmt::Error> { + writeln!(self.writer)?; + self.current_line_length = 0; + self.at_line_start = true; + Ok(()) + } + + fn write_indentation(&mut self) -> Result<(), std::fmt::Error> { + let indent_str = match self.config.indent_style { + IndentStyle::Spaces => { + let spaces = " ".repeat(self.indent_level * self.config.indent_size); + self.current_line_length += spaces.len(); + spaces + } + IndentStyle::Tabs => { + let tabs = "\t".repeat(self.indent_level); + self.current_line_length += self.indent_level * self.config.indent_size; // Approximate + tabs + } + }; + write!(self.writer, "{}", indent_str)?; + Ok(()) + } +} diff --git a/crates/pgt_pretty_print/src/snapshots/pgt_pretty_print__nodes__test__simple_select.snap b/crates/pgt_pretty_print/src/snapshots/pgt_pretty_print__nodes__test__simple_select.snap new file mode 100644 index 000000000..4262a0626 --- /dev/null +++ b/crates/pgt_pretty_print/src/snapshots/pgt_pretty_print__nodes__test__simple_select.snap @@ -0,0 +1,176 @@ +--- +source: crates/pgt_pretty_print/src/nodes.rs +expression: emitter.events +snapshot_kind: text +--- +[ + GroupStart { + kind: SelectStmt, + }, + Token( + SELECT_KW, + ), + IndentStart, + Line( + SoftOrSpace, + ), + GroupStart { + kind: ResTarget, + }, + GroupStart { + kind: ColumnRef, + }, + Token( + IDENT( + "public", + ), + ), + Token( + DOT, + ), + Token( + IDENT( + "t", + ), + ), + Token( + DOT, + ), + Token( + IDENT( + "a", + ), + ), + GroupEnd, + Space, + Token( + AS_KW, + ), + Space, + Token( + IDENT( + "y", + ), + ), + GroupEnd, + Token( + COMMA, + ), + Line( + SoftOrSpace, + ), + GroupStart { + kind: ResTarget, + }, + GroupStart { + kind: ColumnRef, + }, + Token( + IDENT( + "b", + ), + ), + GroupEnd, + Space, + Token( + AS_KW, + ), + Space, + Token( + IDENT( + "z", + ), + ), + GroupEnd, + Token( + COMMA, + ), + Line( + SoftOrSpace, + ), + GroupStart { + kind: ResTarget, + }, + GroupStart { + kind: ColumnRef, + }, + Token( + IDENT( + "c", + ), + ), + GroupEnd, + GroupEnd, + IndentEnd, + Line( + SoftOrSpace, + ), + Token( + FROM_KW, + ), + Line( + SoftOrSpace, + ), + IndentStart, + GroupStart { + kind: RangeVar, + }, + Token( + IDENT( + "t", + ), + ), + GroupEnd, + IndentEnd, + Line( + SoftOrSpace, + ), + Token( + WHERE_KW, + ), + Space, + GroupStart { + kind: AExpr, + }, + GroupStart { + kind: ColumnRef, + }, + Token( + IDENT( + "id", + ), + ), + GroupEnd, + Space, + Token( + IDENT( + "=", + ), + ), + Space, + GroupStart { + kind: AExpr, + }, + Space, + Token( + IDENT( + "@", + ), + ), + Space, + GroupStart { + kind: ColumnRef, + }, + Token( + IDENT( + "id", + ), + ), + GroupEnd, + GroupEnd, + GroupEnd, + Token( + SEMICOLON, + ), + GroupEnd, +] diff --git a/crates/pgt_pretty_print/tests/data/multi/advisory_lock_60.sql b/crates/pgt_pretty_print/tests/data/multi/advisory_lock_60.sql new file mode 100644 index 000000000..8293d5889 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/advisory_lock_60.sql @@ -0,0 +1,123 @@ +SELECT oid AS datoid FROM pg_database WHERE datname = current_database() ; + +BEGIN; + +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2); + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +SELECT pg_advisory_unlock_all(); + +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid'; + +SELECT + pg_advisory_unlock(1), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock_shared(2, 2); + +COMMIT; + +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid'; + +BEGIN; + +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2); + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +SELECT + pg_advisory_lock(1), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2); + +ROLLBACK; + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +SELECT + pg_advisory_unlock(1), pg_advisory_unlock(1), + pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), + pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2); + +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid'; + +BEGIN; + +SELECT + pg_advisory_lock(1), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2); + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2); + +ROLLBACK; + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +SELECT pg_advisory_unlock_all(); + +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid'; + +BEGIN; + +SELECT + pg_advisory_xact_lock(1), pg_advisory_xact_lock(1), + pg_advisory_xact_lock_shared(2), pg_advisory_xact_lock_shared(2), + pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock(1, 1), + pg_advisory_xact_lock_shared(2, 2), pg_advisory_xact_lock_shared(2, 2); + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +COMMIT; + +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid'; + +SELECT + pg_advisory_lock(1), pg_advisory_lock(1), + pg_advisory_lock_shared(2), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock(1, 1), + pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2); + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +SELECT + pg_advisory_unlock(1), pg_advisory_unlock(1), + pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2), + pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1), + pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2); + +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid'; + +SELECT + pg_advisory_lock(1), pg_advisory_lock(1), + pg_advisory_lock_shared(2), pg_advisory_lock_shared(2), + pg_advisory_lock(1, 1), pg_advisory_lock(1, 1), + pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2); + +SELECT locktype, classid, objid, objsubid, mode, granted + FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid' + ORDER BY classid, objid, objsubid; + +SELECT pg_advisory_unlock_all(); + +SELECT count(*) FROM pg_locks WHERE locktype = 'advisory' AND database = 'datoid'; diff --git a/crates/pgt_pretty_print/tests/data/multi/aggregates_60.sql b/crates/pgt_pretty_print/tests/data/multi/aggregates_60.sql new file mode 100644 index 000000000..577017936 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/aggregates_60.sql @@ -0,0 +1,1621 @@ +SET extra_float_digits = 0; + +CREATE TABLE aggtest ( + a int2, + b float4 +); + +COPY aggtest FROM 'filename'; + +ANALYZE aggtest; + +SELECT avg(four) AS avg_1 FROM onek; + +SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100; + +SELECT any_value(v) FROM (VALUES (1), (2), (3)) AS v (v); + +SELECT any_value(v) FROM (VALUES (NULL)) AS v (v); + +SELECT any_value(v) FROM (VALUES (NULL), (1), (2)) AS v (v); + +SELECT any_value(v) FROM (VALUES (array['hello', 'world'])) AS v (v); + +SELECT avg(b)::numeric(10,3) AS avg_107_943 FROM aggtest; + +SELECT avg(gpa) AS avg_3_4 FROM ONLY student; + +SELECT sum(four) AS sum_1500 FROM onek; + +SELECT sum(a) AS sum_198 FROM aggtest; + +SELECT sum(b) AS avg_431_773 FROM aggtest; + +SELECT sum(gpa) AS avg_6_8 FROM ONLY student; + +SELECT max(four) AS max_3 FROM onek; + +SELECT max(a) AS max_100 FROM aggtest; + +SELECT max(aggtest.b) AS max_324_78 FROM aggtest; + +SELECT max(student.gpa) AS max_3_7 FROM student; + +SELECT stddev_pop(b) FROM aggtest; + +SELECT stddev_samp(b) FROM aggtest; + +SELECT var_pop(b) FROM aggtest; + +SELECT var_samp(b) FROM aggtest; + +SELECT stddev_pop(b::numeric) FROM aggtest; + +SELECT stddev_samp(b::numeric) FROM aggtest; + +SELECT var_pop(b::numeric) FROM aggtest; + +SELECT var_samp(b::numeric) FROM aggtest; + +SELECT var_pop(1.0::float8), var_samp(2.0::float8); + +SELECT stddev_pop(3.0::float8), stddev_samp(4.0::float8); + +SELECT var_pop('inf'::float8), var_samp('inf'::float8); + +SELECT stddev_pop('inf'::float8), stddev_samp('inf'::float8); + +SELECT var_pop('nan'::float8), var_samp('nan'::float8); + +SELECT stddev_pop('nan'::float8), stddev_samp('nan'::float8); + +SELECT var_pop(1.0::float4), var_samp(2.0::float4); + +SELECT stddev_pop(3.0::float4), stddev_samp(4.0::float4); + +SELECT var_pop('inf'::float4), var_samp('inf'::float4); + +SELECT stddev_pop('inf'::float4), stddev_samp('inf'::float4); + +SELECT var_pop('nan'::float4), var_samp('nan'::float4); + +SELECT stddev_pop('nan'::float4), stddev_samp('nan'::float4); + +SELECT var_pop(1.0::numeric), var_samp(2.0::numeric); + +SELECT stddev_pop(3.0::numeric), stddev_samp(4.0::numeric); + +SELECT var_pop('inf'::numeric), var_samp('inf'::numeric); + +SELECT stddev_pop('inf'::numeric), stddev_samp('inf'::numeric); + +SELECT var_pop('nan'::numeric), var_samp('nan'::numeric); + +SELECT stddev_pop('nan'::numeric), stddev_samp('nan'::numeric); + +SELECT max(row(a,b)) FROM aggtest; + +SELECT max(row(b,a)) FROM aggtest; + +SELECT min(row(a,b)) FROM aggtest; + +SELECT min(row(b,a)) FROM aggtest; + +select sum(null::int4) from generate_series(1,3); + +select sum(null::int8) from generate_series(1,3); + +select sum(null::numeric) from generate_series(1,3); + +select sum(null::float8) from generate_series(1,3); + +select avg(null::int4) from generate_series(1,3); + +select avg(null::int8) from generate_series(1,3); + +select avg(null::numeric) from generate_series(1,3); + +select avg(null::float8) from generate_series(1,3); + +select sum('NaN'::numeric) from generate_series(1,3); + +select avg('NaN'::numeric) from generate_series(1,3); + +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('1'), ('infinity')) v(x); + +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('1')) v(x); + +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('infinity')) v(x); + +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('infinity')) v(x); + +SELECT sum(x::float8), avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('-infinity')) v(x); + +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('1'), ('infinity')) v(x); + +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('infinity'), ('1')) v(x); + +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('infinity'), ('infinity')) v(x); + +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('-infinity'), ('infinity')) v(x); + +SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) +FROM (VALUES ('-infinity'), ('-infinity')) v(x); + +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (100000003), (100000004), (100000006), (100000007)) v(x); + +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (7000000000005), (7000000000007)) v(x); + +SELECT regr_count(b, a) FROM aggtest; + +SELECT regr_sxx(b, a) FROM aggtest; + +SELECT regr_syy(b, a) FROM aggtest; + +SELECT regr_sxy(b, a) FROM aggtest; + +SELECT regr_avgx(b, a), regr_avgy(b, a) FROM aggtest; + +SELECT regr_r2(b, a) FROM aggtest; + +SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest; + +SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest; + +SELECT corr(b, a) FROM aggtest; + +SELECT covar_pop(1::float8,2::float8), covar_samp(3::float8,4::float8); + +SELECT covar_pop(1::float8,'inf'::float8), covar_samp(3::float8,'inf'::float8); + +SELECT covar_pop(1::float8,'nan'::float8), covar_samp(3::float8,'nan'::float8); + +CREATE TABLE regr_test (x float8, y float8); + +INSERT INTO regr_test VALUES (10,150),(20,250),(30,350),(80,540),(100,200); + +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30,80); + +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test; + +SELECT float8_accum('{4,140,2900}'::float8[], 100); + +SELECT float8_regr_accum('{4,140,2900,1290,83075,15050}'::float8[], 200, 100); + +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30); + +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (80,100); + +SELECT float8_combine('{3,60,200}'::float8[], '{0,0,0}'::float8[]); + +SELECT float8_combine('{0,0,0}'::float8[], '{2,180,200}'::float8[]); + +SELECT float8_combine('{3,60,200}'::float8[], '{2,180,200}'::float8[]); + +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{0,0,0,0,0,0}'::float8[]); + +SELECT float8_regr_combine('{0,0,0,0,0,0}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]); + +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]); + +DROP TABLE regr_test; + +SELECT count(four) AS cnt_1000 FROM onek; + +SELECT count(DISTINCT four) AS cnt_4 FROM onek; + +select ten, count(*), sum(four) from onek +group by ten order by ten; + +select ten, count(four), sum(DISTINCT four) from onek +group by ten order by ten; + +SELECT newavg(four) AS avg_1 FROM onek; + +SELECT newsum(four) AS sum_1500 FROM onek; + +SELECT newcnt(four) AS cnt_1000 FROM onek; + +SELECT newcnt(*) AS cnt_1000 FROM onek; + +SELECT oldcnt(*) AS cnt_1000 FROM onek; + +SELECT sum2(q1,q2) FROM int8_tbl; + +SELECT sum(q1+q2), sum(q1)+sum(q2) FROM int8_tbl; + +SELECT sum(q1-q2), sum(q2-q1), sum(q1)-sum(q2) FROM int8_tbl; + +SELECT sum(q1*2000), sum(-q1*2000), 2000*sum(q1) FROM int8_tbl; + +select ten, sum(distinct four) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four); + +select ten, sum(distinct four) from onek a +group by ten +having exists (select 1 from onek b + where sum(distinct a.four + b.four) = b.four); + +select + (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1))) +from tenk1 o; + +select s1, s2, sm +from generate_series(1, 3) s1, + lateral (select s2, sum(s1 + s2) sm + from generate_series(1, 3) s2 group by s2) ss +order by 1, 2; + +select s1, s2, sm +from generate_series(1, 3) s1, + lateral (select s2, sum(s1 + s2) sm + from generate_series(1, 3) s2 group by s2) ss +order by 1, 2; + +select array(select sum(x+y) s + from generate_series(1,3) y group by y order by s) + from generate_series(1,3) x; + +select array(select sum(x+y) s + from generate_series(1,3) y group by y order by s) + from generate_series(1,3) x; + +CREATE TEMPORARY TABLE bitwise_test( + i2 INT2, + i4 INT4, + i8 INT8, + i INTEGER, + x INT2, + y BIT(4) +); + +SELECT + BIT_AND(i2) AS "?", + BIT_OR(i4) AS "?", + BIT_XOR(i8) AS "?" +FROM bitwise_test; + +SELECT + BIT_AND(i2) AS "1", + BIT_AND(i4) AS "1", + BIT_AND(i8) AS "1", + BIT_AND(i) AS "?", + BIT_AND(x) AS "0", + BIT_AND(y) AS "0100", + + BIT_OR(i2) AS "7", + BIT_OR(i4) AS "7", + BIT_OR(i8) AS "7", + BIT_OR(i) AS "?", + BIT_OR(x) AS "7", + BIT_OR(y) AS "1101", + + BIT_XOR(i2) AS "5", + BIT_XOR(i4) AS "5", + BIT_XOR(i8) AS "5", + BIT_XOR(i) AS "?", + BIT_XOR(x) AS "7", + BIT_XOR(y) AS "1101" +FROM bitwise_test; + +SELECT + -- boolean and transitions + -- null because strict + booland_statefunc(NULL, NULL) IS NULL AS "t", + booland_statefunc(TRUE, NULL) IS NULL AS "t", + booland_statefunc(FALSE, NULL) IS NULL AS "t", + booland_statefunc(NULL, TRUE) IS NULL AS "t", + booland_statefunc(NULL, FALSE) IS NULL AS "t", + -- and actual computations + booland_statefunc(TRUE, TRUE) AS "t", + NOT booland_statefunc(TRUE, FALSE) AS "t", + NOT booland_statefunc(FALSE, TRUE) AS "t", + NOT booland_statefunc(FALSE, FALSE) AS "t"; + +SELECT + -- boolean or transitions + -- null because strict + boolor_statefunc(NULL, NULL) IS NULL AS "t", + boolor_statefunc(TRUE, NULL) IS NULL AS "t", + boolor_statefunc(FALSE, NULL) IS NULL AS "t", + boolor_statefunc(NULL, TRUE) IS NULL AS "t", + boolor_statefunc(NULL, FALSE) IS NULL AS "t", + -- actual computations + boolor_statefunc(TRUE, TRUE) AS "t", + boolor_statefunc(TRUE, FALSE) AS "t", + boolor_statefunc(FALSE, TRUE) AS "t", + NOT boolor_statefunc(FALSE, FALSE) AS "t"; + +CREATE TEMPORARY TABLE bool_test( + b1 BOOL, + b2 BOOL, + b3 BOOL, + b4 BOOL); + +SELECT + BOOL_AND(b1) AS "n", + BOOL_OR(b3) AS "n" +FROM bool_test; + +SELECT + BOOL_AND(b1) AS "f", + BOOL_AND(b2) AS "t", + BOOL_AND(b3) AS "f", + BOOL_AND(b4) AS "n", + BOOL_AND(NOT b2) AS "f", + BOOL_AND(NOT b3) AS "t" +FROM bool_test; + +SELECT + EVERY(b1) AS "f", + EVERY(b2) AS "t", + EVERY(b3) AS "f", + EVERY(b4) AS "n", + EVERY(NOT b2) AS "f", + EVERY(NOT b3) AS "t" +FROM bool_test; + +SELECT + BOOL_OR(b1) AS "t", + BOOL_OR(b2) AS "t", + BOOL_OR(b3) AS "f", + BOOL_OR(b4) AS "n", + BOOL_OR(NOT b2) AS "f", + BOOL_OR(NOT b3) AS "t" +FROM bool_test; + +select min(unique1) from tenk1; + +select min(unique1) from tenk1; + +select max(unique1) from tenk1; + +select max(unique1) from tenk1; + +select max(unique1) from tenk1 where unique1 < 42; + +select max(unique1) from tenk1 where unique1 < 42; + +select max(unique1) from tenk1 where unique1 > 42; + +select max(unique1) from tenk1 where unique1 > 42; + +begin; + +set local max_parallel_workers_per_gather = 0; + +select max(unique1) from tenk1 where unique1 > 42000; + +select max(unique1) from tenk1 where unique1 > 42000; + +rollback; + +select max(tenthous) from tenk1 where thousand = 33; + +select max(tenthous) from tenk1 where thousand = 33; + +select min(tenthous) from tenk1 where thousand = 33; + +select min(tenthous) from tenk1 where thousand = 33; + +select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt + from int4_tbl; + +select f1, (select min(unique1) from tenk1 where unique1 > f1) AS gt + from int4_tbl; + +select distinct max(unique2) from tenk1; + +select distinct max(unique2) from tenk1; + +select max(unique2) from tenk1 order by 1; + +select max(unique2) from tenk1 order by 1; + +select max(unique2) from tenk1 order by max(unique2); + +select max(unique2) from tenk1 order by max(unique2); + +select max(unique2) from tenk1 order by max(unique2)+1; + +select max(unique2) from tenk1 order by max(unique2)+1; + +select max(unique2), generate_series(1,3) as g from tenk1 order by g desc; + +select max(unique2), generate_series(1,3) as g from tenk1 order by g desc; + +select max(100) from tenk1; + +select max(100) from tenk1; + +create table minmaxtest(f1 int); + +create table minmaxtest1() inherits (minmaxtest); + +create table minmaxtest2() inherits (minmaxtest); + +create table minmaxtest3() inherits (minmaxtest); + +create index minmaxtesti on minmaxtest(f1); + +create index minmaxtest1i on minmaxtest1(f1); + +create index minmaxtest2i on minmaxtest2(f1 desc); + +create index minmaxtest3i on minmaxtest3(f1) where f1 is not null; + +insert into minmaxtest values(11), (12); + +insert into minmaxtest1 values(13), (14); + +insert into minmaxtest2 values(15), (16); + +insert into minmaxtest3 values(17), (18); + +select min(f1), max(f1) from minmaxtest; + +select min(f1), max(f1) from minmaxtest; + +select distinct min(f1), max(f1) from minmaxtest; + +select distinct min(f1), max(f1) from minmaxtest; + +drop table minmaxtest cascade; + +begin; + +set local enable_sort = off; + +select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1) + from int4_tbl t0; + +select f1, (select distinct min(t1.f1) from int4_tbl t1 where t1.f1 = t0.f1) +from int4_tbl t0; + +rollback; + +select max(min(unique1)) from tenk1; + +select (select max(min(unique1)) from int8_tbl) from tenk1; + +select avg((select avg(a1.col1 order by (select avg(a2.col2) from tenk1 a3)) + from tenk1 a1(col1))) +from tenk1 a2(col2); + +create temp table t1 (a int, b int, c int, d int, primary key (a, b)); + +create temp table t2 (x int, y int, z int, primary key (x, y)); + +create temp table t3 (a int, b int, c int, primary key(a, b) deferrable); + +select * from t1 group by a,b,c,d; + +select a,c from t1 group by a,c,d; + +select * +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.y,t2.z; + +select t1.*,t2.x,t2.z +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z; + +select * from t3 group by a,b,c; + +create temp table t1c () inherits (t1); + +select * from t1 group by a,b,c,d; + +select * from only t1 group by a,b,c,d; + +create temp table p_t1 ( + a int, + b int, + c int, + d int, + primary key(a,b) +) partition by list(a); + +create temp table p_t1_1 partition of p_t1 for values in(1); + +create temp table p_t1_2 partition of p_t1 for values in(2); + +select * from p_t1 group by a,b,c,d; + +create unique index t2_z_uidx on t2(z); + +select y,z from t2 group by y,z; + +alter table t2 alter column z set not null; + +select y,z from t2 group by y,z; + +select x,y,z from t2 group by x,y,z; + +select x,y,z from t2 group by z,x,y; + +drop index t2_z_uidx; + +create index t2_z_uidx on t2 (z) where z > 0; + +select y,z from t2 group by y,z; + +drop index t2_z_uidx; + +alter table t2 alter column z drop not null; + +create unique index t2_z_uidx on t2(z) nulls not distinct; + +select y,z from t2 group by y,z; + +drop table t1 cascade; + +drop table t2; + +drop table t3; + +drop table p_t1; + +create temp table t1(f1 int, f2 int); + +create temp table t2(f1 bigint, f2 oid); + +select f1 from t1 left join t2 using (f1) group by f1; + +select f1 from t1 left join t2 using (f1) group by t1.f1; + +select t1.f1 from t1 left join t2 using (f1) group by t1.f1; + +select t1.f1 from t1 left join t2 using (f1) group by f1; + +select f1, count(*) from +t1 x(x0,x1) left join (t1 left join t2 using(f1)) on (x0 = 0) +group by f1; + +select f2, count(*) from +t1 x(x0,x1) left join (t1 left join t2 using(f2)) on (x0 = 0) +group by f2; + +drop table t1, t2; + +select sum(two order by two),max(four order by four), min(four order by four) +from tenk1; + +select + sum(two order by two), max(four order by four), + min(four order by four), max(two order by two) +from tenk1; + +select + max(four order by four), sum(two order by two), + min(four order by four), max(two order by two) +from tenk1; + +select + max(four order by four), sum(two order by two), + min(four order by four), max(two order by two), + sum(ten order by ten), min(ten order by ten), max(ten order by ten) +from tenk1; + +select + sum(unique1 order by ten, two), sum(unique1 order by four), + sum(unique1 order by two, four) +from tenk1 +group by ten; + +select + sum(unique1 order by two), sum(unique1 order by four), + sum(unique1 order by four, two), sum(unique1 order by two, random()), + sum(unique1 order by two, random(), random() + 1) +from tenk1 +group by ten; + +select array_agg(distinct val) +from (select null as val from generate_series(1, 2)); + +set enable_presorted_aggregate to off; + +select sum(two order by two) from tenk1; + +reset enable_presorted_aggregate; + +select sum(two order by two) filter (where two > 1) from tenk1; + +select string_agg(distinct f1, ',') filter (where length(f1) > 1) +from varchar_tbl; + +select string_agg(distinct f1::varchar(2), ',') filter (where length(f1) > 1) +from varchar_tbl; + +select array_agg(a order by b) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); + +select array_agg(a order by a) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); + +select array_agg(a order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); + +select array_agg(b order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); + +select array_agg(distinct a) + from (values (1),(2),(1),(3),(null),(2)) v(a); + +select array_agg(distinct a order by a) + from (values (1),(2),(1),(3),(null),(2)) v(a); + +select array_agg(distinct a order by a desc) + from (values (1),(2),(1),(3),(null),(2)) v(a); + +select array_agg(distinct a order by a desc nulls last) + from (values (1),(2),(1),(3),(null),(2)) v(a); + +select aggfstr(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select aggfstr(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select aggfstr(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select aggfns(distinct a,a,c order by c using ~<~,a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +select aggfns(distinct a,a,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +select aggfns(distinct a,a,c order by a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +select + string_agg(distinct 'a', ','), + sum(( + select sum(1) + from (values(1)) b(id) + where a.id = b.id +)) from unnest(array[1]) a(id); + +create view agg_view1 as + select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; + +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select * from agg_view1; + +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select * from agg_view1; + +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(a,b,c order by b+1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; + +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(a,a,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; + +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(a,b,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; + +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +select * from agg_view1; + +select pg_get_viewdef('agg_view1'::regclass); + +drop view agg_view1; + +select aggfns(distinct a,b,c order by i) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; + +select aggfns(distinct a,b,c order by a,b+1) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; + +select aggfns(distinct a,b,c order by a,b,i,c) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; + +select aggfns(distinct a,a,c order by a,b) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; + +select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a); + +select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a); + +select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a); + +select string_agg(a,',') from (values(null),(null)) g(a); + +select string_agg(distinct f1, ',' order by f1) from varchar_tbl; + +select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; + +select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; + +select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; + +create table bytea_test_table(v bytea); + +select string_agg(v, '') from bytea_test_table; + +insert into bytea_test_table values(decode('ff','hex')); + +select string_agg(v, '') from bytea_test_table; + +insert into bytea_test_table values(decode('aa','hex')); + +select string_agg(v, '') from bytea_test_table; + +select string_agg(v, NULL) from bytea_test_table; + +select string_agg(v, decode('ee', 'hex')) from bytea_test_table; + +select min(v) from bytea_test_table; + +select max(v) from bytea_test_table; + +insert into bytea_test_table values(decode('ffff','hex')); + +insert into bytea_test_table values(decode('aaaa','hex')); + +select min(v) from bytea_test_table; + +select max(v) from bytea_test_table; + +drop table bytea_test_table; + +create table pagg_test (x int, y int) with (autovacuum_enabled = off); + +insert into pagg_test +select (case x % 4 when 1 then null else x end), x % 10 +from generate_series(1,5000) x; + +set parallel_setup_cost TO 0; + +set parallel_tuple_cost TO 0; + +set parallel_leader_participation TO 0; + +set min_parallel_table_scan_size = 0; + +set bytea_output = 'escape'; + +set max_parallel_workers_per_gather = 2; + +create view v_pagg_test AS +select + y, + min(t) AS tmin,max(t) AS tmax,count(distinct t) AS tndistinct, + min(b) AS bmin,max(b) AS bmax,count(distinct b) AS bndistinct, + min(a) AS amin,max(a) AS amax,count(distinct a) AS andistinct, + min(aa) AS aamin,max(aa) AS aamax,count(distinct aa) AS aandistinct +from ( + select + y, + unnest(regexp_split_to_array(a1.t, ','))::int AS t, + unnest(regexp_split_to_array(a1.b::text, ',')) AS b, + unnest(a1.a) AS a, + unnest(a1.aa) AS aa + from ( + select + y, + string_agg(x::text, ',') AS t, + string_agg(x::text::bytea, ',') AS b, + array_agg(x) AS a, + array_agg(ARRAY[x]) AS aa + from pagg_test + group by y + ) a1 +) a2 +group by y; + +select * from v_pagg_test order by y; + +select * from v_pagg_test order by y; + +set max_parallel_workers_per_gather = 0; + +select * from v_pagg_test order by y; + +set max_parallel_workers_per_gather = 2; + +select array_dims(array_agg(s)) from (select * from pagg_test) s; + +select array_dims(array_agg(s)) from (select * from pagg_test) s; + +reset max_parallel_workers_per_gather; + +reset bytea_output; + +reset min_parallel_table_scan_size; + +reset parallel_leader_participation; + +reset parallel_tuple_cost; + +reset parallel_setup_cost; + +drop view v_pagg_test; + +drop table pagg_test; + +select min(unique1) filter (where unique1 > 100) from tenk1; + +select sum(1/ten) filter (where ten > 0) from tenk1; + +select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +group by ten; + +select ten, sum(distinct four) filter (where four > 10) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four); + +select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') +from (values ('a', 'b')) AS v(foo,bar); + +select any_value(v) filter (where v > 2) from (values (1), (2), (3)) as v (v); + +select (select count(*) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c); + +select (select count(*) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c); + +select (select count(inner_c) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c); + +select + (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)) + filter (where o.unique1 < 10)) +from tenk1 o; + +select sum(unique1) FILTER (WHERE + unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1; + +select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +select max(0) filter (where b1) from bool_test; + +select (select max(0) filter (where b1)) from bool_test; + +select max(unique1) filter (where sum(ten) > 0) from tenk1; + +select (select max(unique1) filter (where sum(ten) > 0) from int8_tbl) from tenk1; + +select max(unique1) filter (where bool_or(ten > 0)) from tenk1; + +select (select max(unique1) filter (where bool_or(ten > 0)) from int8_tbl) from tenk1; + +select p, percentile_cont(p) within group (order by x::float8) +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p; + +select p, sum() within group (order by x::float8) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p; + +select p, percentile_cont(p,p) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p; + +select percentile_cont(0.5) within group (order by b) from aggtest; + +select percentile_cont(0.5) within group (order by b), sum(b) from aggtest; + +select percentile_cont(0.5) within group (order by thousand) from tenk1; + +select percentile_disc(0.5) within group (order by thousand) from tenk1; + +select rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); + +select cume_dist(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); + +select percent_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4),(5)) v(x); + +select dense_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); + +select percentile_disc(array[0,0.1,0.25,0.5,0.75,0.9,1]) within group (order by thousand) +from tenk1; + +select percentile_cont(array[0,0.25,0.5,0.75,1]) within group (order by thousand) +from tenk1; + +select percentile_disc(array[[null,1,0.5],[0.75,0.25,null]]) within group (order by thousand) +from tenk1; + +select percentile_cont(array[0,1,0.25,0.75,0.5,1,0.3,0.32,0.35,0.38,0.4]) within group (order by x) +from generate_series(1,6) x; + +select ten, mode() within group (order by string4) from tenk1 group by ten; + +select percentile_disc(array[0.25,0.5,0.75]) within group (order by x) +from unnest('{fred,jim,fred,jack,jill,fred,jill,jim,jim,sheila,jim,sheila}'::text[]) u(x); + +select pg_collation_for(percentile_disc(1) within group (order by x collate "POSIX")) + from (values ('fred'),('jim')) v(x); + +select test_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); + +select test_percentile_disc(0.5) within group (order by thousand) from tenk1; + +select rank(x) within group (order by x) from generate_series(1,5) x; + +select array(select percentile_disc(a) within group (order by x) + from (values (0.3),(0.7)) v(a) group by a) + from generate_series(1,5) g(x); + +select rank(sum(x)) within group (order by x) from generate_series(1,5) x; + +select rank(3) within group (order by x) from (values ('fred'),('jim')) v(x); + +select rank(3) within group (order by stringu1,stringu2) from tenk1; + +select rank('fred') within group (order by x) from generate_series(1,5) x; + +select rank('adam'::text collate "C") within group (order by x collate "POSIX") + from (values ('fred'),('jim')) v(x); + +select rank('adam'::varchar) within group (order by x) from (values ('fred'),('jim')) v(x); + +select rank('3') within group (order by x) from generate_series(1,5) x; + +select percent_rank(0) within group (order by x) from generate_series(1,0) x; + +create view aggordview1 as +select ten, + percentile_disc(0.5) within group (order by thousand) as p50, + percentile_disc(0.5) within group (order by thousand) filter (where hundred=1) as px, + rank(5,'AZZZZ',50) within group (order by hundred, string4 desc, hundred) + from tenk1 + group by ten order by ten; + +select pg_get_viewdef('aggordview1'); + +select * from aggordview1 order by ten; + +drop view aggordview1; + +select least_agg(q1,q2) from int8_tbl; + +select least_agg(variadic array[q1,q2]) from int8_tbl; + +select cleast_agg(q1,q2) from int8_tbl; + +select cleast_agg(4.5,f1) from int4_tbl; + +select cleast_agg(variadic array[4.5,f1]) from int4_tbl; + +select pg_typeof(cleast_agg(variadic array[4.5,f1])) from int4_tbl; + +begin work; + +create type avg_state as (total bigint, count bigint); + +create or replace function avg_transfn(state avg_state, n int) returns avg_state as +$$ +declare new_state avg_state; +begin + raise notice 'avg_transfn called with %', n; + if state is null then + if n is not null then + new_state.total := n; + new_state.count := 1; + return new_state; + end if; + return null; + elsif n is not null then + state.total := state.total + n; + state.count := state.count + 1; + return state; + end if; + + return null; +end +$$ language plpgsql; + +create function avg_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total / state.count; + end if; +end +$$ language plpgsql; + +create function sum_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total; + end if; +end +$$ language plpgsql; + +create aggregate my_avg(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn +); + +create aggregate my_sum(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn +); + +select my_avg(one),my_avg(one) from (values(1),(3)) t(one); + +select my_avg(one),my_sum(one) from (values(1),(3)) t(one); + +select my_avg(distinct one),my_sum(distinct one) from (values(1),(3),(1)) t(one); + +select my_avg(distinct one),my_sum(one) from (values(1),(3)) t(one); + +select my_avg(one) filter (where one > 1),my_sum(one) from (values(1),(3)) t(one); + +select my_avg(one),my_sum(two) from (values(1,2),(3,4)) t(one,two); + +select + percentile_cont(0.5) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a); + +select + percentile_cont(0.25) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a); + +select + rank(4) within group (order by a), + dense_rank(4) within group (order by a) +from (values(1),(3),(5),(7)) t(a); + +create aggregate my_sum_init(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn, + initcond = '(10,0)' +); + +create aggregate my_avg_init(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(10,0)' +); + +create aggregate my_avg_init2(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(4,0)' +); + +select my_sum_init(one),my_avg_init(one) from (values(1),(3)) t(one); + +select my_sum_init(one),my_avg_init2(one) from (values(1),(3)) t(one); + +rollback; + +begin work; + +create or replace function sum_transfn(state int4, n int4) returns int4 as +$$ +declare new_state int4; +begin + raise notice 'sum_transfn called with %', n; + if state is null then + if n is not null then + new_state := n; + return new_state; + end if; + return null; + elsif n is not null then + state := state + n; + return state; + end if; + + return null; +end +$$ language plpgsql; + +create function halfsum_finalfn(state int4) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state / 2; + end if; +end +$$ language plpgsql; + +create aggregate my_sum(int4) +( + stype = int4, + sfunc = sum_transfn +); + +create aggregate my_half_sum(int4) +( + stype = int4, + sfunc = sum_transfn, + finalfunc = halfsum_finalfn +); + +select my_sum(one),my_half_sum(one) from (values(1),(2),(3),(4)) t(one); + +rollback; + +BEGIN; + +CREATE FUNCTION balkifnull(int8, int4) +RETURNS int8 +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$; + +CREATE AGGREGATE balk(int4) +( + SFUNC = balkifnull(int8, int4), + STYPE = int8, + PARALLEL = SAFE, + INITCOND = '0' +); + +SELECT balk(hundred) FROM tenk1; + +ROLLBACK; + +CREATE TABLE btg AS SELECT + i % 10 AS x, + i % 10 AS y, + 'abc' || i % 10 AS z, + i AS w +FROM generate_series(1, 100) AS i; + +CREATE INDEX btg_x_y_idx ON btg(x, y); + +ANALYZE btg; + +SET enable_hashagg = off; + +SET enable_seqscan = off; + +SELECT count(*) FROM btg GROUP BY y, x; + +SELECT count(*) FROM btg GROUP BY z, y, w, x; + +SELECT count(*) +FROM (SELECT * FROM btg ORDER BY x, y, w, z) AS q1 +GROUP BY w, x, z, y; + +SET enable_hashjoin = off; + +SET enable_nestloop = off; + +SELECT count(*) + FROM btg t1 JOIN btg t2 ON t1.w = t2.w AND t1.x = t2.x AND t1.z = t2.z + GROUP BY t1.w, t1.z, t1.x; + +RESET enable_nestloop; + +RESET enable_hashjoin; + +SELECT count(*) FROM btg GROUP BY w, x, z, y ORDER BY y, x, z, w; + +SELECT count(*) FROM btg GROUP BY w, x, y, z ORDER BY x*x, z; + +CREATE INDEX btg_y_x_w_idx ON btg(y, x, w); + +SELECT y, x, array_agg(distinct w) + FROM btg WHERE y < 0 GROUP BY x, y; + +CREATE TABLE group_agg_pk AS SELECT + i % 10 AS x, + i % 2 AS y, + i % 2 AS z, + 2 AS w, + i % 10 AS f +FROM generate_series(1,100) AS i; + +ANALYZE group_agg_pk; + +SET enable_nestloop = off; + +SET enable_hashjoin = off; + +SELECT avg(c1.f ORDER BY c1.x, c1.y) +FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x +GROUP BY c1.w, c1.z; + +SELECT avg(c1.f ORDER BY c1.x, c1.y) +FROM group_agg_pk c1 JOIN group_agg_pk c2 ON c1.x = c2.x +GROUP BY c1.w, c1.z; + +SELECT c1.y,c1.x FROM group_agg_pk c1 + JOIN group_agg_pk c2 + ON c1.x = c2.x +GROUP BY c1.y,c1.x,c2.x; + +SELECT c1.y,c1.x FROM group_agg_pk c1 + JOIN group_agg_pk c2 + ON c1.x = c2.x +GROUP BY c1.y,c2.x,c1.x; + +RESET enable_nestloop; + +RESET enable_hashjoin; + +DROP TABLE group_agg_pk; + +CREATE TABLE agg_sort_order (c1 int PRIMARY KEY, c2 int); + +CREATE UNIQUE INDEX agg_sort_order_c2_idx ON agg_sort_order(c2); + +INSERT INTO agg_sort_order SELECT i, i FROM generate_series(1,100)i; + +ANALYZE agg_sort_order; + +SELECT array_agg(c1 ORDER BY c2),c2 +FROM agg_sort_order WHERE c2 < 100 GROUP BY c1 ORDER BY 2; + +DROP TABLE agg_sort_order CASCADE; + +DROP TABLE btg; + +RESET enable_hashagg; + +RESET enable_seqscan; + +BEGIN; + +CREATE FUNCTION balkifnull(int8, int8) +RETURNS int8 +PARALLEL SAFE +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$; + +CREATE AGGREGATE balk(int4) +( + SFUNC = int4_sum(int8, int4), + STYPE = int8, + COMBINEFUNC = balkifnull(int8, int8), + PARALLEL = SAFE, + INITCOND = '0' +); + +ALTER TABLE tenk1 set (parallel_workers = 4); + +SET LOCAL parallel_setup_cost=0; + +SET LOCAL max_parallel_workers_per_gather=4; + +SELECT balk(hundred) FROM tenk1; + +SELECT balk(hundred) FROM tenk1; + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray +LANGUAGE plpgsql IMMUTABLE AS $$ +BEGIN + RETURN array_fill(y[1], ARRAY[4]); +END; +$$; + +CREATE FUNCTION rwagg_finalfunc(x anyarray) RETURNS anyarray +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +DECLARE + res x%TYPE; +BEGIN + -- assignment is essential for this test, it expands the array to R/W + res := array_fill(x[1], ARRAY[4]); + RETURN res; +END; +$$; + +CREATE AGGREGATE rwagg(anyarray) ( + STYPE = anyarray, + SFUNC = rwagg_sfunc, + FINALFUNC = rwagg_finalfunc +); + +CREATE FUNCTION eatarray(x real[]) RETURNS real[] +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +BEGIN + x[1] := x[1] + 1; + RETURN x; +END; +$$; + +SELECT eatarray(rwagg(ARRAY[1.0::real])), eatarray(rwagg(ARRAY[1.0::real])); + +ROLLBACK; + +BEGIN; + +SET parallel_setup_cost = 0; + +SET parallel_tuple_cost = 0; + +SET min_parallel_table_scan_size = 0; + +SET max_parallel_workers_per_gather = 4; + +SET parallel_leader_participation = off; + +SET enable_indexonlyscan = off; + +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u; + +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u; + +SELECT variance(unique1::int8), avg(unique1::numeric) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u; + +SELECT variance(unique1::int8), avg(unique1::numeric) +FROM (SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1 + UNION ALL SELECT * FROM tenk1) u; + +ROLLBACK; + +SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (1),(1),(2),(2),(3),(3)) v(x) GROUP BY (x) ORDER BY 1; + +SELECT min(x ORDER BY y) FROM (VALUES(1, NULL)) AS d(x,y); + +SELECT min(x ORDER BY y) FROM (VALUES(1, 2)) AS d(x,y); + +select v||'a', case v||'a' when 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; + +select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; + +set enable_sort=false; + +set work_mem='64kB'; + +select unique1, count(*), sum(twothousand) from tenk1 +group by unique1 +having sum(fivethous) > 4975 +order by sum(twothousand); + +set work_mem to default; + +set enable_sort to default; + +set work_mem='64kB'; + +create table agg_data_2k as +select g from generate_series(0, 1999) g; + +analyze agg_data_2k; + +create table agg_data_20k as +select g from generate_series(0, 19999) g; + +analyze agg_data_20k; + +set enable_hashagg = false; + +set jit_above_cost = 0; + +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000; + +create table agg_group_1 as +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000; + +create table agg_group_2 as +select * from + (values (100), (300), (500)) as r(a), + lateral ( + select (g/2)::numeric as c1, + array_agg(g::numeric) as c2, + count(*) as c3 + from agg_data_2k + where g < r.a + group by g/2) as s; + +set jit_above_cost to default; + +create table agg_group_3 as +select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 + from agg_data_2k group by g/2; + +create table agg_group_4 as +select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 + from agg_data_2k group by g/2; + +set enable_hashagg = true; + +set enable_sort = false; + +set jit_above_cost = 0; + +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000; + +create table agg_hash_1 as +select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 + from agg_data_20k group by g%10000; + +create table agg_hash_2 as +select * from + (values (100), (300), (500)) as r(a), + lateral ( + select (g/2)::numeric as c1, + array_agg(g::numeric) as c2, + count(*) as c3 + from agg_data_2k + where g < r.a + group by g/2) as s; + +set jit_above_cost to default; + +create table agg_hash_3 as +select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 + from agg_data_2k group by g/2; + +create table agg_hash_4 as +select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 + from agg_data_2k group by g/2; + +set enable_sort = true; + +set work_mem to default; + +(select * from agg_hash_1 except select * from agg_group_1) + union all +(select * from agg_group_1 except select * from agg_hash_1); + +(select * from agg_hash_2 except select * from agg_group_2) + union all +(select * from agg_group_2 except select * from agg_hash_2); + +(select * from agg_hash_3 except select * from agg_group_3) + union all +(select * from agg_group_3 except select * from agg_hash_3); + +(select * from agg_hash_4 except select * from agg_group_4) + union all +(select * from agg_group_4 except select * from agg_hash_4); + +drop table agg_group_1; + +drop table agg_group_2; + +drop table agg_group_3; + +drop table agg_group_4; + +drop table agg_hash_1; + +drop table agg_hash_2; + +drop table agg_hash_3; + +drop table agg_hash_4; diff --git a/crates/pgt_pretty_print/tests/data/multi/alter_generic_60.sql b/crates/pgt_pretty_print/tests/data/multi/alter_generic_60.sql new file mode 100644 index 000000000..1208d56d7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/alter_generic_60.sql @@ -0,0 +1,767 @@ +CREATE FUNCTION test_opclass_options_func(internal) + RETURNS void + AS 'regresslib', 'test_opclass_options_func' + LANGUAGE C; + +SET client_min_messages TO 'warning'; + +DROP ROLE IF EXISTS regress_alter_generic_user1; + +DROP ROLE IF EXISTS regress_alter_generic_user2; + +DROP ROLE IF EXISTS regress_alter_generic_user3; + +RESET client_min_messages; + +CREATE USER regress_alter_generic_user3; + +CREATE USER regress_alter_generic_user2; + +CREATE USER regress_alter_generic_user1 IN ROLE regress_alter_generic_user3; + +CREATE SCHEMA alt_nsp1; + +CREATE SCHEMA alt_nsp2; + +GRANT ALL ON SCHEMA alt_nsp1, alt_nsp2 TO public; + +SET search_path = alt_nsp1, public; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 + 1'; + +CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 - 1'; + +CREATE AGGREGATE alt_agg1 ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 0 +); + +CREATE AGGREGATE alt_agg2 ( + sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = 0 +); + +ALTER AGGREGATE alt_func1(int) RENAME TO alt_func3; + +ALTER AGGREGATE alt_func1(int) OWNER TO regress_alter_generic_user3; + +ALTER AGGREGATE alt_func1(int) SET SCHEMA alt_nsp2; + +ALTER FUNCTION alt_func1(int) RENAME TO alt_func2; + +ALTER FUNCTION alt_func1(int) RENAME TO alt_func3; + +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user2; + +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3; + +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp1; + +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2; + +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg2; + +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg3; + +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user2; + +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3; + +ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; + +SET SESSION AUTHORIZATION regress_alter_generic_user2; + +CREATE FUNCTION alt_func1(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 + 2'; + +CREATE FUNCTION alt_func2(int) RETURNS int LANGUAGE sql + AS 'SELECT $1 - 2'; + +CREATE AGGREGATE alt_agg1 ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond = 100 +); + +CREATE AGGREGATE alt_agg2 ( + sfunc1 = int4mi, basetype = int4, stype1 = int4, initcond = -100 +); + +ALTER FUNCTION alt_func3(int) RENAME TO alt_func4; + +ALTER FUNCTION alt_func1(int) RENAME TO alt_func4; + +ALTER FUNCTION alt_func3(int) OWNER TO regress_alter_generic_user2; + +ALTER FUNCTION alt_func2(int) OWNER TO regress_alter_generic_user3; + +ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2; + +ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2; + +ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4; + +ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4; + +ALTER AGGREGATE alt_agg3(int) OWNER TO regress_alter_generic_user2; + +ALTER AGGREGATE alt_agg2(int) OWNER TO regress_alter_generic_user3; + +ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2; + +ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +SELECT n.nspname, proname, prorettype::regtype, prokind, a.rolname + FROM pg_proc p, pg_namespace n, pg_authid a + WHERE p.pronamespace = n.oid AND p.proowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, proname; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +ALTER CONVERSION alt_conv1 RENAME TO alt_conv2; + +ALTER CONVERSION alt_conv1 RENAME TO alt_conv3; + +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user2; + +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3; + +ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2; + +SET SESSION AUTHORIZATION regress_alter_generic_user2; + +CREATE CONVERSION alt_conv1 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +CREATE CONVERSION alt_conv2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +ALTER CONVERSION alt_conv3 RENAME TO alt_conv4; + +ALTER CONVERSION alt_conv1 RENAME TO alt_conv4; + +ALTER CONVERSION alt_conv3 OWNER TO regress_alter_generic_user2; + +ALTER CONVERSION alt_conv2 OWNER TO regress_alter_generic_user3; + +ALTER CONVERSION alt_conv3 SET SCHEMA alt_nsp2; + +ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +SELECT n.nspname, c.conname, a.rolname + FROM pg_conversion c, pg_namespace n, pg_authid a + WHERE c.connamespace = n.oid AND c.conowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, conname; + +CREATE FOREIGN DATA WRAPPER alt_fdw1; + +CREATE FOREIGN DATA WRAPPER alt_fdw2; + +CREATE SERVER alt_fserv1 FOREIGN DATA WRAPPER alt_fdw1; + +CREATE SERVER alt_fserv2 FOREIGN DATA WRAPPER alt_fdw2; + +ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw2; + +ALTER FOREIGN DATA WRAPPER alt_fdw1 RENAME TO alt_fdw3; + +ALTER SERVER alt_fserv1 RENAME TO alt_fserv2; + +ALTER SERVER alt_fserv1 RENAME TO alt_fserv3; + +SELECT fdwname FROM pg_foreign_data_wrapper WHERE fdwname like 'alt_fdw%'; + +SELECT srvname FROM pg_foreign_server WHERE srvname like 'alt_fserv%'; + +CREATE LANGUAGE alt_lang1 HANDLER plpgsql_call_handler; + +CREATE LANGUAGE alt_lang2 HANDLER plpgsql_call_handler; + +ALTER LANGUAGE alt_lang1 OWNER TO regress_alter_generic_user1; + +ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user2; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +ALTER LANGUAGE alt_lang1 RENAME TO alt_lang2; + +ALTER LANGUAGE alt_lang2 RENAME TO alt_lang3; + +ALTER LANGUAGE alt_lang1 RENAME TO alt_lang3; + +ALTER LANGUAGE alt_lang2 OWNER TO regress_alter_generic_user3; + +ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user2; + +ALTER LANGUAGE alt_lang3 OWNER TO regress_alter_generic_user3; + +RESET SESSION AUTHORIZATION; + +SELECT lanname, a.rolname + FROM pg_language l, pg_authid a + WHERE l.lanowner = a.oid AND l.lanname like 'alt_lang%' + ORDER BY lanname; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi ); + +CREATE OPERATOR @+@ ( leftarg = int4, rightarg = int4, procedure = int4pl ); + +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user3; + +ALTER OPERATOR @-@(int4, int4) SET SCHEMA alt_nsp2; + +SET SESSION AUTHORIZATION regress_alter_generic_user2; + +CREATE OPERATOR @-@ ( leftarg = int4, rightarg = int4, procedure = int4mi ); + +ALTER OPERATOR @+@(int4, int4) OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR @-@(int4, int4) OWNER TO regress_alter_generic_user3; + +ALTER OPERATOR @+@(int4, int4) SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +SELECT n.nspname, oprname, a.rolname, + oprleft::regtype, oprright::regtype, oprcode::regproc + FROM pg_operator o, pg_namespace n, pg_authid a + WHERE o.oprnamespace = n.oid AND o.oprowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, oprname; + +CREATE OPERATOR FAMILY alt_opf1 USING hash; + +CREATE OPERATOR FAMILY alt_opf2 USING hash; + +ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user1; + +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user1; + +CREATE OPERATOR CLASS alt_opc1 FOR TYPE uuid USING hash AS STORAGE uuid; + +CREATE OPERATOR CLASS alt_opc2 FOR TYPE uuid USING hash AS STORAGE uuid; + +ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user1; + +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user1; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf2; + +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf3; + +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3; + +ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; + +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc2; + +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc3; + +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3; + +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +CREATE OPERATOR FAMILY alt_opf1 USING hash; + +CREATE OPERATOR FAMILY alt_opf2 USING hash; + +ALTER OPERATOR FAMILY alt_opf1 USING hash OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user2; + +CREATE OPERATOR CLASS alt_opc1 FOR TYPE macaddr USING hash AS STORAGE macaddr; + +CREATE OPERATOR CLASS alt_opc2 FOR TYPE macaddr USING hash AS STORAGE macaddr; + +ALTER OPERATOR CLASS alt_opc1 USING hash OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user2; + +SET SESSION AUTHORIZATION regress_alter_generic_user2; + +ALTER OPERATOR FAMILY alt_opf3 USING hash RENAME TO alt_opf4; + +ALTER OPERATOR FAMILY alt_opf1 USING hash RENAME TO alt_opf4; + +ALTER OPERATOR FAMILY alt_opf3 USING hash OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR FAMILY alt_opf2 USING hash OWNER TO regress_alter_generic_user3; + +ALTER OPERATOR FAMILY alt_opf3 USING hash SET SCHEMA alt_nsp2; + +ALTER OPERATOR FAMILY alt_opf2 USING hash SET SCHEMA alt_nsp2; + +ALTER OPERATOR CLASS alt_opc3 USING hash RENAME TO alt_opc4; + +ALTER OPERATOR CLASS alt_opc1 USING hash RENAME TO alt_opc4; + +ALTER OPERATOR CLASS alt_opc3 USING hash OWNER TO regress_alter_generic_user2; + +ALTER OPERATOR CLASS alt_opc2 USING hash OWNER TO regress_alter_generic_user3; + +ALTER OPERATOR CLASS alt_opc3 USING hash SET SCHEMA alt_nsp2; + +ALTER OPERATOR CLASS alt_opc2 USING hash SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +SELECT nspname, opfname, amname, rolname + FROM pg_opfamily o, pg_am m, pg_namespace n, pg_authid a + WHERE o.opfmethod = m.oid AND o.opfnamespace = n.oid AND o.opfowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + AND NOT opfname LIKE 'alt_opc%' + ORDER BY nspname, opfname; + +SELECT nspname, opcname, amname, rolname + FROM pg_opclass o, pg_am m, pg_namespace n, pg_authid a + WHERE o.opcmethod = m.oid AND o.opcnamespace = n.oid AND o.opcowner = a.oid + AND n.nspname IN ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, opcname; + +BEGIN TRANSACTION; + +CREATE OPERATOR FAMILY alt_opf4 USING btree; + +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD + -- int4 vs int2 + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf4 USING btree DROP + -- int4 vs int2 + OPERATOR 1 (int4, int2) , + OPERATOR 2 (int4, int2) , + OPERATOR 3 (int4, int2) , + OPERATOR 4 (int4, int2) , + OPERATOR 5 (int4, int2) , + FUNCTION 1 (int4, int2) ; + +DROP OPERATOR FAMILY alt_opf4 USING btree; + +ROLLBACK; + +CREATE OPERATOR FAMILY alt_opf4 USING btree; + +ALTER OPERATOR FAMILY alt_opf4 USING invalid_index_method ADD OPERATOR 1 < (int4, int2); + +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 6 < (int4, int2); + +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 0 < (int4, int2); + +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 1 < ; + +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 0 btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 7 btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf4 USING btree ADD STORAGE invalid_storage; + +DROP OPERATOR FAMILY alt_opf4 USING btree; + +BEGIN TRANSACTION; + +CREATE ROLE regress_alter_generic_user5 NOSUPERUSER; + +CREATE OPERATOR FAMILY alt_opf5 USING btree; + +SET ROLE regress_alter_generic_user5; + +ALTER OPERATOR FAMILY alt_opf5 USING btree ADD OPERATOR 1 < (int4, int2), FUNCTION 1 btint42cmp(int4, int2); + +RESET ROLE; + +DROP OPERATOR FAMILY alt_opf5 USING btree; + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE ROLE regress_alter_generic_user6; + +CREATE SCHEMA alt_nsp6; + +REVOKE ALL ON SCHEMA alt_nsp6 FROM regress_alter_generic_user6; + +CREATE OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree; + +SET ROLE regress_alter_generic_user6; + +ALTER OPERATOR FAMILY alt_nsp6.alt_opf6 USING btree ADD OPERATOR 1 < (int4, int2); + +ROLLBACK; + +CREATE OPERATOR FAMILY alt_opf7 USING btree; + +ALTER OPERATOR FAMILY alt_opf7 USING btree ADD OPERATOR 1 < (int4, int2); + +ALTER OPERATOR FAMILY alt_opf7 USING btree DROP OPERATOR 1 (int4, int2, int8); + +DROP OPERATOR FAMILY alt_opf7 USING btree; + +CREATE OPERATOR FAMILY alt_opf8 USING btree; + +ALTER OPERATOR FAMILY alt_opf8 USING btree ADD OPERATOR 1 < (int4, int4); + +DROP OPERATOR FAMILY alt_opf8 USING btree; + +CREATE OPERATOR FAMILY alt_opf9 USING gist; + +ALTER OPERATOR FAMILY alt_opf9 USING gist ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops; + +DROP OPERATOR FAMILY alt_opf9 USING gist; + +CREATE OPERATOR FAMILY alt_opf10 USING btree; + +ALTER OPERATOR FAMILY alt_opf10 USING btree ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops; + +DROP OPERATOR FAMILY alt_opf10 USING btree; + +CREATE OPERATOR FAMILY alt_opf11 USING gist; + +ALTER OPERATOR FAMILY alt_opf11 USING gist ADD OPERATOR 1 < (int4, int4) FOR ORDER BY float_ops; + +ALTER OPERATOR FAMILY alt_opf11 USING gist DROP OPERATOR 1 (int4, int4); + +DROP OPERATOR FAMILY alt_opf11 USING gist; + +BEGIN TRANSACTION; + +CREATE OPERATOR FAMILY alt_opf12 USING btree; + +CREATE FUNCTION fn_opf12 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; + +ALTER OPERATOR FAMILY alt_opf12 USING btree ADD FUNCTION 1 fn_opf12(int4, int2); + +DROP OPERATOR FAMILY alt_opf12 USING btree; + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OPERATOR FAMILY alt_opf13 USING hash; + +CREATE FUNCTION fn_opf13 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; + +ALTER OPERATOR FAMILY alt_opf13 USING hash ADD FUNCTION 1 fn_opf13(int4); + +DROP OPERATOR FAMILY alt_opf13 USING hash; + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OPERATOR FAMILY alt_opf14 USING btree; + +CREATE FUNCTION fn_opf14 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; + +ALTER OPERATOR FAMILY alt_opf14 USING btree ADD FUNCTION 1 fn_opf14(int4); + +DROP OPERATOR FAMILY alt_opf14 USING btree; + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OPERATOR FAMILY alt_opf15 USING hash; + +CREATE FUNCTION fn_opf15 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; + +ALTER OPERATOR FAMILY alt_opf15 USING hash ADD FUNCTION 1 fn_opf15(int4, int2); + +DROP OPERATOR FAMILY alt_opf15 USING hash; + +ROLLBACK; + +CREATE OPERATOR FAMILY alt_opf16 USING gist; + +ALTER OPERATOR FAMILY alt_opf16 USING gist ADD FUNCTION 1 btint42cmp(int4, int2); + +DROP OPERATOR FAMILY alt_opf16 USING gist; + +CREATE OPERATOR FAMILY alt_opf17 USING btree; + +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4), OPERATOR 1 < (int4, int4); + +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4); + +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int4); + +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) , + FUNCTION 1 btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf17 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2); + +DROP OPERATOR FAMILY alt_opf17 USING btree; + +CREATE OPERATOR FAMILY alt_opf18 USING btree; + +ALTER OPERATOR FAMILY alt_opf18 USING btree DROP OPERATOR 1 (int4, int4); + +ALTER OPERATOR FAMILY alt_opf18 USING btree ADD + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf18 USING btree + ADD FUNCTION 4 (int4, int2) btequalimage(oid); + +ALTER OPERATOR FAMILY alt_opf18 USING btree + ADD FUNCTION 6 (int4, int2) btint4skipsupport(internal); + +ALTER OPERATOR FAMILY alt_opf18 USING btree DROP FUNCTION 2 (int4, int4); + +DROP OPERATOR FAMILY alt_opf18 USING btree; + +CREATE OPERATOR FAMILY alt_opf19 USING btree; + +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 test_opclass_options_func(internal, text[], bool); + +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4, int2) btint42cmp(int4, int2); + +ALTER OPERATOR FAMILY alt_opf19 USING btree ADD FUNCTION 5 (int4) test_opclass_options_func(internal); + +ALTER OPERATOR FAMILY alt_opf19 USING btree DROP FUNCTION 5 (int4, int4); + +DROP OPERATOR FAMILY alt_opf19 USING btree; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +CREATE TABLE alt_regress_1 (a INTEGER, b INTEGER); + +CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_1; + +CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_1; + +ALTER STATISTICS alt_stat1 RENAME TO alt_stat2; + +ALTER STATISTICS alt_stat1 RENAME TO alt_stat3; + +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user2; + +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3; + +ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2; + +SET SESSION AUTHORIZATION regress_alter_generic_user2; + +CREATE TABLE alt_regress_2 (a INTEGER, b INTEGER); + +CREATE STATISTICS alt_stat1 ON a, b FROM alt_regress_2; + +CREATE STATISTICS alt_stat2 ON a, b FROM alt_regress_2; + +ALTER STATISTICS alt_stat3 RENAME TO alt_stat4; + +ALTER STATISTICS alt_stat1 RENAME TO alt_stat4; + +ALTER STATISTICS alt_stat3 OWNER TO regress_alter_generic_user2; + +ALTER STATISTICS alt_stat2 OWNER TO regress_alter_generic_user3; + +ALTER STATISTICS alt_stat3 SET SCHEMA alt_nsp2; + +ALTER STATISTICS alt_stat2 SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +SELECT nspname, stxname, rolname + FROM pg_statistic_ext s, pg_namespace n, pg_authid a + WHERE s.stxnamespace = n.oid AND s.stxowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, stxname; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple); + +CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple); + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict2; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict3; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user2; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2; + +SET SESSION AUTHORIZATION regress_alter_generic_user2; + +CREATE TEXT SEARCH DICTIONARY alt_ts_dict1 (template=simple); + +CREATE TEXT SEARCH DICTIONARY alt_ts_dict2 (template=simple); + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 RENAME TO alt_ts_dict4; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 RENAME TO alt_ts_dict4; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 OWNER TO regress_alter_generic_user2; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 OWNER TO regress_alter_generic_user3; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 SET SCHEMA alt_nsp2; + +ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +SELECT nspname, dictname, rolname + FROM pg_ts_dict t, pg_namespace n, pg_authid a + WHERE t.dictnamespace = n.oid AND t.dictowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, dictname; + +SET SESSION AUTHORIZATION regress_alter_generic_user1; + +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english); + +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english); + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf2; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf3; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user2; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2; + +SET SESSION AUTHORIZATION regress_alter_generic_user2; + +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf1 (copy=english); + +CREATE TEXT SEARCH CONFIGURATION alt_ts_conf2 (copy=english); + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 RENAME TO alt_ts_conf4; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 RENAME TO alt_ts_conf4; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 OWNER TO regress_alter_generic_user2; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 OWNER TO regress_alter_generic_user3; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 SET SCHEMA alt_nsp2; + +ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2; + +RESET SESSION AUTHORIZATION; + +SELECT nspname, cfgname, rolname + FROM pg_ts_config t, pg_namespace n, pg_authid a + WHERE t.cfgnamespace = n.oid AND t.cfgowner = a.oid + AND n.nspname in ('alt_nsp1', 'alt_nsp2') + ORDER BY nspname, cfgname; + +CREATE TEXT SEARCH TEMPLATE alt_ts_temp1 (lexize=dsimple_lexize); + +CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize); + +ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp2; + +ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp3; + +ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2; + +CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize); + +ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2; + +CREATE TEXT SEARCH TEMPLATE tstemp_case ("Init" = init_function); + +SELECT nspname, tmplname + FROM pg_ts_template t, pg_namespace n + WHERE t.tmplnamespace = n.oid AND nspname like 'alt_nsp%' + ORDER BY nspname, tmplname; + +CREATE TEXT SEARCH PARSER alt_ts_prs1 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype); + +CREATE TEXT SEARCH PARSER alt_ts_prs2 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype); + +ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs2; + +ALTER TEXT SEARCH PARSER alt_ts_prs1 RENAME TO alt_ts_prs3; + +ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2; + +CREATE TEXT SEARCH PARSER alt_ts_prs2 + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype); + +ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2; + +CREATE TEXT SEARCH PARSER tspars_case ("Start" = start_function); + +SELECT nspname, prsname + FROM pg_ts_parser t, pg_namespace n + WHERE t.prsnamespace = n.oid AND nspname like 'alt_nsp%' + ORDER BY nspname, prsname; + +DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE; + +DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE; + +DROP LANGUAGE alt_lang2 CASCADE; + +DROP LANGUAGE alt_lang3 CASCADE; + +DROP SCHEMA alt_nsp1 CASCADE; + +DROP SCHEMA alt_nsp2 CASCADE; + +DROP USER regress_alter_generic_user1; + +DROP USER regress_alter_generic_user2; + +DROP USER regress_alter_generic_user3; diff --git a/crates/pgt_pretty_print/tests/data/multi/alter_operator_60.sql b/crates/pgt_pretty_print/tests/data/multi/alter_operator_60.sql new file mode 100644 index 000000000..14c02d2ad --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/alter_operator_60.sql @@ -0,0 +1,206 @@ +CREATE FUNCTION alter_op_test_fn(boolean, boolean) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE; + +CREATE FUNCTION customcontsel(internal, oid, internal, integer) +RETURNS float8 AS 'contsel' LANGUAGE internal STABLE STRICT; + +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn, + COMMUTATOR = ===, + NEGATOR = !==, + RESTRICT = customcontsel, + JOIN = contjoinsel, + HASHES, MERGES +); + +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1; + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE); + +ALTER OPERATOR === (boolean, boolean) SET (JOIN = NONE); + +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype; + +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1; + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = contsel); + +ALTER OPERATOR === (boolean, boolean) SET (JOIN = contjoinsel); + +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype; + +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1; + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE, JOIN = NONE); + +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype; + +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1; + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = customcontsel, JOIN = contjoinsel); + +SELECT oprrest, oprjoin FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'boolean'::regtype; + +SELECT pg_describe_object(refclassid,refobjid,refobjsubid) as ref, deptype +FROM pg_depend +WHERE classid = 'pg_operator'::regclass AND + objid = '===(bool,bool)'::regoperator +ORDER BY 1; + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = non_existent_func); + +ALTER OPERATOR === (boolean, boolean) SET (JOIN = non_existent_func); + +ALTER OPERATOR & (bit, bit) SET ("Restrict" = _int_contsel, "Join" = _int_contjoinsel); + +CREATE USER regress_alter_op_user; + +SET SESSION AUTHORIZATION regress_alter_op_user; + +ALTER OPERATOR === (boolean, boolean) SET (RESTRICT = NONE); + +RESET SESSION AUTHORIZATION; + +CREATE FUNCTION alter_op_test_fn_bool_real(boolean, real) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE; + +CREATE FUNCTION alter_op_test_fn_real_bool(real, boolean) +RETURNS boolean AS $$ SELECT NULL::BOOLEAN; $$ LANGUAGE sql IMMUTABLE; + +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +); + +CREATE OPERATOR ==== ( + LEFTARG = real, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn_real_bool +); + +CREATE OPERATOR !==== ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +); + +ALTER OPERATOR === (boolean, real) SET (MERGES = false); + +ALTER OPERATOR === (boolean, real) SET (HASHES = false); + +ALTER OPERATOR === (boolean, real) SET (MERGES); + +ALTER OPERATOR === (boolean, real) SET (HASHES); + +SELECT oprcanmerge, oprcanhash +FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype; + +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = ====); + +SELECT op.oprname AS operator_name, com.oprname AS commutator_name, + com.oprcode AS commutator_func + FROM pg_operator op + INNER JOIN pg_operator com ON (op.oid = com.oprcom AND op.oprcom = com.oid) + WHERE op.oprname = '===' + AND op.oprleft = 'boolean'::regtype AND op.oprright = 'real'::regtype; + +ALTER OPERATOR === (boolean, real) SET (NEGATOR = ===); + +ALTER OPERATOR === (boolean, real) SET (NEGATOR = !====); + +SELECT op.oprname AS operator_name, neg.oprname AS negator_name, + neg.oprcode AS negator_func + FROM pg_operator op + INNER JOIN pg_operator neg ON (op.oid = neg.oprnegate AND op.oprnegate = neg.oid) + WHERE op.oprname = '===' + AND op.oprleft = 'boolean'::regtype AND op.oprright = 'real'::regtype; + +ALTER OPERATOR === (boolean, real) SET (NEGATOR = !====); + +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = ====); + +ALTER OPERATOR === (boolean, real) SET (MERGES); + +ALTER OPERATOR === (boolean, real) SET (HASHES); + +SELECT oprcanmerge, oprcanhash, + pg_describe_object('pg_operator'::regclass, oprcom, 0) AS commutator, + pg_describe_object('pg_operator'::regclass, oprnegate, 0) AS negator + FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype; + +CREATE OPERATOR @= ( + LEFTARG = real, + RIGHTARG = boolean, + PROCEDURE = alter_op_test_fn_real_bool +); + +CREATE OPERATOR @!= ( + LEFTARG = boolean, + RIGHTARG = real, + PROCEDURE = alter_op_test_fn_bool_real +); + +ALTER OPERATOR === (boolean, real) SET (COMMUTATOR = @=); + +ALTER OPERATOR === (boolean, real) SET (NEGATOR = @!=); + +ALTER OPERATOR === (boolean, real) SET (MERGES = false); + +ALTER OPERATOR === (boolean, real) SET (HASHES = false); + +ALTER OPERATOR @=(real, boolean) SET (COMMUTATOR = ===); + +ALTER OPERATOR @!=(boolean, real) SET (NEGATOR = ===); + +SELECT oprcanmerge, oprcanhash, + pg_describe_object('pg_operator'::regclass, oprcom, 0) AS commutator, + pg_describe_object('pg_operator'::regclass, oprnegate, 0) AS negator + FROM pg_operator WHERE oprname = '===' + AND oprleft = 'boolean'::regtype AND oprright = 'real'::regtype; + +DROP USER regress_alter_op_user; + +DROP OPERATOR === (boolean, boolean); + +DROP OPERATOR === (boolean, real); + +DROP OPERATOR ==== (real, boolean); + +DROP OPERATOR !==== (boolean, real); + +DROP OPERATOR @= (real, boolean); + +DROP OPERATOR @!= (boolean, real); + +DROP FUNCTION customcontsel(internal, oid, internal, integer); + +DROP FUNCTION alter_op_test_fn(boolean, boolean); + +DROP FUNCTION alter_op_test_fn_bool_real(boolean, real); + +DROP FUNCTION alter_op_test_fn_real_bool(real, boolean); diff --git a/crates/pgt_pretty_print/tests/data/multi/alter_table_60.sql b/crates/pgt_pretty_print/tests/data/multi/alter_table_60.sql new file mode 100644 index 000000000..ef179a3f1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/alter_table_60.sql @@ -0,0 +1,1214 @@ +SET client_min_messages TO 'warning'; + +DROP ROLE IF EXISTS regress_alter_table_user1; + +RESET client_min_messages; + +CREATE USER regress_alter_table_user1; + +CREATE TABLE attmp (initial int4); + +COMMENT ON TABLE attmp_wrong IS 'table comment'; + +COMMENT ON TABLE attmp IS 'table comment'; + +COMMENT ON TABLE attmp IS NULL; + +ALTER TABLE attmp ADD COLUMN xmin integer; + +ALTER TABLE attmp ADD COLUMN a int4 default 3; + +ALTER TABLE attmp ADD COLUMN b name; + +ALTER TABLE attmp ADD COLUMN c text; + +ALTER TABLE attmp ADD COLUMN d float8; + +ALTER TABLE attmp ADD COLUMN e float4; + +ALTER TABLE attmp ADD COLUMN f int2; + +ALTER TABLE attmp ADD COLUMN g polygon; + +ALTER TABLE attmp ADD COLUMN i char; + +ALTER TABLE attmp ADD COLUMN k int4; + +ALTER TABLE attmp ADD COLUMN l tid; + +ALTER TABLE attmp ADD COLUMN m xid; + +ALTER TABLE attmp ADD COLUMN n oidvector; + +ALTER TABLE attmp ADD COLUMN p boolean; + +ALTER TABLE attmp ADD COLUMN q point; + +ALTER TABLE attmp ADD COLUMN r lseg; + +ALTER TABLE attmp ADD COLUMN s path; + +ALTER TABLE attmp ADD COLUMN t box; + +ALTER TABLE attmp ADD COLUMN v timestamp; + +ALTER TABLE attmp ADD COLUMN w interval; + +ALTER TABLE attmp ADD COLUMN x float8[]; + +ALTER TABLE attmp ADD COLUMN y float4[]; + +ALTER TABLE attmp ADD COLUMN z int2[]; + +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, + v, w, x, y, z) + VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', + 'c', + 314159, '(1,1)', '512', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', + 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}'); + +SELECT * FROM attmp; + +DROP TABLE attmp; + +CREATE TABLE attmp ( + initial int4 +); + +ALTER TABLE attmp ADD COLUMN a int4; + +ALTER TABLE attmp ADD COLUMN b name; + +ALTER TABLE attmp ADD COLUMN c text; + +ALTER TABLE attmp ADD COLUMN d float8; + +ALTER TABLE attmp ADD COLUMN e float4; + +ALTER TABLE attmp ADD COLUMN f int2; + +ALTER TABLE attmp ADD COLUMN g polygon; + +ALTER TABLE attmp ADD COLUMN i char; + +ALTER TABLE attmp ADD COLUMN k int4; + +ALTER TABLE attmp ADD COLUMN l tid; + +ALTER TABLE attmp ADD COLUMN m xid; + +ALTER TABLE attmp ADD COLUMN n oidvector; + +ALTER TABLE attmp ADD COLUMN p boolean; + +ALTER TABLE attmp ADD COLUMN q point; + +ALTER TABLE attmp ADD COLUMN r lseg; + +ALTER TABLE attmp ADD COLUMN s path; + +ALTER TABLE attmp ADD COLUMN t box; + +ALTER TABLE attmp ADD COLUMN v timestamp; + +ALTER TABLE attmp ADD COLUMN w interval; + +ALTER TABLE attmp ADD COLUMN x float8[]; + +ALTER TABLE attmp ADD COLUMN y float4[]; + +ALTER TABLE attmp ADD COLUMN z int2[]; + +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, + v, w, x, y, z) + VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', + 'c', + 314159, '(1,1)', '512', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', + 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}'); + +SELECT * FROM attmp; + +CREATE INDEX attmp_idx ON attmp (a, (d + e), b); + +ALTER INDEX attmp_idx ALTER COLUMN 1 SET STATISTICS 1000; + +ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000; + +ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000; + +ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000; + +ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS -1; + +DROP TABLE attmp; + +CREATE TABLE attmp (regtable int); + +CREATE TEMP TABLE attmp (attmptable int); + +ALTER TABLE attmp RENAME TO attmp_new; + +SELECT * FROM attmp; + +SELECT * FROM attmp_new; + +ALTER TABLE attmp RENAME TO attmp_new2; + +SELECT * FROM attmp; + +SELECT * FROM attmp_new; + +SELECT * FROM attmp_new2; + +DROP TABLE attmp_new; + +DROP TABLE attmp_new2; + +CREATE TABLE part_attmp (a int primary key) partition by range (a); + +CREATE TABLE part_attmp1 PARTITION OF part_attmp FOR VALUES FROM (0) TO (100); + +ALTER INDEX part_attmp_pkey RENAME TO part_attmp_index; + +ALTER INDEX part_attmp1_pkey RENAME TO part_attmp1_index; + +ALTER TABLE part_attmp RENAME TO part_at2tmp; + +ALTER TABLE part_attmp1 RENAME TO part_at2tmp1; + +SET ROLE regress_alter_table_user1; + +ALTER INDEX part_attmp_index RENAME TO fail; + +ALTER INDEX part_attmp1_index RENAME TO fail; + +ALTER TABLE part_at2tmp RENAME TO fail; + +ALTER TABLE part_at2tmp1 RENAME TO fail; + +RESET ROLE; + +DROP TABLE part_at2tmp; + +CREATE TABLE attmp_array (id int); + +CREATE TABLE attmp_array2 (id int); + +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype; + +SELECT typname FROM pg_type WHERE oid = 'attmp_array2[]'::regtype; + +ALTER TABLE attmp_array2 RENAME TO _attmp_array; + +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype; + +SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype; + +DROP TABLE _attmp_array; + +DROP TABLE attmp_array; + +CREATE TABLE attmp_array (id int); + +SELECT typname FROM pg_type WHERE oid = 'attmp_array[]'::regtype; + +ALTER TABLE attmp_array RENAME TO _attmp_array; + +SELECT typname FROM pg_type WHERE oid = '_attmp_array[]'::regtype; + +DROP TABLE _attmp_array; + +ALTER INDEX IF EXISTS __onek_unique1 RENAME TO attmp_onek_unique1; + +ALTER INDEX IF EXISTS __attmp_onek_unique1 RENAME TO onek_unique1; + +ALTER INDEX onek_unique1 RENAME TO attmp_onek_unique1; + +ALTER INDEX attmp_onek_unique1 RENAME TO onek_unique1; + +SET ROLE regress_alter_table_user1; + +ALTER INDEX onek_unique1 RENAME TO fail; + +RESET ROLE; + +CREATE TABLE alter_idx_rename_test (a INT); + +CREATE INDEX alter_idx_rename_test_idx ON alter_idx_rename_test (a); + +CREATE TABLE alter_idx_rename_test_parted (a INT) PARTITION BY LIST (a); + +CREATE INDEX alter_idx_rename_test_parted_idx ON alter_idx_rename_test_parted (a); + +BEGIN; + +ALTER INDEX alter_idx_rename_test RENAME TO alter_idx_rename_test_2; + +ALTER INDEX alter_idx_rename_test_parted RENAME TO alter_idx_rename_test_parted_2; + +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C"; + +COMMIT; + +BEGIN; + +ALTER INDEX alter_idx_rename_test_idx RENAME TO alter_idx_rename_test_idx_2; + +ALTER INDEX alter_idx_rename_test_parted_idx RENAME TO alter_idx_rename_test_parted_idx_2; + +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C"; + +COMMIT; + +BEGIN; + +ALTER TABLE alter_idx_rename_test_idx_2 RENAME TO alter_idx_rename_test_idx_3; + +ALTER TABLE alter_idx_rename_test_parted_idx_2 RENAME TO alter_idx_rename_test_parted_idx_3; + +SELECT relation::regclass, mode FROM pg_locks +WHERE pid = pg_backend_pid() AND locktype = 'relation' + AND relation::regclass::text LIKE 'alter\_idx%' +ORDER BY relation::regclass::text COLLATE "C"; + +COMMIT; + +DROP TABLE alter_idx_rename_test_2; + +CREATE VIEW attmp_view (unique1) AS SELECT unique1 FROM tenk1; + +ALTER TABLE attmp_view RENAME TO attmp_view_new; + +SET ROLE regress_alter_table_user1; + +ALTER VIEW attmp_view_new RENAME TO fail; + +RESET ROLE; + +set enable_seqscan to off; + +set enable_bitmapscan to off; + +SELECT unique1 FROM tenk1 WHERE unique1 < 5; + +reset enable_seqscan; + +reset enable_bitmapscan; + +DROP VIEW attmp_view_new; + +alter table stud_emp rename to pg_toast_stud_emp; + +alter table pg_toast_stud_emp rename to stud_emp; + +ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1); + +ALTER INDEX onek_unique1_constraint RENAME TO onek_unique1_constraint_foo; + +ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo; + +ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= 0); + +ALTER TABLE onek RENAME CONSTRAINT onek_check_constraint TO onek_check_constraint_foo; + +ALTER TABLE onek DROP CONSTRAINT onek_check_constraint_foo; + +ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1); + +DROP INDEX onek_unique1_constraint; + +ALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo; + +DROP INDEX onek_unique1_constraint_foo; + +ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo; + +CREATE TABLE constraint_rename_test (a int CONSTRAINT con1 CHECK (a > 0), b int, c int); + +CREATE TABLE constraint_rename_test2 (a int CONSTRAINT con1 CHECK (a > 0), d int) INHERITS (constraint_rename_test); + +ALTER TABLE constraint_rename_test2 RENAME CONSTRAINT con1 TO con1foo; + +ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con1 TO con1foo; + +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con1 TO con1foo; + +ALTER TABLE constraint_rename_test ADD CONSTRAINT con2 CHECK (b > 0) NO INHERIT; + +ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con2 TO con2foo; + +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con2foo TO con2bar; + +ALTER TABLE constraint_rename_test ADD CONSTRAINT con3 PRIMARY KEY (a); + +ALTER TABLE constraint_rename_test RENAME CONSTRAINT con3 TO con3foo; + +DROP TABLE constraint_rename_test2; + +DROP TABLE constraint_rename_test; + +ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; + +ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a); + +CREATE TABLE constraint_rename_cache (a int, + CONSTRAINT chk_a CHECK (a > 0), + PRIMARY KEY (a)); + +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT chk_a TO chk_a_new; + +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT constraint_rename_cache_pkey TO constraint_rename_pkey_new; + +CREATE TABLE like_constraint_rename_cache + (LIKE constraint_rename_cache INCLUDING ALL); + +DROP TABLE constraint_rename_cache; + +DROP TABLE like_constraint_rename_cache; + +CREATE TABLE attmp2 (a int primary key); + +CREATE TABLE attmp3 (a int, b int); + +CREATE TABLE attmp4 (a int, b int, unique(a,b)); + +CREATE TABLE attmp5 (a int, b int); + +INSERT INTO attmp2 values (1); + +INSERT INTO attmp2 values (2); + +INSERT INTO attmp2 values (3); + +INSERT INTO attmp2 values (4); + +INSERT INTO attmp3 values (1,10); + +INSERT INTO attmp3 values (1,20); + +INSERT INTO attmp3 values (5,50); + +ALTER TABLE attmp3 add constraint attmpconstr foreign key(c) references attmp2 match full; + +ALTER TABLE attmp3 add constraint attmpconstr foreign key(a) references attmp2(b) match full; + +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full; + +DELETE FROM attmp3 where a=5; + +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full; + +ALTER TABLE attmp3 drop constraint attmpconstr; + +INSERT INTO attmp3 values (5,50); + +ALTER TABLE attmp3 add constraint attmpconstr foreign key (a) references attmp2 match full NOT VALID; + +ALTER TABLE attmp3 validate constraint attmpconstr; + +DELETE FROM attmp3 where a=5; + +ALTER TABLE attmp3 validate constraint attmpconstr; + +ALTER TABLE attmp3 validate constraint attmpconstr; + +ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); + +ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; + +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; + +DELETE FROM attmp3 WHERE NOT b > 10; + +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; + +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; + +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten_not_enforced; + +select * from attmp3; + +CREATE TABLE attmp6 () INHERITS (attmp3); + +CREATE TABLE attmp7 () INHERITS (attmp3); + +INSERT INTO attmp6 VALUES (6, 30), (7, 16); + +ALTER TABLE attmp3 ADD CONSTRAINT b_le_20 CHECK (b <= 20) NOT VALID; + +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; + +DELETE FROM attmp6 WHERE b > 20; + +ALTER TABLE attmp3 VALIDATE CONSTRAINT b_le_20; + +CREATE FUNCTION boo(int) RETURNS int IMMUTABLE STRICT LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'boo: %', $1; RETURN $1; END; $$; + +INSERT INTO attmp7 VALUES (8, 18); + +ALTER TABLE attmp7 ADD CONSTRAINT identity CHECK (b = boo(b)); + +ALTER TABLE attmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID; + +ALTER TABLE attmp3 VALIDATE CONSTRAINT identity; + +create table parent_noinh_convalid (a int); + +create table child_noinh_convalid () inherits (parent_noinh_convalid); + +insert into parent_noinh_convalid values (1); + +insert into child_noinh_convalid values (1); + +alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid; + +alter table parent_noinh_convalid validate constraint check_a_is_2; + +delete from only parent_noinh_convalid; + +alter table parent_noinh_convalid validate constraint check_a_is_2; + +select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid'::regclass and conname = 'check_a_is_2'; + +drop table parent_noinh_convalid, child_noinh_convalid; + +ALTER TABLE attmp5 add constraint attmpconstr foreign key(a) references attmp4(a) match full; + +DROP TABLE attmp7; + +DROP TABLE attmp6; + +DROP TABLE attmp5; + +DROP TABLE attmp4; + +DROP TABLE attmp3; + +DROP TABLE attmp2; + +set constraint_exclusion TO 'partition'; + +create table nv_parent (d date, check (false) no inherit not valid); + +create table nv_child_2010 () inherits (nv_parent); + +create table nv_child_2011 () inherits (nv_parent); + +alter table nv_child_2010 add check (d between '2010-01-01'::date and '2010-12-31'::date) not valid; + +alter table nv_child_2011 add check (d between '2011-01-01'::date and '2011-12-31'::date) not valid; + +select * from nv_parent where d between '2011-08-01' and '2011-08-31'; + +create table nv_child_2009 (check (d between '2009-01-01'::date and '2009-12-31'::date)) inherits (nv_parent); + +select * from nv_parent where d between '2011-08-01'::date and '2011-08-31'::date; + +select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date; + +alter table nv_child_2011 VALIDATE CONSTRAINT nv_child_2011_d_check; + +select * from nv_parent where d between '2009-08-01'::date and '2009-08-31'::date; + +alter table nv_parent add check (d between '2001-01-01'::date and '2099-12-31'::date) not valid; + +CREATE TEMP TABLE PKTABLE (ptest1 int PRIMARY KEY); + +INSERT INTO PKTABLE VALUES(42); + +CREATE TEMP TABLE FKTABLE (ftest1 inet); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1); + +DROP TABLE FKTABLE; + +CREATE TEMP TABLE FKTABLE (ftest1 int8); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; + +INSERT INTO FKTABLE VALUES(42); + +INSERT INTO FKTABLE VALUES(43); + +DROP TABLE FKTABLE; + +CREATE TEMP TABLE FKTABLE (ftest1 numeric); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TEMP TABLE PKTABLE (ptest1 numeric PRIMARY KEY); + +INSERT INTO PKTABLE VALUES(42); + +CREATE TEMP TABLE FKTABLE (ftest1 int); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; + +INSERT INTO FKTABLE VALUES(42); + +INSERT INTO FKTABLE VALUES(43); + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet, + PRIMARY KEY(ptest1, ptest2)); + +CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable; + +DROP TABLE FKTABLE; + +CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) + references pktable(ptest1, ptest2); + +DROP TABLE FKTABLE; + +CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) + references pktable(ptest2, ptest1); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1) + references pktable(ptest1, ptest2); + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TEMP TABLE PKTABLE (ptest1 int primary key); + +CREATE TEMP TABLE FKTABLE (ftest1 int); + +ALTER TABLE FKTABLE ADD CONSTRAINT fknd FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE; + +ALTER TABLE FKTABLE ADD CONSTRAINT fkdd FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE FKTABLE ADD CONSTRAINT fkdi FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY IMMEDIATE; + +ALTER TABLE FKTABLE ADD CONSTRAINT fknd2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE FKTABLE ALTER CONSTRAINT fknd2 NOT DEFERRABLE; + +ALTER TABLE FKTABLE ADD CONSTRAINT fkdd2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE; + +ALTER TABLE FKTABLE ALTER CONSTRAINT fkdd2 DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE FKTABLE ADD CONSTRAINT fkdi2 FOREIGN KEY(ftest1) REFERENCES pktable + ON DELETE CASCADE ON UPDATE NO ACTION NOT DEFERRABLE; + +ALTER TABLE FKTABLE ALTER CONSTRAINT fkdi2 DEFERRABLE INITIALLY IMMEDIATE; + +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred +FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint +WHERE tgrelid = 'pktable'::regclass +ORDER BY 1,2,3; + +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred +FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint +WHERE tgrelid = 'fktable'::regclass +ORDER BY 1,2,3; + +create table atacc1 ( test int ); + +alter table atacc1 add constraint atacc_test1 check (test>3); + +insert into atacc1 (test) values (2); + +insert into atacc1 (test) values (4); + +drop table atacc1; + +create table atacc1 ( test int ); + +insert into atacc1 (test) values (2); + +alter table atacc1 add constraint atacc_test1 check (test>3); + +insert into atacc1 (test) values (4); + +drop table atacc1; + +create table atacc1 ( test int ); + +alter table atacc1 add constraint atacc_test1 check (test1>3); + +drop table atacc1; + +create table atacc1 ( test int, test2 int, test3 int); + +alter table atacc1 add constraint atacc_test1 check (test+test23), test2 int); + +alter table atacc1 add check (test2>test); + +insert into atacc1 (test2, test) values (3, 4); + +drop table atacc1; + +create table atacc1 (test int); + +create table atacc2 (test2 int); + +create table atacc3 (test3 int) inherits (atacc1, atacc2); + +alter table atacc2 add constraint foo check (test2>0); + +insert into atacc2 (test2) values (-3); + +insert into atacc2 (test2) values (3); + +insert into atacc3 (test2) values (-3); + +insert into atacc3 (test2) values (3); + +drop table atacc3; + +drop table atacc2; + +drop table atacc1; + +create table atacc1 (test int); + +create table atacc2 (test2 int); + +create table atacc3 (test3 int) inherits (atacc1, atacc2); + +alter table atacc3 no inherit atacc2; + +alter table atacc3 no inherit atacc2; + +insert into atacc3 (test2) values (3); + +select test2 from atacc2; + +alter table atacc2 add constraint foo check (test2>0); + +alter table atacc3 inherit atacc2; + +alter table atacc3 rename test2 to testx; + +alter table atacc3 inherit atacc2; + +alter table atacc3 add test2 bool; + +alter table atacc3 inherit atacc2; + +alter table atacc3 drop test2; + +alter table atacc3 add test2 int; + +update atacc3 set test2 = 4 where test2 is null; + +alter table atacc3 add constraint foo check (test2>0); + +alter table atacc3 inherit atacc2; + +alter table atacc3 inherit atacc2; + +alter table atacc2 inherit atacc3; + +alter table atacc2 inherit atacc2; + +select test2 from atacc2; + +drop table atacc2 cascade; + +drop table atacc1; + +create table atacc1 (test int); + +create table atacc2 (test2 int) inherits (atacc1); + +alter table atacc1 add constraint foo check (test>0) no inherit; + +insert into atacc2 (test) values (-3); + +insert into atacc1 (test) values (-3); + +insert into atacc1 (test) values (3); + +alter table atacc2 add constraint foo check (test>0) no inherit; + +drop table atacc2; + +drop table atacc1; + +create table atacc1 ( test int ) ; + +alter table atacc1 add constraint atacc_test1 unique (test); + +insert into atacc1 (test) values (2); + +insert into atacc1 (test) values (2); + +insert into atacc1 (test) values (4); + +alter table atacc1 alter column test type integer using 0; + +drop table atacc1; + +create table atacc1 ( test int ); + +insert into atacc1 (test) values (2); + +insert into atacc1 (test) values (2); + +alter table atacc1 add constraint atacc_test1 unique (test); + +insert into atacc1 (test) values (3); + +drop table atacc1; + +create table atacc1 ( test int ); + +alter table atacc1 add constraint atacc_test1 unique (test1); + +drop table atacc1; + +create table atacc1 ( test int, test2 int); + +alter table atacc1 add constraint atacc_test1 unique (test, test2); + +insert into atacc1 (test,test2) values (4,4); + +insert into atacc1 (test,test2) values (4,4); + +insert into atacc1 (test,test2) values (4,5); + +insert into atacc1 (test,test2) values (5,4); + +insert into atacc1 (test,test2) values (5,5); + +drop table atacc1; + +create table atacc1 (test int, test2 int, unique(test)); + +alter table atacc1 add unique (test2); + +insert into atacc1 (test2, test) values (3, 3); + +insert into atacc1 (test2, test) values (2, 3); + +drop table atacc1; + +create table atacc1 ( id serial, test int) ; + +alter table atacc1 add constraint atacc_test1 primary key (test); + +insert into atacc1 (test) values (2); + +insert into atacc1 (test) values (2); + +insert into atacc1 (test) values (4); + +insert into atacc1 (test) values(NULL); + +alter table atacc1 add constraint atacc_oid1 primary key(id); + +alter table atacc1 drop constraint atacc_test1 restrict; + +alter table atacc1 add constraint atacc_oid1 primary key(id); + +drop table atacc1; + +create table atacc1 ( test int ); + +insert into atacc1 (test) values (2); + +insert into atacc1 (test) values (2); + +alter table atacc1 add constraint atacc_test1 primary key (test); + +insert into atacc1 (test) values (3); + +drop table atacc1; + +create table atacc1 ( test int ); + +insert into atacc1 (test) values (NULL); + +alter table atacc1 add constraint atacc_test1 primary key (test); + +insert into atacc1 (test) values (3); + +drop table atacc1; + +create table atacc1 ( test int ); + +alter table atacc1 add constraint atacc_test1 primary key (test1); + +drop table atacc1; + +create table atacc1 ( test int ); + +insert into atacc1 (test) values (0); + +alter table atacc1 add column test2 int primary key; + +alter table atacc1 add column test2 int default 0 primary key; + +drop table atacc1; + +create table atacc1 (a int); + +insert into atacc1 values(1); + +alter table atacc1 + add column b float8 not null default random(), + add primary key(a); + +drop table atacc1; + +create table atacc1 (a int primary key); + +alter table atacc1 add constraint atacc1_fkey foreign key (a) references atacc1 (a) not valid; + +alter table atacc1 validate constraint atacc1_fkey, alter a type bigint; + +drop table atacc1; + +create table atacc1 (a bigint, b int); + +insert into atacc1 values(1,1); + +alter table atacc1 add constraint atacc1_chk check(b = 1) not valid; + +alter table atacc1 validate constraint atacc1_chk, alter a type int; + +drop table atacc1; + +create table atacc1 (a bigint, b int); + +insert into atacc1 values(1,2); + +alter table atacc1 add constraint atacc1_chk check(b = 1) not valid; + +alter table atacc1 validate constraint atacc1_chk, alter a type int; + +drop table atacc1; + +create table atacc1 ( test int, test2 int); + +alter table atacc1 add constraint atacc_test1 primary key (test, test2); + +alter table atacc1 add constraint atacc_test2 primary key (test); + +insert into atacc1 (test,test2) values (4,4); + +insert into atacc1 (test,test2) values (4,4); + +insert into atacc1 (test,test2) values (NULL,3); + +insert into atacc1 (test,test2) values (3, NULL); + +insert into atacc1 (test,test2) values (NULL,NULL); + +insert into atacc1 (test,test2) values (4,5); + +insert into atacc1 (test,test2) values (5,4); + +insert into atacc1 (test,test2) values (5,5); + +drop table atacc1; + +create table atacc1 (test int, test2 int, primary key(test)); + +insert into atacc1 (test2, test) values (3, 3); + +insert into atacc1 (test2, test) values (2, 3); + +insert into atacc1 (test2, test) values (1, NULL); + +drop table atacc1; + +alter table pg_class alter column relname drop not null; + +alter table pg_class alter relname set not null; + +alter table non_existent alter column bar set not null; + +alter table non_existent alter column bar drop not null; + +create table atacc1 (test int not null); + +alter table atacc1 add constraint "atacc1_pkey" primary key (test); + +alter table atacc1 alter column test drop not null; + +alter table atacc1 drop constraint "atacc1_pkey"; + +alter table atacc1 alter column test drop not null; + +insert into atacc1 values (null); + +alter table atacc1 alter test set not null; + +delete from atacc1; + +alter table atacc1 alter test set not null; + +alter table atacc1 alter bar set not null; + +alter table atacc1 alter bar drop not null; + +create view myview as select * from atacc1; + +alter table myview alter column test drop not null; + +alter table myview alter column test set not null; + +drop view myview; + +drop table atacc1; + +create table atacc1 (test_a int, test_b int); + +insert into atacc1 values (null, 1); + +alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10); + +alter table atacc1 alter test_a set not null; + +alter table atacc1 drop constraint atacc1_constr_or; + +alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid; + +alter table atacc1 alter test_a set not null; + +alter table atacc1 drop constraint atacc1_constr_invalid; + +update atacc1 set test_a = 1; + +alter table atacc1 add constraint atacc1_constr_a_valid check(test_a is not null); + +alter table atacc1 alter test_a set not null; + +delete from atacc1; + +insert into atacc1 values (2, null); + +alter table atacc1 alter test_a drop not null; + +alter table atacc1 alter test_a set not null, alter test_b set not null; + +alter table atacc1 alter test_b set not null, alter test_a set not null; + +update atacc1 set test_b = 1; + +alter table atacc1 alter test_b set not null, alter test_a set not null; + +alter table atacc1 alter test_a drop not null, alter test_b drop not null; + +alter table atacc1 add constraint atacc1_constr_b_valid check(test_b is not null); + +alter table atacc1 alter test_b set not null, alter test_a set not null; + +drop table atacc1; + +CREATE TABLE atnnparted (id int, col1 int) PARTITION BY LIST (id); + +CREATE TABLE atnnpart1 (col1 int, id int); + +ALTER TABLE atnnpart1 ADD PRIMARY KEY (id); + +ALTER TABLE atnnparted ATTACH PARTITION atnnpart1 FOR VALUES IN ('1'); + +BEGIN; + +ALTER TABLE atnnparted VALIDATE CONSTRAINT dummy_constr; + +ROLLBACK; + +create table parent (a int); + +create table child (b varchar(255)) inherits (parent); + +alter table parent alter a set not null; + +insert into parent values (NULL); + +insert into child (a, b) values (NULL, 'foo'); + +alter table parent alter a drop not null; + +insert into parent values (NULL); + +insert into child (a, b) values (NULL, 'foo'); + +alter table only parent alter a set not null; + +alter table child alter a set not null; + +drop table child; + +drop table parent; + +create table def_test ( + c1 int4 default 5, + c2 text default 'initial_default' +); + +insert into def_test default values; + +alter table def_test alter column c1 drop default; + +insert into def_test default values; + +alter table def_test alter column c2 drop default; + +insert into def_test default values; + +alter table def_test alter column c1 set default 10; + +alter table def_test alter column c2 set default 'new_default'; + +insert into def_test default values; + +select * from def_test; + +alter table def_test alter column c1 set default 'wrong_datatype'; + +alter table def_test alter column c2 set default 20; + +alter table def_test alter column c3 set default 30; + +create view def_view_test as select * from def_test; + +select new.*; + +insert into def_view_test default values; + +alter table def_view_test alter column c1 set default 45; + +insert into def_view_test default values; + +alter table def_view_test alter column c2 set default 'view_default'; + +insert into def_view_test default values; + +select * from def_view_test; + +drop rule def_view_test_ins on def_view_test; + +drop view def_view_test; + +drop table def_test; + +alter table pg_class drop column relname; + +alter table nosuchtable drop column bar; + +create table atacc1 (a int4 not null, b int4, c int4 not null, d int4); + +insert into atacc1 values (1, 2, 3, 4); + +alter table atacc1 drop a; + +alter table atacc1 drop a; + +select * from atacc1; + +select * from atacc1 order by a; + +select * from atacc1 order by "........pg.dropped.1........"; + +select * from atacc1 group by a; + +select * from atacc1 group by "........pg.dropped.1........"; + +select atacc1.* from atacc1; + +select a from atacc1; + +select atacc1.a from atacc1; + +select b,c,d from atacc1; + +select a,b,c,d from atacc1; + +select * from atacc1 where a = 1; + +select "........pg.dropped.1........" from atacc1; + +select atacc1."........pg.dropped.1........" from atacc1; + +select "........pg.dropped.1........",b,c,d from atacc1; + +select * from atacc1 where "........pg.dropped.1........" = 1; + +update atacc1 set a = 3; + +update atacc1 set b = 2 where a = 3; + +update atacc1 set "........pg.dropped.1........" = 3; + +update atacc1 set b = 2 where "........pg.dropped.1........" = 3; + +insert into atacc1 values (10, 11, 12, 13); + +insert into atacc1 values (default, 11, 12, 13); + +insert into atacc1 values (11, 12, 13); + +insert into atacc1 (a) values (10); + +insert into atacc1 (a) values (default); + +insert into atacc1 (a,b,c,d) values (10,11,12,13); + +insert into atacc1 (a,b,c,d) values (default,11,12,13); + +insert into atacc1 (b,c,d) values (11,12,13); + +insert into atacc1 ("........pg.dropped.1........") values (10); + +insert into atacc1 ("........pg.dropped.1........") values (default); + +insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13); + +insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13); + +delete from atacc1 where a = 3; + +delete from atacc1 where "........pg.dropped.1........" = 3; + +delete from atacc1; + +alter table atacc1 drop bar; + +alter table atacc1 SET WITHOUT OIDS; diff --git a/crates/pgt_pretty_print/tests/data/multi/amutils_60.sql b/crates/pgt_pretty_print/tests/data/multi/amutils_60.sql new file mode 100644 index 000000000..5c69c5028 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/amutils_60.sql @@ -0,0 +1,92 @@ +select prop, + pg_indexam_has_property(a.oid, prop) as "AM", + pg_index_has_property('onek_hundred'::regclass, prop) as "Index", + pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as "Column" + from pg_am a, + unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'can_order', 'can_unique', 'can_multi_col', + 'can_exclude', 'can_include', + 'bogus']::text[]) + with ordinality as u(prop,ord) + where a.amname = 'btree' + order by ord; + +select prop, + pg_indexam_has_property(a.oid, prop) as "AM", + pg_index_has_property('gcircleind'::regclass, prop) as "Index", + pg_index_column_has_property('gcircleind'::regclass, 1, prop) as "Column" + from pg_am a, + unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'can_order', 'can_unique', 'can_multi_col', + 'can_exclude', 'can_include', + 'bogus']::text[]) + with ordinality as u(prop,ord) + where a.amname = 'gist' + order by ord; + +select prop, + pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as btree, + pg_index_column_has_property('hash_i4_index'::regclass, 1, prop) as hash, + pg_index_column_has_property('gcircleind'::regclass, 1, prop) as gist, + pg_index_column_has_property('sp_radix_ind'::regclass, 1, prop) as spgist_radix, + pg_index_column_has_property('sp_quad_ind'::regclass, 1, prop) as spgist_quad, + pg_index_column_has_property('botharrayidx'::regclass, 1, prop) as gin, + pg_index_column_has_property('brinidx'::regclass, 1, prop) as brin + from unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', + 'orderable', 'distance_orderable', 'returnable', + 'search_array', 'search_nulls', + 'bogus']::text[]) + with ordinality as u(prop,ord) + order by ord; + +select prop, + pg_index_has_property('onek_hundred'::regclass, prop) as btree, + pg_index_has_property('hash_i4_index'::regclass, prop) as hash, + pg_index_has_property('gcircleind'::regclass, prop) as gist, + pg_index_has_property('sp_radix_ind'::regclass, prop) as spgist, + pg_index_has_property('botharrayidx'::regclass, prop) as gin, + pg_index_has_property('brinidx'::regclass, prop) as brin + from unnest(array['clusterable', 'index_scan', 'bitmap_scan', + 'backward_scan', + 'bogus']::text[]) + with ordinality as u(prop,ord) + order by ord; + +select amname, prop, pg_indexam_has_property(a.oid, prop) as p + from pg_am a, + unnest(array['can_order', 'can_unique', 'can_multi_col', + 'can_exclude', 'can_include', 'bogus']::text[]) + with ordinality as u(prop,ord) + where amtype = 'i' + order by amname, ord; + +CREATE TEMP TABLE foo (f1 int, f2 int, f3 int, f4 int); + +CREATE INDEX fooindex ON foo (f1 desc, f2 asc, f3 nulls first, f4 nulls last); + +select col, prop, pg_index_column_has_property(o, col, prop) + from (values ('fooindex'::regclass)) v1(o), + (values (1,'orderable'),(2,'asc'),(3,'desc'), + (4,'nulls_first'),(5,'nulls_last'), + (6, 'bogus')) v2(idx,prop), + generate_series(1,4) col + order by col, idx; + +CREATE INDEX foocover ON foo (f1) INCLUDE (f2,f3); + +select col, prop, pg_index_column_has_property(o, col, prop) + from (values ('foocover'::regclass)) v1(o), + (values (1,'orderable'),(2,'asc'),(3,'desc'), + (4,'nulls_first'),(5,'nulls_last'), + (6,'distance_orderable'),(7,'returnable'), + (8, 'bogus')) v2(idx,prop), + generate_series(1,3) col + order by col, idx; diff --git a/crates/pgt_pretty_print/tests/data/multi/arrays_60.sql b/crates/pgt_pretty_print/tests/data/multi/arrays_60.sql new file mode 100644 index 000000000..f421cecfc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/arrays_60.sql @@ -0,0 +1,1192 @@ +CREATE TABLE arrtest ( + a int2[], + b int4[][][], + c name[], + d text[][], + e float8[], + f char(5)[], + g varchar(5)[] +); + +CREATE TABLE array_op_test ( + seqno int4, + i int4[], + t text[] +); + +COPY array_op_test FROM 'filename'; + +ANALYZE array_op_test; + +INSERT INTO arrtest (a[1:5], b[1:1][1:2][1:2], c, d, f, g) + VALUES ('{1,2,3,4,5}', '{{{0,0},{1,2}}}', '{}', '{}', '{}', '{}'); + +UPDATE arrtest SET e[0] = '1.1'; + +UPDATE arrtest SET e[1] = '2.2'; + +INSERT INTO arrtest (f) + VALUES ('{"too long"}'); + +INSERT INTO arrtest (a, b[1:2][1:2], c, d, e, f, g) + VALUES ('{11,12,23}', '{{3,4},{4,5}}', '{"foobar"}', + '{{"elt1", "elt2"}}', '{"3.4", "6.7"}', + '{"abc","abcde"}', '{"abc","abcde"}'); + +INSERT INTO arrtest (a, b[1:2], c, d[1:2]) + VALUES ('{}', '{3,4}', '{foo,bar}', '{bar,foo}'); + +INSERT INTO arrtest (b[2]) VALUES(now()); + +INSERT INTO arrtest (b[1:2]) VALUES(now()); + +SELECT * FROM arrtest; + +SELECT arrtest.a[1], + arrtest.b[1][1][1], + arrtest.c[1], + arrtest.d[1][1], + arrtest.e[0] + FROM arrtest; + +SELECT a[1], b[1][1][1], c[1], d[1][1], e[0] + FROM arrtest; + +SELECT a[1:3], + b[1:1][1:2][1:2], + c[1:2], + d[1:1][1:2] + FROM arrtest; + +SELECT array_ndims(a) AS a,array_ndims(b) AS b,array_ndims(c) AS c + FROM arrtest; + +SELECT array_dims(a) AS a,array_dims(b) AS b,array_dims(c) AS c + FROM arrtest; + +SELECT * + FROM arrtest + WHERE a[1] < 5 and + c = '{"foobar"}'::_name; + +UPDATE arrtest + SET a[1:2] = '{16,25}' + WHERE NOT a = '{}'::_int2; + +UPDATE arrtest + SET b[1:1][1:1][1:2] = '{113, 117}', + b[1:1][1:2][2:2] = '{142, 147}' + WHERE array_dims(b) = '[1:1][1:2][1:2]'; + +UPDATE arrtest + SET c[2:2] = '{"new_word"}' + WHERE array_dims(c) is not null; + +SELECT a,b,c FROM arrtest; + +SELECT a[1:3], + b[1:1][1:2][1:2], + c[1:2], + d[1:1][2:2] + FROM arrtest; + +SELECT b[1:1][2][2], + d[1:1][2] + FROM arrtest; + +INSERT INTO arrtest(a) VALUES('{1,null,3}'); + +SELECT a FROM arrtest; + +UPDATE arrtest SET a[4] = NULL WHERE a[2] IS NULL; + +SELECT a FROM arrtest WHERE a[2] IS NULL; + +DELETE FROM arrtest WHERE a[2] IS NULL AND b IS NULL; + +SELECT a,b,c FROM arrtest; + +SELECT pg_input_is_valid('{1,2,3}', 'integer[]'); + +SELECT pg_input_is_valid('{1,2', 'integer[]'); + +SELECT pg_input_is_valid('{1,zed}', 'integer[]'); + +SELECT * FROM pg_input_error_info('{1,zed}', 'integer[]'); + +select '{{1,2,3},{4,5,6},{7,8,9}}'::int[]; + +select ('{{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2]; + +select '[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[]; + +select ('[0:2][0:2]={{1,2,3},{4,5,6},{7,8,9}}'::int[])[1:2][2]; + +SELECT ('{}'::int[])[1][2][3][4][5][6][7]; + +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL][1]; + +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][NULL:1][1]; + +SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][1:NULL][1]; + +UPDATE arrtest + SET c[NULL] = '{"can''t assign"}' + WHERE array_dims(c) is not null; + +UPDATE arrtest + SET c[NULL:1] = '{"can''t assign"}' + WHERE array_dims(c) is not null; + +UPDATE arrtest + SET c[1:NULL] = '{"can''t assign"}' + WHERE array_dims(c) is not null; + +SELECT (now())[1]; + +CREATE TEMP TABLE arrtest_s ( + a int2[], + b int2[][] +); + +INSERT INTO arrtest_s VALUES ('{1,2,3,4,5}', '{{1,2,3}, {4,5,6}, {7,8,9}}'); + +INSERT INTO arrtest_s VALUES ('[0:4]={1,2,3,4,5}', '[0:2][0:2]={{1,2,3}, {4,5,6}, {7,8,9}}'); + +SELECT * FROM arrtest_s; + +SELECT a[:3], b[:2][:2] FROM arrtest_s; + +SELECT a[2:], b[2:][2:] FROM arrtest_s; + +SELECT a[:], b[:] FROM arrtest_s; + +UPDATE arrtest_s SET a[:3] = '{11, 12, 13}', b[:2][:2] = '{{11,12}, {14,15}}' + WHERE array_lower(a,1) = 1; + +SELECT * FROM arrtest_s; + +UPDATE arrtest_s SET a[3:] = '{23, 24, 25}', b[2:][2:] = '{{25,26}, {28,29}}'; + +SELECT * FROM arrtest_s; + +UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}'; + +SELECT * FROM arrtest_s; + +UPDATE arrtest_s SET a[:] = '{23, 24, 25}'; + +INSERT INTO arrtest_s VALUES(NULL, NULL); + +UPDATE arrtest_s SET a[:] = '{11, 12, 13, 14, 15}'; + +CREATE TEMP TABLE point_tbl AS SELECT * FROM public.point_tbl; + +INSERT INTO POINT_TBL(f1) VALUES (NULL); + +SELECT f1[0:1] FROM POINT_TBL; + +SELECT f1[0:] FROM POINT_TBL; + +SELECT f1[:1] FROM POINT_TBL; + +SELECT f1[:] FROM POINT_TBL; + +UPDATE point_tbl SET f1[0] = 10 WHERE f1 IS NULL RETURNING *; + +INSERT INTO point_tbl(f1[0]) VALUES(0) RETURNING *; + +UPDATE point_tbl SET f1[0] = NULL WHERE f1::text = '(10,10)'::point::text RETURNING *; + +UPDATE point_tbl SET f1[0] = -10, f1[1] = -10 WHERE f1::text = '(10,10)'::point::text RETURNING *; + +UPDATE point_tbl SET f1[3] = 10 WHERE f1::text = '(-10,-10)'::point::text RETURNING *; + +CREATE TEMP TABLE arrtest1 (i int[], t text[]); + +insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']); + +select * from arrtest1; + +update arrtest1 set i[2] = 22, t[2] = 'twenty-two'; + +select * from arrtest1; + +update arrtest1 set i[5] = 5, t[5] = 'five'; + +select * from arrtest1; + +update arrtest1 set i[8] = 8, t[8] = 'eight'; + +select * from arrtest1; + +update arrtest1 set i[0] = 0, t[0] = 'zero'; + +select * from arrtest1; + +update arrtest1 set i[-3] = -3, t[-3] = 'minus-three'; + +select * from arrtest1; + +update arrtest1 set i[0:2] = array[10,11,12], t[0:2] = array['ten','eleven','twelve']; + +select * from arrtest1; + +update arrtest1 set i[8:10] = array[18,null,20], t[8:10] = array['p18',null,'p20']; + +select * from arrtest1; + +update arrtest1 set i[11:12] = array[null,22], t[11:12] = array[null,'p22']; + +select * from arrtest1; + +update arrtest1 set i[15:16] = array[null,26], t[15:16] = array[null,'p26']; + +select * from arrtest1; + +update arrtest1 set i[-5:-3] = array[-15,-14,-13], t[-5:-3] = array['m15','m14','m13']; + +select * from arrtest1; + +update arrtest1 set i[-7:-6] = array[-17,null], t[-7:-6] = array['m17',null]; + +select * from arrtest1; + +update arrtest1 set i[-12:-10] = array[-22,null,-20], t[-12:-10] = array['m22',null,'m20']; + +select * from arrtest1; + +delete from arrtest1; + +insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']); + +select * from arrtest1; + +update arrtest1 set i[0:5] = array[0,1,2,null,4,5], t[0:5] = array['z','p1','p2',null,'p4','p5']; + +select * from arrtest1; + +CREATE TEMP TABLE arrtest2 (i integer ARRAY[4], f float8[], n numeric[], t text[], d timestamp[]); + +INSERT INTO arrtest2 VALUES( + ARRAY[[[113,142],[1,147]]], + ARRAY[1.1,1.2,1.3]::float8[], + ARRAY[1.1,1.2,1.3], + ARRAY[[['aaa','aab'],['aba','abb'],['aca','acb']],[['baa','bab'],['bba','bbb'],['bca','bcb']]], + ARRAY['19620326','19931223','19970117']::timestamp[] +); + +CREATE TEMP TABLE arrtest_f (f0 int, f1 text, f2 float8); + +insert into arrtest_f values(1,'cat1',1.21); + +insert into arrtest_f values(2,'cat1',1.24); + +insert into arrtest_f values(3,'cat1',1.18); + +insert into arrtest_f values(4,'cat1',1.26); + +insert into arrtest_f values(5,'cat1',1.15); + +insert into arrtest_f values(6,'cat2',1.15); + +insert into arrtest_f values(7,'cat2',1.26); + +insert into arrtest_f values(8,'cat2',1.32); + +insert into arrtest_f values(9,'cat2',1.30); + +CREATE TEMP TABLE arrtest_i (f0 int, f1 text, f2 int); + +insert into arrtest_i values(1,'cat1',21); + +insert into arrtest_i values(2,'cat1',24); + +insert into arrtest_i values(3,'cat1',18); + +insert into arrtest_i values(4,'cat1',26); + +insert into arrtest_i values(5,'cat1',15); + +insert into arrtest_i values(6,'cat2',15); + +insert into arrtest_i values(7,'cat2',26); + +insert into arrtest_i values(8,'cat2',32); + +insert into arrtest_i values(9,'cat2',30); + +SELECT t.f[1][3][1] AS "131", t.f[2][2][1] AS "221" FROM ( + SELECT ARRAY[[[111,112],[121,122],[131,132]],[[211,212],[221,122],[231,232]]] AS f +) AS t; + +SELECT ARRAY[[[[[['hello'],['world']]]]]]; + +SELECT ARRAY[ARRAY['hello'],ARRAY['world']]; + +SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY"; + +SELECT '{1,null,3}'::int[]; + +SELECT ARRAY[1,NULL,3]; + +SELECT array_append(array[42], 6) AS "{42,6}"; + +SELECT array_prepend(6, array[42]) AS "{6,42}"; + +SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}"; + +SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}"; + +SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}"; + +SELECT array_position(ARRAY[1,2,3,4,5], 4); + +SELECT array_position(ARRAY[5,3,4,2,1], 4); + +SELECT array_position(ARRAY[[1,2],[3,4]], 3); + +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon'); + +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'sat'); + +SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], NULL); + +SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], NULL); + +SELECT array_position(ARRAY['sun','mon','tue','wed','thu',NULL,'fri','sat'], 'sat'); + +SELECT array_positions(NULL, 10); + +SELECT array_positions(NULL, NULL::int); + +SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], 4); + +SELECT array_positions(ARRAY[[1,2],[3,4]], 4); + +SELECT array_positions(ARRAY[1,2,3,4,5,6,1,2,3,4,5,6], NULL); + +SELECT array_positions(ARRAY[1,2,3,NULL,5,6,1,2,3,NULL,5,6], NULL); + +SELECT array_length(array_positions(ARRAY(SELECT 'AAAAAAAAAAAAAAAAAAAAAAAAA'::text || i % 10 + FROM generate_series(1,100) g(i)), + 'AAAAAAAAAAAAAAAAAAAAAAAAA5'), 1); + +DO $$ +DECLARE + o int; + a int[] := ARRAY[1,2,3,2,3,1,2]; +BEGIN + o := array_position(a, 2); + WHILE o IS NOT NULL + LOOP + RAISE NOTICE '%', o; + o := array_position(a, 2, o + 1); + END LOOP; +END +$$ LANGUAGE plpgsql; + +SELECT array_position('[2:4]={1,2,3}'::int[], 1); + +SELECT array_positions('[2:4]={1,2,3}'::int[], 1); + +SELECT + array_position(ids, (1, 1)), + array_positions(ids, (1, 1)) + FROM +(VALUES + (ARRAY[(0, 0), (1, 1)]), + (ARRAY[(1, 1)]) +) AS f (ids); + +SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]]; + +SELECT NOT ARRAY[1.1,1.2,1.3] = ARRAY[1.1,1.2,1.3] AS "FALSE"; + +SELECT ARRAY[1,2] || 3 AS "{1,2,3}"; + +SELECT 0 || ARRAY[1,2] AS "{0,1,2}"; + +SELECT ARRAY[1,2] || ARRAY[3,4] AS "{1,2,3,4}"; + +SELECT ARRAY[[['hello','world']]] || ARRAY[[['happy','birthday']]] AS "ARRAY"; + +SELECT ARRAY[[1,2],[3,4]] || ARRAY[5,6] AS "{{1,2},{3,4},{5,6}}"; + +SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}"; + +SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}"; + +SELECT ARRAY[1.1] || ARRAY[2,3,4]; + +SELECT array_agg(x) || array_agg(x) FROM (VALUES (ROW(1,2)), (ROW(3,4))) v(x); + +SELECT ROW(1,2) || array_agg(x) FROM (VALUES (ROW(3,4)), (ROW(5,6))) v(x); + +SELECT * FROM array_op_test WHERE i @> '{32}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i && '{32}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i @> '{17}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i && '{17}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i @> '{32,17}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i && '{32,17}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i = '{}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i @> '{}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i && '{}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i <@ '{}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i @> '{NULL}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i && '{NULL}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t = '{}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t @> '{}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t && '{}' ORDER BY seqno; + +SELECT * FROM array_op_test WHERE t <@ '{}' ORDER BY seqno; + +SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}"; + +SELECT pg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[]) AS "double precision[]"; + +SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}"; + +SELECT pg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]) AS "character varying[]"; + +SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}"; + +SELECT NULL::text[]::int[] AS "NULL"; + +select 33 = any ('{1,2,3}'); + +select 33 = any ('{1,2,33}'); + +select 33 = all ('{1,2,33}'); + +select 33 >= all ('{1,2,33}'); + +select null::int >= all ('{1,2,33}'); + +select null::int >= all ('{}'); + +select null::int >= any ('{}'); + +select 33.4 = any (array[1,2,3]); + +select 33.4 > all (array[1,2,3]); + +select 33 * any ('{1,2,3}'); + +select 33 * any (44); + +select 33 = any (null::int[]); + +select null::int = any ('{1,2,3}'); + +select 33 = any ('{1,null,3}'); + +select 33 = any ('{1,null,33}'); + +select 33 = all (null::int[]); + +select null::int = all ('{1,2,3}'); + +select 33 = all ('{1,null,3}'); + +select 33 = all ('{33,null,33}'); + +SELECT -1 != ALL(ARRAY(SELECT NULLIF(g.i, 900) FROM generate_series(1,1000) g(i))); + +create temp table arr_tbl (f1 int[] unique); + +insert into arr_tbl values ('{1,2,3}'); + +insert into arr_tbl values ('{1,2}'); + +insert into arr_tbl values ('{1,2,3}'); + +insert into arr_tbl values ('{2,3,4}'); + +insert into arr_tbl values ('{1,5,3}'); + +insert into arr_tbl values ('{1,2,10}'); + +set enable_seqscan to off; + +set enable_bitmapscan to off; + +select * from arr_tbl where f1 > '{1,2,3}' and f1 <= '{1,5,3}'; + +select * from arr_tbl where f1 >= '{1,2,3}' and f1 < '{1,5,3}'; + +create temp table arr_pk_tbl (pk int4 primary key, f1 int[]); + +insert into arr_pk_tbl values (1, '{1,2,3}'); + +insert into arr_pk_tbl values (1, '{3,4,5}') on conflict (pk) + do update set f1[1] = excluded.f1[1], f1[3] = excluded.f1[3] + returning pk, f1; + +insert into arr_pk_tbl(pk, f1[1:2]) values (1, '{6,7,8}') on conflict (pk) + do update set f1[1] = excluded.f1[1], + f1[2] = excluded.f1[2], + f1[3] = excluded.f1[3] + returning pk, f1; + +reset enable_seqscan; + +reset enable_bitmapscan; + +insert into arr_pk_tbl values(10, '[-2147483648:-2147483647]={1,2}'); + +update arr_pk_tbl set f1[2147483647] = 42 where pk = 10; + +update arr_pk_tbl set f1[2147483646:2147483647] = array[4,2] where pk = 10; + +insert into arr_pk_tbl(pk, f1[0:2147483647]) values (2, '{}'); + +insert into arr_pk_tbl(pk, f1[-2147483648:2147483647]) values (2, '{}'); + +do $$ declare a int[]; +begin + a := '[-2147483648:-2147483647]={1,2}'::int[]; + a[2147483647] := 42; +end $$; + +select 'foo' like any (array['%a', '%o']); + +select 'foo' like any (array['%a', '%b']); + +select 'foo' like all (array['f%', '%o']); + +select 'foo' like all (array['f%', '%b']); + +select 'foo' not like any (array['%a', '%b']); + +select 'foo' not like all (array['%a', '%o']); + +select 'foo' ilike any (array['%A', '%O']); + +select 'foo' ilike all (array['F%', '%O']); + +select '{{1,{2}},{2,3}}'::text[]; + +select E'{{1,2},\\{2,3}}'::text[]; + +select '{"a"b}'::text[]; + +select '{a"b"}'::text[]; + +select '{"a""b"}'::text[]; + +select '{{"1 2" x},{3}}'::text[]; + +select '{{"1 2"} x,{3}}'::text[]; + +select '{}}'::text[]; + +select '{ }}'::text[]; + +select '}{'::text[]; + +select '{foo{}}'::text[]; + +select '{"foo"{}}'::text[]; + +select '{foo,,bar}'::text[]; + +select '{{1},{{2}}}'::text[]; + +select '{{{1}},{2}}'::text[]; + +select '{{},{{}}}'::text[]; + +select '{{{}},{}}'::text[]; + +select '{{1},{}}'::text[]; + +select '{{},{1}}'::text[]; + +select '[1:0]={}'::int[]; + +select '[2147483646:2147483647]={1,2}'::int[]; + +select '[1:-1]={}'::int[]; + +select '[2]={1}'::int[]; + +select '[1:]={1}'::int[]; + +select '[:1]={1}'::int[]; + +select array[]; + +select '{{1,},{1},}'::text[]; + +select '{{1,},{1}}'::text[]; + +select '{{1,}}'::text[]; + +select '{1,}'::text[]; + +select '[21474836488:21474836489]={1,2}'::int[]; + +select '[-2147483649:-2147483648]={1,2}'::int[]; + +select '{}'::text[]; + +select '{{},{}}'::text[]; + +select '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[]; + +select '{null,n\ull,"null"}'::text[]; + +select '{ ab\c , "ab\"c" }'::text[]; + +select '{0 second ,0 second}'::interval[]; + +select '{ { "," } , { 3 } }'::text[]; + +select ' { { " 0 second " , 0 second } }'::text[]; + +select '{ + 0 second, + @ 1 hour @ 42 minutes @ 20 seconds + }'::interval[]; + +select array[]::text[]; + +select '[2]={1,7}'::int[]; + +select '[0:1]={1.1,2.2}'::float8[]; + +select '[2147483646:2147483646]={1}'::int[]; + +select '[-2147483648:-2147483647]={1,2}'::int[]; + +CREATE TEMP TABLE arraggtest ( f1 INT[], f2 TEXT[][], f3 FLOAT[]); + +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{1,2,3,4}','{{grey,red},{blue,blue}}','{1.6, 0.0}'); + +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{1,2,3}','{{grey,red},{grey,blue}}','{1.6}'); + +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest; + +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{3,3,2,4,5,6}','{{white,yellow},{pink,orange}}','{2.1,3.3,1.8,1.7,1.6}'); + +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest; + +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{2}','{{black,red},{green,orange}}','{1.6,2.2,2.6,0.4}'); + +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest; + +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{4,2,6,7,8,1}','{{red},{black},{purple},{blue},{blue}}',NULL); + +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest; + +INSERT INTO arraggtest (f1, f2, f3) VALUES +('{}','{{pink,white,blue,red,grey,orange}}','{2.1,1.87,1.4,2.2}'); + +SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest; + +create type comptype as (f1 int, f2 text); + +create table comptable (c1 comptype, c2 comptype[]); + +insert into comptable + values (row(1,'foo'), array[row(2,'bar')::comptype, row(3,'baz')::comptype]); + +create type _comptype as enum('fooey'); + +select * from comptable; + +select c2[2].f2 from comptable; + +drop type _comptype; + +drop table comptable; + +drop type comptype; + +create or replace function unnest1(anyarray) +returns setof anyelement as $$ +select $1[s] from generate_subscripts($1,1) g(s); +$$ language sql immutable; + +create or replace function unnest2(anyarray) +returns setof anyelement as $$ +select $1[s1][s2] from generate_subscripts($1,1) g1(s1), + generate_subscripts($1,2) g2(s2); +$$ language sql immutable; + +select * from unnest1(array[1,2,3]); + +select * from unnest2(array[[1,2,3],[4,5,6]]); + +drop function unnest1(anyarray); + +drop function unnest2(anyarray); + +select array_fill(null::integer, array[3,3],array[2,2]); + +select array_fill(null::integer, array[3,3]); + +select array_fill(null::text, array[3,3],array[2,2]); + +select array_fill(null::text, array[3,3]); + +select array_fill(7, array[3,3],array[2,2]); + +select array_fill(7, array[3,3]); + +select array_fill('juhu'::text, array[3,3],array[2,2]); + +select array_fill('juhu'::text, array[3,3]); + +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, array[0]) as a) ss; + +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, '{}') as a) ss; + +select a, a = '{}' as is_eq, array_dims(a) + from (select array_fill(42, '{}', '{}') as a) ss; + +select array_fill(1, null, array[2,2]); + +select array_fill(1, array[2,2], null); + +select array_fill(1, array[2,2], '{}'); + +select array_fill(1, array[3,3], array[1,1,1]); + +select array_fill(1, array[1,2,null]); + +select array_fill(1, array[[1,2],[3,4]]); + +select string_to_array('1|2|3', '|'); + +select string_to_array('1|2|3|', '|'); + +select string_to_array('1||2|3||', '||'); + +select string_to_array('1|2|3', ''); + +select string_to_array('', '|'); + +select string_to_array('1|2|3', NULL); + +select string_to_array(NULL, '|') IS NULL; + +select string_to_array('abc', ''); + +select string_to_array('abc', '', 'abc'); + +select string_to_array('abc', ','); + +select string_to_array('abc', ',', 'abc'); + +select string_to_array('1,2,3,4,,6', ','); + +select string_to_array('1,2,3,4,,6', ',', ''); + +select string_to_array('1,2,3,4,*,6', ',', '*'); + +select v, v is null as "is null" from string_to_table('1|2|3', '|') g(v); + +select v, v is null as "is null" from string_to_table('1|2|3|', '|') g(v); + +select v, v is null as "is null" from string_to_table('1||2|3||', '||') g(v); + +select v, v is null as "is null" from string_to_table('1|2|3', '') g(v); + +select v, v is null as "is null" from string_to_table('', '|') g(v); + +select v, v is null as "is null" from string_to_table('1|2|3', NULL) g(v); + +select v, v is null as "is null" from string_to_table(NULL, '|') g(v); + +select v, v is null as "is null" from string_to_table('abc', '') g(v); + +select v, v is null as "is null" from string_to_table('abc', '', 'abc') g(v); + +select v, v is null as "is null" from string_to_table('abc', ',') g(v); + +select v, v is null as "is null" from string_to_table('abc', ',', 'abc') g(v); + +select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',') g(v); + +select v, v is null as "is null" from string_to_table('1,2,3,4,,6', ',', '') g(v); + +select v, v is null as "is null" from string_to_table('1,2,3,4,*,6', ',', '*') g(v); + +select array_to_string(NULL::int4[], ',') IS NULL; + +select array_to_string('{}'::int4[], ','); + +select array_to_string(array[1,2,3,4,NULL,6], ','); + +select array_to_string(array[1,2,3,4,NULL,6], ',', '*'); + +select array_to_string(array[1,2,3,4,NULL,6], NULL); + +select array_to_string(array[1,2,3,4,NULL,6], ',', NULL); + +select array_to_string(string_to_array('1|2|3', '|'), '|'); + +select array_length(array[1,2,3], 1); + +select array_length(array[[1,2,3], [4,5,6]], 0); + +select array_length(array[[1,2,3], [4,5,6]], 1); + +select array_length(array[[1,2,3], [4,5,6]], 2); + +select array_length(array[[1,2,3], [4,5,6]], 3); + +select cardinality(NULL::int[]); + +select cardinality('{}'::int[]); + +select cardinality(array[1,2,3]); + +select cardinality('[2:4]={5,6,7}'::int[]); + +select cardinality('{{1,2}}'::int[]); + +select cardinality('{{1,2},{3,4},{5,6}}'::int[]); + +select cardinality('{{{1,9},{5,6}},{{2,3},{3,4}}}'::int[]); + +select array_agg(unique1) from (select unique1 from tenk1 where unique1 < 15 order by unique1) ss; + +select array_agg(ten) from (select ten from tenk1 where unique1 < 15 order by unique1) ss; + +select array_agg(nullif(ten, 4)) from (select ten from tenk1 where unique1 < 15 order by unique1) ss; + +select array_agg(unique1) from tenk1 where unique1 < -15; + +select array_agg(ar) + from (values ('{1,2}'::int[]), ('{3,4}'::int[])) v(ar); + +select array_agg(distinct ar order by ar desc) + from (select array[i / 2] from generate_series(1,10) a(i)) b(ar); + +select array_agg(ar) + from (select array_agg(array[i, i+1, i-1]) + from generate_series(1,2) a(i)) b(ar); + +select array_agg(array[i+1.2, i+1.3, i+1.4]) from generate_series(1,3) g(i); + +select array_agg(array['Hello', i::text]) from generate_series(9,11) g(i); + +select array_agg(array[i, nullif(i, 3), i+1]) from generate_series(1,4) g(i); + +select array_agg('{}'::int[]) from generate_series(1,2); + +select array_agg(null::int[]) from generate_series(1,2); + +select array_agg(ar) + from (values ('{1,2}'::int[]), ('{3}'::int[])) v(ar); + +select unnest(array[1,2,3]); + +select * from unnest(array[1,2,3]); + +select unnest(array[1,2,3,4.5]::float8[]); + +select unnest(array[1,2,3,4.5]::numeric[]); + +select unnest(array[1,2,3,null,4,null,null,5,6]); + +select unnest(array[1,2,3,null,4,null,null,5,6]::text[]); + +select abs(unnest(array[1,2,null,-3])); + +select array_remove(array[1,2,2,3], 2); + +select array_remove(array[1,2,2,3], 5); + +select array_remove(array[1,NULL,NULL,3], NULL); + +select array_remove(array['A','CC','D','C','RR'], 'RR'); + +select array_remove(array[1.0, 2.1, 3.3], 1); + +select array_remove('{{1,2,2},{1,4,3}}', 2); + +select array_remove(array['X','X','X'], 'X') = '{}'; + +select array_replace(array[1,2,5,4],5,3); + +select array_replace(array[1,2,5,4],5,NULL); + +select array_replace(array[1,2,NULL,4,NULL],NULL,5); + +select array_replace(array['A','B','DD','B'],'B','CC'); + +select array_replace(array[1,NULL,3],NULL,NULL); + +select array_replace(array['AB',NULL,'CDE'],NULL,'12'); + +select array(select array[i,i/2] from generate_series(1,5) i); + +select array(select array['Hello', i::text] from generate_series(9,11) i); + +select pg_typeof(array(select '11 22 33'::int2vector from generate_series(1,5))); + +select array(select '11 22 33'::int2vector from generate_series(1,5)); + +select unnest(array(select '11 22 33'::int2vector from generate_series(1,5))); + +select pg_typeof(array(select '11 22 33'::oidvector from generate_series(1,5))); + +select array(select '11 22 33'::oidvector from generate_series(1,5)); + +select unnest(array(select '11 22 33'::oidvector from generate_series(1,5))); + +select pg_typeof(array['11 22 33'::int2vector]); + +select array['11 22 33'::int2vector]; + +select pg_typeof(unnest(array['11 22 33'::int2vector])); + +select unnest(array['11 22 33'::int2vector]); + +select pg_typeof(unnest('11 22 33'::int2vector)); + +select unnest('11 22 33'::int2vector); + +select pg_typeof(array['11 22 33'::oidvector]); + +select array['11 22 33'::oidvector]; + +select pg_typeof(unnest(array['11 22 33'::oidvector])); + +select unnest(array['11 22 33'::oidvector]); + +select pg_typeof(unnest('11 22 33'::oidvector)); + +select unnest('11 22 33'::oidvector); + +create temp table t1 (f1 int8_tbl[]); + +insert into t1 (f1[5].q1) values(42); + +select * from t1; + +update t1 set f1[5].q2 = 43; + +select * from t1; + +create temp table src (f1 text); + +insert into src + select string_agg(random()::text,'') from generate_series(1,10000); + +create type textandtext as (c1 text, c2 text); + +create temp table dest (f1 textandtext[]); + +insert into dest select array[row(f1,f1)::textandtext] from src; + +select length(fipshash((f1[1]).c2)) from dest; + +delete from src; + +select length(fipshash((f1[1]).c2)) from dest; + +truncate table src; + +drop table src; + +select length(fipshash((f1[1]).c2)) from dest; + +drop table dest; + +drop type textandtext; + +SELECT + op, + width_bucket(op::numeric, ARRAY[1, 3, 5, 10.0]::numeric[]) AS wb_n1, + width_bucket(op::numeric, ARRAY[0, 5.5, 9.99]::numeric[]) AS wb_n2, + width_bucket(op::numeric, ARRAY[-6, -5, 2.0]::numeric[]) AS wb_n3, + width_bucket(op::float8, ARRAY[1, 3, 5, 10.0]::float8[]) AS wb_f1, + width_bucket(op::float8, ARRAY[0, 5.5, 9.99]::float8[]) AS wb_f2, + width_bucket(op::float8, ARRAY[-6, -5, 2.0]::float8[]) AS wb_f3 +FROM (VALUES + (-5.2), + (-0.0000000001), + (0.000000000001), + (1), + (1.99999999999999), + (2), + (2.00000000000001), + (3), + (4), + (4.5), + (5), + (5.5), + (6), + (7), + (8), + (9), + (9.99999999999999), + (10), + (10.0000000000001) +) v(op); + +SELECT + op, + width_bucket(op, ARRAY[1, 3, 9, 'NaN', 'NaN']::float8[]) AS wb +FROM (VALUES + (-5.2::float8), + (4::float8), + (77::float8), + ('NaN'::float8) +) v(op); + +SELECT + op, + width_bucket(op, ARRAY[1, 3, 5, 10]) AS wb_1 +FROM generate_series(0,11) as op; + +SELECT width_bucket(now(), + array['yesterday', 'today', 'tomorrow']::timestamptz[]); + +SELECT width_bucket(5, ARRAY[3]); + +SELECT width_bucket(5, '{}'); + +SELECT width_bucket('5'::text, ARRAY[3, 4]::integer[]); + +SELECT width_bucket(5, ARRAY[3, 4, NULL]); + +SELECT width_bucket(5, ARRAY[ARRAY[1, 2], ARRAY[3, 4]]); + +SELECT arr, trim_array(arr, 2) +FROM +(VALUES ('{1,2,3,4,5,6}'::bigint[]), + ('{1,2}'), + ('[10:16]={1,2,3,4,5,6,7}'), + ('[-15:-10]={1,2,3,4,5,6}'), + ('{{1,10},{2,20},{3,30},{4,40}}')) v(arr); + +SELECT trim_array(ARRAY[1, 2, 3], -1); + +SELECT trim_array(ARRAY[1, 2, 3], 10); + +SELECT trim_array(ARRAY[]::int[], 1); + +SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) <@ '{1,2,3,4,5,6}'; + +SELECT array_shuffle('{1,2,3,4,5,6}'::int[]) @> '{1,2,3,4,5,6}'; + +SELECT array_dims(array_shuffle('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[])); + +SELECT array_dims(array_shuffle('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[])); + +SELECT array_sample('{1,2,3,4,5,6}'::int[], 3) <@ '{1,2,3,4,5,6}'; + +SELECT array_length(array_sample('{1,2,3,4,5,6}'::int[], 3), 1); + +SELECT array_dims(array_sample('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[], 3)); + +SELECT array_dims(array_sample('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[], 2)); + +SELECT array_sample('{1,2,3,4,5,6}'::int[], -1); + +SELECT array_sample('{1,2,3,4,5,6}'::int[], 7); + +SELECT array_reverse('{}'::int[]); + +SELECT array_reverse('{1}'::int[]); + +SELECT array_reverse('{1,2}'::int[]); + +SELECT array_reverse('{1,2,3,NULL,4,5,6}'::int[]); + +SELECT array_reverse('{{1,2},{3,4},{5,6},{7,8}}'::int[]); + +SELECT array_sort('{}'::int[]); + +SELECT array_sort('{1}'::int[]); + +SELECT array_sort('{1,3,5,2,4,6}'::int[]); + +SELECT array_sort('{1.1,3.3,5.5,2.2,4.4,6.6}'::numeric[]); + +SELECT array_sort('{foo,bar,CCC,Abc,bbc}'::text[] COLLATE "C"); + +SELECT array_sort('{foo,bar,null,CCC,Abc,bbc}'::text[] COLLATE "C"); + +SELECT array_sort(ARRAY(SELECT '1 4'::int2vector UNION ALL SELECT '1 2'::int2vector)); + +SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true); + +SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false); + +SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true, true); + +SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], true, false); + +SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false, true); + +SELECT array_sort('{1.1,3.3,5.5,2.2,null,4.4,6.6}'::float8[], false, false); + +SELECT array_sort('{{1}}'::int[]); + +SELECT array_sort(ARRAY[[2,4],[2,1],[6,5]]); + +SELECT array_sort('{{"1 2","3 4"}, {"1 -2","-1 4"}}'::int2vector[]); + +SELECT array_sort('{1}'::xid[]); + +SELECT array_sort('{1,2,3}'::xid[]); + +SELECT array_sort('{{1,2,3},{2,3,4}}'::xid[]); + +SELECT array_sort(a) FROM (VALUES ('[10:12][20:21]={{1,2},{10,20},{3,4}}'::int[])) v(a); + +SELECT array_sort(a) FROM (VALUES ('[-1:0]={7,1}'::int[])) v(a); + +SELECT array_sort(a) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a); + +SELECT array_sort(a [-1:0]) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a); + +SELECT array_sort(a [-1:0][20:20]) FROM (VALUES ('[-2:0][20:21]={{1,2},{10,20},{1,-4}}'::int[])) v(a); diff --git a/crates/pgt_pretty_print/tests/data/multi/async_60.sql b/crates/pgt_pretty_print/tests/data/multi/async_60.sql new file mode 100644 index 000000000..b06d288b8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/async_60.sql @@ -0,0 +1,21 @@ +SELECT pg_notify('notify_async1','sample message1'); + +SELECT pg_notify('notify_async1',''); + +SELECT pg_notify('notify_async1',NULL); + +SELECT pg_notify('','sample message1'); + +SELECT pg_notify(NULL,'sample message1'); + +SELECT pg_notify('notify_async_channel_name_too_long______________________________','sample_message1'); + +NOTIFY notify_async2; + +LISTEN notify_async2; + +UNLISTEN notify_async2; + +UNLISTEN *; + +SELECT pg_notification_queue_usage(); diff --git a/crates/pgt_pretty_print/tests/data/multi/bit_60.sql b/crates/pgt_pretty_print/tests/data/multi/bit_60.sql new file mode 100644 index 000000000..655fe1462 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/bit_60.sql @@ -0,0 +1,292 @@ +CREATE TABLE BIT_TABLE(b BIT(11)); + +INSERT INTO BIT_TABLE VALUES (B'10'); + +INSERT INTO BIT_TABLE VALUES (B'00000000000'); + +INSERT INTO BIT_TABLE VALUES (B'11011000000'); + +INSERT INTO BIT_TABLE VALUES (B'01010101010'); + +INSERT INTO BIT_TABLE VALUES (B'101011111010'); + +SELECT * FROM BIT_TABLE; + +CREATE TABLE VARBIT_TABLE(v BIT VARYING(11)); + +INSERT INTO VARBIT_TABLE VALUES (B''); + +INSERT INTO VARBIT_TABLE VALUES (B'0'); + +INSERT INTO VARBIT_TABLE VALUES (B'010101'); + +INSERT INTO VARBIT_TABLE VALUES (B'01010101010'); + +INSERT INTO VARBIT_TABLE VALUES (B'101011111010'); + +SELECT * FROM VARBIT_TABLE; + +SELECT b' 0'; + +SELECT b'0 '; + +SELECT x' 0'; + +SELECT x'0 '; + +SELECT v, b, (v || b) AS concat + FROM BIT_TABLE, VARBIT_TABLE + ORDER BY 3; + +SELECT b, length(b) AS lb + FROM BIT_TABLE; + +SELECT v, length(v) AS lv + FROM VARBIT_TABLE; + +SELECT b, + SUBSTRING(b FROM 2 FOR 4) AS sub_2_4, + SUBSTRING(b FROM 7 FOR 13) AS sub_7_13, + SUBSTRING(b FROM 6) AS sub_6 + FROM BIT_TABLE; + +SELECT v, + SUBSTRING(v FROM 2 FOR 4) AS sub_2_4, + SUBSTRING(v FROM 7 FOR 13) AS sub_7_13, + SUBSTRING(v FROM 6) AS sub_6 + FROM VARBIT_TABLE; + +SELECT SUBSTRING('01010101'::bit(8) FROM 2 FOR 2147483646) AS "1010101"; + +SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR 2147483646) AS "01010101"; + +SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR -2147483646) AS "error"; + +SELECT SUBSTRING('01010101'::varbit FROM 2 FOR 2147483646) AS "1010101"; + +SELECT SUBSTRING('01010101'::varbit FROM -10 FOR 2147483646) AS "01010101"; + +SELECT SUBSTRING('01010101'::varbit FROM -10 FOR -2147483646) AS "error"; + +DROP TABLE varbit_table; + +CREATE TABLE varbit_table (a BIT VARYING(16), b BIT VARYING(16)); + +SELECT a, b, ~a AS "~ a", a & b AS "a & b", + a | b AS "a | b", a # b AS "a # b" FROM varbit_table; + +SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM varbit_table; + +SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM varbit_table; + +DROP TABLE varbit_table; + +DROP TABLE bit_table; + +CREATE TABLE bit_table (a BIT(16), b BIT(16)); + +SELECT a,b,~a AS "~ a",a & b AS "a & b", + a|b AS "a | b", a # b AS "a # b" FROM bit_table; + +SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM bit_table; + +SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM bit_table; + +DROP TABLE bit_table; + +select B'001' & B'10'; + +select B'0111' | B'011'; + +select B'0010' # B'011101'; + +SELECT POSITION(B'1010' IN B'0000101'); + +SELECT POSITION(B'1010' IN B'00001010'); + +SELECT POSITION(B'1010' IN B'00000101'); + +SELECT POSITION(B'1010' IN B'000001010'); + +SELECT POSITION(B'' IN B'00001010'); + +SELECT POSITION(B'0' IN B''); + +SELECT POSITION(B'' IN B''); + +SELECT POSITION(B'101101' IN B'001011011011011000'); + +SELECT POSITION(B'10110110' IN B'001011011011010'); + +SELECT POSITION(B'1011011011011' IN B'001011011011011'); + +SELECT POSITION(B'1011011011011' IN B'00001011011011011'); + +SELECT POSITION(B'11101011' IN B'11101011'); + +SELECT POSITION(B'11101011' IN B'011101011'); + +SELECT POSITION(B'11101011' IN B'00011101011'); + +SELECT POSITION(B'11101011' IN B'0000011101011'); + +SELECT POSITION(B'111010110' IN B'111010110'); + +SELECT POSITION(B'111010110' IN B'0111010110'); + +SELECT POSITION(B'111010110' IN B'000111010110'); + +SELECT POSITION(B'111010110' IN B'00000111010110'); + +SELECT POSITION(B'111010110' IN B'11101011'); + +SELECT POSITION(B'111010110' IN B'011101011'); + +SELECT POSITION(B'111010110' IN B'00011101011'); + +SELECT POSITION(B'111010110' IN B'0000011101011'); + +SELECT POSITION(B'111010110' IN B'111010110'); + +SELECT POSITION(B'111010110' IN B'0111010110'); + +SELECT POSITION(B'111010110' IN B'000111010110'); + +SELECT POSITION(B'111010110' IN B'00000111010110'); + +SELECT POSITION(B'111010110' IN B'000001110101111101011'); + +SELECT POSITION(B'111010110' IN B'0000001110101111101011'); + +SELECT POSITION(B'111010110' IN B'000000001110101111101011'); + +SELECT POSITION(B'111010110' IN B'00000000001110101111101011'); + +SELECT POSITION(B'111010110' IN B'0000011101011111010110'); + +SELECT POSITION(B'111010110' IN B'00000011101011111010110'); + +SELECT POSITION(B'111010110' IN B'0000000011101011111010110'); + +SELECT POSITION(B'111010110' IN B'000000000011101011111010110'); + +SELECT POSITION(B'000000000011101011111010110' IN B'000000000011101011111010110'); + +SELECT POSITION(B'00000000011101011111010110' IN B'000000000011101011111010110'); + +SELECT POSITION(B'0000000000011101011111010110' IN B'000000000011101011111010110'); + +CREATE TABLE BIT_SHIFT_TABLE(b BIT(16)); + +INSERT INTO BIT_SHIFT_TABLE VALUES (B'1101100000000000'); + +INSERT INTO BIT_SHIFT_TABLE SELECT b>>1 FROM BIT_SHIFT_TABLE; + +INSERT INTO BIT_SHIFT_TABLE SELECT b>>2 FROM BIT_SHIFT_TABLE; + +INSERT INTO BIT_SHIFT_TABLE SELECT b>>4 FROM BIT_SHIFT_TABLE; + +INSERT INTO BIT_SHIFT_TABLE SELECT b>>8 FROM BIT_SHIFT_TABLE; + +SELECT POSITION(B'1101' IN b), + POSITION(B'11011' IN b), + b + FROM BIT_SHIFT_TABLE ; + +SELECT b, b >> 1 AS bsr, b << 1 AS bsl + FROM BIT_SHIFT_TABLE ; + +SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8 + FROM BIT_SHIFT_TABLE ; + +SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl + FROM BIT_SHIFT_TABLE ; + +SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8 + FROM BIT_SHIFT_TABLE ; + +CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20)); + +INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011'); + +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0' AS BIT VARYING(6)) >>1 FROM VARBIT_SHIFT_TABLE; + +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00' AS BIT VARYING(8)) >>2 FROM VARBIT_SHIFT_TABLE; + +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0000' AS BIT VARYING(12)) >>4 FROM VARBIT_SHIFT_TABLE; + +INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00000000' AS BIT VARYING(20)) >>8 FROM VARBIT_SHIFT_TABLE; + +SELECT POSITION(B'1101' IN v), + POSITION(B'11011' IN v), + v + FROM VARBIT_SHIFT_TABLE ; + +SELECT v, v >> 1 AS vsr, v << 1 AS vsl + FROM VARBIT_SHIFT_TABLE ; + +SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8 + FROM VARBIT_SHIFT_TABLE ; + +DROP TABLE BIT_SHIFT_TABLE; + +DROP TABLE VARBIT_SHIFT_TABLE; + +SELECT get_bit(B'0101011000100', 10); + +SELECT set_bit(B'0101011000100100', 15, 1); + +SELECT set_bit(B'0101011000100100', 16, 1); + +SELECT overlay(B'0101011100' placing '001' from 2 for 3); + +SELECT overlay(B'0101011100' placing '101' from 6); + +SELECT overlay(B'0101011100' placing '001' from 11); + +SELECT overlay(B'0101011100' placing '001' from 20); + +SELECT bit_count(B'0101011100'::bit(10)); + +SELECT bit_count(B'1111111111'::bit(10)); + +SELECT bit_count(repeat('0', 100)::bit(100)); + +SELECT bit_count(repeat('1', 100)::bit(100)); + +SELECT bit_count(repeat('01', 500)::bit(1000)); + +SELECT bit_count(repeat('10101', 200)::bit(1000)); + +CREATE TABLE bit_defaults( + b1 bit(4) DEFAULT '1001', + b2 bit(4) DEFAULT B'0101', + b3 bit varying(5) DEFAULT '1001', + b4 bit varying(5) DEFAULT B'0101' +); + +INSERT INTO bit_defaults DEFAULT VALUES; + +TABLE bit_defaults; + +SELECT pg_input_is_valid('01010001', 'bit(10)'); + +SELECT * FROM pg_input_error_info('01010001', 'bit(10)'); + +SELECT pg_input_is_valid('01010Z01', 'bit(8)'); + +SELECT * FROM pg_input_error_info('01010Z01', 'bit(8)'); + +SELECT pg_input_is_valid('x01010Z01', 'bit(32)'); + +SELECT * FROM pg_input_error_info('x01010Z01', 'bit(32)'); + +SELECT pg_input_is_valid('01010Z01', 'varbit'); + +SELECT * FROM pg_input_error_info('01010Z01', 'varbit'); + +SELECT pg_input_is_valid('x01010Z01', 'varbit'); + +SELECT * FROM pg_input_error_info('x01010Z01', 'varbit'); diff --git a/crates/pgt_pretty_print/tests/data/multi/bitmapops_60.sql b/crates/pgt_pretty_print/tests/data/multi/bitmapops_60.sql new file mode 100644 index 000000000..4cdfc04cb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/bitmapops_60.sql @@ -0,0 +1,25 @@ +CREATE TABLE bmscantest (a int, b int, t text) WITH (autovacuum_enabled = false); + +INSERT INTO bmscantest + SELECT (r%53), (r%59), 'foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' + FROM generate_series(1,70000) r; + +CREATE INDEX i_bmtest_a ON bmscantest(a); + +CREATE INDEX i_bmtest_b ON bmscantest(b); + +set enable_indexscan=false; + +set enable_seqscan=false; + +set work_mem = 64; + +SELECT count(*) FROM bmscantest WHERE a = 1 AND b = 1; + +VACUUM (FREEZE) bmscantest; + +SELECT count(*) FROM bmscantest WHERE a = 1 AND b = 1; + +SELECT count(*) FROM bmscantest WHERE a = 1 OR b = 1; + +DROP TABLE bmscantest; diff --git a/crates/pgt_pretty_print/tests/data/multi/boolean_60.sql b/crates/pgt_pretty_print/tests/data/multi/boolean_60.sql new file mode 100644 index 000000000..f49a05c76 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/boolean_60.sql @@ -0,0 +1,238 @@ +SELECT 1 AS one; + +SELECT true AS true; + +SELECT false AS false; + +SELECT bool 't' AS true; + +SELECT bool ' f ' AS false; + +SELECT bool 'true' AS true; + +SELECT bool 'test' AS error; + +SELECT bool 'false' AS false; + +SELECT bool 'foo' AS error; + +SELECT bool 'y' AS true; + +SELECT bool 'yes' AS true; + +SELECT bool 'yeah' AS error; + +SELECT bool 'n' AS false; + +SELECT bool 'no' AS false; + +SELECT bool 'nay' AS error; + +SELECT bool 'on' AS true; + +SELECT bool 'off' AS false; + +SELECT bool 'of' AS false; + +SELECT bool 'o' AS error; + +SELECT bool 'on_' AS error; + +SELECT bool 'off_' AS error; + +SELECT bool '1' AS true; + +SELECT bool '11' AS error; + +SELECT bool '0' AS false; + +SELECT bool '000' AS error; + +SELECT bool '' AS error; + +SELECT pg_input_is_valid('true', 'bool'); + +SELECT pg_input_is_valid('asdf', 'bool'); + +SELECT * FROM pg_input_error_info('junk', 'bool'); + +SELECT bool 't' or bool 'f' AS true; + +SELECT bool 't' and bool 'f' AS false; + +SELECT not bool 'f' AS true; + +SELECT bool 't' = bool 'f' AS false; + +SELECT bool 't' <> bool 'f' AS true; + +SELECT bool 't' > bool 'f' AS true; + +SELECT bool 't' >= bool 'f' AS true; + +SELECT bool 'f' < bool 't' AS true; + +SELECT bool 'f' <= bool 't' AS true; + +SELECT 'TrUe'::text::boolean AS true, 'fAlse'::text::boolean AS false; + +SELECT ' true '::text::boolean AS true, + ' FALSE'::text::boolean AS false; + +SELECT true::boolean::text AS true, false::boolean::text AS false; + +SELECT ' tru e '::text::boolean AS invalid; + +SELECT ''::text::boolean AS invalid; + +CREATE TABLE BOOLTBL1 (f1 bool); + +INSERT INTO BOOLTBL1 (f1) VALUES (bool 't'); + +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'True'); + +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'true'); + +SELECT BOOLTBL1.* FROM BOOLTBL1; + +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 = bool 'true'; + +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 <> bool 'false'; + +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE booleq(bool 'false', f1); + +INSERT INTO BOOLTBL1 (f1) VALUES (bool 'f'); + +SELECT BOOLTBL1.* + FROM BOOLTBL1 + WHERE f1 = bool 'false'; + +CREATE TABLE BOOLTBL2 (f1 bool); + +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'f'); + +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'false'); + +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'False'); + +INSERT INTO BOOLTBL2 (f1) VALUES (bool 'FALSE'); + +INSERT INTO BOOLTBL2 (f1) + VALUES (bool 'XXX'); + +SELECT BOOLTBL2.* FROM BOOLTBL2; + +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 <> BOOLTBL1.f1; + +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE boolne(BOOLTBL2.f1,BOOLTBL1.f1); + +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 = BOOLTBL1.f1 and BOOLTBL1.f1 = bool 'false'; + +SELECT BOOLTBL1.*, BOOLTBL2.* + FROM BOOLTBL1, BOOLTBL2 + WHERE BOOLTBL2.f1 = BOOLTBL1.f1 or BOOLTBL1.f1 = bool 'true' + ORDER BY BOOLTBL1.f1, BOOLTBL2.f1; + +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS TRUE; + +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS NOT FALSE; + +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS FALSE; + +SELECT f1 + FROM BOOLTBL1 + WHERE f1 IS NOT TRUE; + +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS TRUE; + +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS NOT FALSE; + +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS FALSE; + +SELECT f1 + FROM BOOLTBL2 + WHERE f1 IS NOT TRUE; + +CREATE TABLE BOOLTBL3 (d text, b bool, o int); + +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('true', true, 1); + +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('false', false, 2); + +INSERT INTO BOOLTBL3 (d, b, o) VALUES ('null', null, 3); + +SELECT + d, + b IS TRUE AS istrue, + b IS NOT TRUE AS isnottrue, + b IS FALSE AS isfalse, + b IS NOT FALSE AS isnotfalse, + b IS UNKNOWN AS isunknown, + b IS NOT UNKNOWN AS isnotunknown +FROM booltbl3 ORDER BY o; + +CREATE TABLE booltbl4(isfalse bool, istrue bool, isnul bool); + +INSERT INTO booltbl4 VALUES (false, true, null); + +SELECT istrue AND isnul AND istrue FROM booltbl4; + +SELECT istrue AND istrue AND isnul FROM booltbl4; + +SELECT isnul AND istrue AND istrue FROM booltbl4; + +SELECT isfalse AND isnul AND istrue FROM booltbl4; + +SELECT istrue AND isfalse AND isnul FROM booltbl4; + +SELECT isnul AND istrue AND isfalse FROM booltbl4; + +SELECT isfalse OR isnul OR isfalse FROM booltbl4; + +SELECT isfalse OR isfalse OR isnul FROM booltbl4; + +SELECT isnul OR isfalse OR isfalse FROM booltbl4; + +SELECT isfalse OR isnul OR istrue FROM booltbl4; + +SELECT istrue OR isfalse OR isnul FROM booltbl4; + +SELECT isnul OR istrue OR isfalse FROM booltbl4; + +SELECT 0::boolean; + +SELECT 1::boolean; + +SELECT 2::boolean; + +DROP TABLE BOOLTBL1; + +DROP TABLE BOOLTBL2; + +DROP TABLE BOOLTBL3; + +DROP TABLE BOOLTBL4; diff --git a/crates/pgt_pretty_print/tests/data/multi/box_60.sql b/crates/pgt_pretty_print/tests/data/multi/box_60.sql new file mode 100644 index 000000000..28ede3de7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/box_60.sql @@ -0,0 +1,268 @@ +CREATE TABLE BOX_TBL (f1 box); + +INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)'); + +INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)'); + +INSERT INTO BOX_TBL (f1) VALUES ('((-8, 2), (-2, -10))'); + +INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)'); + +INSERT INTO BOX_TBL (f1) VALUES ('(3.0, 3.0,3.0,3.0)'); + +INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)'); + +INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)'); + +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]'); + +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x'); + +INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad'); + +SELECT * FROM BOX_TBL; + +SELECT b.*, area(b.f1) as barea + FROM BOX_TBL b; + +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 && box '(2.5,2.5,1.0,1.0)'; + +SELECT b1.* + FROM BOX_TBL b1 + WHERE b1.f1 &< box '(2.0,2.0,2.5,2.5)'; + +SELECT b1.* + FROM BOX_TBL b1 + WHERE b1.f1 &> box '(2.0,2.0,2.5,2.5)'; + +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 << box '(3.0,3.0,5.0,5.0)'; + +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 <= box '(3.0,3.0,5.0,5.0)'; + +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 < box '(3.0,3.0,5.0,5.0)'; + +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 = box '(3.0,3.0,5.0,5.0)'; + +SELECT b.f1 + FROM BOX_TBL b -- zero area + WHERE b.f1 > box '(3.5,3.0,4.5,3.0)'; + +SELECT b.f1 + FROM BOX_TBL b -- zero area + WHERE b.f1 >= box '(3.5,3.0,4.5,3.0)'; + +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(3.0,3.0,5.0,5.0)' >> b.f1; + +SELECT b.f1 + FROM BOX_TBL b + WHERE b.f1 <@ box '(0,0,3,3)'; + +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(0,0,3,3)' @> b.f1; + +SELECT b.f1 + FROM BOX_TBL b + WHERE box '(1,1,3,3)' ~= b.f1; + +SELECT @@(b1.f1) AS p + FROM BOX_TBL b1; + +SELECT b1.*, b2.* + FROM BOX_TBL b1, BOX_TBL b2 + WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1; + +SELECT height(f1), width(f1) FROM BOX_TBL; + +CREATE TEMPORARY TABLE box_temp (f1 box); + +INSERT INTO box_temp + SELECT box(point(i, i), point(i * 2, i * 2)) + FROM generate_series(1, 50) AS i; + +CREATE INDEX box_spgist ON box_temp USING spgist (f1); + +INSERT INTO box_temp + VALUES (NULL), + ('(0,0)(0,100)'), + ('(-3,4.3333333333)(40,1)'), + ('(0,100)(0,infinity)'), + ('(-infinity,0)(0,infinity)'), + ('(-infinity,-infinity)(infinity,infinity)'); + +SET enable_seqscan = false; + +SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)'; + +SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)'; + +SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)'; + +SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)'; + +SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)'; + +SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)'; + +SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)'; + +SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)'; + +SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)'; + +SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)'; + +SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)'; + +SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)'; + +SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)'; + +SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)'; + +SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)'; + +SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)'; + +SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)'; + +SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)'; + +SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)'; + +SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)'; + +SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)'; + +SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)'; + +SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)'; + +SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)'; + +RESET enable_seqscan; + +DROP INDEX box_spgist; + +CREATE TABLE quad_box_tbl (id int, b box); + +INSERT INTO quad_box_tbl + SELECT (x - 1) * 100 + y, box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y; + +INSERT INTO quad_box_tbl + SELECT i, '((200, 300),(210, 310))' + FROM generate_series(10001, 11000) AS i; + +INSERT INTO quad_box_tbl +VALUES + (11001, NULL), + (11002, NULL), + (11003, '((-infinity,-infinity),(infinity,infinity))'), + (11004, '((-infinity,100),(-infinity,500))'), + (11005, '((-infinity,-infinity),(700,infinity))'); + +CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b); + +SET enable_seqscan = ON; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = OFF; + +CREATE TABLE quad_box_tbl_ord_seq1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; + +CREATE TABLE quad_box_tbl_ord_seq2 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; + +SET enable_seqscan = OFF; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = ON; + +SELECT count(*) FROM quad_box_tbl WHERE b << box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b &< box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b && box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b &> box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b <<| box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b &<| box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b |&> box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b |>> box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b @> box '((201,301),(202,303))'; + +SELECT count(*) FROM quad_box_tbl WHERE b <@ box '((100,200),(300,500))'; + +SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))'; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = OFF; + +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; + +CREATE TEMP TABLE quad_box_tbl_ord_idx1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; + +SELECT * +FROM quad_box_tbl_ord_seq1 seq FULL JOIN quad_box_tbl_ord_idx1 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; + +CREATE TEMP TABLE quad_box_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; + +SELECT * +FROM quad_box_tbl_ord_seq2 seq FULL JOIN quad_box_tbl_ord_idx2 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +SELECT pg_input_is_valid('200', 'box'); + +SELECT * FROM pg_input_error_info('200', 'box'); + +SELECT pg_input_is_valid('((200,300),(500, xyz))', 'box'); + +SELECT * FROM pg_input_error_info('((200,300),(500, xyz))', 'box'); diff --git a/crates/pgt_pretty_print/tests/data/multi/brin_60.sql b/crates/pgt_pretty_print/tests/data/multi/brin_60.sql new file mode 100644 index 000000000..c32e462e1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/brin_60.sql @@ -0,0 +1,552 @@ +CREATE TABLE brintest (byteacol bytea, + charcol "char", + namecol name, + int8col bigint, + int2col smallint, + int4col integer, + textcol text, + oidcol oid, + tidcol tid, + float4col real, + float8col double precision, + macaddrcol macaddr, + inetcol inet, + cidrcol cidr, + bpcharcol character, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + bitcol bit(10), + varbitcol bit varying(16), + numericcol numeric, + uuidcol uuid, + int4rangecol int4range, + lsncol pg_lsn, + boxcol box +) WITH (fillfactor=10, autovacuum_enabled=off); + +INSERT INTO brintest SELECT + repeat(stringu1, 8)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 8), + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + thousand::bit(10), + tenthous::bit(16)::varbit, + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) +FROM tenk1 ORDER BY unique2 LIMIT 100; + +INSERT INTO brintest (inetcol, cidrcol, int4rangecol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous, + 'empty'::int4range +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25; + +CREATE INDEX brinidx ON brintest USING brin ( + byteacol, + charcol, + namecol, + int8col, + int2col, + int4col, + textcol, + oidcol, + tidcol, + float4col, + float8col, + macaddrcol, + inetcol inet_inclusion_ops, + inetcol inet_minmax_ops, + cidrcol inet_inclusion_ops, + cidrcol inet_minmax_ops, + bpcharcol, + datecol, + timecol, + timestampcol, + timestamptzcol, + intervalcol, + timetzcol, + bitcol, + varbitcol, + numericcol, + uuidcol, + int4rangecol, + lsncol, + boxcol +) with (pages_per_range = 1); + +CREATE TABLE brinopers (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))); + +INSERT INTO brinopers VALUES + ('byteacol', 'bytea', + '{>, >=, =, <=, <}', + '{AAAAAA, AAAAAA, BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA, ZZZZZZ, ZZZZZZ}', + '{100, 100, 1, 100, 100}'), + ('charcol', '"char"', + '{>, >=, =, <=, <}', + '{A, A, M, Z, Z}', + '{97, 100, 6, 100, 98}'), + ('namecol', 'name', + '{>, >=, =, <=, <}', + '{AAAAAA, AAAAAA, MAAAAA, ZZAAAA, ZZAAAA}', + '{100, 100, 2, 100, 100}'), + ('int2col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int8col', 'int2', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int4', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 1257141600, 1428427143, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('textcol', 'text', + '{>, >=, =, <=, <}', + '{ABABAB, ABABAB, BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA, ZZAAAA, ZZAAAA}', + '{100, 100, 1, 100, 100}'), + ('oidcol', 'oid', + '{>, >=, =, <=, <}', + '{0, 0, 8800, 9999, 9999}', + '{100, 100, 1, 100, 100}'), + ('tidcol', 'tid', + '{>, >=, =, <=, <}', + '{"(0,0)", "(0,0)", "(8800,0)", "(9999,19)", "(9999,19)"}', + '{100, 100, 1, 100, 100}'), + ('float4col', 'float4', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float4col', 'float8', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float8col', 'float4', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('float8col', 'float8', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('macaddrcol', 'macaddr', + '{>, >=, =, <=, <}', + '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}', + '{99, 100, 2, 100, 100}'), + ('inetcol', 'inet', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}', + '{100, 1, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('inetcol', 'inet', + '{&&, >>=, <<=, =}', + '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('inetcol', 'cidr', + '{&&, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}', + '{100, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('inetcol', 'cidr', + '{&&, >>=, <<=, =}', + '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('cidrcol', 'inet', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14.231/24, 10.2.14.231/25, 10.2.14.231/8, 0/0}', + '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('cidrcol', 'inet', + '{&&, >>=, <<=, =}', + '{fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46, fe80::6e40:8ff:fea9:a673/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('cidrcol', 'cidr', + '{&&, =, <, <=, >, >=, >>=, >>, <<=, <<}', + '{10/8, 10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0, 10.2.14/24, 10.2.14/25, 10/8, 0/0}', + '{100, 2, 100, 100, 125, 125, 2, 2, 100, 100}'), + ('cidrcol', 'cidr', + '{&&, >>=, <<=, =}', + '{fe80::/32, fe80::6e40:8ff:fea9:8c46, fe80::/32, fe80::6e40:8ff:fea9:8c46}', + '{25, 1, 25, 1}'), + ('bpcharcol', 'bpchar', + '{>, >=, =, <=, <}', + '{A, A, W, Z, Z}', + '{97, 100, 6, 100, 98}'), + ('datecol', 'date', + '{>, >=, =, <=, <}', + '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}', + '{100, 100, 1, 100, 100}'), + ('timecol', 'time', + '{>, >=, =, <=, <}', + '{01:20:30, 01:20:30, 02:28:57, 06:28:31.5, 06:28:31.5}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamp', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestamptzcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-19 09:00:00-07, 1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03}', + '{100, 100, 1, 100, 100}'), + ('intervalcol', 'interval', + '{>, >=, =, <=, <}', + '{00:00:00, 00:00:00, 1 mons 13 days 12:24, 2 mons 23 days 07:48:00, 1 year}', + '{100, 100, 1, 100, 100}'), + ('timetzcol', 'timetz', + '{>, >=, =, <=, <}', + '{01:30:20+02, 01:30:20+02, 01:35:50+02, 23:55:05+02, 23:55:05+02}', + '{99, 100, 2, 100, 100}'), + ('bitcol', 'bit(10)', + '{>, >=, =, <=, <}', + '{0000000010, 0000000010, 0011011110, 1111111000, 1111111000}', + '{100, 100, 1, 100, 100}'), + ('varbitcol', 'varbit(16)', + '{>, >=, =, <=, <}', + '{0000000000000100, 0000000000000100, 0001010001100110, 1111111111111000, 1111111111111000}', + '{100, 100, 1, 100, 100}'), + ('numericcol', 'numeric', + '{>, >=, =, <=, <}', + '{0.00, 0.01, 2268164.347826086956521739130434782609, 99470151.9, 99470151.9}', + '{100, 100, 1, 100, 100}'), + ('uuidcol', 'uuid', + '{>, >=, =, <=, <}', + '{00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 52225222-5222-5222-5222-522252225222, 99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998}', + '{100, 100, 1, 100, 100}'), + ('int4rangecol', 'int4range', + '{<<, &<, &&, &>, >>, @>, <@, =, <, <=, >, >=}', + '{"[10000,)","[10000,)","(,]","[3,4)","[36,44)","(1500,1501]","[3,4)","[222,1222)","[36,44)","[43,1043)","[367,4466)","[519,)"}', + '{53, 53, 53, 53, 50, 22, 72, 1, 74, 75, 34, 21}'), + ('int4rangecol', 'int4range', + '{@>, <@, =, <=, >, >=}', + '{empty, empty, empty, empty, empty, empty}', + '{125, 72, 72, 72, 53, 125}'), + ('int4rangecol', 'int4', + '{@>}', + '{1500}', + '{22}'), + ('lsncol', 'pg_lsn', + '{>, >=, =, <=, <, IS, IS NOT}', + '{0/1200, 0/1200, 44/455222, 198/1999799, 198/1999799, NULL, NULL}', + '{100, 100, 1, 100, 100, 25, 100}'), + ('boxcol', 'point', + '{@>}', + '{"(500,43)"}', + '{11}'), + ('boxcol', 'box', + '{<<, &<, &&, &>, >>, <<|, &<|, |&>, |>>, @>, <@, ~=}', + '{"((1000,2000),(3000,4000))","((1,2),(3000,4000))","((1,2),(3000,4000))","((1,2),(3000,4000))","((1,2),(3,4))","((1000,2000),(3000,4000))","((1,2000),(3,4000))","((1000,2),(3000,4))","((1,2),(3,4))","((1,2),(300,400))","((1,2),(3000,4000))","((222,1222),(44,45))"}', + '{100, 100, 100, 99, 96, 100, 100, 99, 96, 1, 99, 1}'); + +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$; + +RESET enable_seqscan; + +RESET enable_bitmapscan; + +INSERT INTO brintest SELECT + repeat(stringu1, 42)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 42), + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + thousand::bit(10), + tenthous::bit(16)::varbit, + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5; + +SELECT brin_desummarize_range('brinidx', 0); + +VACUUM brintest; + +UPDATE brintest SET int8col = int8col * int4col; + +UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL; + +SELECT brin_summarize_new_values('brintest'); + +SELECT brin_summarize_new_values('tenk1_unique1'); + +SELECT brin_summarize_new_values('brinidx'); + +SELECT brin_desummarize_range('brinidx', -1); + +SELECT brin_desummarize_range('brinidx', 0); + +SELECT brin_desummarize_range('brinidx', 0); + +SELECT brin_desummarize_range('brinidx', 100000000); + +CREATE TABLE brin_summarize ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false); + +CREATE INDEX brin_summarize_idx ON brin_summarize USING brin (value) WITH (pages_per_range=2); + +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$; + +SELECT brin_summarize_range('brin_summarize_idx', 0); + +SELECT brin_summarize_range('brin_summarize_idx', 1); + +SELECT brin_summarize_range('brin_summarize_idx', 2); + +SELECT brin_summarize_range('brin_summarize_idx', 4294967295); + +SELECT brin_summarize_range('brin_summarize_idx', -1); + +SELECT brin_summarize_range('brin_summarize_idx', 4294967296); + +CREATE TABLE brintest_2 (n numrange); + +CREATE INDEX brinidx_2 ON brintest_2 USING brin (n); + +INSERT INTO brintest_2 VALUES ('empty'); + +INSERT INTO brintest_2 VALUES (numrange(0, 2^1000::numeric)); + +INSERT INTO brintest_2 VALUES ('(-1, 0)'); + +SELECT brin_desummarize_range('brinidx', 0); + +SELECT brin_summarize_range('brinidx', 0); + +DROP TABLE brintest_2; + +CREATE TABLE brin_test (a INT, b INT); + +INSERT INTO brin_test SELECT x/100,x%100 FROM generate_series(1,10000) x(x); + +CREATE INDEX brin_test_a_idx ON brin_test USING brin (a) WITH (pages_per_range = 2); + +CREATE INDEX brin_test_b_idx ON brin_test USING brin (b) WITH (pages_per_range = 2); + +VACUUM ANALYZE brin_test; + +SELECT * FROM brin_test WHERE a = 1; + +SELECT * FROM brin_test WHERE b = 1; + +CREATE TABLE brintest_3 (a text, b text, c text, d text); + +WITH rand_value AS (SELECT string_agg(fipshash(i::text),'') AS val FROM generate_series(1,60) s(i)) +INSERT INTO brintest_3 +SELECT val, val, val, val FROM rand_value; + +CREATE INDEX brin_test_toast_idx ON brintest_3 USING brin (b, c); + +DELETE FROM brintest_3; + +CREATE INDEX CONCURRENTLY brin_test_temp_idx ON brintest_3(a); + +DROP INDEX brin_test_temp_idx; + +VACUUM brintest_3; + +WITH rand_value AS (SELECT string_agg(fipshash((-i)::text),'') AS val FROM generate_series(1,60) s(i)) +INSERT INTO brintest_3 +SELECT val, val, val, val FROM rand_value; + +SET enable_seqscan = off; + +SELECT * FROM brintest_3 WHERE b < '0'; + +SELECT * FROM brintest_3 WHERE b < '0'; + +DROP TABLE brintest_3; + +RESET enable_seqscan; + +CREATE TABLE brintest_expr (n int); + +CREATE FUNCTION brintest_func() RETURNS int LANGUAGE sql IMMUTABLE RETURN 0; + +BEGIN; + +SET LOCAL min_parallel_table_scan_size = 0; + +SET LOCAL max_parallel_maintenance_workers = 4; + +CREATE INDEX brintest_expr_idx ON brintest_expr USING brin (brintest_func()); + +COMMIT; + +DROP TABLE brintest_expr; + +DROP FUNCTION brintest_func(); + +CREATE UNLOGGED TABLE brintest_unlogged (n numrange); + +CREATE INDEX brinidx_unlogged ON brintest_unlogged USING brin (n); + +INSERT INTO brintest_unlogged VALUES (numrange(0, 2^1000::numeric)); + +DROP TABLE brintest_unlogged; + +CREATE TABLE brin_insert_optimization (a int); + +INSERT INTO brin_insert_optimization VALUES (1); + +CREATE INDEX brin_insert_optimization_idx ON brin_insert_optimization USING brin (a); + +UPDATE brin_insert_optimization SET a = a; + +REINDEX INDEX CONCURRENTLY brin_insert_optimization_idx; + +DROP TABLE brin_insert_optimization; diff --git a/crates/pgt_pretty_print/tests/data/multi/brin_bloom_60.sql b/crates/pgt_pretty_print/tests/data/multi/brin_bloom_60.sql new file mode 100644 index 000000000..ab5357c04 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/brin_bloom_60.sql @@ -0,0 +1,381 @@ +CREATE TABLE brintest_bloom (byteacol bytea, + charcol "char", + namecol name, + int8col bigint, + int2col smallint, + int4col integer, + textcol text, + oidcol oid, + float4col real, + float8col double precision, + macaddrcol macaddr, + inetcol inet, + cidrcol cidr, + bpcharcol character, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + numericcol numeric, + uuidcol uuid, + lsncol pg_lsn +) WITH (fillfactor=10); + +INSERT INTO brintest_bloom SELECT + repeat(stringu1, 8)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 8), + unique1::oid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 100; + +INSERT INTO brintest_bloom (inetcol, cidrcol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25; + +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(n_distinct_per_range = -1.1) +); + +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(false_positive_rate = 0.00009) +); + +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops(false_positive_rate = 0.26) +); + +CREATE INDEX brinidx_bloom ON brintest_bloom USING brin ( + byteacol bytea_bloom_ops, + charcol char_bloom_ops, + namecol name_bloom_ops, + int8col int8_bloom_ops, + int2col int2_bloom_ops, + int4col int4_bloom_ops, + textcol text_bloom_ops, + oidcol oid_bloom_ops, + float4col float4_bloom_ops, + float8col float8_bloom_ops, + macaddrcol macaddr_bloom_ops, + inetcol inet_bloom_ops, + cidrcol inet_bloom_ops, + bpcharcol bpchar_bloom_ops, + datecol date_bloom_ops, + timecol time_bloom_ops, + timestampcol timestamp_bloom_ops, + timestamptzcol timestamptz_bloom_ops, + intervalcol interval_bloom_ops, + timetzcol timetz_bloom_ops, + numericcol numeric_bloom_ops, + uuidcol uuid_bloom_ops, + lsncol pg_lsn_bloom_ops +) with (pages_per_range = 1); + +CREATE TABLE brinopers_bloom (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))); + +INSERT INTO brinopers_bloom VALUES + ('byteacol', 'bytea', + '{=}', + '{BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA}', + '{1}'), + ('charcol', '"char"', + '{=}', + '{M}', + '{6}'), + ('namecol', 'name', + '{=}', + '{MAAAAA}', + '{2}'), + ('int2col', 'int2', + '{=}', + '{800}', + '{1}'), + ('int4col', 'int4', + '{=}', + '{800}', + '{1}'), + ('int8col', 'int8', + '{=}', + '{1257141600}', + '{1}'), + ('textcol', 'text', + '{=}', + '{BNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAABNAAAA}', + '{1}'), + ('oidcol', 'oid', + '{=}', + '{8800}', + '{1}'), + ('float4col', 'float4', + '{=}', + '{1}', + '{4}'), + ('float8col', 'float8', + '{=}', + '{0}', + '{1}'), + ('macaddrcol', 'macaddr', + '{=}', + '{2c:00:2d:00:16:00}', + '{2}'), + ('inetcol', 'inet', + '{=}', + '{10.2.14.231/24}', + '{1}'), + ('inetcol', 'cidr', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('cidrcol', 'inet', + '{=}', + '{10.2.14/24}', + '{2}'), + ('cidrcol', 'inet', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('cidrcol', 'cidr', + '{=}', + '{10.2.14/24}', + '{2}'), + ('cidrcol', 'cidr', + '{=}', + '{fe80::6e40:8ff:fea9:8c46}', + '{1}'), + ('bpcharcol', 'bpchar', + '{=}', + '{W}', + '{6}'), + ('datecol', 'date', + '{=}', + '{2009-12-01}', + '{1}'), + ('timecol', 'time', + '{=}', + '{02:28:57}', + '{1}'), + ('timestampcol', 'timestamp', + '{=}', + '{1964-03-24 19:26:45}', + '{1}'), + ('timestamptzcol', 'timestamptz', + '{=}', + '{1972-10-19 09:00:00-07}', + '{1}'), + ('intervalcol', 'interval', + '{=}', + '{1 mons 13 days 12:24}', + '{1}'), + ('timetzcol', 'timetz', + '{=}', + '{01:35:50+02}', + '{2}'), + ('numericcol', 'numeric', + '{=}', + '{2268164.347826086956521739130434782609}', + '{1}'), + ('uuidcol', 'uuid', + '{=}', + '{52225222-5222-5222-5222-522252225222}', + '{1}'), + ('lsncol', 'pg_lsn', + '{=, IS, IS NOT}', + '{44/455222, NULL, NULL}', + '{1, 25, 100}'); + +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers_bloom, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest_bloom%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest_bloom%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_bloom WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_bloom WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_bloom WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$; + +RESET enable_seqscan; + +RESET enable_bitmapscan; + +INSERT INTO brintest_bloom SELECT + repeat(stringu1, 42)::bytea, + substr(stringu1, 1, 1)::"char", + stringu1::name, 142857 * tenthous, + thousand, + twothousand, + repeat(stringu1, 42), + unique1::oid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + substr(stringu1, 1, 1)::bpchar, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5; + +SELECT brin_desummarize_range('brinidx_bloom', 0); + +VACUUM brintest_bloom; + +UPDATE brintest_bloom SET int8col = int8col * int4col; + +UPDATE brintest_bloom SET textcol = '' WHERE textcol IS NOT NULL; + +SELECT brin_summarize_new_values('brintest_bloom'); + +SELECT brin_summarize_new_values('tenk1_unique1'); + +SELECT brin_summarize_new_values('brinidx_bloom'); + +SELECT brin_desummarize_range('brinidx_bloom', -1); + +SELECT brin_desummarize_range('brinidx_bloom', 0); + +SELECT brin_desummarize_range('brinidx_bloom', 0); + +SELECT brin_desummarize_range('brinidx_bloom', 100000000); + +CREATE TABLE brin_summarize_bloom ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false); + +CREATE INDEX brin_summarize_bloom_idx ON brin_summarize_bloom USING brin (value) WITH (pages_per_range=2); + +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize_bloom VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$; + +SELECT brin_summarize_range('brin_summarize_bloom_idx', 0); + +SELECT brin_summarize_range('brin_summarize_bloom_idx', 1); + +SELECT brin_summarize_range('brin_summarize_bloom_idx', 2); + +SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967295); + +SELECT brin_summarize_range('brin_summarize_bloom_idx', -1); + +SELECT brin_summarize_range('brin_summarize_bloom_idx', 4294967296); + +CREATE TABLE brin_test_bloom (a INT, b INT); + +INSERT INTO brin_test_bloom SELECT x/100,x%100 FROM generate_series(1,10000) x(x); + +CREATE INDEX brin_test_bloom_a_idx ON brin_test_bloom USING brin (a) WITH (pages_per_range = 2); + +CREATE INDEX brin_test_bloom_b_idx ON brin_test_bloom USING brin (b) WITH (pages_per_range = 2); + +VACUUM ANALYZE brin_test_bloom; + +SELECT * FROM brin_test_bloom WHERE a = 1; + +SELECT * FROM brin_test_bloom WHERE b = 1; diff --git a/crates/pgt_pretty_print/tests/data/multi/brin_multi_60.sql b/crates/pgt_pretty_print/tests/data/multi/brin_multi_60.sql new file mode 100644 index 000000000..f6db719da --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/brin_multi_60.sql @@ -0,0 +1,684 @@ +CREATE TABLE brintest_multi ( + int8col bigint, + int2col smallint, + int4col integer, + oidcol oid, + tidcol tid, + float4col real, + float8col double precision, + macaddrcol macaddr, + macaddr8col macaddr8, + inetcol inet, + cidrcol cidr, + datecol date, + timecol time without time zone, + timestampcol timestamp without time zone, + timestamptzcol timestamp with time zone, + intervalcol interval, + timetzcol time with time zone, + numericcol numeric, + uuidcol uuid, + lsncol pg_lsn +) WITH (fillfactor=10); + +INSERT INTO brintest_multi SELECT + 142857 * tenthous, + thousand, + twothousand, + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + substr(fipshash(unique1::text), 1, 16)::macaddr8, + inet '10.2.3.4/24' + tenthous, + cidr '10.2.3/24' + tenthous, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20+02' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 100; + +INSERT INTO brintest_multi (inetcol, cidrcol) SELECT + inet 'fe80::6e40:8ff:fea9:8c46' + tenthous, + cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous +FROM tenk1 ORDER BY thousand, tenthous LIMIT 25; + +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops(values_per_range = 7) +); + +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops(values_per_range = 257) +); + +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops, + int2col int2_minmax_multi_ops, + int4col int4_minmax_multi_ops, + oidcol oid_minmax_multi_ops, + tidcol tid_minmax_multi_ops, + float4col float4_minmax_multi_ops, + float8col float8_minmax_multi_ops, + macaddrcol macaddr_minmax_multi_ops, + macaddr8col macaddr8_minmax_multi_ops, + inetcol inet_minmax_multi_ops, + cidrcol inet_minmax_multi_ops, + datecol date_minmax_multi_ops, + timecol time_minmax_multi_ops, + timestampcol timestamp_minmax_multi_ops, + timestamptzcol timestamptz_minmax_multi_ops, + intervalcol interval_minmax_multi_ops, + timetzcol timetz_minmax_multi_ops, + numericcol numeric_minmax_multi_ops, + uuidcol uuid_minmax_multi_ops, + lsncol pg_lsn_minmax_multi_ops +); + +DROP INDEX brinidx_multi; + +CREATE INDEX brinidx_multi ON brintest_multi USING brin ( + int8col int8_minmax_multi_ops, + int2col int2_minmax_multi_ops, + int4col int4_minmax_multi_ops, + oidcol oid_minmax_multi_ops, + tidcol tid_minmax_multi_ops, + float4col float4_minmax_multi_ops, + float8col float8_minmax_multi_ops, + macaddrcol macaddr_minmax_multi_ops, + macaddr8col macaddr8_minmax_multi_ops, + inetcol inet_minmax_multi_ops, + cidrcol inet_minmax_multi_ops, + datecol date_minmax_multi_ops, + timecol time_minmax_multi_ops, + timestampcol timestamp_minmax_multi_ops, + timestamptzcol timestamptz_minmax_multi_ops, + intervalcol interval_minmax_multi_ops, + timetzcol timetz_minmax_multi_ops, + numericcol numeric_minmax_multi_ops, + uuidcol uuid_minmax_multi_ops, + lsncol pg_lsn_minmax_multi_ops +) with (pages_per_range = 1); + +CREATE TABLE brinopers_multi (colname name, typ text, + op text[], value text[], matches int[], + check (cardinality(op) = cardinality(value)), + check (cardinality(op) = cardinality(matches))); + +INSERT INTO brinopers_multi VALUES + ('int2col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int2col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int2', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int4', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1999}', + '{100, 100, 1, 100, 100}'), + ('int4col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 800, 1999, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('int8col', 'int2', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int4', + '{>, >=}', + '{0, 0}', + '{100, 100}'), + ('int8col', 'int8', + '{>, >=, =, <=, <}', + '{0, 0, 1257141600, 1428427143, 1428427143}', + '{100, 100, 1, 100, 100}'), + ('oidcol', 'oid', + '{>, >=, =, <=, <}', + '{0, 0, 8800, 9999, 9999}', + '{100, 100, 1, 100, 100}'), + ('tidcol', 'tid', + '{>, >=, =, <=, <}', + '{"(0,0)", "(0,0)", "(8800,0)", "(9999,19)", "(9999,19)"}', + '{100, 100, 1, 100, 100}'), + ('float4col', 'float4', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float4col', 'float8', + '{>, >=, =, <=, <}', + '{0.0103093, 0.0103093, 1, 1, 1}', + '{100, 100, 4, 100, 96}'), + ('float8col', 'float4', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('float8col', 'float8', + '{>, >=, =, <=, <}', + '{0, 0, 0, 1.98, 1.98}', + '{99, 100, 1, 100, 100}'), + ('macaddrcol', 'macaddr', + '{>, >=, =, <=, <}', + '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}', + '{99, 100, 2, 100, 100}'), + ('macaddr8col', 'macaddr8', + '{>, >=, =, <=, <}', + '{b1:d1:0e:7b:af:a4:42:12, d9:35:91:bd:f7:86:0e:1e, 72:8f:20:6c:2a:01:bf:57, 23:e8:46:63:86:07:ad:cb, 13:16:8e:6a:2e:6c:84:b4}', + '{31, 17, 1, 11, 4}'), + ('inetcol', 'inet', + '{=, <, <=, >, >=}', + '{10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{1, 100, 100, 125, 125}'), + ('inetcol', 'cidr', + '{<, <=, >, >=}', + '{255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{100, 100, 125, 125}'), + ('cidrcol', 'inet', + '{=, <, <=, >, >=}', + '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{2, 100, 100, 125, 125}'), + ('cidrcol', 'cidr', + '{=, <, <=, >, >=}', + '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}', + '{2, 100, 100, 125, 125}'), + ('datecol', 'date', + '{>, >=, =, <=, <}', + '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}', + '{100, 100, 1, 100, 100}'), + ('timecol', 'time', + '{>, >=, =, <=, <}', + '{01:20:30, 01:20:30, 02:28:57, 06:28:31.5, 06:28:31.5}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamp', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestampcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}', + '{100, 100, 1, 100, 100}'), + ('timestamptzcol', 'timestamptz', + '{>, >=, =, <=, <}', + '{1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-19 09:00:00-07, 1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03}', + '{100, 100, 1, 100, 100}'), + ('intervalcol', 'interval', + '{>, >=, =, <=, <}', + '{00:00:00, 00:00:00, 1 mons 13 days 12:24, 2 mons 23 days 07:48:00, 1 year}', + '{100, 100, 1, 100, 100}'), + ('timetzcol', 'timetz', + '{>, >=, =, <=, <}', + '{01:30:20+02, 01:30:20+02, 01:35:50+02, 23:55:05+02, 23:55:05+02}', + '{99, 100, 2, 100, 100}'), + ('numericcol', 'numeric', + '{>, >=, =, <=, <}', + '{0.00, 0.01, 2268164.347826086956521739130434782609, 99470151.9, 99470151.9}', + '{100, 100, 1, 100, 100}'), + ('uuidcol', 'uuid', + '{>, >=, =, <=, <}', + '{00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 52225222-5222-5222-5222-522252225222, 99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998}', + '{100, 100, 1, 100, 100}'), + ('lsncol', 'pg_lsn', + '{>, >=, =, <=, <, IS, IS NOT}', + '{0/1200, 0/1200, 44/455222, 198/1999799, 198/1999799, NULL, NULL}', + '{100, 100, 1, 100, 100, 25, 100}'); + +DO $x$ +DECLARE + r record; + r2 record; + cond text; + idx_ctids tid[]; + ss_ctids tid[]; + count int; + plan_ok bool; + plan_line text; +BEGIN + FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers_multi, unnest(op) WITH ORDINALITY AS oper LOOP + + -- prepare the condition + IF r.value IS NULL THEN + cond := format('%I %s %L', r.colname, r.oper, r.value); + ELSE + cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ); + END IF; + + -- run the query using the brin index + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Bitmap Heap Scan on brintest_multi%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get bitmap indexscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) + INTO idx_ctids; + + -- run the query using a seqscan + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + + plan_ok := false; + FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP + IF plan_line LIKE '%Seq Scan on brintest_multi%' THEN + plan_ok := true; + END IF; + END LOOP; + IF NOT plan_ok THEN + RAISE WARNING 'did not get seqscan plan for %', r; + END IF; + + EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) + INTO ss_ctids; + + -- make sure both return the same results + count := array_length(idx_ctids, 1); + + IF NOT (count = array_length(ss_ctids, 1) AND + idx_ctids @> ss_ctids AND + idx_ctids <@ ss_ctids) THEN + -- report the results of each scan to make the differences obvious + RAISE WARNING 'something not right in %: count %', r, count; + SET enable_seqscan = 1; + SET enable_bitmapscan = 0; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP + RAISE NOTICE 'seqscan: %', r2; + END LOOP; + + SET enable_seqscan = 0; + SET enable_bitmapscan = 1; + FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP + RAISE NOTICE 'bitmapscan: %', r2; + END LOOP; + END IF; + + -- make sure we found expected number of matches + IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF; + END LOOP; +END; +$x$; + +RESET enable_seqscan; + +RESET enable_bitmapscan; + +INSERT INTO brintest_multi SELECT + 142857 * tenthous, + thousand, + twothousand, + unique1::oid, + format('(%s,%s)', tenthous, twenty)::tid, + (four + 1.0)/(hundred+1), + odd::float8 / (tenthous + 1), + format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr, + substr(fipshash(unique1::text), 1, 16)::macaddr8, + inet '10.2.3.4' + tenthous, + cidr '10.2.3/24' + tenthous, + date '1995-08-15' + tenthous, + time '01:20:30' + thousand * interval '18.5 second', + timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', + timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', + justify_days(justify_hours(tenthous * interval '12 minutes')), + timetz '01:30:20' + hundred * interval '15 seconds', + tenthous::numeric(36,30) * fivethous * even / (hundred + 1), + format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, + format('%s/%s%s', odd, even, tenthous)::pg_lsn +FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5; + +SELECT brin_desummarize_range('brinidx_multi', 0); + +VACUUM brintest_multi; + +insert into public.brintest_multi (float4col) values (real 'nan'); + +insert into public.brintest_multi (float8col) values (real 'nan'); + +UPDATE brintest_multi SET int8col = int8col * int4col; + +CREATE TABLE brin_test_inet (a inet); + +CREATE INDEX ON brin_test_inet USING brin (a inet_minmax_multi_ops); + +INSERT INTO brin_test_inet VALUES ('127.0.0.1/0'); + +INSERT INTO brin_test_inet VALUES ('0.0.0.0/12'); + +DROP TABLE brin_test_inet; + +SELECT brin_summarize_new_values('brintest_multi'); + +SELECT brin_summarize_new_values('tenk1_unique1'); + +SELECT brin_summarize_new_values('brinidx_multi'); + +SELECT brin_desummarize_range('brinidx_multi', -1); + +SELECT brin_desummarize_range('brinidx_multi', 0); + +SELECT brin_desummarize_range('brinidx_multi', 0); + +SELECT brin_desummarize_range('brinidx_multi', 100000000); + +CREATE TABLE brin_large_range (a int4); + +INSERT INTO brin_large_range SELECT i FROM generate_series(1,10000) s(i); + +CREATE INDEX brin_large_range_idx ON brin_large_range USING brin (a int4_minmax_multi_ops); + +DROP TABLE brin_large_range; + +CREATE TABLE brin_summarize_multi ( + value int +) WITH (fillfactor=10, autovacuum_enabled=false); + +CREATE INDEX brin_summarize_multi_idx ON brin_summarize_multi USING brin (value) WITH (pages_per_range=2); + +DO $$ +DECLARE curtid tid; +BEGIN + LOOP + INSERT INTO brin_summarize_multi VALUES (1) RETURNING ctid INTO curtid; + EXIT WHEN curtid > tid '(2, 0)'; + END LOOP; +END; +$$; + +SELECT brin_summarize_range('brin_summarize_multi_idx', 0); + +SELECT brin_summarize_range('brin_summarize_multi_idx', 1); + +SELECT brin_summarize_range('brin_summarize_multi_idx', 2); + +SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967295); + +SELECT brin_summarize_range('brin_summarize_multi_idx', -1); + +SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967296); + +CREATE TABLE brin_test_multi (a INT, b INT); + +INSERT INTO brin_test_multi SELECT x/100,x%100 FROM generate_series(1,10000) x(x); + +CREATE INDEX brin_test_multi_a_idx ON brin_test_multi USING brin (a) WITH (pages_per_range = 2); + +CREATE INDEX brin_test_multi_b_idx ON brin_test_multi USING brin (b) WITH (pages_per_range = 2); + +VACUUM ANALYZE brin_test_multi; + +SELECT * FROM brin_test_multi WHERE a = 1; + +SELECT * FROM brin_test_multi WHERE b = 1; + +CREATE TABLE brin_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10); + +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i); + +CREATE INDEX brin_test_multi_1_idx_1 ON brin_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=5); + +CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=5); + +SET enable_seqscan=off; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103; + +TRUNCATE brin_test_multi_1; + +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i); + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103; + +DROP TABLE brin_test_multi_1; + +RESET enable_seqscan; + +CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10); + +INSERT INTO brin_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random(); + +CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5); + +SET enable_seqscan=off; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6'; + +TRUNCATE brin_test_multi_2; + +INSERT INTO brin_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random(); + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6'; + +DROP TABLE brin_test_multi_2; + +RESET enable_seqscan; + +CREATE TABLE brin_timestamp_test(a TIMESTAMPTZ); + +SET datestyle TO iso; + +INSERT INTO brin_timestamp_test +SELECT '4713-01-01 00:00:01 BC'::timestamptz + (i || ' seconds')::interval + FROM generate_series(1,30) s(i); + +INSERT INTO brin_timestamp_test +SELECT '294276-12-01 00:00:01'::timestamptz + (i || ' seconds')::interval + FROM generate_series(1,30) s(i); + +CREATE INDEX ON brin_timestamp_test USING brin (a timestamptz_minmax_multi_ops) WITH (pages_per_range=1); + +DROP TABLE brin_timestamp_test; + +CREATE TABLE brin_date_test(a DATE); + +INSERT INTO brin_date_test SELECT '4713-01-01 BC'::date + i FROM generate_series(1, 30) s(i); + +INSERT INTO brin_date_test SELECT '5874897-12-01'::date + i FROM generate_series(1, 30) s(i); + +CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1); + +SET enable_seqscan = off; + +SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date; + +DROP TABLE brin_date_test; + +RESET enable_seqscan; + +CREATE TABLE brin_timestamp_test(a TIMESTAMP); + +INSERT INTO brin_timestamp_test VALUES ('-infinity'), ('infinity'); + +INSERT INTO brin_timestamp_test +SELECT i FROM generate_series('2000-01-01'::timestamp, '2000-02-09'::timestamp, '1 day'::interval) s(i); + +CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WITH (pages_per_range=1); + +SET enable_seqscan = off; + +SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp; + +SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp; + +DROP TABLE brin_timestamp_test; + +RESET enable_seqscan; + +CREATE TABLE brin_date_test(a DATE); + +INSERT INTO brin_date_test VALUES ('-infinity'), ('infinity'); + +INSERT INTO brin_date_test SELECT '2000-01-01'::date + i FROM generate_series(1, 40) s(i); + +CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1); + +SET enable_seqscan = off; + +SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date; + +SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date; + +DROP TABLE brin_date_test; + +RESET enable_seqscan; + +RESET datestyle; + +CREATE TABLE brin_interval_test(a INTERVAL); + +INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series(-178000000, -177999980) s(i); + +INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series( 177999980, 178000000) s(i); + +CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1); + +SET enable_seqscan = off; + +SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval; + +SELECT * FROM brin_interval_test WHERE a = '30 years'::interval; + +DROP TABLE brin_interval_test; + +RESET enable_seqscan; + +CREATE TABLE brin_interval_test(a INTERVAL); + +INSERT INTO brin_interval_test VALUES ('-infinity'), ('infinity'); + +INSERT INTO brin_interval_test SELECT (i || ' days')::interval FROM generate_series(100, 140) s(i); + +CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1); + +SET enable_seqscan = off; + +SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval; + +SELECT * FROM brin_interval_test WHERE a = '30 years'::interval; + +DROP TABLE brin_interval_test; + +RESET enable_seqscan; + +RESET datestyle; diff --git a/crates/pgt_pretty_print/tests/data/multi/btree_index_60.sql b/crates/pgt_pretty_print/tests/data/multi/btree_index_60.sql new file mode 100644 index 000000000..be44ee4a9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/btree_index_60.sql @@ -0,0 +1,351 @@ +CREATE TABLE bt_i4_heap ( + seqno int4, + random int4 +); + +CREATE TABLE bt_name_heap ( + seqno name, + random int4 +); + +CREATE TABLE bt_txt_heap ( + seqno text, + random int4 +); + +CREATE TABLE bt_f8_heap ( + seqno float8, + random int4 +); + +COPY bt_i4_heap FROM 'filename'; + +COPY bt_name_heap FROM 'filename'; + +COPY bt_txt_heap FROM 'filename'; + +COPY bt_f8_heap FROM 'filename'; + +ANALYZE bt_i4_heap; + +ANALYZE bt_name_heap; + +ANALYZE bt_txt_heap; + +ANALYZE bt_f8_heap; + +CREATE INDEX bt_i4_index ON bt_i4_heap USING btree (seqno int4_ops); + +CREATE INDEX bt_name_index ON bt_name_heap USING btree (seqno name_ops); + +CREATE INDEX bt_txt_index ON bt_txt_heap USING btree (seqno text_ops); + +CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops); + +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno < 1; + +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno >= 9999; + +SELECT b.* + FROM bt_i4_heap b + WHERE b.seqno = 4500; + +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno < '1'::name; + +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno >= '9999'::name; + +SELECT b.* + FROM bt_name_heap b + WHERE b.seqno = '4500'::name; + +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno < '1'::text; + +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno >= '9999'::text; + +SELECT b.* + FROM bt_txt_heap b + WHERE b.seqno = '4500'::text; + +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno < '1'::float8; + +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno >= '9999'::float8; + +SELECT b.* + FROM bt_f8_heap b + WHERE b.seqno = '4500'::float8; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, pronamespace) > ('abs', 0) +ORDER BY proname, proargtypes, pronamespace LIMIT 1; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, pronamespace) > ('abs', 0) +ORDER BY proname, proargtypes, pronamespace LIMIT 1; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, pronamespace) < ('abs', 1_000_000) +ORDER BY proname DESC, proargtypes DESC, pronamespace DESC LIMIT 1; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, pronamespace) < ('abs', 1_000_000) +ORDER BY proname DESC, proargtypes DESC, pronamespace DESC LIMIT 1; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, proargtypes) >= ('abs', NULL) AND proname <= 'abs' +ORDER BY proname, proargtypes, pronamespace; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, proargtypes) >= ('abs', NULL) AND proname <= 'abs' +ORDER BY proname, proargtypes, pronamespace; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE proname >= 'abs' AND (proname, proargtypes) < ('abs', NULL) +ORDER BY proname, proargtypes, pronamespace; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE proname >= 'abs' AND (proname, proargtypes) < ('abs', NULL) +ORDER BY proname, proargtypes, pronamespace; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE proname >= 'abs' AND (proname, proargtypes) <= ('abs', NULL) +ORDER BY proname DESC, proargtypes DESC, pronamespace DESC; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE proname >= 'abs' AND (proname, proargtypes) <= ('abs', NULL) +ORDER BY proname DESC, proargtypes DESC, pronamespace DESC; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, proargtypes) > ('abs', NULL) AND proname <= 'abs' +ORDER BY proname DESC, proargtypes DESC, pronamespace DESC; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE (proname, proargtypes) > ('abs', NULL) AND proname <= 'abs' +ORDER BY proname DESC, proargtypes DESC, pronamespace DESC; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE proname = 'zzzzzz' AND (proname, proargtypes) > ('abs', NULL) + AND pronamespace IN (1, 2, 3) AND proargtypes IN ('26 23', '5077') +ORDER BY proname, proargtypes, pronamespace; + +SELECT proname, proargtypes, pronamespace + FROM pg_proc + WHERE proname = 'zzzzzz' AND (proname, proargtypes) > ('abs', NULL) + AND pronamespace IN (1, 2, 3) AND proargtypes IN ('26 23', '5077') +ORDER BY proname, proargtypes, pronamespace; + +SELECT thousand, tenthous + FROM tenk1 + WHERE thousand IN (182, 183) AND tenthous > 7550; + +SELECT thousand, tenthous + FROM tenk1 + WHERE thousand IN (182, 183) AND tenthous > 7550; + +set enable_seqscan to false; + +set enable_indexscan to true; + +set enable_bitmapscan to false; + +select hundred, twenty from tenk1 where hundred < 48 order by hundred desc limit 1; + +select hundred, twenty from tenk1 where hundred < 48 order by hundred desc limit 1; + +select hundred, twenty from tenk1 where hundred <= 48 order by hundred desc limit 1; + +select hundred, twenty from tenk1 where hundred <= 48 order by hundred desc limit 1; + +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82); + +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82); + +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) order by hundred desc; + +select distinct hundred from tenk1 where hundred in (47, 48, 72, 82) order by hundred desc; + +select thousand from tenk1 where thousand in (364, 366,380) and tenthous = 200000; + +select thousand from tenk1 where thousand in (364, 366,380) and tenthous = 200000; + +set enable_seqscan to false; + +set enable_indexscan to true; + +set enable_bitmapscan to false; + +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; + +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; + +select proname from pg_proc where proname ilike '00%foo' order by 1; + +select proname from pg_proc where proname ilike '00%foo' order by 1; + +select proname from pg_proc where proname ilike 'ri%foo' order by 1; + +set enable_indexscan to false; + +set enable_bitmapscan to true; + +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; + +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; + +select proname from pg_proc where proname ilike '00%foo' order by 1; + +select proname from pg_proc where proname ilike '00%foo' order by 1; + +select proname from pg_proc where proname ilike 'ri%foo' order by 1; + +reset enable_seqscan; + +reset enable_indexscan; + +reset enable_bitmapscan; + +create temp table btree_bpchar (f1 text collate "C"); + +create index on btree_bpchar(f1 bpchar_ops) WITH (deduplicate_items=on); + +insert into btree_bpchar values ('foo'), ('fool'), ('bar'), ('quux'); + +select * from btree_bpchar where f1 like 'foo'; + +select * from btree_bpchar where f1 like 'foo'; + +select * from btree_bpchar where f1 like 'foo%'; + +select * from btree_bpchar where f1 like 'foo%'; + +select * from btree_bpchar where f1::bpchar like 'foo'; + +select * from btree_bpchar where f1::bpchar like 'foo'; + +select * from btree_bpchar where f1::bpchar like 'foo%'; + +select * from btree_bpchar where f1::bpchar like 'foo%'; + +insert into btree_bpchar select 'foo' from generate_series(1,1500); + +CREATE TABLE dedup_unique_test_table (a int) WITH (autovacuum_enabled=false); + +CREATE UNIQUE INDEX dedup_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=on); + +CREATE UNIQUE INDEX plain_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=off); + +DO $$ +BEGIN + FOR r IN 1..1350 LOOP + DELETE FROM dedup_unique_test_table; + INSERT INTO dedup_unique_test_table SELECT 1; + END LOOP; +END$$; + +DROP INDEX plain_unique; + +DELETE FROM dedup_unique_test_table WHERE a = 1; + +INSERT INTO dedup_unique_test_table SELECT i FROM generate_series(0,450) i; + +create table btree_tall_tbl(id int4, t text); + +alter table btree_tall_tbl alter COLUMN t set storage plain; + +create index btree_tall_idx on btree_tall_tbl (t, id) with (fillfactor = 10); + +insert into btree_tall_tbl select g, repeat('x', 250) +from generate_series(1, 130) g; + +insert into btree_tall_tbl select g, NULL +from generate_series(50, 60) g; + +set enable_seqscan to false; + +set enable_bitmapscan to false; + +SELECT id FROM btree_tall_tbl WHERE id = 55 ORDER BY t, id; + +SELECT id FROM btree_tall_tbl WHERE id = 55 ORDER BY t, id; + +SELECT id FROM btree_tall_tbl WHERE id = 55 ORDER BY t DESC, id DESC; + +SELECT id FROM btree_tall_tbl WHERE id = 55 ORDER BY t DESC, id DESC; + +reset enable_seqscan; + +reset enable_bitmapscan; + +CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint); + +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i; + +ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d); + +DELETE FROM delete_test_table WHERE a < 79990; + +VACUUM delete_test_table; + +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,1000) i; + +create index on btree_tall_tbl (id int4_ops(foo=1)); + +CREATE TABLE btree_test_expr (n int); + +CREATE FUNCTION btree_test_func() RETURNS int LANGUAGE sql IMMUTABLE RETURN 0; + +BEGIN; + +SET LOCAL min_parallel_table_scan_size = 0; + +SET LOCAL max_parallel_maintenance_workers = 4; + +CREATE INDEX btree_test_expr_idx ON btree_test_expr USING btree (btree_test_func()); + +COMMIT; + +DROP TABLE btree_test_expr; + +DROP FUNCTION btree_test_func(); + +CREATE INDEX btree_tall_idx2 ON btree_tall_tbl (id); + +ALTER INDEX btree_tall_idx2 ALTER COLUMN id SET (n_distinct=100); + +DROP INDEX btree_tall_idx2; + +CREATE TABLE btree_part (id int4) PARTITION BY RANGE (id); + +CREATE INDEX btree_part_idx ON btree_part(id); + +ALTER INDEX btree_part_idx ALTER COLUMN id SET (n_distinct=100); + +DROP TABLE btree_part; diff --git a/crates/pgt_pretty_print/tests/data/multi/case_60.sql b/crates/pgt_pretty_print/tests/data/multi/case_60.sql new file mode 100644 index 000000000..f664079b1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/case_60.sql @@ -0,0 +1,218 @@ +CREATE TABLE CASE_TBL ( + i integer, + f double precision +); + +CREATE TABLE CASE2_TBL ( + i integer, + j integer +); + +INSERT INTO CASE_TBL VALUES (1, 10.1); + +INSERT INTO CASE_TBL VALUES (2, 20.2); + +INSERT INTO CASE_TBL VALUES (3, -30.3); + +INSERT INTO CASE_TBL VALUES (4, NULL); + +INSERT INTO CASE2_TBL VALUES (1, -1); + +INSERT INTO CASE2_TBL VALUES (2, -2); + +INSERT INTO CASE2_TBL VALUES (3, -3); + +INSERT INTO CASE2_TBL VALUES (2, -4); + +INSERT INTO CASE2_TBL VALUES (1, NULL); + +INSERT INTO CASE2_TBL VALUES (NULL, -6); + +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + END AS "Simple WHEN"; + +SELECT '' AS "One", + CASE + WHEN 1 > 2 THEN 3 + END AS "Simple default"; + +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + ELSE 4 + END AS "Simple ELSE"; + +SELECT '4' AS "One", + CASE + WHEN 1 > 2 THEN 3 + ELSE 4 + END AS "ELSE default"; + +SELECT '6' AS "One", + CASE + WHEN 1 > 2 THEN 3 + WHEN 4 < 5 THEN 6 + ELSE 7 + END AS "Two WHEN with default"; + +SELECT '7' AS "None", + CASE WHEN random() < 0 THEN 1 + END AS "NULL on no matches"; + +SELECT CASE WHEN 1=0 THEN 1/0 WHEN 1=1 THEN 1 ELSE 2/0 END; + +SELECT CASE 1 WHEN 0 THEN 1/0 WHEN 1 THEN 1 ELSE 2/0 END; + +SELECT CASE WHEN i > 100 THEN 1/0 ELSE 0 END FROM case_tbl; + +SELECT CASE 'a' WHEN 'a' THEN 1 ELSE 2 END; + +SELECT + CASE + WHEN i >= 3 THEN i + END AS ">= 3 or Null" + FROM CASE_TBL; + +SELECT + CASE WHEN i >= 3 THEN (i + i) + ELSE i + END AS "Simplest Math" + FROM CASE_TBL; + +SELECT i AS "Value", + CASE WHEN (i < 0) THEN 'small' + WHEN (i = 0) THEN 'zero' + WHEN (i = 1) THEN 'one' + WHEN (i = 2) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL; + +SELECT + CASE WHEN ((i < 0) or (i < 0)) THEN 'small' + WHEN ((i = 0) or (i = 0)) THEN 'zero' + WHEN ((i = 1) or (i = 1)) THEN 'one' + WHEN ((i = 2) or (i = 2)) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL; + +SELECT * FROM CASE_TBL WHERE COALESCE(f,i) = 4; + +SELECT * FROM CASE_TBL WHERE NULLIF(f,i) = 2; + +SELECT COALESCE(a.f, b.i, b.j) + FROM CASE_TBL a, CASE2_TBL b; + +SELECT * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(a.f, b.i, b.j) = 2; + +SELECT NULLIF(a.i,b.i) AS "NULLIF(a.i,b.i)", + NULLIF(b.i, 4) AS "NULLIF(b.i,4)" + FROM CASE_TBL a, CASE2_TBL b; + +SELECT * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(f,b.i) = 2; + +SELECT * FROM CASE_TBL WHERE NULLIF(1, 2) = 2; + +SELECT * FROM CASE_TBL WHERE NULLIF(1, 1) IS NOT NULL; + +SELECT * FROM CASE_TBL WHERE NULLIF(1, null) = 2; + +UPDATE CASE_TBL + SET i = CASE WHEN i >= 3 THEN (- i) + ELSE (2 * i) END; + +SELECT * FROM CASE_TBL; + +UPDATE CASE_TBL + SET i = CASE WHEN i >= 2 THEN (2 * i) + ELSE (3 * i) END; + +SELECT * FROM CASE_TBL; + +UPDATE CASE_TBL + SET i = CASE WHEN b.i >= 2 THEN (2 * j) + ELSE (3 * j) END + FROM CASE2_TBL b + WHERE j = -CASE_TBL.i; + +SELECT * FROM CASE_TBL; + +BEGIN; + +CREATE FUNCTION vol(text) returns text as + 'begin return $1; end' language plpgsql volatile; + +SELECT CASE + (CASE vol('bar') + WHEN 'foo' THEN 'it was foo!' + WHEN vol(null) THEN 'null input' + WHEN 'bar' THEN 'it was bar!' END + ) + WHEN 'it was foo!' THEN 'foo recognized' + WHEN 'it was bar!' THEN 'bar recognized' + ELSE 'unrecognized' END; + +CREATE DOMAIN foodomain AS text; + +CREATE FUNCTION volfoo(text) returns foodomain as + 'begin return $1::foodomain; end' language plpgsql volatile; + +CREATE FUNCTION inline_eq(foodomain, foodomain) returns boolean as + 'SELECT CASE $2::text WHEN $1::text THEN true ELSE false END' language sql; + +CREATE OPERATOR = (procedure = inline_eq, + leftarg = foodomain, rightarg = foodomain); + +SELECT CASE volfoo('bar') WHEN 'foo'::foodomain THEN 'is foo' ELSE 'is not foo' END; + +ROLLBACK; + +BEGIN; + +CREATE DOMAIN arrdomain AS int[]; + +CREATE FUNCTION make_ad(int,int) returns arrdomain as + 'declare x arrdomain; + begin + x := array[$1,$2]; + return x; + end' language plpgsql volatile; + +CREATE FUNCTION ad_eq(arrdomain, arrdomain) returns boolean as + 'begin return array_eq($1, $2); end' language plpgsql; + +CREATE OPERATOR = (procedure = ad_eq, + leftarg = arrdomain, rightarg = arrdomain); + +SELECT CASE make_ad(1,2) + WHEN array[2,4]::arrdomain THEN 'wrong' + WHEN array[2,5]::arrdomain THEN 'still wrong' + WHEN array[1,2]::arrdomain THEN 'right' + END; + +SELECT NULLIF(make_ad(1,2), array[2,3]::arrdomain); + +ROLLBACK; + +BEGIN; + +CREATE TYPE casetestenum AS ENUM ('e', 'f', 'g'); + +SELECT + CASE 'foo'::text + WHEN 'foo' THEN ARRAY['a', 'b', 'c', 'd'] || enum_range(NULL::casetestenum)::text[] + ELSE ARRAY['x', 'y'] + END; + +ROLLBACK; + +DROP TABLE CASE_TBL; + +DROP TABLE CASE2_TBL; diff --git a/crates/pgt_pretty_print/tests/data/multi/char_60.sql b/crates/pgt_pretty_print/tests/data/multi/char_60.sql new file mode 100644 index 000000000..5f12ecab4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/char_60.sql @@ -0,0 +1,75 @@ +SELECT char 'c' = char 'c' AS true; + +CREATE TEMP TABLE CHAR_TBL(f1 char); + +INSERT INTO CHAR_TBL (f1) VALUES ('a'); + +INSERT INTO CHAR_TBL (f1) VALUES ('A'); + +INSERT INTO CHAR_TBL (f1) VALUES ('1'); + +INSERT INTO CHAR_TBL (f1) VALUES (2); + +INSERT INTO CHAR_TBL (f1) VALUES ('3'); + +INSERT INTO CHAR_TBL (f1) VALUES (''); + +INSERT INTO CHAR_TBL (f1) VALUES ('cd'); + +INSERT INTO CHAR_TBL (f1) VALUES ('c '); + +SELECT * FROM CHAR_TBL; + +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 <> 'a'; + +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 = 'a'; + +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 < 'a'; + +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 <= 'a'; + +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 > 'a'; + +SELECT c.* + FROM CHAR_TBL c + WHERE c.f1 >= 'a'; + +DROP TABLE CHAR_TBL; + +INSERT INTO CHAR_TBL (f1) VALUES ('abcde'); + +SELECT * FROM CHAR_TBL; + +SELECT pg_input_is_valid('abcd ', 'char(4)'); + +SELECT pg_input_is_valid('abcde', 'char(4)'); + +SELECT * FROM pg_input_error_info('abcde', 'char(4)'); + +SELECT 'a'::"char"; + +SELECT '\101'::"char"; + +SELECT '\377'::"char"; + +SELECT 'a'::"char"::text; + +SELECT '\377'::"char"::text; + +SELECT '\000'::"char"::text; + +SELECT 'a'::text::"char"; + +SELECT '\377'::text::"char"; + +SELECT ''::text::"char"; diff --git a/crates/pgt_pretty_print/tests/data/multi/circle_60.sql b/crates/pgt_pretty_print/tests/data/multi/circle_60.sql new file mode 100644 index 000000000..a5239604f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/circle_60.sql @@ -0,0 +1,49 @@ +SET extra_float_digits = -1; + +CREATE TABLE CIRCLE_TBL (f1 circle); + +INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>'); + +INSERT INTO CIRCLE_TBL VALUES ('((1,2),100)'); + +INSERT INTO CIRCLE_TBL VALUES (' 1 , 3 , 5 '); + +INSERT INTO CIRCLE_TBL VALUES (' ( ( 1 , 2 ) , 3 ) '); + +INSERT INTO CIRCLE_TBL VALUES (' ( 100 , 200 ) , 10 '); + +INSERT INTO CIRCLE_TBL VALUES (' < ( 100 , 1 ) , 115 > '); + +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),0>'); + +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),NaN>'); + +INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>'); + +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10'); + +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10> x'); + +INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5'); + +INSERT INTO CIRCLE_TBL VALUES ('(3,(1,2),3)'); + +SELECT * FROM CIRCLE_TBL; + +SELECT center(f1) AS center + FROM CIRCLE_TBL; + +SELECT radius(f1) AS radius + FROM CIRCLE_TBL; + +SELECT diameter(f1) AS diameter + FROM CIRCLE_TBL; + +SELECT f1 FROM CIRCLE_TBL WHERE radius(f1) < 5; + +SELECT f1 FROM CIRCLE_TBL WHERE diameter(f1) >= 10; + +SELECT c1.f1 AS one, c2.f1 AS two, (c1.f1 <-> c2.f1) AS distance + FROM CIRCLE_TBL c1, CIRCLE_TBL c2 + WHERE (c1.f1 < c2.f1) AND ((c1.f1 <-> c2.f1) > 0) + ORDER BY distance, area(c1.f1), area(c2.f1); diff --git a/crates/pgt_pretty_print/tests/data/multi/cluster_60.sql b/crates/pgt_pretty_print/tests/data/multi/cluster_60.sql new file mode 100644 index 000000000..27ec4baf7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/cluster_60.sql @@ -0,0 +1,390 @@ +CREATE TABLE clstr_tst_s (rf_a SERIAL PRIMARY KEY, + b INT); + +CREATE TABLE clstr_tst (a SERIAL PRIMARY KEY, + b INT, + c TEXT, + d TEXT, + CONSTRAINT clstr_tst_con FOREIGN KEY (b) REFERENCES clstr_tst_s); + +CREATE INDEX clstr_tst_b ON clstr_tst (b); + +CREATE INDEX clstr_tst_c ON clstr_tst (c); + +CREATE INDEX clstr_tst_c_b ON clstr_tst (c,b); + +CREATE INDEX clstr_tst_b_c ON clstr_tst (b,c); + +INSERT INTO clstr_tst_s (b) VALUES (0); + +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; + +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; + +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; + +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; + +INSERT INTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; + +CREATE TABLE clstr_tst_inh () INHERITS (clstr_tst); + +INSERT INTO clstr_tst (b, c) VALUES (11, 'once'); + +INSERT INTO clstr_tst (b, c) VALUES (10, 'diez'); + +INSERT INTO clstr_tst (b, c) VALUES (31, 'treinta y uno'); + +INSERT INTO clstr_tst (b, c) VALUES (22, 'veintidos'); + +INSERT INTO clstr_tst (b, c) VALUES (3, 'tres'); + +INSERT INTO clstr_tst (b, c) VALUES (20, 'veinte'); + +INSERT INTO clstr_tst (b, c) VALUES (23, 'veintitres'); + +INSERT INTO clstr_tst (b, c) VALUES (21, 'veintiuno'); + +INSERT INTO clstr_tst (b, c) VALUES (4, 'cuatro'); + +INSERT INTO clstr_tst (b, c) VALUES (14, 'catorce'); + +INSERT INTO clstr_tst (b, c) VALUES (2, 'dos'); + +INSERT INTO clstr_tst (b, c) VALUES (18, 'dieciocho'); + +INSERT INTO clstr_tst (b, c) VALUES (27, 'veintisiete'); + +INSERT INTO clstr_tst (b, c) VALUES (25, 'veinticinco'); + +INSERT INTO clstr_tst (b, c) VALUES (13, 'trece'); + +INSERT INTO clstr_tst (b, c) VALUES (28, 'veintiocho'); + +INSERT INTO clstr_tst (b, c) VALUES (32, 'treinta y dos'); + +INSERT INTO clstr_tst (b, c) VALUES (5, 'cinco'); + +INSERT INTO clstr_tst (b, c) VALUES (29, 'veintinueve'); + +INSERT INTO clstr_tst (b, c) VALUES (1, 'uno'); + +INSERT INTO clstr_tst (b, c) VALUES (24, 'veinticuatro'); + +INSERT INTO clstr_tst (b, c) VALUES (30, 'treinta'); + +INSERT INTO clstr_tst (b, c) VALUES (12, 'doce'); + +INSERT INTO clstr_tst (b, c) VALUES (17, 'diecisiete'); + +INSERT INTO clstr_tst (b, c) VALUES (9, 'nueve'); + +INSERT INTO clstr_tst (b, c) VALUES (19, 'diecinueve'); + +INSERT INTO clstr_tst (b, c) VALUES (26, 'veintiseis'); + +INSERT INTO clstr_tst (b, c) VALUES (15, 'quince'); + +INSERT INTO clstr_tst (b, c) VALUES (7, 'siete'); + +INSERT INTO clstr_tst (b, c) VALUES (16, 'dieciseis'); + +INSERT INTO clstr_tst (b, c) VALUES (8, 'ocho'); + +INSERT INTO clstr_tst (b, c, d) VALUES (6, 'seis', repeat('xyzzy', 100000)); + +CLUSTER clstr_tst_c ON clstr_tst; + +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst; + +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY a; + +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY b; + +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst ORDER BY c; + +INSERT INTO clstr_tst_inh VALUES (0, 100, 'in child table'); + +SELECT a,b,c,substring(d for 30), length(d) from clstr_tst; + +INSERT INTO clstr_tst (b, c) VALUES (1111, 'this should fail'); + +SELECT conname FROM pg_constraint WHERE conrelid = 'clstr_tst'::regclass +ORDER BY 1; + +SELECT relname, relkind, + EXISTS(SELECT 1 FROM pg_class WHERE oid = c.reltoastrelid) AS hastoast +FROM pg_class c WHERE relname LIKE 'clstr_tst%' ORDER BY relname; + +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered; + +ALTER TABLE clstr_tst CLUSTER ON clstr_tst_b_c; + +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered; + +ALTER TABLE clstr_tst SET WITHOUT CLUSTER; + +SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 +WHERE pg_class.oid=indexrelid + AND indrelid=pg_class_2.oid + AND pg_class_2.relname = 'clstr_tst' + AND indisclustered; + +CLUSTER pg_toast.pg_toast_826 USING pg_toast_826_index; + +CREATE USER regress_clstr_user; + +CREATE TABLE clstr_1 (a INT PRIMARY KEY); + +CREATE TABLE clstr_2 (a INT PRIMARY KEY); + +CREATE TABLE clstr_3 (a INT PRIMARY KEY); + +ALTER TABLE clstr_1 OWNER TO regress_clstr_user; + +ALTER TABLE clstr_3 OWNER TO regress_clstr_user; + +GRANT SELECT ON clstr_2 TO regress_clstr_user; + +INSERT INTO clstr_1 VALUES (2); + +INSERT INTO clstr_1 VALUES (1); + +INSERT INTO clstr_2 VALUES (2); + +INSERT INTO clstr_2 VALUES (1); + +INSERT INTO clstr_3 VALUES (2); + +INSERT INTO clstr_3 VALUES (1); + +CLUSTER clstr_2; + +CLUSTER clstr_1_pkey ON clstr_1; + +CLUSTER clstr_2 USING clstr_2_pkey; + +SELECT * FROM clstr_1 UNION ALL + SELECT * FROM clstr_2 UNION ALL + SELECT * FROM clstr_3; + +DELETE FROM clstr_1; + +DELETE FROM clstr_2; + +DELETE FROM clstr_3; + +INSERT INTO clstr_1 VALUES (2); + +INSERT INTO clstr_1 VALUES (1); + +INSERT INTO clstr_2 VALUES (2); + +INSERT INTO clstr_2 VALUES (1); + +INSERT INTO clstr_3 VALUES (2); + +INSERT INTO clstr_3 VALUES (1); + +SET SESSION AUTHORIZATION regress_clstr_user; + +SET client_min_messages = ERROR; + +CLUSTER; + +RESET client_min_messages; + +SELECT * FROM clstr_1 UNION ALL + SELECT * FROM clstr_2 UNION ALL + SELECT * FROM clstr_3; + +DELETE FROM clstr_1; + +INSERT INTO clstr_1 VALUES (2); + +INSERT INTO clstr_1 VALUES (1); + +CLUSTER clstr_1; + +SELECT * FROM clstr_1; + +CREATE TABLE clustertest (key int PRIMARY KEY); + +INSERT INTO clustertest VALUES (10); + +INSERT INTO clustertest VALUES (20); + +INSERT INTO clustertest VALUES (30); + +INSERT INTO clustertest VALUES (40); + +INSERT INTO clustertest VALUES (50); + +BEGIN; + +UPDATE clustertest SET key = 100 WHERE key = 10; + +UPDATE clustertest SET key = 35 WHERE key = 40; + +UPDATE clustertest SET key = 60 WHERE key = 50; + +UPDATE clustertest SET key = 70 WHERE key = 60; + +UPDATE clustertest SET key = 80 WHERE key = 70; + +SELECT * FROM clustertest; + +CLUSTER clustertest_pkey ON clustertest; + +SELECT * FROM clustertest; + +COMMIT; + +SELECT * FROM clustertest; + +create temp table clstr_temp (col1 int primary key, col2 text); + +insert into clstr_temp values (2, 'two'), (1, 'one'); + +cluster clstr_temp using clstr_temp_pkey; + +select * from clstr_temp; + +drop table clstr_temp; + +RESET SESSION AUTHORIZATION; + +DROP TABLE clustertest; + +CREATE TABLE clustertest (f1 int PRIMARY KEY); + +CLUSTER clustertest USING clustertest_pkey; + +CLUSTER clustertest; + +CREATE TABLE clstrpart (a int) PARTITION BY RANGE (a); + +CREATE TABLE clstrpart1 PARTITION OF clstrpart FOR VALUES FROM (1) TO (10) PARTITION BY RANGE (a); + +CREATE TABLE clstrpart11 PARTITION OF clstrpart1 FOR VALUES FROM (1) TO (5); + +CREATE TABLE clstrpart12 PARTITION OF clstrpart1 FOR VALUES FROM (5) TO (10) PARTITION BY RANGE (a); + +CREATE TABLE clstrpart2 PARTITION OF clstrpart FOR VALUES FROM (10) TO (20); + +CREATE TABLE clstrpart3 PARTITION OF clstrpart DEFAULT PARTITION BY RANGE (a); + +CREATE TABLE clstrpart33 PARTITION OF clstrpart3 DEFAULT; + +CREATE INDEX clstrpart_only_idx ON ONLY clstrpart (a); + +CLUSTER clstrpart USING clstrpart_only_idx; + +DROP INDEX clstrpart_only_idx; + +CREATE INDEX clstrpart_idx ON clstrpart (a); + +CREATE TEMP TABLE old_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid ; + +CLUSTER clstrpart USING clstrpart_idx; + +CREATE TEMP TABLE new_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid ; + +SELECT relname, old.level, old.relkind, old.relfilenode = new.relfilenode FROM old_cluster_info AS old JOIN new_cluster_info AS new USING (relname) ORDER BY relname COLLATE "C"; + +CLUSTER clstrpart; + +ALTER TABLE clstrpart SET WITHOUT CLUSTER; + +ALTER TABLE clstrpart CLUSTER ON clstrpart_idx; + +DROP TABLE clstrpart; + +CREATE TABLE ptnowner(i int unique) PARTITION BY LIST (i); + +CREATE INDEX ptnowner_i_idx ON ptnowner(i); + +CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1); + +CREATE ROLE regress_ptnowner; + +CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2); + +ALTER TABLE ptnowner1 OWNER TO regress_ptnowner; + +SET SESSION AUTHORIZATION regress_ptnowner; + +CLUSTER ptnowner USING ptnowner_i_idx; + +RESET SESSION AUTHORIZATION; + +ALTER TABLE ptnowner OWNER TO regress_ptnowner; + +CREATE TEMP TABLE ptnowner_oldnodes AS + SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree + JOIN pg_class AS c ON c.oid=tree.relid; + +SET SESSION AUTHORIZATION regress_ptnowner; + +CLUSTER ptnowner USING ptnowner_i_idx; + +RESET SESSION AUTHORIZATION; + +SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a + JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C"; + +DROP TABLE ptnowner; + +DROP ROLE regress_ptnowner; + +create table clstr_4 as select * from tenk1; + +create index cluster_sort on clstr_4 (hundred, thousand, tenthous); + +set enable_indexscan = off; + +set maintenance_work_mem = '1MB'; + +cluster clstr_4 using cluster_sort; + +select * from +(select hundred, lag(hundred) over () as lhundred, + thousand, lag(thousand) over () as lthousand, + tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss +where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous); + +reset enable_indexscan; + +reset maintenance_work_mem; + +CREATE TABLE clstr_expression(id serial primary key, a int, b text COLLATE "C"); + +INSERT INTO clstr_expression(a, b) SELECT g.i % 42, 'prefix'||g.i FROM generate_series(1, 133) g(i); + +CREATE INDEX clstr_expression_minus_a ON clstr_expression ((-a), b); + +CREATE INDEX clstr_expression_upper_b ON clstr_expression ((upper(b))); + +BEGIN; + +SET LOCAL enable_seqscan = false; + +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; + +SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; + +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b; + +SELECT * FROM clstr_expression WHERE -a = -3 ORDER BY -a, b; + +COMMIT; + +CLUSTER clstr_expression USING clstr_expression_minus_a; diff --git a/crates/pgt_pretty_print/tests/data/multi/collate.icu.utf8_60.sql b/crates/pgt_pretty_print/tests/data/multi/collate.icu.utf8_60.sql new file mode 100644 index 000000000..82f9ff751 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/collate.icu.utf8_60.sql @@ -0,0 +1,1220 @@ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collprovider = 'i' AND collname <> 'unicode') = 0 + AS skip_test ; + +SET client_encoding TO UTF8; + +CREATE SCHEMA collate_tests; + +SET search_path = collate_tests; + +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en-x-icu" NOT NULL +); + +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp-x-icu" +); + +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo-x-icu" +); + +CREATE TABLE collate_test_fail ( + a int COLLATE "en-x-icu", + b text +); + +CREATE TABLE collate_test_like ( + LIKE collate_test1 +); + +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv-x-icu" +); + +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +); + +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC'); + +INSERT INTO collate_test2 SELECT * FROM collate_test1; + +INSERT INTO collate_test3 SELECT * FROM collate_test1; + +SELECT * FROM collate_test1 WHERE b >= 'bbc'; + +SELECT * FROM collate_test2 WHERE b >= 'bbc'; + +SELECT * FROM collate_test3 WHERE b >= 'bbc'; + +SELECT * FROM collate_test3 WHERE b >= 'BBC'; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; + +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C"; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C"; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en-x-icu"; + +CREATE DOMAIN testdomain_sv AS text COLLATE "sv-x-icu"; + +CREATE DOMAIN testdomain_i AS int COLLATE "sv-x-icu"; + +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +); + +INSERT INTO collate_test4 SELECT * FROM collate_test1; + +SELECT a, b FROM collate_test4 ORDER BY b; + +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en-x-icu" +); + +INSERT INTO collate_test5 SELECT * FROM collate_test1; + +SELECT a, b FROM collate_test5 ORDER BY b; + +SELECT a, b FROM collate_test1 ORDER BY b; + +SELECT a, b FROM collate_test2 ORDER BY b; + +SELECT a, b FROM collate_test3 ORDER BY b; + +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; + +SELECT * FROM collate_test1 ORDER BY b; + +SELECT * FROM collate_test2 ORDER BY b; + +SELECT * FROM collate_test3 ORDER BY b; + +SELECT 'bbc' COLLATE "en-x-icu" > 'äbc' COLLATE "en-x-icu" AS "true"; + +SELECT 'bbc' COLLATE "sv-x-icu" > 'äbc' COLLATE "sv-x-icu" AS "false"; + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "en-x-icu", + y text COLLATE "tr-x-icu" +); + +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ'); + +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10; + +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10; + +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a; + +SELECT lower('AbCd 123 #$% ıiIİ ẞ ß DŽDždž Σσς' COLLATE "en-x-icu"); + +SELECT casefold('AbCd 123 #$% ıiIİ ẞ ß DŽDždž Σσς' COLLATE "en-x-icu"); + +SELECT lower('AbCd 123 #$% ıiIİ ẞ ß DŽDždž Σσς' COLLATE "tr-x-icu"); + +SELECT casefold('AbCd 123 #$% ıiIİ ẞ ß DŽDždž Σσς' COLLATE "tr-x-icu"); + +SELECT * FROM collate_test1 WHERE b LIKE 'abc'; + +SELECT * FROM collate_test1 WHERE b LIKE 'abc%'; + +SELECT * FROM collate_test1 WHERE b LIKE '%bc%'; + +SELECT * FROM collate_test1 WHERE b ILIKE 'abc'; + +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%'; + +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%'; + +SELECT 'Türkiye' COLLATE "en-x-icu" ILIKE '%KI%' AS "true"; + +SELECT 'Türkiye' COLLATE "tr-x-icu" ILIKE '%KI%' AS "false"; + +SELECT 'bıt' ILIKE 'BIT' COLLATE "en-x-icu" AS "false"; + +SELECT 'bıt' ILIKE 'BIT' COLLATE "tr-x-icu" AS "true"; + +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%'; + +SELECT * FROM collate_test1 WHERE b ~ '^abc$'; + +SELECT * FROM collate_test1 WHERE b ~ '^abc'; + +SELECT * FROM collate_test1 WHERE b ~ 'bc'; + +SELECT * FROM collate_test1 WHERE b ~* '^abc$'; + +SELECT * FROM collate_test1 WHERE b ~* '^abc'; + +SELECT * FROM collate_test1 WHERE b ~* 'bc'; + +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en-x-icu" +); + +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, 'äbç'), (10, 'ÄBÇ'); + +SELECT b, + b ~ '^[[:alpha:]]+$' AS is_alpha, + b ~ '^[[:upper:]]+$' AS is_upper, + b ~ '^[[:lower:]]+$' AS is_lower, + b ~ '^[[:digit:]]+$' AS is_digit, + b ~ '^[[:alnum:]]+$' AS is_alnum, + b ~ '^[[:graph:]]+$' AS is_graph, + b ~ '^[[:print:]]+$' AS is_print, + b ~ '^[[:punct:]]+$' AS is_punct, + b ~ '^[[:space:]]+$' AS is_space +FROM collate_test6; + +SELECT 'Türkiye' COLLATE "en-x-icu" ~* 'KI' AS "true"; + +SELECT 'Türkiye' COLLATE "tr-x-icu" ~* 'KI' AS "true"; + +SELECT 'bıt' ~* 'BIT' COLLATE "en-x-icu" AS "false"; + +SELECT 'bıt' ~* 'BIT' COLLATE "tr-x-icu" AS "false"; + +SELECT relname FROM pg_class WHERE relname ~* '^abc'; + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; + +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; + +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10; + +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1; + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2; + +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2; + +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2; + +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3; + +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10; + +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2; + +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2; + +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2; + +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2; + +CREATE DOMAIN testdomain AS text; + +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2; + +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2; + +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2; + +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2; + +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10; + +SELECT min(b), max(b) FROM collate_test1; + +SELECT min(b), max(b) FROM collate_test2; + +SELECT min(b), max(b) FROM collate_test3; + +SELECT array_agg(b ORDER BY b) FROM collate_test1; + +SELECT array_agg(b ORDER BY b) FROM collate_test2; + +SELECT array_agg(b ORDER BY b) FROM collate_test3; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2; + +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2; + +SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2; + +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3; + +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2; + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3; + +select x < y from collate_test10; + +select x || y from collate_test10; + +select x, y from collate_test10 order by x || y; + +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "en-x-icu"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "de-x-icu" FROM foo WHERE length(x) < 10) +SELECT * FROM foo; + +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2; + +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2; + +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2; + +CREATE FUNCTION mylt (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 $$; + +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$; + +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$; + +SELECT a.b AS a, b.b AS b, a.b < b.b AS lt, + mylt(a.b, b.b), mylt_noninline(a.b, b.b), mylt_plpgsql(a.b, b.b) +FROM collate_test1 a, collate_test1 b +ORDER BY a.b, b.b; + +SELECT a.b AS a, b.b AS b, a.b < b.b COLLATE "C" AS lt, + mylt(a.b, b.b COLLATE "C"), mylt_noninline(a.b, b.b COLLATE "C"), + mylt_plpgsql(a.b, b.b COLLATE "C") +FROM collate_test1 a, collate_test1 b +ORDER BY a.b, b.b; + +CREATE FUNCTION mylt2 (x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$ +declare + xx text := x; + yy text := y; +begin + return xx < yy; +end +$$; + +SELECT mylt2('a', 'B' collate "en-x-icu") as t, mylt2('a', 'B' collate "C") as f; + +CREATE OR REPLACE FUNCTION + mylt2 (x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$ +declare + xx text COLLATE "POSIX" := x; + yy text := y; +begin + return xx < yy; +end +$$; + +SELECT mylt2('a', 'B') as f; + +SELECT mylt2('a', 'B' collate "C") as fail; + +SELECT mylt2('a', 'B' collate "POSIX") as f; + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1; + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1; + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1; + +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql; + +SELECT a, dup(b) FROM collate_test1 ORDER BY 2; + +SELECT a, dup(b) FROM collate_test2 ORDER BY 2; + +SELECT a, dup(b) FROM collate_test3 ORDER BY 2; + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b); + +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C"); + +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")); + +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")); + +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C"); + +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")); + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1; + +set enable_seqscan = off; + +select * from collate_test1 where b ilike 'abc'; + +select * from collate_test1 where b ilike 'abc'; + +select * from collate_test1 where b ilike 'ABC'; + +select * from collate_test1 where b ilike 'ABC'; + +reset enable_seqscan; + +CREATE ROLE regress_test_role; + +CREATE SCHEMA test_schema; + +SET client_min_messages TO WARNING; + +SET icu_validation_level = disabled; + +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (provider = icu, locale = ' || + quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');'; +END +$$; + +CREATE COLLATION test0 FROM "C"; + +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (provider = icu, locale = ' || + quote_literal((SELECT CASE WHEN datlocprovider='i' THEN datlocale ELSE datcollate END FROM pg_database WHERE datname = current_database())) || ');'; +END +$$; + +RESET icu_validation_level; + +RESET client_min_messages; + +CREATE COLLATION test3 (provider = icu, lc_collate = 'en_US.utf8'); + +SET icu_validation_level = ERROR; + +CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere'); + +CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes'); + +RESET icu_validation_level; + +CREATE COLLATION testx (provider = icu, locale = '@colStrength=primary;nonsense=yes'); + +DROP COLLATION testx; + +CREATE COLLATION testx (provider = icu, locale = 'nonsense-nowhere'); + +DROP COLLATION testx; + +CREATE COLLATION test4 FROM nonsense; + +CREATE COLLATION test5 FROM test0; + +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1; + +ALTER COLLATION test1 RENAME TO test11; + +ALTER COLLATION test0 RENAME TO test11; + +ALTER COLLATION test1 RENAME TO test22; + +ALTER COLLATION test11 OWNER TO regress_test_role; + +ALTER COLLATION test11 OWNER TO nonsense; + +ALTER COLLATION test11 SET SCHEMA test_schema; + +COMMENT ON COLLATION test0 IS 'US English'; + +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1; + +DROP COLLATION test0, test_schema.test11, test5; + +DROP COLLATION test0; + +DROP COLLATION IF EXISTS test0; + +SELECT collname FROM pg_collation WHERE collname LIKE 'test%'; + +DROP SCHEMA test_schema; + +DROP ROLE regress_test_role; + +ALTER COLLATION "en-x-icu" REFRESH VERSION; + +SELECT current_database() AS datname ; + +CREATE COLLATION test0 FROM "C"; + +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0); + +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0; + +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0); + +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo; + +CREATE TABLE collate_dep_test4t (a int, b text); + +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0); + +DROP COLLATION test0 RESTRICT; + +DROP COLLATION test0 CASCADE; + +DROP TABLE collate_dep_test1, collate_dep_test4t; + +DROP TYPE collate_dep_test2; + +create type textrange_c as range(subtype=text, collation="C"); + +create type textrange_en_us as range(subtype=text, collation="en-x-icu"); + +select textrange_c('A','Z') @> 'b'::text; + +select textrange_en_us('A','Z') @> 'b'::text; + +drop type textrange_c; + +drop type textrange_en_us; + +SELECT * FROM collate_test2 ORDER BY b COLLATE UCS_BASIC; + +SELECT * FROM collate_test2 ORDER BY b COLLATE UNICODE; + +SET client_min_messages=WARNING; + +CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes'); + +RESET client_min_messages; + +SELECT 'aaá' > 'AAA' COLLATE "und-x-icu", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents; + +SET client_min_messages=WARNING; + +CREATE COLLATION testcoll_backwards (provider = icu, locale = '@colBackwards=yes'); + +RESET client_min_messages; + +SELECT 'coté' < 'côte' COLLATE "und-x-icu", 'coté' > 'côte' COLLATE testcoll_backwards; + +CREATE COLLATION testcoll_lower_first (provider = icu, locale = '@colCaseFirst=lower'); + +CREATE COLLATION testcoll_upper_first (provider = icu, locale = '@colCaseFirst=upper'); + +SELECT 'aaa' < 'AAA' COLLATE testcoll_lower_first, 'aaa' > 'AAA' COLLATE testcoll_upper_first; + +CREATE COLLATION testcoll_shifted (provider = icu, locale = '@colAlternate=shifted'); + +SELECT 'de-luge' < 'deanza' COLLATE "und-x-icu", 'de-luge' > 'deanza' COLLATE testcoll_shifted; + +SET client_min_messages=WARNING; + +CREATE COLLATION testcoll_numeric (provider = icu, locale = '@colNumeric=yes'); + +RESET client_min_messages; + +SELECT 'A-21' > 'A-123' COLLATE "und-x-icu", 'A-21' < 'A-123' COLLATE testcoll_numeric; + +CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower'); + +CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook'); + +SELECT 'Goldmann' < 'Götz' COLLATE "de-x-icu", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook; + +CREATE COLLATION testcoll_rules1 (provider = icu, locale = '', rules = '&a < g'); + +CREATE TABLE test7 (a text); + +INSERT INTO test7 VALUES ('Abernathy'), ('apple'), ('bird'), ('Boston'), ('Graham'), ('green'); + +SELECT * FROM test7 ORDER BY a COLLATE "en-x-icu"; + +SELECT * FROM test7 ORDER BY a COLLATE testcoll_rules1; + +DROP TABLE test7; + +CREATE COLLATION testcoll_rulesx (provider = icu, locale = '', rules = '!!wrong!!'); + +CREATE COLLATION ctest_det (provider = icu, locale = '', deterministic = true); + +CREATE COLLATION ctest_nondet (provider = icu, locale = '', deterministic = false); + +SELECT 'abc' LIKE 'abc' COLLATE ctest_det; + +SELECT 'abc' LIKE 'a\bc' COLLATE ctest_det; + +SELECT 'abc' LIKE 'abc' COLLATE ctest_nondet; + +SELECT 'abc' LIKE 'a\bc' COLLATE ctest_nondet; + +CREATE TABLE test6 (a int, b text); + +INSERT INTO test6 VALUES (1, U&'zy\00E4bc'); + +INSERT INTO test6 VALUES (2, U&'zy\0061\0308bc'); + +SELECT * FROM test6; + +SELECT * FROM test6 WHERE b = 'zyäbc' COLLATE ctest_det; + +SELECT * FROM test6 WHERE b = 'zyäbc' COLLATE ctest_nondet; + +SELECT strpos(b COLLATE ctest_det, 'bc') FROM test6; + +SELECT strpos(b COLLATE ctest_nondet, 'bc') FROM test6; + +SELECT replace(b COLLATE ctest_det, U&'\00E4b', 'X') FROM test6; + +SELECT replace(b COLLATE ctest_nondet, U&'\00E4b', 'X') FROM test6; + +SELECT a, split_part(b COLLATE ctest_det, U&'\00E4b', 2) FROM test6; + +SELECT a, split_part(b COLLATE ctest_nondet, U&'\00E4b', 2) FROM test6; + +SELECT a, split_part(b COLLATE ctest_det, U&'\00E4b', -1) FROM test6; + +SELECT a, split_part(b COLLATE ctest_nondet, U&'\00E4b', -1) FROM test6; + +SELECT a, string_to_array(b COLLATE ctest_det, U&'\00E4b') FROM test6; + +SELECT a, string_to_array(b COLLATE ctest_nondet, U&'\00E4b') FROM test6; + +SELECT * FROM test6 WHERE b LIKE 'zyäbc' COLLATE ctest_det; + +SELECT * FROM test6 WHERE b LIKE 'zyäbc' COLLATE ctest_nondet; + +CREATE TABLE test6a (a int, b text[]); + +INSERT INTO test6a VALUES (1, ARRAY[U&'\00E4bc']); + +INSERT INTO test6a VALUES (2, ARRAY[U&'\0061\0308bc']); + +SELECT * FROM test6a; + +SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_det; + +SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_nondet; + +CREATE COLLATION case_sensitive (provider = icu, locale = ''); + +CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', deterministic = false); + +SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive; + +SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive; + +SELECT array_sort('{a,B}'::text[] COLLATE case_insensitive); + +SELECT array_sort('{a,B}'::text[] COLLATE "C"); + +CREATE COLLATION lt_insensitive (provider = icu, locale = 'en-u-ks-level1', deterministic = false); + +SELECT 'aBcD' COLLATE lt_insensitive = 'AbCd' COLLATE lt_insensitive; + +CREATE COLLATION lt_upperfirst (provider = icu, locale = 'und-u-kf-upper'); + +SELECT 'Z' COLLATE lt_upperfirst < 'z' COLLATE lt_upperfirst; + +CREATE TABLE test1cs (x text COLLATE case_sensitive); + +CREATE TABLE test2cs (x text COLLATE case_sensitive); + +CREATE TABLE test3cs (x text COLLATE case_sensitive); + +INSERT INTO test1cs VALUES ('abc'), ('def'), ('ghi'); + +INSERT INTO test2cs VALUES ('ABC'), ('ghi'); + +INSERT INTO test3cs VALUES ('abc'), ('ABC'), ('def'), ('ghi'); + +SELECT x FROM test3cs WHERE x = 'abc'; + +SELECT x FROM test3cs WHERE x <> 'abc'; + +SELECT x FROM test3cs WHERE x LIKE 'a%'; + +SELECT x FROM test3cs WHERE x ILIKE 'a%'; + +SELECT x FROM test3cs WHERE x SIMILAR TO 'a%'; + +SELECT x FROM test3cs WHERE x ~ 'a'; + +SET enable_hashagg TO off; + +SELECT x FROM test1cs UNION SELECT x FROM test2cs ORDER BY x; + +SELECT x FROM test2cs UNION SELECT x FROM test1cs ORDER BY x; + +SELECT x FROM test2cs; + +SELECT x FROM test1cs; + +SELECT x FROM test1cs EXCEPT SELECT x FROM test2cs; + +SELECT x FROM test2cs EXCEPT SELECT x FROM test1cs; + +SELECT DISTINCT x FROM test3cs ORDER BY x; + +RESET enable_hashagg; + +SELECT count(DISTINCT x) FROM test3cs; + +SELECT x, count(*) FROM test3cs GROUP BY x ORDER BY x; + +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3cs ORDER BY x; + +CREATE UNIQUE INDEX ON test1cs (x); + +INSERT INTO test1cs VALUES ('ABC'); + +CREATE UNIQUE INDEX ON test3cs (x); + +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_sensitive, ',', 'abc'); + +SELECT string_to_array('ABCDEFGHI' COLLATE case_sensitive, NULL, 'b'); + +CREATE TABLE test1ci (x text COLLATE case_insensitive); + +CREATE TABLE test2ci (x text COLLATE case_insensitive); + +CREATE TABLE test3ci (x text COLLATE case_insensitive); + +CREATE INDEX ON test3ci (x text_pattern_ops); + +INSERT INTO test1ci VALUES ('abc'), ('def'), ('ghi'); + +INSERT INTO test2ci VALUES ('ABC'), ('ghi'); + +INSERT INTO test3ci VALUES ('abc'), ('ABC'), ('def'), ('ghi'); + +SELECT x FROM test3ci WHERE x = 'abc'; + +SELECT x FROM test3ci WHERE x <> 'abc'; + +SELECT x FROM test3ci WHERE x LIKE 'a%'; + +SELECT x FROM test3ci WHERE x ILIKE 'a%'; + +SELECT x FROM test3ci WHERE x SIMILAR TO 'a%'; + +SELECT x FROM test3ci WHERE x ~ 'a'; + +SELECT x FROM test1ci UNION SELECT x FROM test2ci ORDER BY x; + +SELECT x FROM test2ci UNION SELECT x FROM test1ci ORDER BY x; + +SELECT x FROM test2ci ORDER BY x; + +SELECT x FROM test1ci ORDER BY x; + +SELECT x FROM test1ci EXCEPT SELECT x FROM test2ci; + +SELECT x FROM test2ci EXCEPT SELECT x FROM test1ci; + +SELECT DISTINCT x FROM test3ci ORDER BY x; + +SELECT count(DISTINCT x) FROM test3ci; + +SELECT x, count(*) FROM test3ci GROUP BY x ORDER BY x; + +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3ci ORDER BY x; + +CREATE UNIQUE INDEX ON test1ci (x); + +INSERT INTO test1ci VALUES ('ABC'); + +CREATE UNIQUE INDEX ON test3ci (x); + +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc'); + +SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b'); + +CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive); + +CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive); + +CREATE TABLE test3bpci (x char(3) COLLATE case_insensitive); + +CREATE INDEX ON test3bpci (x bpchar_pattern_ops); + +INSERT INTO test1bpci VALUES ('abc'), ('def'), ('ghi'); + +INSERT INTO test2bpci VALUES ('ABC'), ('ghi'); + +INSERT INTO test3bpci VALUES ('abc'), ('ABC'), ('def'), ('ghi'); + +SELECT x FROM test3bpci WHERE x = 'abc'; + +SELECT x FROM test3bpci WHERE x <> 'abc'; + +SELECT x FROM test3bpci WHERE x LIKE 'a%'; + +SELECT x FROM test3bpci WHERE x ILIKE 'a%'; + +SELECT x FROM test3bpci WHERE x SIMILAR TO 'a%'; + +SELECT x FROM test3bpci WHERE x ~ 'a'; + +SELECT x FROM test1bpci UNION SELECT x FROM test2bpci ORDER BY x; + +SELECT x FROM test2bpci UNION SELECT x FROM test1bpci ORDER BY x; + +SELECT x FROM test2bpci ORDER BY x; + +SELECT x FROM test1bpci ORDER BY x; + +SELECT x FROM test1bpci EXCEPT SELECT x FROM test2bpci; + +SELECT x FROM test2bpci EXCEPT SELECT x FROM test1bpci; + +SELECT DISTINCT x FROM test3bpci ORDER BY x; + +SELECT count(DISTINCT x) FROM test3bpci; + +SELECT x, count(*) FROM test3bpci GROUP BY x ORDER BY x; + +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3bpci ORDER BY x; + +CREATE UNIQUE INDEX ON test1bpci (x); + +INSERT INTO test1bpci VALUES ('ABC'); + +CREATE UNIQUE INDEX ON test3bpci (x); + +SELECT string_to_array('ABC,DEF,GHI'::char(11) COLLATE case_insensitive, ',', 'abc'); + +SELECT string_to_array('ABCDEFGHI'::char(9) COLLATE case_insensitive, NULL, 'b'); + +CREATE TABLE test4c (x text COLLATE case_insensitive); + +INSERT INTO test4c VALUES ('abc'); + +CREATE INDEX ON test4c (x); + +SET enable_seqscan = off; + +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_sensitive; + +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_sensitive; + +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_insensitive; + +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_insensitive; + +RESET enable_seqscan; + +SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_sensitive; + +SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_insensitive; + +SELECT relname FROM pg_class WHERE relname = 'PG_CLASS'::text COLLATE case_insensitive; + +SELECT relname FROM pg_class WHERE 'PG_CLASS'::text = relname COLLATE case_insensitive; + +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND typname <> 'INT2'::text + COLLATE case_insensitive ORDER BY typname; + +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND 'INT2'::text <> typname + COLLATE case_insensitive ORDER BY typname; + +CREATE TEMP TABLE outer_text (f1 text COLLATE case_insensitive, f2 text); + +INSERT INTO outer_text VALUES ('a', 'a'); + +INSERT INTO outer_text VALUES ('b', 'a'); + +INSERT INTO outer_text VALUES ('A', NULL); + +INSERT INTO outer_text VALUES ('B', NULL); + +CREATE TEMP TABLE inner_text (c1 text COLLATE case_insensitive, c2 text); + +INSERT INTO inner_text VALUES ('a', NULL); + +SELECT * FROM outer_text WHERE (f1, f2) NOT IN (SELECT * FROM inner_text); + +SET client_min_messages=WARNING; + +CREATE COLLATION ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes', deterministic = false); + +RESET client_min_messages; + +CREATE TABLE test4 (a int, b text); + +INSERT INTO test4 VALUES (1, 'cote'), (2, 'côte'), (3, 'coté'), (4, 'côté'); + +SELECT * FROM test4 WHERE b = 'cote'; + +SELECT * FROM test4 WHERE b = 'cote' COLLATE ignore_accents; + +SELECT * FROM test4 WHERE b = 'Cote' COLLATE ignore_accents; + +SELECT * FROM test4 WHERE b = 'Cote' COLLATE case_insensitive; + +CREATE TABLE test4nfd (a int, b text); + +INSERT INTO test4nfd VALUES (1, 'cote'), (2, 'côte'), (3, 'coté'), (4, 'côté'); + +UPDATE test4nfd SET b = normalize(b, nfd); + +SELECT a, b, replace(b COLLATE ignore_accents, 'co', 'ma') FROM test4; + +SELECT a, b, replace(b COLLATE ignore_accents, 'co', 'ma') FROM test4nfd; + +SELECT U&'\0061\0308bc' LIKE U&'\00E4_c' COLLATE ignore_accents; + +SELECT U&'\00E4bc' LIKE U&'\0061\0308_c' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'\00E4%c' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'\00E4%%c' COLLATE ignore_accents; + +SELECT U&'cb\0061\0308' LIKE U&'c%%\00E4' COLLATE ignore_accents; + +SELECT U&'cb\0061\0308' LIKE U&'cb_' COLLATE ignore_accents; + +SELECT U&'cb\0061\0308' LIKE U&'cb__' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'%\00E4bc' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'%\00E4%c' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'\00E4bc%' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'\00E4%c%' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'_bc' COLLATE ignore_accents; + +SELECT U&'\0308bc' = 'bc' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'__bc' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'_\0308bc' COLLATE ignore_accents; + +SELECT U&'\0061\0308bc' LIKE U&'_\00e4bc' COLLATE ignore_accents; + +SELECT 'foox' LIKE 'foo\' COLLATE ignore_accents; + +CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY); + +CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE); + +CREATE TABLE test11pk (x text COLLATE case_insensitive PRIMARY KEY); + +CREATE TABLE test11fk (x text COLLATE case_sensitive REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE); + +CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY); + +CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE NO ACTION); + +INSERT INTO test12pk VALUES ('abc'); + +INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC'); + +UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; + +SELECT * FROM test12pk; + +SELECT * FROM test12fk; + +DROP TABLE test12pk, test12fk; + +CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY); + +CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE RESTRICT); + +INSERT INTO test12pk VALUES ('abc'); + +INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC'); + +UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; + +SELECT * FROM test12pk; + +SELECT * FROM test12fk; + +DROP TABLE test12pk, test12fk; + +CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY); + +CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE CASCADE); + +INSERT INTO test12pk VALUES ('abc'); + +INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC'); + +UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; + +SELECT * FROM test12pk; + +SELECT * FROM test12fk; + +DROP TABLE test12pk, test12fk; + +CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b); + +CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc'); + +INSERT INTO test20 VALUES (1, 'abc'); + +INSERT INTO test20 VALUES (2, 'ABC'); + +SELECT * FROM test20_1; + +CREATE TABLE test21 (a int, b text COLLATE case_insensitive) PARTITION BY RANGE (b); + +CREATE TABLE test21_1 PARTITION OF test21 FOR VALUES FROM ('ABC') TO ('DEF'); + +INSERT INTO test21 VALUES (1, 'abc'); + +INSERT INTO test21 VALUES (2, 'ABC'); + +SELECT * FROM test21_1; + +CREATE TABLE test22 (a int, b text COLLATE case_sensitive) PARTITION BY HASH (b); + +CREATE TABLE test22_0 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE test22_1 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +INSERT INTO test22 VALUES (1, 'def'); + +INSERT INTO test22 VALUES (2, 'DEF'); + +SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1); + +CREATE TABLE test22a (a int, b text[] COLLATE case_sensitive) PARTITION BY HASH (b); + +CREATE TABLE test22a_0 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE test22a_1 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +INSERT INTO test22a VALUES (1, ARRAY['def']); + +INSERT INTO test22a VALUES (2, ARRAY['DEF']); + +SELECT (SELECT count(*) FROM test22a_0) = (SELECT count(*) FROM test22a_1); + +CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b); + +CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +INSERT INTO test23 VALUES (1, 'def'); + +INSERT INTO test23 VALUES (2, 'DEF'); + +SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1); + +CREATE TABLE test23a (a int, b text[] COLLATE case_insensitive) PARTITION BY HASH (b); + +CREATE TABLE test23a_0 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE test23a_1 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +INSERT INTO test23a VALUES (1, ARRAY['def']); + +INSERT INTO test23a VALUES (2, ARRAY['DEF']); + +SELECT (SELECT count(*) FROM test23a_0) <> (SELECT count(*) FROM test23a_1); + +CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b); + +CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc'); + +INSERT INTO test30 VALUES (1, 'abc'); + +INSERT INTO test30 VALUES (2, 'ABC'); + +SELECT * FROM test30_1; + +CREATE TABLE test31 (a int, b char(3) COLLATE case_insensitive) PARTITION BY RANGE (b); + +CREATE TABLE test31_1 PARTITION OF test31 FOR VALUES FROM ('ABC') TO ('DEF'); + +INSERT INTO test31 VALUES (1, 'abc'); + +INSERT INTO test31 VALUES (2, 'ABC'); + +SELECT * FROM test31_1; + +CREATE TABLE test32 (a int, b char(3) COLLATE case_sensitive) PARTITION BY HASH (b); + +CREATE TABLE test32_0 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE test32_1 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +INSERT INTO test32 VALUES (1, 'def'); + +INSERT INTO test32 VALUES (2, 'DEF'); + +SELECT (SELECT count(*) FROM test32_0) = (SELECT count(*) FROM test32_1); + +CREATE TABLE test33 (a int, b char(3) COLLATE case_insensitive) PARTITION BY HASH (b); + +CREATE TABLE test33_0 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE test33_1 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +INSERT INTO test33 VALUES (1, 'def'); + +INSERT INTO test33 VALUES (2, 'DEF'); + +SELECT (SELECT count(*) FROM test33_0) <> (SELECT count(*) FROM test33_1); + +SET max_parallel_workers_per_gather TO 0; + +SET enable_incremental_sort TO off; + +CREATE TABLE pagg_tab3 (a text, c text collate case_insensitive) PARTITION BY LIST(c collate "C"); + +CREATE TABLE pagg_tab3_p1 PARTITION OF pagg_tab3 FOR VALUES IN ('a', 'b'); + +CREATE TABLE pagg_tab3_p2 PARTITION OF pagg_tab3 FOR VALUES IN ('B', 'A'); + +INSERT INTO pagg_tab3 SELECT i % 4 + 1, substr('abAB', (i % 4) + 1 , 1) FROM generate_series(0, 19) i; + +ANALYZE pagg_tab3; + +SET enable_partitionwise_aggregate TO false; + +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1; + +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1; + +SET enable_partitionwise_aggregate TO true; + +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1; + +SELECT upper(c collate case_insensitive), count(c) FROM pagg_tab3 GROUP BY c collate case_insensitive ORDER BY 1; + +SELECT c collate "C", count(c) FROM pagg_tab3 GROUP BY c collate "C" ORDER BY 1; + +SELECT c collate "C", count(c) FROM pagg_tab3 GROUP BY c collate "C" ORDER BY 1; + +SET enable_partitionwise_join TO false; + +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SET enable_partitionwise_join TO true; + +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C"; + +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C"; + +SET enable_partitionwise_join TO false; + +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C"; + +SELECT t1.c COLLATE "C", count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab3 t2 ON t1.c = t2.c COLLATE "C" GROUP BY t1.c COLLATE "C" ORDER BY t1.c COLLATE "C"; + +SET enable_partitionwise_join TO true; + +CREATE TABLE pagg_tab4 (c text collate case_insensitive, b text collate case_insensitive) PARTITION BY LIST (b collate "C"); + +CREATE TABLE pagg_tab4_p1 PARTITION OF pagg_tab4 FOR VALUES IN ('a', 'b'); + +CREATE TABLE pagg_tab4_p2 PARTITION OF pagg_tab4 FOR VALUES IN ('B', 'A'); + +INSERT INTO pagg_tab4 (b, c) SELECT substr('abAB', (i % 4) + 1 , 1), substr('abAB', (i % 2) + 1 , 1) FROM generate_series(0, 11) i; + +ANALYZE pagg_tab4; + +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab4 t2 ON t1.c = t2.c AND t1.c = t2.b GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SELECT t1.c, count(t2.c) FROM pagg_tab3 t1 JOIN pagg_tab4 t2 ON t1.c = t2.c AND t1.c = t2.b GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +CREATE TABLE pagg_tab5 (c text collate case_insensitive, b text collate case_insensitive) PARTITION BY LIST (c collate case_insensitive); + +CREATE TABLE pagg_tab5_p1 PARTITION OF pagg_tab5 FOR VALUES IN ('a', 'b'); + +CREATE TABLE pagg_tab5_p2 PARTITION OF pagg_tab5 FOR VALUES IN ('c', 'd'); + +INSERT INTO pagg_tab5 (b, c) SELECT substr('abAB', (i % 4) + 1 , 1), substr('abAB', (i % 2) + 1 , 1) FROM generate_series(0, 5) i; + +INSERT INTO pagg_tab5 (b, c) SELECT substr('cdCD', (i % 4) + 1 , 1), substr('cdCD', (i % 2) + 1 , 1) FROM generate_series(0, 5) i; + +ANALYZE pagg_tab5; + +CREATE TABLE pagg_tab6 (c text collate case_insensitive, b text collate case_insensitive) PARTITION BY LIST (b collate case_insensitive); + +CREATE TABLE pagg_tab6_p1 PARTITION OF pagg_tab6 FOR VALUES IN ('a', 'b'); + +CREATE TABLE pagg_tab6_p2 PARTITION OF pagg_tab6 FOR VALUES IN ('c', 'd'); + +INSERT INTO pagg_tab6 (b, c) SELECT substr('abAB', (i % 4) + 1 , 1), substr('abAB', (i % 2) + 1 , 1) FROM generate_series(0, 5) i; + +INSERT INTO pagg_tab6 (b, c) SELECT substr('cdCD', (i % 4) + 1 , 1), substr('cdCD', (i % 2) + 1 , 1) FROM generate_series(0, 5) i; + +ANALYZE pagg_tab6; + +SELECT t1.c, count(t2.c) FROM pagg_tab5 t1 JOIN pagg_tab6 t2 ON t1.c = t2.c AND t1.c = t2.b GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SELECT t1.c, count(t2.c) FROM pagg_tab5 t1 JOIN pagg_tab6 t2 ON t1.c = t2.c AND t1.c = t2.b GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SET enable_partitionwise_join TO false; + +SELECT t1.c, count(t2.c) FROM pagg_tab5 t1 JOIN pagg_tab6 t2 ON t1.c = t2.c AND t1.c = t2.b GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +SELECT t1.c, count(t2.c) FROM pagg_tab5 t1 JOIN pagg_tab6 t2 ON t1.c = t2.c AND t1.c = t2.b GROUP BY 1 ORDER BY t1.c COLLATE "C"; + +DROP TABLE pagg_tab3; + +DROP TABLE pagg_tab4; + +DROP TABLE pagg_tab5; + +DROP TABLE pagg_tab6; + +RESET enable_partitionwise_aggregate; + +RESET max_parallel_workers_per_gather; + +RESET enable_incremental_sort; + +INSERT INTO t5 (a, b) values (1, 'D1'), (2, 'D2'), (3, 'd1'); + +SELECT * FROM t5 ORDER BY c ASC, a ASC; + +RESET search_path; + +SET client_min_messages TO warning; + +DROP SCHEMA collate_tests CASCADE; + +RESET client_min_messages; + +CREATE COLLATION coll_icu_upgrade FROM "und-x-icu"; diff --git a/crates/pgt_pretty_print/tests/data/multi/collate.linux.utf8_60.sql b/crates/pgt_pretty_print/tests/data/multi/collate.linux.utf8_60.sql new file mode 100644 index 000000000..26d7c54ac --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/collate.linux.utf8_60.sql @@ -0,0 +1,495 @@ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR + version() !~ 'linux-gnu' + AS skip_test ; + +SET client_encoding TO UTF8; + +CREATE SCHEMA collate_tests; + +SET search_path = collate_tests; + +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en_US" NOT NULL +); + +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp" +); + +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo" +); + +CREATE TABLE collate_test_fail ( + a int COLLATE "en_US", + b text +); + +CREATE TABLE collate_test_like ( + LIKE collate_test1 +); + +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv_SE" +); + +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +); + +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC'); + +INSERT INTO collate_test2 SELECT * FROM collate_test1; + +INSERT INTO collate_test3 SELECT * FROM collate_test1; + +SELECT * FROM collate_test1 WHERE b >= 'bbc'; + +SELECT * FROM collate_test2 WHERE b >= 'bbc'; + +SELECT * FROM collate_test3 WHERE b >= 'bbc'; + +SELECT * FROM collate_test3 WHERE b >= 'BBC'; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; + +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C"; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C"; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en_US"; + +CREATE DOMAIN testdomain_sv AS text COLLATE "sv_SE"; + +CREATE DOMAIN testdomain_i AS int COLLATE "sv_SE"; + +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +); + +INSERT INTO collate_test4 SELECT * FROM collate_test1; + +SELECT a, b FROM collate_test4 ORDER BY b; + +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en_US" +); + +INSERT INTO collate_test5 SELECT * FROM collate_test1; + +SELECT a, b FROM collate_test5 ORDER BY b; + +SELECT a, b FROM collate_test1 ORDER BY b; + +SELECT a, b FROM collate_test2 ORDER BY b; + +SELECT a, b FROM collate_test3 ORDER BY b; + +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; + +SELECT * FROM collate_test1 ORDER BY b; + +SELECT * FROM collate_test2 ORDER BY b; + +SELECT * FROM collate_test3 ORDER BY b; + +SELECT 'bbc' COLLATE "en_US" > 'äbc' COLLATE "en_US" AS "true"; + +SELECT 'bbc' COLLATE "sv_SE" > 'äbc' COLLATE "sv_SE" AS "false"; + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "en_US", + y text COLLATE "tr_TR" +); + +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ'); + +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10; + +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10; + +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a; + +SELECT * FROM collate_test1 WHERE b LIKE 'abc'; + +SELECT * FROM collate_test1 WHERE b LIKE 'abc%'; + +SELECT * FROM collate_test1 WHERE b LIKE '%bc%'; + +SELECT * FROM collate_test1 WHERE b ILIKE 'abc'; + +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%'; + +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%'; + +SELECT 'Türkiye' COLLATE "en_US" ILIKE '%KI%' AS "true"; + +SELECT 'Türkiye' COLLATE "tr_TR" ILIKE '%KI%' AS "false"; + +SELECT 'bıt' ILIKE 'BIT' COLLATE "en_US" AS "false"; + +SELECT 'bıt' ILIKE 'BIT' COLLATE "tr_TR" AS "true"; + +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%'; + +SELECT * FROM collate_test1 WHERE b ~ '^abc$'; + +SELECT * FROM collate_test1 WHERE b ~ '^abc'; + +SELECT * FROM collate_test1 WHERE b ~ 'bc'; + +SELECT * FROM collate_test1 WHERE b ~* '^abc$'; + +SELECT * FROM collate_test1 WHERE b ~* '^abc'; + +SELECT * FROM collate_test1 WHERE b ~* 'bc'; + +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en_US" +); + +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, 'äbç'), (10, 'ÄBÇ'); + +SELECT b, + b ~ '^[[:alpha:]]+$' AS is_alpha, + b ~ '^[[:upper:]]+$' AS is_upper, + b ~ '^[[:lower:]]+$' AS is_lower, + b ~ '^[[:digit:]]+$' AS is_digit, + b ~ '^[[:alnum:]]+$' AS is_alnum, + b ~ '^[[:graph:]]+$' AS is_graph, + b ~ '^[[:print:]]+$' AS is_print, + b ~ '^[[:punct:]]+$' AS is_punct, + b ~ '^[[:space:]]+$' AS is_space +FROM collate_test6; + +SELECT 'Türkiye' COLLATE "en_US" ~* 'KI' AS "true"; + +SELECT 'Türkiye' COLLATE "tr_TR" ~* 'KI' AS "false"; + +SELECT 'bıt' ~* 'BIT' COLLATE "en_US" AS "false"; + +SELECT 'bıt' ~* 'BIT' COLLATE "tr_TR" AS "true"; + +SELECT relname FROM pg_class WHERE relname ~* '^abc'; + +SET lc_time TO 'tr_TR'; + +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY'); + +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY' COLLATE "tr_TR"); + +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY'); + +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY' COLLATE "tr_TR"); + +SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY'); + +SELECT to_date('01 Şub 2010', 'DD TMMON YYYY'); + +SELECT to_date('1234567890ab 2010', 'TMMONTH YYYY'); + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; + +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; + +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10; + +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1; + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2; + +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2; + +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2; + +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3; + +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10; + +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2; + +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2; + +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2; + +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2; + +CREATE DOMAIN testdomain AS text; + +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2; + +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2; + +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2; + +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2; + +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10; + +SELECT min(b), max(b) FROM collate_test1; + +SELECT min(b), max(b) FROM collate_test2; + +SELECT min(b), max(b) FROM collate_test3; + +SELECT array_agg(b ORDER BY b) FROM collate_test1; + +SELECT array_agg(b ORDER BY b) FROM collate_test2; + +SELECT array_agg(b ORDER BY b) FROM collate_test3; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2; + +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2; + +SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2; + +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3; + +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b FROM collate_test3 ORDER BY 2; + +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2; + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3; + +select x < y from collate_test10; + +select x || y from collate_test10; + +select x, y from collate_test10 order by x || y; + +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "en_US"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "de_DE" FROM foo WHERE length(x) < 10) +SELECT * FROM foo; + +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2; + +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2; + +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2; + +CREATE FUNCTION mylt (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 $$; + +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$; + +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$; + +SELECT a.b AS a, b.b AS b, a.b < b.b AS lt, + mylt(a.b, b.b), mylt_noninline(a.b, b.b), mylt_plpgsql(a.b, b.b) +FROM collate_test1 a, collate_test1 b +ORDER BY a.b, b.b; + +SELECT a.b AS a, b.b AS b, a.b < b.b COLLATE "C" AS lt, + mylt(a.b, b.b COLLATE "C"), mylt_noninline(a.b, b.b COLLATE "C"), + mylt_plpgsql(a.b, b.b COLLATE "C") +FROM collate_test1 a, collate_test1 b +ORDER BY a.b, b.b; + +CREATE FUNCTION mylt2 (x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$ +declare + xx text := x; + yy text := y; +begin + return xx < yy; +end +$$; + +SELECT mylt2('a', 'B' collate "en_US") as t, mylt2('a', 'B' collate "C") as f; + +CREATE OR REPLACE FUNCTION + mylt2 (x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$ +declare + xx text COLLATE "POSIX" := x; + yy text := y; +begin + return xx < yy; +end +$$; + +SELECT mylt2('a', 'B') as f; + +SELECT mylt2('a', 'B' collate "C") as fail; + +SELECT mylt2('a', 'B' collate "POSIX") as f; + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1; + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1; + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1; + +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql; + +SELECT a, dup(b) FROM collate_test1 ORDER BY 2; + +SELECT a, dup(b) FROM collate_test2 ORDER BY 2; + +SELECT a, dup(b) FROM collate_test3 ORDER BY 2; + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b); + +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C"); + +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")); + +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")); + +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C"); + +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")); + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1; + +CREATE ROLE regress_test_role; + +CREATE SCHEMA test_schema; + +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test0 (locale = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || ');'; +END +$$; + +CREATE COLLATION test0 FROM "C"; + +CREATE COLLATION IF NOT EXISTS test0 FROM "C"; + +CREATE COLLATION IF NOT EXISTS test0 (locale = 'foo'); + +do $$ +BEGIN + EXECUTE 'CREATE COLLATION test1 (lc_collate = ' || + quote_literal((SELECT datcollate FROM pg_database WHERE datname = current_database())) || + ', lc_ctype = ' || + quote_literal((SELECT datctype FROM pg_database WHERE datname = current_database())) || ');'; +END +$$; + +CREATE COLLATION test3 (lc_collate = 'en_US.utf8'); + +CREATE COLLATION testx (locale = 'nonsense'); + +CREATE COLLATION test4 FROM nonsense; + +CREATE COLLATION test5 FROM test0; + +SELECT collname FROM pg_collation WHERE collname LIKE 'test%' ORDER BY 1; + +ALTER COLLATION test1 RENAME TO test11; + +ALTER COLLATION test0 RENAME TO test11; + +ALTER COLLATION test1 RENAME TO test22; + +ALTER COLLATION test11 OWNER TO regress_test_role; + +ALTER COLLATION test11 OWNER TO nonsense; + +ALTER COLLATION test11 SET SCHEMA test_schema; + +COMMENT ON COLLATION test0 IS 'US English'; + +SELECT collname, nspname, obj_description(pg_collation.oid, 'pg_collation') + FROM pg_collation JOIN pg_namespace ON (collnamespace = pg_namespace.oid) + WHERE collname LIKE 'test%' + ORDER BY 1; + +DROP COLLATION test0, test_schema.test11, test5; + +DROP COLLATION test0; + +DROP COLLATION IF EXISTS test0; + +SELECT collname FROM pg_collation WHERE collname LIKE 'test%'; + +DROP SCHEMA test_schema; + +DROP ROLE regress_test_role; + +ALTER COLLATION "en_US" REFRESH VERSION; + +SELECT current_database() AS datname ; + +CREATE COLLATION test0 FROM "C"; + +CREATE TABLE collate_dep_test1 (a int, b text COLLATE test0); + +CREATE DOMAIN collate_dep_dom1 AS text COLLATE test0; + +CREATE TYPE collate_dep_test2 AS (x int, y text COLLATE test0); + +CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo; + +CREATE TABLE collate_dep_test4t (a int, b text); + +CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0); + +DROP COLLATION test0 RESTRICT; + +DROP COLLATION test0 CASCADE; + +DROP TABLE collate_dep_test1, collate_dep_test4t; + +DROP TYPE collate_dep_test2; + +create type textrange_c as range(subtype=text, collation="C"); + +create type textrange_en_us as range(subtype=text, collation="en_US"); + +select textrange_c('A','Z') @> 'b'::text; + +select textrange_en_us('A','Z') @> 'b'::text; + +drop type textrange_c; + +drop type textrange_en_us; + +SELECT * FROM collate_test2 ORDER BY b COLLATE UCS_BASIC; + +CREATE COLLATION ctest_det (locale = 'en_US.utf8', deterministic = true); + +CREATE COLLATION ctest_nondet (locale = 'en_US.utf8', deterministic = false); + +SET client_min_messages TO warning; + +DROP SCHEMA collate_tests CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/collate.utf8_60.sql b/crates/pgt_pretty_print/tests/data/multi/collate.utf8_60.sql new file mode 100644 index 000000000..8cb94f2a5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/collate.utf8_60.sql @@ -0,0 +1,149 @@ +SELECT getdatabaseencoding() <> 'UTF8' AS skip_test ; + +SET client_encoding TO UTF8; + +CREATE COLLATION regress_builtin_c ( + provider = builtin, locale = 'C'); + +SELECT LOWER(U&'\00C1' COLLATE regress_builtin_c) = U&'\00C1'; + +SELECT UPPER(U&'\00E1' COLLATE regress_builtin_c) = U&'\00E1'; + +SELECT U&'\00C1\00E1' !~ '[[:alpha:]]' COLLATE regress_builtin_c; + +DROP COLLATION regress_builtin_c; + +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C_UTF8'); + +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C.UTF8'); + +DROP COLLATION regress_pg_c_utf8; + +CREATE COLLATION regress_pg_c_utf8 ( + provider = builtin, locale = 'C.UTF-8'); + +CREATE TABLE test_pg_c_utf8 ( + t TEXT COLLATE PG_C_UTF8 +); + +INSERT INTO test_pg_c_utf8 VALUES + ('abc DEF 123abc'), + ('ábc sßs ßss DÉF'), + ('DŽxxDŽ džxxDž Džxxdž'), + (U&'Λλ 1a \FF11a'), + ('ȺȺȺ'), + ('ⱥⱥⱥ'), + ('ⱥȺ'); + +SELECT + t, lower(t), initcap(t), upper(t), + length(convert_to(t, 'UTF8')) AS t_bytes, + length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes, + length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes, + length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes + FROM test_pg_c_utf8; + +DROP TABLE test_pg_c_utf8; + +SELECT lower('ΑΣ' COLLATE PG_C_UTF8); + +SELECT lower('ΑͺΣͺ' COLLATE PG_C_UTF8); + +SELECT lower('Α΄Σ΄' COLLATE PG_C_UTF8); + +SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_C_UTF8; + +SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_C_UTF8; + +SELECT '@' !~ '[[:alnum:]]' COLLATE PG_C_UTF8; + +SELECT '=' ~ '[[:punct:]]' COLLATE PG_C_UTF8; + +SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_C_UTF8; + +SELECT '൧' !~ '\d' COLLATE PG_C_UTF8; + +SELECT 'xYz' ~* 'XyZ' COLLATE PG_C_UTF8; + +SELECT 'xAb' ~* '[W-Y]' COLLATE PG_C_UTF8; + +SELECT 'xAb' !~* '[c-d]' COLLATE PG_C_UTF8; + +SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_C_UTF8; + +SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_C_UTF8; + +select casefold('AbCd 123 #$% ıiIİ ẞ ß DŽDždž Σσς' collate PG_C_UTF8); + +CREATE COLLATION regress_pg_unicode_fast ( + provider = builtin, locale = 'unicode'); + +CREATE COLLATION regress_pg_unicode_fast ( + provider = builtin, locale = 'PG_UNICODE_FAST'); + +CREATE TABLE test_pg_unicode_fast ( + t TEXT COLLATE PG_UNICODE_FAST +); + +INSERT INTO test_pg_unicode_fast VALUES + ('abc DEF 123abc'), + ('ábc sßs ßss DÉF'), + ('DŽxxDŽ džxxDž Džxxdž'), + (U&'Λλ 1a \FF11a'), + ('ȺȺȺ'), + ('ⱥⱥⱥ'), + ('ⱥȺ'); + +SELECT + t, lower(t), initcap(t), upper(t), + length(convert_to(t, 'UTF8')) AS t_bytes, + length(convert_to(lower(t), 'UTF8')) AS lower_t_bytes, + length(convert_to(initcap(t), 'UTF8')) AS initcap_t_bytes, + length(convert_to(upper(t), 'UTF8')) AS upper_t_bytes + FROM test_pg_unicode_fast; + +DROP TABLE test_pg_unicode_fast; + +SELECT lower('ΑΣ' COLLATE PG_UNICODE_FAST); + +SELECT lower('ΑΣ0' COLLATE PG_UNICODE_FAST); + +SELECT lower('ἈΣ̓' COLLATE PG_UNICODE_FAST); + +SELECT lower('ᾼΣͅ' COLLATE PG_UNICODE_FAST); + +SELECT lower('Σ' COLLATE PG_UNICODE_FAST); + +SELECT lower('0Σ' COLLATE PG_UNICODE_FAST); + +SELECT lower('ΑΣΑ' COLLATE PG_UNICODE_FAST); + +SELECT lower('ἈΣ̓Α' COLLATE PG_UNICODE_FAST); + +SELECT lower('ᾼΣͅΑ' COLLATE PG_UNICODE_FAST); + +SELECT 'xyz' ~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST; + +SELECT 'xyz' !~ '[[:upper:]]' COLLATE PG_UNICODE_FAST; + +SELECT '@' !~ '[[:alnum:]]' COLLATE PG_UNICODE_FAST; + +SELECT '=' !~ '[[:punct:]]' COLLATE PG_UNICODE_FAST; + +SELECT 'a8a' ~ '[[:digit:]]' COLLATE PG_UNICODE_FAST; + +SELECT '൧' ~ '\d' COLLATE PG_UNICODE_FAST; + +SELECT 'xYz' ~* 'XyZ' COLLATE PG_UNICODE_FAST; + +SELECT 'xAb' ~* '[W-Y]' COLLATE PG_UNICODE_FAST; + +SELECT 'xAb' !~* '[c-d]' COLLATE PG_UNICODE_FAST; + +SELECT 'Δ' ~* '[γ-λ]' COLLATE PG_UNICODE_FAST; + +SELECT 'δ' ~* '[Γ-Λ]' COLLATE PG_UNICODE_FAST; + +select casefold('AbCd 123 #$% ıiIİ ẞ ß DŽDždž Σσς' collate PG_UNICODE_FAST); diff --git a/crates/pgt_pretty_print/tests/data/multi/collate_60.sql b/crates/pgt_pretty_print/tests/data/multi/collate_60.sql new file mode 100644 index 000000000..21b687610 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/collate_60.sql @@ -0,0 +1,316 @@ +CREATE SCHEMA collate_tests; + +SET search_path = collate_tests; + +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "C" NOT NULL +); + +CREATE TABLE collate_test_fail ( + a int COLLATE "C", + b text +); + +CREATE TABLE collate_test_like ( + LIKE collate_test1 +); + +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "POSIX" +); + +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'Abc'), (3, 'bbc'), (4, 'ABD'); + +INSERT INTO collate_test2 SELECT * FROM collate_test1; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc'; + +SELECT * FROM collate_test1 WHERE b >= 'abc' COLLATE "C"; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'abc' COLLATE "C"; + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "POSIX"; + +CREATE DOMAIN testdomain_p AS text COLLATE "POSIX"; + +CREATE DOMAIN testdomain_i AS int COLLATE "POSIX"; + +CREATE TABLE collate_test4 ( + a int, + b testdomain_p +); + +INSERT INTO collate_test4 SELECT * FROM collate_test1; + +SELECT a, b FROM collate_test4 ORDER BY b; + +CREATE TABLE collate_test5 ( + a int, + b testdomain_p COLLATE "C" +); + +INSERT INTO collate_test5 SELECT * FROM collate_test1; + +SELECT a, b FROM collate_test5 ORDER BY b; + +SELECT a, b FROM collate_test1 ORDER BY b; + +SELECT a, b FROM collate_test2 ORDER BY b; + +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; + +SELECT * FROM collate_test1 ORDER BY b; + +SELECT * FROM collate_test2 ORDER BY b; + +SELECT 'bbc' COLLATE "C" > 'Abc' COLLATE "C" AS "true"; + +SELECT 'bbc' COLLATE "POSIX" < 'Abc' COLLATE "POSIX" AS "false"; + +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "C", + y text COLLATE "POSIX" +); + +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ'); + +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10; + +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10; + +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a; + +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; + +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; + +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "POSIX") FROM collate_test10; + +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1; + +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2; + +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2; + +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3; + +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3; + +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10; + +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2; + +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2; + +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2; + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2; + +CREATE DOMAIN testdomain AS text; + +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2; + +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2; + +SELECT a, b::testdomain_p FROM collate_test2 ORDER BY 2; + +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10; + +SELECT min(b), max(b) FROM collate_test1; + +SELECT min(b), max(b) FROM collate_test2; + +SELECT array_agg(b ORDER BY b) FROM collate_test1; + +SELECT array_agg(b ORDER BY b) FROM collate_test2; + +SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM collate_test10; + +SELECT array_agg(x COLLATE "C" ORDER BY y COLLATE "POSIX") FROM collate_test10; + +SELECT array_agg(a ORDER BY x COLLATE "C", y COLLATE "POSIX") FROM collate_test10; + +SELECT array_agg(a ORDER BY x||y) FROM collate_test10; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2; + +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2; + +SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2; + +SELECT a, b FROM collate_test2 EXCEPT SELECT a, b FROM collate_test2 WHERE a < 2 ORDER BY 2; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2 ORDER BY 2; + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; + +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; + +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test2 ORDER BY 2; + +SELECT a, b FROM collate_test2 ORDER BY 2; + +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test2 ORDER BY 2; + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test2; + +select x < y from collate_test10; + +select x || y from collate_test10; + +select x, y from collate_test10 order by x || y; + +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "POSIX" FROM foo WHERE length(x) < 10) +SELECT * FROM foo; + +SELECT a, b, a < b as lt FROM + (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b); + +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y, x FROM collate_test10); + +SELECT * FROM collate_test10 WHERE (x COLLATE "POSIX", y COLLATE "C") NOT IN (SELECT y, x FROM collate_test10); + +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y COLLATE "C", x COLLATE "POSIX" FROM collate_test10); + +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2; + +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2; + +CREATE FUNCTION vc (text) RETURNS text LANGUAGE sql + AS 'select $1::varchar'; + +SELECT a, b FROM collate_test1 ORDER BY a, vc(b); + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1; + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1; + +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql; + +SELECT a, dup(b) FROM collate_test1 ORDER BY 2; + +SELECT a, dup(b) FROM collate_test2 ORDER BY 2; + +CREATE INDEX collate_test1_idx1 ON collate_test1 (b); + +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "POSIX"); + +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "POSIX")); + +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")); + +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "POSIX"); + +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "POSIX")); + +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1; + +SET enable_seqscan TO 0; + +SET enable_hashjoin TO 0; + +SET enable_nestloop TO 0; + +CREATE TABLE collate_test20 (f1 text COLLATE "C" PRIMARY KEY); + +INSERT INTO collate_test20 VALUES ('foo'), ('bar'); + +CREATE TABLE collate_test21 (f2 text COLLATE "POSIX" REFERENCES collate_test20); + +INSERT INTO collate_test21 VALUES ('foo'), ('bar'); + +INSERT INTO collate_test21 VALUES ('baz'); + +CREATE TABLE collate_test22 (f2 text COLLATE "POSIX"); + +INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz'); + +ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; + +DELETE FROM collate_test22 WHERE f2 = 'baz'; + +ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; + +RESET enable_seqscan; + +RESET enable_hashjoin; + +RESET enable_nestloop; + +SELECT * FROM collate_test10 ORDER BY x, y; + +SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE "C" ASC NULLS FIRST; + +CREATE COLLATION builtin_c ( PROVIDER = builtin, LOCALE = "C" ); + +SELECT b FROM collate_test1 ORDER BY b COLLATE builtin_c; + +CREATE COLLATION builtin2 ( PROVIDER = builtin ); + +CREATE COLLATION builtin2 ( PROVIDER = builtin, LOCALE = "en_US" ); + +CREATE COLLATION builtin2 ( PROVIDER = builtin, LC_CTYPE = "C", LC_COLLATE = "C" ); + +CREATE COLLATION mycoll1 FROM "C"; + +CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" ); + +CREATE COLLATION mycoll3 FROM "default"; + +DROP COLLATION mycoll1; + +CREATE TABLE collate_test23 (f1 text collate mycoll2); + +DROP COLLATION mycoll2; + +CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctype" = "POSIX"); + +CREATE TEMP TABLE vctable (f1 varchar(25)); + +INSERT INTO vctable VALUES ('foo' COLLATE "C"); + +SELECT collation for ('foo'); + +SELECT collation for ('foo'::text); + +SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)); + +SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)); + +CREATE VIEW collate_on_int AS +SELECT c1+1 AS c1p FROM + (SELECT ('4' COLLATE "C")::INT AS c1) ss; + +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_COLLATE = "NONSENSE", LC_CTYPE = "POSIX"); + +CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LC_CTYPE = "NONSENSE", LC_COLLATE = "POSIX"); + +CREATE COLLATION coll_dup_chk (PROVIDER = icu, PROVIDER = NONSENSE, LC_COLLATE = "POSIX", LC_CTYPE = "POSIX"); + +CREATE COLLATION case_sensitive (LOCALE = '', LOCALE = "NONSENSE"); + +CREATE COLLATION coll_dup_chk (DETERMINISTIC = TRUE, DETERMINISTIC = NONSENSE, LOCALE = ''); + +CREATE COLLATION coll_dup_chk (VERSION = '1', VERSION = "NONSENSE", LOCALE = ''); + +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LC_CTYPE = "POSIX", LOCALE = ''); + +CREATE COLLATION coll_dup_chk (LC_COLLATE = "POSIX", LOCALE = ''); + +CREATE COLLATION coll_dup_chk (LC_CTYPE = "POSIX", LOCALE = ''); + +CREATE COLLATION coll_dup_chk (FROM = "C", VERSION = "1"); + +DROP SCHEMA collate_tests CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/combocid_60.sql b/crates/pgt_pretty_print/tests/data/multi/combocid_60.sql new file mode 100644 index 000000000..4e1e91286 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/combocid_60.sql @@ -0,0 +1,126 @@ +CREATE TEMP TABLE combocidtest (foobar int); + +BEGIN; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest VALUES (1); + +INSERT INTO combocidtest VALUES (2); + +SELECT ctid,cmin,* FROM combocidtest; + +SAVEPOINT s1; + +UPDATE combocidtest SET foobar = foobar + 10; + +SELECT ctid,cmin,* FROM combocidtest; + +ROLLBACK TO s1; + +SELECT ctid,cmin,* FROM combocidtest; + +COMMIT; + +SELECT ctid,cmin,* FROM combocidtest; + +BEGIN; + +INSERT INTO combocidtest VALUES (333); + +DECLARE c CURSOR FOR SELECT ctid,cmin,* FROM combocidtest; + +DELETE FROM combocidtest; + +FETCH ALL FROM c; + +ROLLBACK; + +SELECT ctid,cmin,* FROM combocidtest; + +BEGIN; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest SELECT 1 LIMIT 0; + +INSERT INTO combocidtest VALUES (444); + +SELECT ctid,cmin,* FROM combocidtest; + +SAVEPOINT s1; + +SELECT ctid,cmin,* FROM combocidtest FOR UPDATE; + +SELECT ctid,cmin,* FROM combocidtest; + +UPDATE combocidtest SET foobar = foobar + 10; + +SELECT ctid,cmin,* FROM combocidtest; + +ROLLBACK TO s1; + +SELECT ctid,cmin,* FROM combocidtest; + +COMMIT; + +SELECT ctid,cmin,* FROM combocidtest; + +CREATE TABLE IF NOT EXISTS testcase( + id int PRIMARY KEY, + balance numeric +); + +INSERT INTO testcase VALUES (1, 0); + +BEGIN; + +SELECT * FROM testcase WHERE testcase.id = 1 FOR UPDATE; + +UPDATE testcase SET balance = balance + 400 WHERE id=1; + +SAVEPOINT subxact; + +UPDATE testcase SET balance = balance - 100 WHERE id=1; + +ROLLBACK TO SAVEPOINT subxact; + +SELECT * FROM testcase WHERE id = 1 FOR UPDATE; + +ROLLBACK; + +DROP TABLE testcase; diff --git a/crates/pgt_pretty_print/tests/data/multi/comments_60.sql b/crates/pgt_pretty_print/tests/data/multi/comments_60.sql new file mode 100644 index 000000000..ac3db45e1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/comments_60.sql @@ -0,0 +1,24 @@ +SELECT 'trailing' AS first; + +SELECT /* embedded single line */ 'embedded' AS second; + +SELECT /* both embedded and trailing single line */ 'both' AS third; + +SELECT 'before multi-line' AS fourth; + +SELECT 'after multi-line' AS fifth; + +SELECT -- continued after the following block comments... +/* Deeply nested comment. + This includes a single apostrophe to make sure we aren't decoding this part as a string. +SELECT 'deep nest' AS n1; +/* Second level of nesting... +SELECT 'deeper nest' as n2; +/* Third level of nesting... +SELECT 'deepest nest' as n3; +*/ +Hoo boy. Still two deep... +*/ +Now just one deep... +*/ +'deeply nested example' AS sixth; diff --git a/crates/pgt_pretty_print/tests/data/multi/compression_60.sql b/crates/pgt_pretty_print/tests/data/multi/compression_60.sql new file mode 100644 index 000000000..a74284b22 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/compression_60.sql @@ -0,0 +1,82 @@ +CREATE SCHEMA pglz; + +SET search_path TO pglz, public; + +SET default_toast_compression = 'pglz'; + +CREATE TABLE cmdata(f1 text COMPRESSION pglz); + +CREATE INDEX idx ON cmdata(f1); + +INSERT INTO cmdata VALUES(repeat('1234567890', 1000)); + +SELECT pg_column_compression(f1) FROM cmdata; + +SELECT SUBSTR(f1, 200, 5) FROM cmdata; + +SELECT * INTO cmmove1 FROM cmdata; + +SELECT pg_column_compression(f1) FROM cmmove1; + +CREATE TABLE cmdata2 (f1 int COMPRESSION pglz); + +CREATE OR REPLACE FUNCTION large_val() RETURNS TEXT LANGUAGE SQL AS +'select array_agg(fipshash(g::text))::text from generate_series(1, 256) g'; + +CREATE TABLE cmdata2 (f1 text COMPRESSION pglz); + +INSERT INTO cmdata2 SELECT large_val() || repeat('a', 4000); + +SELECT pg_column_compression(f1) FROM cmdata2; + +SELECT SUBSTR(f1, 200, 5) FROM cmdata2; + +DROP TABLE cmdata2; + +CREATE TABLE cmdata2 (f1 int); + +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar; + +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE int USING f1::integer; + +ALTER TABLE cmdata2 ALTER COLUMN f1 TYPE varchar; + +ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION pglz; + +ALTER TABLE cmdata2 ALTER COLUMN f1 SET STORAGE plain; + +INSERT INTO cmdata2 VALUES (repeat('123456789', 800)); + +SELECT pg_column_compression(f1) FROM cmdata2; + +CREATE TABLE cmdata3(f1 text); + +CREATE TABLE cminh() INHERITS (cmdata, cmdata3); + +SET default_toast_compression = ''; + +SET default_toast_compression = 'I do not exist compression'; + +SET default_toast_compression = 'pglz'; + +ALTER TABLE cmdata2 ALTER COLUMN f1 SET COMPRESSION default; + +DROP TABLE cmdata2; + +SELECT pg_column_compression(f1) FROM cmdata; + +VACUUM FULL cmdata; + +SELECT pg_column_compression(f1) FROM cmdata; + +SELECT length(f1) FROM cmdata; + +SELECT length(f1) FROM cmmove1; + +CREATE TABLE badcompresstbl (a text COMPRESSION I_Do_Not_Exist_Compression); + +CREATE TABLE badcompresstbl (a text); + +ALTER TABLE badcompresstbl ALTER a SET COMPRESSION I_Do_Not_Exist_Compression; + +DROP TABLE badcompresstbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/compression_lz4_60.sql b/crates/pgt_pretty_print/tests/data/multi/compression_lz4_60.sql new file mode 100644 index 000000000..061c60c76 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/compression_lz4_60.sql @@ -0,0 +1,134 @@ +SELECT NOT(enumvals @> '{lz4}') AS skip_test FROM pg_settings WHERE + name = 'default_toast_compression' ; + +CREATE SCHEMA lz4; + +SET search_path TO lz4, public; + +SET default_toast_compression = 'pglz'; + +CREATE TABLE cmdata_pglz(f1 text COMPRESSION pglz); + +CREATE INDEX idx ON cmdata_pglz(f1); + +INSERT INTO cmdata_pglz VALUES(repeat('1234567890', 1000)); + +CREATE TABLE cmdata_lz4(f1 TEXT COMPRESSION lz4); + +INSERT INTO cmdata_lz4 VALUES(repeat('1234567890', 1004)); + +SELECT pg_column_compression(f1) FROM cmdata_lz4; + +SELECT SUBSTR(f1, 200, 5) FROM cmdata_pglz; + +SELECT SUBSTR(f1, 2000, 50) FROM cmdata_lz4; + +SELECT * INTO cmmove1 FROM cmdata_lz4; + +SELECT pg_column_compression(f1) FROM cmmove1; + +CREATE TABLE cmdata2 (LIKE cmdata_lz4 INCLUDING COMPRESSION); + +DROP TABLE cmdata2; + +CREATE TABLE cmmove3(f1 text COMPRESSION pglz); + +INSERT INTO cmmove3 SELECT * FROM cmdata_pglz; + +INSERT INTO cmmove3 SELECT * FROM cmdata_lz4; + +SELECT pg_column_compression(f1) FROM cmmove3; + +CREATE TABLE cmmove2(f1 text COMPRESSION pglz); + +INSERT INTO cmmove2 VALUES (repeat('1234567890', 1004)); + +SELECT pg_column_compression(f1) FROM cmmove2; + +UPDATE cmmove2 SET f1 = cmdata_lz4.f1 FROM cmdata_lz4; + +SELECT pg_column_compression(f1) FROM cmmove2; + +CREATE OR REPLACE FUNCTION large_val_lz4() RETURNS TEXT LANGUAGE SQL AS +'select array_agg(fipshash(g::text))::text from generate_series(1, 256) g'; + +CREATE TABLE cmdata2 (f1 text COMPRESSION lz4); + +INSERT INTO cmdata2 SELECT large_val_lz4() || repeat('a', 4000); + +SELECT pg_column_compression(f1) FROM cmdata2; + +SELECT SUBSTR(f1, 200, 5) FROM cmdata2; + +DROP TABLE cmdata2; + +DROP FUNCTION large_val_lz4; + +CREATE MATERIALIZED VIEW compressmv(x) AS SELECT * FROM cmdata_lz4; + +SELECT pg_column_compression(f1) FROM cmdata_lz4; + +SELECT pg_column_compression(x) FROM compressmv; + +CREATE TABLE cmpart(f1 text COMPRESSION lz4) PARTITION BY HASH(f1); + +CREATE TABLE cmpart1 PARTITION OF cmpart FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE cmpart2(f1 text COMPRESSION pglz); + +INSERT INTO cmpart VALUES (repeat('123456789', 1004)); + +INSERT INTO cmpart VALUES (repeat('123456789', 4004)); + +SELECT pg_column_compression(f1) FROM cmpart1; + +SELECT pg_column_compression(f1) FROM cmpart2; + +CREATE TABLE cminh() INHERITS(cmdata_pglz, cmdata_lz4); + +CREATE TABLE cminh(f1 TEXT COMPRESSION lz4) INHERITS(cmdata_pglz); + +CREATE TABLE cmdata3(f1 text); + +CREATE TABLE cminh() INHERITS (cmdata_pglz, cmdata3); + +SET default_toast_compression = 'lz4'; + +ALTER TABLE cmdata_pglz ALTER COLUMN f1 SET COMPRESSION lz4; + +INSERT INTO cmdata_pglz VALUES (repeat('123456789', 4004)); + +SELECT pg_column_compression(f1) FROM cmdata_pglz; + +ALTER TABLE cmdata_pglz ALTER COLUMN f1 SET COMPRESSION pglz; + +ALTER MATERIALIZED VIEW compressmv ALTER COLUMN x SET COMPRESSION lz4; + +ALTER TABLE cmpart1 ALTER COLUMN f1 SET COMPRESSION pglz; + +ALTER TABLE cmpart2 ALTER COLUMN f1 SET COMPRESSION lz4; + +INSERT INTO cmpart VALUES (repeat('123456789', 1004)); + +INSERT INTO cmpart VALUES (repeat('123456789', 4004)); + +SELECT pg_column_compression(f1) FROM cmpart1; + +SELECT pg_column_compression(f1) FROM cmpart2; + +CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4); + +CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2)); + +INSERT INTO cmdata2 VALUES((SELECT array_agg(fipshash(g::TEXT))::TEXT FROM +generate_series(1, 50) g), VERSION()); + +SELECT length(f1) FROM cmdata_pglz; + +SELECT length(f1) FROM cmdata_lz4; + +SELECT length(f1) FROM cmmove1; + +SELECT length(f1) FROM cmmove2; + +SELECT length(f1) FROM cmmove3; diff --git a/crates/pgt_pretty_print/tests/data/multi/constraints_60.sql b/crates/pgt_pretty_print/tests/data/multi/constraints_60.sql new file mode 100644 index 000000000..d9d9dc77b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/constraints_60.sql @@ -0,0 +1,190 @@ +CREATE TABLE DEFAULT_TBL (i int DEFAULT 100, + x text DEFAULT 'vadim', f float8 DEFAULT 123.456); + +INSERT INTO DEFAULT_TBL VALUES (1, 'thomas', 57.0613); + +INSERT INTO DEFAULT_TBL VALUES (1, 'bruce'); + +INSERT INTO DEFAULT_TBL (i, f) VALUES (2, 987.654); + +INSERT INTO DEFAULT_TBL (x) VALUES ('marc'); + +INSERT INTO DEFAULT_TBL VALUES (3, null, 1.0); + +SELECT * FROM DEFAULT_TBL; + +CREATE SEQUENCE DEFAULT_SEQ; + +CREATE TABLE DEFAULTEXPR_TBL (i1 int DEFAULT 100 + (200-199) * 2, + i2 int DEFAULT nextval('default_seq')); + +INSERT INTO DEFAULTEXPR_TBL VALUES (-1, -2); + +INSERT INTO DEFAULTEXPR_TBL (i1) VALUES (-3); + +INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (-4); + +INSERT INTO DEFAULTEXPR_TBL (i2) VALUES (NULL); + +SELECT * FROM DEFAULTEXPR_TBL; + +CREATE TABLE error_tbl (b1 bool DEFAULT (1 IN (1, 2))); + +DROP TABLE error_tbl; + +CREATE TABLE CHECK_TBL (x int, + CONSTRAINT CHECK_CON CHECK (x > 3)); + +INSERT INTO CHECK_TBL VALUES (5); + +INSERT INTO CHECK_TBL VALUES (4); + +INSERT INTO CHECK_TBL VALUES (3); + +INSERT INTO CHECK_TBL VALUES (2); + +INSERT INTO CHECK_TBL VALUES (6); + +INSERT INTO CHECK_TBL VALUES (1); + +SELECT * FROM CHECK_TBL; + +INSERT INTO NE_CHECK_TBL VALUES (5); + +INSERT INTO NE_CHECK_TBL VALUES (4); + +INSERT INTO NE_CHECK_TBL VALUES (3); + +INSERT INTO NE_CHECK_TBL VALUES (2); + +INSERT INTO NE_CHECK_TBL VALUES (6); + +INSERT INTO NE_CHECK_TBL VALUES (1); + +SELECT * FROM NE_CHECK_TBL; + +CREATE SEQUENCE CHECK_SEQ; + +CREATE TABLE CHECK2_TBL (x int, y text, z int, + CONSTRAINT SEQUENCE_CON + CHECK (x > 3 and y <> 'check failed' and z < 8)); + +INSERT INTO CHECK2_TBL VALUES (4, 'check ok', -2); + +INSERT INTO CHECK2_TBL VALUES (1, 'x check failed', -2); + +INSERT INTO CHECK2_TBL VALUES (5, 'z check failed', 10); + +INSERT INTO CHECK2_TBL VALUES (0, 'check failed', -2); + +INSERT INTO CHECK2_TBL VALUES (6, 'check failed', 11); + +INSERT INTO CHECK2_TBL VALUES (7, 'check ok', 7); + +SELECT * from CHECK2_TBL; + +CREATE SEQUENCE INSERT_SEQ; + +INSERT INTO INSERT_TBL(x,z) VALUES (2, -2); + +SELECT * FROM INSERT_TBL; + +SELECT 'one' AS one, nextval('insert_seq'); + +INSERT INTO INSERT_TBL(y) VALUES ('Y'); + +INSERT INTO INSERT_TBL(y) VALUES ('Y'); + +INSERT INTO INSERT_TBL(x,z) VALUES (1, -2); + +INSERT INTO INSERT_TBL(z,x) VALUES (-7, 7); + +INSERT INTO INSERT_TBL VALUES (5, 'check failed', -5); + +INSERT INTO INSERT_TBL VALUES (7, '!check failed', -7); + +INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-'); + +SELECT * FROM INSERT_TBL; + +INSERT INTO INSERT_TBL(y,z) VALUES ('check failed', 4); + +INSERT INTO INSERT_TBL(x,y) VALUES (5, 'check failed'); + +INSERT INTO INSERT_TBL(x,y) VALUES (5, '!check failed'); + +INSERT INTO INSERT_TBL(y) VALUES ('-!NULL-'); + +SELECT * FROM INSERT_TBL; + +SELECT 'seven' AS one, nextval('insert_seq'); + +INSERT INTO INSERT_TBL(y) VALUES ('Y'); + +SELECT 'eight' AS one, currval('insert_seq'); + +INSERT INTO INSERT_TBL VALUES (null, null, null); + +SELECT * FROM INSERT_TBL; + +CREATE TABLE SYS_COL_CHECK_TBL (city text, state text, is_capital bool, + altitude int, + CHECK (NOT (is_capital AND tableoid::regclass::text = 'sys_col_check_tbl'))); + +INSERT INTO SYS_COL_CHECK_TBL VALUES ('Seattle', 'Washington', false, 100); + +INSERT INTO SYS_COL_CHECK_TBL VALUES ('Olympia', 'Washington', true, 100); + +SELECT *, tableoid::regclass::text FROM SYS_COL_CHECK_TBL; + +DROP TABLE SYS_COL_CHECK_TBL; + +CREATE TABLE SYS_COL_CHECK_TBL (city text, state text, is_capital bool, + altitude int, + CHECK (NOT (is_capital AND ctid::text = 'sys_col_check_tbl'))); + +CREATE TABLE INSERT_CHILD (cx INT default 42, + cy INT CHECK (cy > x)) + INHERITS (INSERT_TBL); + +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,11); + +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,6); + +INSERT INTO INSERT_CHILD(x,z,cy) VALUES (6,-7,7); + +INSERT INTO INSERT_CHILD(x,y,z,cy) VALUES (6,'check failed',-6,7); + +SELECT * FROM INSERT_CHILD; + +DROP TABLE INSERT_CHILD; + +CREATE TABLE ATACC1 (TEST INT + CHECK (TEST > 0) NO INHERIT); + +CREATE TABLE ATACC2 (TEST2 INT) INHERITS (ATACC1); + +INSERT INTO ATACC2 (TEST) VALUES (-3); + +INSERT INTO ATACC1 (TEST) VALUES (-3); + +DROP TABLE ATACC1 CASCADE; + +CREATE TABLE ATACC1 (TEST INT, TEST2 INT + CHECK (TEST > 0), CHECK (TEST2 > 10) NO INHERIT); + +CREATE TABLE ATACC2 () INHERITS (ATACC1); + +INSERT INTO ATACC2 (TEST) VALUES (-3); + +INSERT INTO ATACC1 (TEST) VALUES (-3); + +INSERT INTO ATACC2 (TEST2) VALUES (3); + +INSERT INTO ATACC1 (TEST2) VALUES (3); + +DROP TABLE ATACC1 CASCADE; + +DELETE FROM INSERT_TBL; + +ALTER SEQUENCE INSERT_SEQ RESTART diff --git a/crates/pgt_pretty_print/tests/data/multi/conversion_60.sql b/crates/pgt_pretty_print/tests/data/multi/conversion_60.sql new file mode 100644 index 000000000..c0cf1e62e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/conversion_60.sql @@ -0,0 +1,322 @@ +CREATE FUNCTION test_enc_setup() RETURNS void + AS 'regresslib', 'test_enc_setup' + LANGUAGE C STRICT; + +SELECT FROM test_enc_setup(); + +CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea) + AS 'regresslib', 'test_enc_conversion' + LANGUAGE C STRICT; + +CREATE USER regress_conversion_user WITH NOCREATEDB NOCREATEROLE; + +SET SESSION AUTHORIZATION regress_conversion_user; + +CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +CREATE CONVERSION myconv FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +CREATE DEFAULT CONVERSION public.mydef FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +CREATE DEFAULT CONVERSION public.mydef2 FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +COMMENT ON CONVERSION myconv_bad IS 'foo'; + +COMMENT ON CONVERSION myconv IS 'bar'; + +COMMENT ON CONVERSION myconv IS NULL; + +DROP CONVERSION myconv; + +DROP CONVERSION mydef; + +RESET SESSION AUTHORIZATION; + +DROP USER regress_conversion_user; + +create or replace function test_conv( + input IN bytea, + src_encoding IN text, + dst_encoding IN text, + + result OUT bytea, + errorat OUT bytea, + error OUT text) +language plpgsql as +$$ +declare + validlen int; +begin + -- First try to perform the conversion with noError = false. If that errors out, + -- capture the error message, and try again with noError = true. The second call + -- should succeed and return the position of the error, return that too. + begin + select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, false); + errorat = NULL; + error := NULL; + exception when others then + error := sqlerrm; + select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, true); + errorat = substr(input, validlen + 1); + end; + return; +end; +$$; + +CREATE TABLE utf8_verification_inputs (inbytes bytea, description text PRIMARY KEY); + +insert into utf8_verification_inputs values + ('\x66006f', 'NUL byte'), + ('\xaf', 'bare continuation'), + ('\xc5', 'missing second byte in 2-byte char'), + ('\xc080', 'smallest 2-byte overlong'), + ('\xc1bf', 'largest 2-byte overlong'), + ('\xc280', 'next 2-byte after overlongs'), + ('\xdfbf', 'largest 2-byte'), + ('\xe9af', 'missing third byte in 3-byte char'), + ('\xe08080', 'smallest 3-byte overlong'), + ('\xe09fbf', 'largest 3-byte overlong'), + ('\xe0a080', 'next 3-byte after overlong'), + ('\xed9fbf', 'last before surrogates'), + ('\xeda080', 'smallest surrogate'), + ('\xedbfbf', 'largest surrogate'), + ('\xee8080', 'next after surrogates'), + ('\xefbfbf', 'largest 3-byte'), + ('\xf1afbf', 'missing fourth byte in 4-byte char'), + ('\xf0808080', 'smallest 4-byte overlong'), + ('\xf08fbfbf', 'largest 4-byte overlong'), + ('\xf0908080', 'next 4-byte after overlong'), + ('\xf48fbfbf', 'largest 4-byte'), + ('\xf4908080', 'smallest too large'), + ('\xfa9a9a8a8a', '5-byte'); + +select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_verification_inputs; + +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description; + +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description; + +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64)::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description; + +with test_bytes as ( + select + inbytes, + description, + (test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from utf8_verification_inputs +), test_padded as ( + select + description, + (test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error + from test_bytes +) +select + description, + b.error as orig_error, + p.error as error_after_padding +from test_padded p +join test_bytes b +using (description) +where p.error is distinct from b.error +order by description; + +CREATE TABLE utf8_inputs (inbytes bytea, description text); + +insert into utf8_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\xc3a4c3b6', 'valid, extra latin chars'), + ('\xd184d0bed0be', 'valid, cyrillic'), + ('\x666f6fe8b1a1', 'valid, kanji/Chinese'), + ('\xe382abe3829a', 'valid, two chars that combine to one in EUC_JIS_2004'), + ('\xe382ab', 'only first half of combined char in EUC_JIS_2004'), + ('\xe382abe382', 'incomplete combination when converted EUC_JIS_2004'), + ('\xecbd94eb81bceba6ac', 'valid, Hangul, Korean'), + ('\x666f6fefa8aa', 'valid, needs mapping function to convert to GB18030'), + ('\x66e8b1ff6f6f', 'invalid byte sequence'), + ('\x66006f', 'invalid, NUL byte'), + ('\x666f6fe8b100', 'invalid, NUL byte'), + ('\x666f6fe8b1', 'incomplete character at end'); + +select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_inputs; + +select description, inbytes, (test_conv(inbytes, 'utf8', 'euc_jis_2004')).* from utf8_inputs; + +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin1')).* from utf8_inputs; + +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin2')).* from utf8_inputs; + +select description, inbytes, (test_conv(inbytes, 'utf8', 'latin5')).* from utf8_inputs; + +select description, inbytes, (test_conv(inbytes, 'utf8', 'koi8r')).* from utf8_inputs; + +select description, inbytes, (test_conv(inbytes, 'utf8', 'gb18030')).* from utf8_inputs; + +CREATE TABLE euc_jis_2004_inputs (inbytes bytea, description text); + +insert into euc_jis_2004_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fbedd', 'valid'), + ('\xa5f7', 'valid, translates to two UTF-8 chars '), + ('\xbeddbe', 'incomplete char '), + ('\x666f6f00bedd', 'invalid, NUL byte'), + ('\x666f6fbe00dd', 'invalid, NUL byte'), + ('\x666f6fbedd00', 'invalid, NUL byte'), + ('\xbe04', 'invalid byte sequence'); + +select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'euc_jis_2004')).* from euc_jis_2004_inputs; + +select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'utf8')).* from euc_jis_2004_inputs; + +CREATE TABLE shiftjis2004_inputs (inbytes bytea, description text); + +insert into shiftjis2004_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6f8fdb', 'valid'), + ('\x666f6f81c0', 'valid, no translation to UTF-8'), + ('\x666f6f82f5', 'valid, translates to two UTF-8 chars '), + ('\x666f6f8fdb8f', 'incomplete char '), + ('\x666f6f820a', 'incomplete char, followed by newline '), + ('\x666f6f008fdb', 'invalid, NUL byte'), + ('\x666f6f8f00db', 'invalid, NUL byte'), + ('\x666f6f8fdb00', 'invalid, NUL byte'); + +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'shiftjis2004')).* from shiftjis2004_inputs; + +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'utf8')).* from shiftjis2004_inputs; + +select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'euc_jis_2004')).* from shiftjis2004_inputs; + +CREATE TABLE gb18030_inputs (inbytes bytea, description text); + +insert into gb18030_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fcff3', 'valid'), + ('\x666f6f8431a530', 'valid, no translation to UTF-8'), + ('\x666f6f84309c38', 'valid, translates to UTF-8 by mapping function'), + ('\x666f6f84309c', 'incomplete char '), + ('\x666f6f84309c0a', 'incomplete char, followed by newline '), + ('\x666f6f84', 'incomplete char at end'), + ('\x666f6f84309c3800', 'invalid, NUL byte'), + ('\x666f6f84309c0038', 'invalid, NUL byte'); + +select description, inbytes, (test_conv(inbytes::text::bytea, 'gb18030', 'gb18030')).* from gb18030_inputs; + +select description, inbytes, (test_conv(inbytes, 'gb18030', 'utf8')).* from gb18030_inputs; + +CREATE TABLE iso8859_5_inputs (inbytes bytea, description text); + +insert into iso8859_5_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\xe4dede', 'valid'), + ('\x00', 'invalid, NUL byte'), + ('\xe400dede', 'invalid, NUL byte'), + ('\xe4dede00', 'invalid, NUL byte'); + +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'iso8859-5')).* from iso8859_5_inputs; + +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'utf8')).* from iso8859_5_inputs; + +select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'koi8r')).* from iso8859_5_inputs; + +select description, inbytes, (test_conv(inbytes, 'iso8859_5', 'mule_internal')).* from iso8859_5_inputs; + +CREATE TABLE big5_inputs (inbytes bytea, description text); + +insert into big5_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x666f6fb648', 'valid'), + ('\x666f6fa27f', 'valid, no translation to UTF-8'), + ('\x666f6fb60048', 'invalid, NUL byte'), + ('\x666f6fb64800', 'invalid, NUL byte'); + +select description, inbytes, (test_conv(inbytes, 'big5', 'big5')).* from big5_inputs; + +select description, inbytes, (test_conv(inbytes, 'big5', 'utf8')).* from big5_inputs; + +select description, inbytes, (test_conv(inbytes, 'big5', 'mule_internal')).* from big5_inputs; + +CREATE TABLE mic_inputs (inbytes bytea, description text); + +insert into mic_inputs values + ('\x666f6f', 'valid, pure ASCII'), + ('\x8bc68bcf8bcf', 'valid (in KOI8R)'), + ('\x8bc68bcf8b', 'invalid,incomplete char'), + ('\x92bedd', 'valid (in SHIFT_JIS)'), + ('\x92be', 'invalid, incomplete char)'), + ('\x666f6f95a3c1', 'valid (in Big5)'), + ('\x666f6f95a3', 'invalid, incomplete char'), + ('\x9200bedd', 'invalid, NUL byte'), + ('\x92bedd00', 'invalid, NUL byte'), + ('\x8b00c68bcf8bcf', 'invalid, NUL byte'); + +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'mule_internal')).* from mic_inputs; + +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'koi8r')).* from mic_inputs; + +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'iso8859-5')).* from mic_inputs; + +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'sjis')).* from mic_inputs; + +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'big5')).* from mic_inputs; + +select description, inbytes, (test_conv(inbytes, 'mule_internal', 'euc_jp')).* from mic_inputs; diff --git a/crates/pgt_pretty_print/tests/data/multi/copy2_60.sql b/crates/pgt_pretty_print/tests/data/multi/copy2_60.sql new file mode 100644 index 000000000..9fe312b42 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/copy2_60.sql @@ -0,0 +1,35 @@ +CREATE TEMP TABLE x ( + a serial, + b int, + c text not null default 'stuff', + d text, + e text +) ; + +CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS ' + BEGIN + NEW.e := ''before trigger fired''::text; + return NEW; + END; +' LANGUAGE plpgsql; + +CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS ' + BEGIN + UPDATE x set e=''after trigger fired'' where c=''stuff''; + return NULL; + END; +' LANGUAGE plpgsql; + +CREATE TRIGGER trg_x_after AFTER INSERT ON x +FOR EACH ROW EXECUTE PROCEDURE fn_x_after(); + +CREATE TRIGGER trg_x_before BEFORE INSERT ON x +FOR EACH ROW EXECUTE PROCEDURE fn_x_before(); + +SELECT * FROM x; + +COPY x TO stdout; + +COPY x (c, e) TO stdout; + +COPY x (b, e) TO stdout diff --git a/crates/pgt_pretty_print/tests/data/multi/copy_60.sql b/crates/pgt_pretty_print/tests/data/multi/copy_60.sql new file mode 100644 index 000000000..aa9c73143 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/copy_60.sql @@ -0,0 +1,273 @@ +create temp table copytest ( + style text, + test text, + filler int); + +insert into copytest values('DOS',E'abc\r\ndef',1); + +insert into copytest values('Unix',E'abc\ndef',2); + +insert into copytest values('Mac',E'abc\rdef',3); + +insert into copytest values(E'esc\\ape',E'a\\r\\\r\\\n\\nb',4); + +copy copytest to 'filename' csv; + +create temp table copytest2 (like copytest); + +copy copytest2 from 'filename' csv; + +select * from copytest except select * from copytest2; + +truncate copytest2; + +copy copytest to 'filename' csv quote '''' escape E'\\'; + +copy copytest2 from 'filename' csv quote '''' escape E'\\'; + +select * from copytest except select * from copytest2; + +truncate copytest2; + +copy copytest2(test) from 'filename' csv; + +select test from copytest2 order by test collate "C"; + +truncate copytest2; + +copy copytest2(test) from stdin; + +select test from copytest2; + +create temp table copytest3 ( + c1 int, + "col with , comma" text, + "col with "" quote" int); + +copy copytest3 from stdin csv header; + +copy copytest3 to stdout csv header; + +create temp table copytest4 ( + c1 int, + "colname with tab: " text); + +copy copytest4 from stdin (header); + +copy copytest4 to stdout (header); + +create temp table copytest5 (c1 int); + +copy copytest5 from stdin (format csv, header 2); + +truncate copytest5; + +copy copytest5 from stdin (format csv, header 4); + +select count(*) from copytest5; + +truncate copytest5; + +copy copytest5 from stdin (format csv, header 5); + +select count(*) from copytest5; + +create table parted_copytest ( + a int, + b int, + c text +) partition by list (b); + +create table parted_copytest_a1 (c text, b int, a int); + +create table parted_copytest_a2 (a int, c text, b int); + +alter table parted_copytest attach partition parted_copytest_a1 for values in(1); + +alter table parted_copytest attach partition parted_copytest_a2 for values in(2); + +insert into parted_copytest select x,1,'One' from generate_series(1,1000) x; + +insert into parted_copytest select x,2,'Two' from generate_series(1001,1010) x; + +insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x; + +copy (select * from parted_copytest order by a) to 'filename'; + +truncate parted_copytest; + +copy parted_copytest from 'filename'; + +begin; + +truncate parted_copytest; + +copy parted_copytest from 'filename' (freeze); + +rollback; + +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name; + +truncate parted_copytest; + +create function part_ins_func() returns trigger language plpgsql as $$ +begin + return new; +end; +$$; + +create trigger part_ins_trig + before insert on parted_copytest_a2 + for each row + execute procedure part_ins_func(); + +copy parted_copytest from 'filename'; + +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name; + +truncate table parted_copytest; + +create index on parted_copytest (b); + +drop trigger part_ins_trig on parted_copytest_a2; + +copy parted_copytest from stdin; + +select * from parted_copytest where b = 1; + +select * from parted_copytest where b = 2; + +drop table parted_copytest; + +create table tab_progress_reporting ( + name text, + age int4, + location point, + salary int4, + manager name +); + +create function notice_after_tab_progress_reporting() returns trigger AS +$$ +declare report record; +begin + -- The fields ignored here are the ones that may not remain + -- consistent across multiple runs. The sizes reported may differ + -- across platforms, so just check if these are strictly positive. + with progress_data as ( + select + relid::regclass::text as relname, + command, + type, + bytes_processed > 0 as has_bytes_processed, + bytes_total > 0 as has_bytes_total, + tuples_processed, + tuples_excluded, + tuples_skipped + from pg_stat_progress_copy + where pid = pg_backend_pid()) + select into report (to_jsonb(r)) as value + from progress_data r; + + raise info 'progress: %', report.value::text; + return new; +end; +$$ language plpgsql; + +create trigger check_after_tab_progress_reporting + after insert on tab_progress_reporting + for each statement + execute function notice_after_tab_progress_reporting(); + +copy tab_progress_reporting from stdin; + +truncate tab_progress_reporting; + +copy tab_progress_reporting from 'filename' + where (salary < 2000); + +copy tab_progress_reporting from stdin(on_error ignore); + +drop trigger check_after_tab_progress_reporting on tab_progress_reporting; + +drop function notice_after_tab_progress_reporting(); + +drop table tab_progress_reporting; + +create table header_copytest ( + a int, + b int, + c text +); + +alter table header_copytest drop column c; + +alter table header_copytest add column c text; + +copy header_copytest to stdout + +copy header_copytest from stdin + +copy header_copytest from stdin + +SELECT * FROM header_copytest ORDER BY a; + +alter table header_copytest drop column b; + +copy header_copytest (c, a) from stdin + +SELECT * FROM header_copytest ORDER BY a; + +drop table header_copytest; + +create temp table oversized_column_default ( + col1 varchar(5) DEFAULT 'more than 5 chars', + col2 varchar(5)); + +copy oversized_column_default from stdin; + +copy oversized_column_default (col2) from stdin; + +copy oversized_column_default from stdin (default ''); + +drop table oversized_column_default; + +CREATE TABLE parted_si ( + id int not null, + data text not null, + -- prevent use of bulk insert by having a volatile function + rand float8 not null default random() +) +PARTITION BY LIST((id % 2)); + +CREATE TABLE parted_si_p_even PARTITION OF parted_si FOR VALUES IN (0); + +CREATE TABLE parted_si_p_odd PARTITION OF parted_si FOR VALUES IN (1); + +COPY parted_si(id, data) FROM 'filename'; + +SELECT tableoid::regclass, id % 2 = 0 is_even, count(*) from parted_si GROUP BY 1, 2 ORDER BY 1; + +DROP TABLE parted_si; + +begin; + +create foreign data wrapper copytest_wrapper; + +create server copytest_server foreign data wrapper copytest_wrapper; + +create foreign table copytest_foreign_table (a int) server copytest_server; + +copy copytest_foreign_table from stdin (freeze); + +CREATE MATERIALIZED VIEW copytest_mv AS SELECT 1 AS id WITH NO DATA; + +COPY copytest_mv(id) TO stdout + +REFRESH MATERIALIZED VIEW copytest_mv; + +COPY copytest_mv(id) TO stdout + +DROP MATERIALIZED VIEW copytest_mv; diff --git a/crates/pgt_pretty_print/tests/data/multi/copydml_60.sql b/crates/pgt_pretty_print/tests/data/multi/copydml_60.sql new file mode 100644 index 000000000..0baca80fa --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/copydml_60.sql @@ -0,0 +1,129 @@ +create table copydml_test (id serial, t text); + +insert into copydml_test (t) values ('a'); + +insert into copydml_test (t) values ('b'); + +insert into copydml_test (t) values ('c'); + +insert into copydml_test (t) values ('d'); + +insert into copydml_test (t) values ('e'); + +copy (insert into copydml_test (t) values ('f') returning id) to stdout; + +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; + +copy (delete from copydml_test where t = 'g' returning id) to stdout; + +copy (insert into copydml_test default values) to stdout; + +copy (update copydml_test set t = 'g') to stdout; + +copy (delete from copydml_test) to stdout; + +create rule qqq as on insert to copydml_test do instead nothing; + +copy (insert into copydml_test default values) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on insert to copydml_test do also delete from copydml_test; + +copy (insert into copydml_test default values) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on insert to copydml_test do instead (delete from copydml_test; delete from copydml_test); + +copy (insert into copydml_test default values) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on insert to copydml_test where new.t <> 'f' do instead delete from copydml_test; + +copy (insert into copydml_test default values) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on update to copydml_test do instead nothing; + +copy (update copydml_test set t = 'f') to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on update to copydml_test do also delete from copydml_test; + +copy (update copydml_test set t = 'f') to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on update to copydml_test do instead (delete from copydml_test; delete from copydml_test); + +copy (update copydml_test set t = 'f') to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on update to copydml_test where new.t <> 'f' do instead delete from copydml_test; + +copy (update copydml_test set t = 'f') to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on delete to copydml_test do instead nothing; + +copy (delete from copydml_test) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on delete to copydml_test do also insert into copydml_test default values; + +copy (delete from copydml_test) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on delete to copydml_test do instead (insert into copydml_test default values; insert into copydml_test default values); + +copy (delete from copydml_test) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on delete to copydml_test where old.t <> 'f' do instead insert into copydml_test default values; + +copy (delete from copydml_test) to stdout; + +drop rule qqq on copydml_test; + +create rule qqq as on insert to copydml_test do instead notify copydml_test; + +copy (insert into copydml_test default values) to stdout; + +drop rule qqq on copydml_test; + +create function qqq_trig() returns trigger as $$ +begin +if tg_op in ('INSERT', 'UPDATE') then + raise notice '% % %', tg_when, tg_op, new.id; + return new; +else + raise notice '% % %', tg_when, tg_op, old.id; + return old; +end if; +end +$$ language plpgsql; + +create trigger qqqbef before insert or update or delete on copydml_test + for each row execute procedure qqq_trig(); + +create trigger qqqaf after insert or update or delete on copydml_test + for each row execute procedure qqq_trig(); + +copy (insert into copydml_test (t) values ('f') returning id) to stdout; + +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; + +copy (delete from copydml_test where t = 'g' returning id) to stdout; + +drop table copydml_test; + +drop function qqq_trig(); diff --git a/crates/pgt_pretty_print/tests/data/multi/copyencoding_60.sql b/crates/pgt_pretty_print/tests/data/multi/copyencoding_60.sql new file mode 100644 index 000000000..8af790d01 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/copyencoding_60.sql @@ -0,0 +1,34 @@ +SELECT getdatabaseencoding() <> 'UTF8' + AS skip_test ; + +CREATE TABLE copy_encoding_tab (t text); + +COPY (SELECT E'\u3042') TO 'utf8_csv' + +COPY copy_encoding_tab FROM 'utf8_csv' + +SET client_encoding TO UTF8; + +COPY (SELECT E'\u3042') TO 'utf8_csv' + +SET client_encoding TO LATIN1; + +COPY copy_encoding_tab FROM 'utf8_csv' + +RESET client_encoding; + +COPY (SELECT E'\u3042') TO 'utf8_csv' + +COPY copy_encoding_tab FROM 'utf8_csv' + +SET client_encoding TO UTF8; + +COPY (SELECT E'\u3042') TO 'utf8_csv' + +SET client_encoding TO EUC_JP; + +COPY copy_encoding_tab FROM 'utf8_csv' + +RESET client_encoding; + +DROP TABLE copy_encoding_tab; diff --git a/crates/pgt_pretty_print/tests/data/multi/copyselect_60.sql b/crates/pgt_pretty_print/tests/data/multi/copyselect_60.sql new file mode 100644 index 000000000..e73b3d674 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/copyselect_60.sql @@ -0,0 +1,64 @@ +create table test1 (id serial, t text); + +insert into test1 (t) values ('a'); + +insert into test1 (t) values ('b'); + +insert into test1 (t) values ('c'); + +insert into test1 (t) values ('d'); + +insert into test1 (t) values ('e'); + +create table test2 (id serial, t text); + +insert into test2 (t) values ('A'); + +insert into test2 (t) values ('B'); + +insert into test2 (t) values ('C'); + +insert into test2 (t) values ('D'); + +insert into test2 (t) values ('E'); + +create view v_test1 +as select 'v_'||t from test1; + +copy test1 to stdout; + +copy v_test1 to stdout; + +copy (select t from test1 where id=1) to stdout; + +copy (select t from test1 where id=3 for update) to stdout; + +copy (select t into temp test3 from test1 where id=3) to stdout; + +copy (select * from test1 join test2 using (id)) to stdout; + +copy (select t from test1 where id = 1 UNION select * from v_test1 ORDER BY 1) to stdout; + +copy (select * from (select t from test1 where id = 1 UNION select * from v_test1 ORDER BY 1) t1) to stdout; + +copy (select t from test1 where id = 1) to stdout csv header force quote t; + +drop table test2; + +drop view v_test1; + +drop table test1; + +select 1/0; + +copy (select 1) to stdout; + +select 4; + +create table test3 (c int); + +select 1; + +select * from test3; + +drop table test3; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_aggregate_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_aggregate_60.sql new file mode 100644 index 000000000..dc759a3a8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_aggregate_60.sql @@ -0,0 +1,296 @@ +CREATE AGGREGATE newavg ( + sfunc = int4_avg_accum, basetype = int4, stype = _int8, + finalfunc = int8_avg, + initcond1 = '{0,0}' +); + +COMMENT ON AGGREGATE newavg_wrong (int4) IS 'an agg comment'; + +COMMENT ON AGGREGATE newavg (int4) IS 'an agg comment'; + +COMMENT ON AGGREGATE newavg (int4) IS NULL; + +CREATE AGGREGATE newsum ( + sfunc1 = int4pl, basetype = int4, stype1 = int4, + initcond1 = '0' +); + +CREATE AGGREGATE newcnt (*) ( + sfunc = int8inc, stype = int8, + initcond = '0', parallel = safe +); + +CREATE AGGREGATE oldcnt ( + sfunc = int8inc, basetype = 'ANY', stype = int8, + initcond = '0' +); + +CREATE AGGREGATE newcnt ("any") ( + sfunc = int8inc_any, stype = int8, + initcond = '0' +); + +COMMENT ON AGGREGATE nosuchagg (*) IS 'should fail'; + +COMMENT ON AGGREGATE newcnt (*) IS 'an agg(*) comment'; + +COMMENT ON AGGREGATE newcnt ("any") IS 'an agg(any) comment'; + +create function sum3(int8,int8,int8) returns int8 as +'select $1 + $2 + $3' language sql strict immutable; + +create aggregate sum2(int8,int8) ( + sfunc = sum3, stype = int8, + initcond = '0' +); + +create type aggtype as (a integer, b integer, c text); + +create function aggf_trans(aggtype[],integer,integer,text) returns aggtype[] +as 'select array_append($1,ROW($2,$3,$4)::aggtype)' +language sql strict immutable; + +create function aggfns_trans(aggtype[],integer,integer,text) returns aggtype[] +as 'select array_append($1,ROW($2,$3,$4)::aggtype)' +language sql immutable; + +create aggregate aggfstr(integer,integer,text) ( + sfunc = aggf_trans, stype = aggtype[], + initcond = '{}' +); + +create aggregate aggfns(integer,integer,text) ( + sfunc = aggfns_trans, stype = aggtype[], sspace = 10000, + initcond = '{}' +); + +create function least_accum(int8, int8) returns int8 language sql as + 'select least($1, $2)'; + +create aggregate least_agg(int4) ( + stype = int8, sfunc = least_accum +); + +drop function least_accum(int8, int8); + +create function least_accum(anycompatible, anycompatible) +returns anycompatible language sql as + 'select least($1, $2)'; + +create aggregate least_agg(int4) ( + stype = int8, sfunc = least_accum +); + +create aggregate least_agg(int8) ( + stype = int8, sfunc = least_accum +); + +drop function least_accum(anycompatible, anycompatible) cascade; + +create function least_accum(anyelement, variadic anyarray) +returns anyelement language sql as + 'select least($1, min($2[i])) from generate_subscripts($2,1) g(i)'; + +create aggregate least_agg(variadic items anyarray) ( + stype = anyelement, sfunc = least_accum +); + +create function cleast_accum(anycompatible, variadic anycompatiblearray) +returns anycompatible language sql as + 'select least($1, min($2[i])) from generate_subscripts($2,1) g(i)'; + +create aggregate cleast_agg(variadic items anycompatiblearray) ( + stype = anycompatible, sfunc = cleast_accum +); + +create aggregate my_percentile_disc(float8 ORDER BY anyelement) ( + stype = internal, + sfunc = ordered_set_transition, + finalfunc = percentile_disc_final, + finalfunc_extra = true, + finalfunc_modify = read_write +); + +create aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") ( + stype = internal, + sfunc = ordered_set_transition_multi, + finalfunc = rank_final, + finalfunc_extra = true, + hypothetical +); + +alter aggregate my_percentile_disc(float8 ORDER BY anyelement) + rename to test_percentile_disc; + +alter aggregate my_rank(VARIADIC "any" ORDER BY VARIADIC "any") + rename to test_rank; + +CREATE AGGREGATE sumdouble (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi +); + +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize +); + +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_deserialize, + deserialfunc = numeric_avg_deserialize +); + +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_serialize +); + +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = int4larger +); + +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +); + +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC; + +DROP AGGREGATE myavg (numeric); + +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg +); + +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +); + +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC; + +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add +); + +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC; + +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add, + finalfunc = numeric_out +); + +CREATE OR REPLACE AGGREGATE myavg (order by numeric) +( + stype = numeric, + sfunc = numeric_add +); + +create function sum4(int8,int8,int8,int8) returns int8 as +'select $1 + $2 + $3 + $4' language sql strict immutable; + +CREATE OR REPLACE AGGREGATE sum3 (int8,int8,int8) +( + stype = int8, + sfunc = sum4 +); + +drop function sum4(int8,int8,int8,int8); + +DROP AGGREGATE myavg (numeric); + +CREATE AGGREGATE mysum (int) +( + stype = int, + sfunc = int4pl, + parallel = pear +); + +CREATE FUNCTION float8mi_n(float8, float8) RETURNS float8 AS +$$ SELECT $1 - $2; $$ +LANGUAGE SQL; + +CREATE AGGREGATE invalidsumdouble (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi_n +); + +CREATE FUNCTION float8mi_int(float8, float8) RETURNS int AS +$$ SELECT CAST($1 - $2 AS INT); $$ +LANGUAGE SQL; + +CREATE AGGREGATE wrongreturntype (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi_int +); + +CREATE AGGREGATE case_agg ( -- old syntax + "Sfunc1" = int4pl, + "Basetype" = int4, + "Stype1" = int4, + "Initcond1" = '0', + "Parallel" = safe +); + +CREATE AGGREGATE case_agg(float8) +( + "Stype" = internal, + "Sfunc" = ordered_set_transition, + "Finalfunc" = percentile_disc_final, + "Finalfunc_extra" = true, + "Finalfunc_modify" = read_write, + "Parallel" = safe +); diff --git a/crates/pgt_pretty_print/tests/data/multi/create_am_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_am_60.sql new file mode 100644 index 000000000..b57dc544e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_am_60.sql @@ -0,0 +1,383 @@ +CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler; + +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER int4in; + +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER heap_tableam_handler; + +CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base); + +CREATE OPERATOR CLASS box_ops DEFAULT + FOR TYPE box USING gist2 AS + OPERATOR 1 <<, + OPERATOR 2 &<, + OPERATOR 3 &&, + OPERATOR 4 &>, + OPERATOR 5 >>, + OPERATOR 6 ~=, + OPERATOR 7 @>, + OPERATOR 8 <@, + OPERATOR 9 &<|, + OPERATOR 10 <<|, + OPERATOR 11 |>>, + OPERATOR 12 |&>, + FUNCTION 1 gist_box_consistent(internal, box, smallint, oid, internal), + FUNCTION 2 gist_box_union(internal, internal), + -- don't need compress, decompress, or fetch functions + FUNCTION 5 gist_box_penalty(internal, internal, internal), + FUNCTION 6 gist_box_picksplit(internal, internal), + FUNCTION 7 gist_box_same(box, box, internal); + +CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base); + +BEGIN; + +DROP INDEX grect2ind; + +SET enable_seqscan = OFF; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = OFF; + +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0]; + +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0]; + +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box; + +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box; + +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; + +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; + +ROLLBACK; + +DROP ACCESS METHOD gist2; + +BEGIN; + +LOCK TABLE fast_emp4000; + +DROP ACCESS METHOD gist2 CASCADE; + +COMMIT; + +SET default_table_access_method = ''; + +SET default_table_access_method = 'I do not exist AM'; + +SET default_table_access_method = 'btree'; + +CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler; + +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER int4in; + +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER bthandler; + +SELECT amname, amhandler, amtype FROM pg_am where amtype = 't' ORDER BY 1, 2; + +CREATE TABLE tableam_tbl_heap2(f1 int) USING heap2; + +INSERT INTO tableam_tbl_heap2 VALUES(1); + +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1; + +CREATE TABLE tableam_tblas_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; + +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1; + +CREATE MATERIALIZED VIEW tableam_tblmv_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; + +SELECT f1 FROM tableam_tblmv_heap2 ORDER BY f1; + +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a) USING heap2; + +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'tableam_parted_heap2' AND a.oid = c.relam; + +DROP TABLE tableam_parted_heap2; + +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a); + +SET default_table_access_method = 'heap'; + +CREATE TABLE tableam_parted_a_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('a'); + +SET default_table_access_method = 'heap2'; + +CREATE TABLE tableam_parted_b_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('b'); + +RESET default_table_access_method; + +CREATE TABLE tableam_parted_c_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('c') USING heap; + +CREATE TABLE tableam_parted_d_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('d') USING heap2; + +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc, + pg_am AS pa +WHERE pa.oid = pc.relam + AND pa.amname = 'heap2' +ORDER BY 3, 1, 2; + +SELECT pg_describe_object(classid,objid,objsubid) AS obj +FROM pg_depend, pg_am +WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_am.amname = 'heap2' +ORDER BY classid, objid, objsubid; + +CREATE TABLE heaptable USING heap AS + SELECT a, repeat(a::text, 100) FROM generate_series(1,9) AS a; + +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass; + +ALTER TABLE heaptable SET ACCESS METHOD heap2; + +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_class'::regclass AND + objid = 'heaptable'::regclass + ORDER BY 1, 2; + +ALTER TABLE heaptable SET ACCESS METHOD heap; + +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_class'::regclass AND + objid = 'heaptable'::regclass + ORDER BY 1, 2; + +ALTER TABLE heaptable SET ACCESS METHOD heap2; + +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass; + +SELECT COUNT(a), COUNT(1) FILTER(WHERE a=1) FROM heaptable; + +BEGIN; + +SET LOCAL default_table_access_method TO heap2; + +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT; + +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass; + +SET LOCAL default_table_access_method TO heap; + +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT; + +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heaptable'::regclass; + +ROLLBACK; + +CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT * FROM heaptable; + +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass; + +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2; + +SELECT amname FROM pg_class c, pg_am am + WHERE c.relam = am.oid AND c.oid = 'heapmv'::regclass; + +SELECT COUNT(a), COUNT(1) FILTER(WHERE a=1) FROM heapmv; + +ALTER TABLE heaptable SET ACCESS METHOD heap, SET ACCESS METHOD heap2; + +ALTER TABLE heaptable SET ACCESS METHOD DEFAULT, SET ACCESS METHOD heap2; + +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap, SET ACCESS METHOD heap2; + +DROP MATERIALIZED VIEW heapmv; + +DROP TABLE heaptable; + +CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x) USING heap2; + +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass; + +DROP TABLE am_partitioned; + +BEGIN; + +SET LOCAL default_table_access_method = 'heap'; + +CREATE TABLE am_partitioned(x INT, y INT) PARTITION BY hash (x); + +SELECT relam FROM pg_class WHERE relname = 'am_partitioned'; + +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass; + +ALTER TABLE am_partitioned SET ACCESS METHOD heap2; + +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam; + +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass; + +SET LOCAL default_table_access_method = 'heap2'; + +ALTER TABLE am_partitioned SET ACCESS METHOD heap; + +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam; + +SELECT pg_describe_object(classid, objid, objsubid) AS obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as refobj + FROM pg_depend, pg_am + WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_depend.objid = 'am_partitioned'::regclass; + +SET LOCAL default_table_access_method = 'heap2'; + +ALTER TABLE am_partitioned SET ACCESS METHOD heap2; + +SELECT a.amname FROM pg_class c, pg_am a + WHERE c.relname = 'am_partitioned' AND a.oid = c.relam; + +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT; + +SELECT relam FROM pg_class WHERE relname = 'am_partitioned'; + +SELECT relam FROM pg_class WHERE relname = 'am_partitioned'; + +SET LOCAL default_table_access_method = 'heap'; + +CREATE TABLE am_partitioned_0 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 0); + +SET LOCAL default_table_access_method = 'heap2'; + +CREATE TABLE am_partitioned_1 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 1); + +SET LOCAL default_table_access_method = 'heap'; + +ALTER TABLE am_partitioned SET ACCESS METHOD heap2; + +CREATE TABLE am_partitioned_2 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 2); + +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT; + +SELECT relam FROM pg_class WHERE relname = 'am_partitioned'; + +CREATE TABLE am_partitioned_3 PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 3); + +ALTER TABLE am_partitioned SET ACCESS METHOD DEFAULT; + +CREATE TABLE am_partitioned_5p PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 5) PARTITION BY hash(y); + +CREATE TABLE am_partitioned_5p1 PARTITION OF am_partitioned_5p + FOR VALUES WITH (MODULUS 10, REMAINDER 1); + +ALTER TABLE am_partitioned SET ACCESS METHOD heap2; + +CREATE TABLE am_partitioned_6p PARTITION OF am_partitioned + FOR VALUES WITH (MODULUS 10, REMAINDER 6) PARTITION BY hash(y); + +CREATE TABLE am_partitioned_6p1 PARTITION OF am_partitioned_6p + FOR VALUES WITH (MODULUS 10, REMAINDER 1); + +SELECT c.relname, a.amname FROM pg_class c, pg_am a + WHERE c.relam = a.oid AND + c.relname LIKE 'am_partitioned%' +UNION ALL +SELECT c.relname, 'default' FROM pg_class c + WHERE c.relam = 0 + AND c.relname LIKE 'am_partitioned%' ORDER BY 1; + +DROP TABLE am_partitioned; + +COMMIT; + +BEGIN; + +SET LOCAL default_table_access_method = 'heap2'; + +CREATE TABLE tableam_tbl_heapx(f1 int); + +CREATE TABLE tableam_tblas_heapx AS SELECT * FROM tableam_tbl_heapx; + +SELECT INTO tableam_tblselectinto_heapx FROM tableam_tbl_heapx; + +CREATE MATERIALIZED VIEW tableam_tblmv_heapx USING heap2 AS SELECT * FROM tableam_tbl_heapx; + +CREATE TABLE tableam_parted_heapx (a text, b int) PARTITION BY list (a); + +CREATE TABLE tableam_parted_1_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('a', 'b'); + +CREATE TABLE tableam_parted_2_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('c', 'd') USING heap; + +CREATE VIEW tableam_view_heapx AS SELECT * FROM tableam_tbl_heapx; + +CREATE SEQUENCE tableam_seq_heapx; + +CREATE FOREIGN DATA WRAPPER fdw_heap2 VALIDATOR postgresql_fdw_validator; + +CREATE SERVER fs_heap2 FOREIGN DATA WRAPPER fdw_heap2 ; + +CREATE FOREIGN table tableam_fdw_heapx () SERVER fs_heap2; + +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc + LEFT JOIN pg_am AS pa ON (pa.oid = pc.relam) +WHERE pc.relname LIKE 'tableam_%_heapx' +ORDER BY 3, 1, 2; + +ROLLBACK; + +CREATE TABLE i_am_a_failure() USING i_do_not_exist_am; + +CREATE TABLE i_am_a_failure() USING "I do not exist AM"; + +CREATE TABLE i_am_a_failure() USING "btree"; + +CREATE FOREIGN TABLE fp PARTITION OF tableam_parted_a_heap2 DEFAULT SERVER x; + +DROP ACCESS METHOD heap2; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_cast_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_cast_60.sql new file mode 100644 index 000000000..862347601 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_cast_60.sql @@ -0,0 +1,69 @@ +CREATE TYPE casttesttype; + +CREATE FUNCTION casttesttype_in(cstring) + RETURNS casttesttype + AS 'textin' + LANGUAGE internal STRICT IMMUTABLE; + +CREATE FUNCTION casttesttype_out(casttesttype) + RETURNS cstring + AS 'textout' + LANGUAGE internal STRICT IMMUTABLE; + +CREATE TYPE casttesttype ( + internallength = variable, + input = casttesttype_in, + output = casttesttype_out, + alignment = int4 +); + +CREATE FUNCTION casttestfunc(casttesttype) RETURNS int4 LANGUAGE SQL AS +$$ SELECT 1; $$; + +SELECT casttestfunc('foo'::text); + +CREATE CAST (text AS casttesttype) WITHOUT FUNCTION; + +SELECT casttestfunc('foo'::text); + +SELECT casttestfunc('foo'::text::casttesttype); + +DROP CAST (text AS casttesttype); + +CREATE CAST (text AS casttesttype) WITHOUT FUNCTION AS IMPLICIT; + +SELECT casttestfunc('foo'::text); + +SELECT 1234::int4::casttesttype; + +CREATE CAST (int4 AS casttesttype) WITH INOUT; + +SELECT 1234::int4::casttesttype; + +DROP CAST (int4 AS casttesttype); + +CREATE FUNCTION int4_casttesttype(int4) RETURNS casttesttype LANGUAGE SQL AS +$$ SELECT ('foo'::text || $1::text)::casttesttype; $$; + +CREATE CAST (int4 AS casttesttype) WITH FUNCTION int4_casttesttype(int4) AS IMPLICIT; + +SELECT 1234::int4::casttesttype; + +DROP FUNCTION int4_casttesttype(int4) CASCADE; + +CREATE FUNCTION bar_int4_text(int4) RETURNS text LANGUAGE SQL AS +$$ SELECT ('bar'::text || $1::text); $$; + +CREATE CAST (int4 AS casttesttype) WITH FUNCTION bar_int4_text(int4) AS IMPLICIT; + +SELECT 1234::int4::casttesttype; + +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype +FROM pg_depend +WHERE classid = 'pg_cast'::regclass AND + objid = (SELECT oid FROM pg_cast + WHERE castsource = 'int4'::regtype + AND casttarget = 'casttesttype'::regtype) +ORDER BY refclassid; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_function_c_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_function_c_60.sql new file mode 100644 index 000000000..13afd0373 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_function_c_60.sql @@ -0,0 +1,12 @@ +LOAD 'regresslib'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS 'nosuchfile'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS 'regresslib', 'nosuchsymbol'; + +SELECT regexp_replace('LAST_ERROR_MESSAGE', 'file ".*"', 'file "..."'); + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal + AS 'nosuch'; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_function_sql_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_function_sql_60.sql new file mode 100644 index 000000000..2a8c57179 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_function_sql_60.sql @@ -0,0 +1,472 @@ +CREATE USER regress_unpriv_user; + +CREATE SCHEMA temp_func_test; + +GRANT ALL ON SCHEMA temp_func_test TO public; + +SET search_path TO temp_func_test, public; + +CREATE FUNCTION functest_A_1(text, date) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 = ''abcd'' AND $2 > ''2001-01-01'''; + +CREATE FUNCTION functest_A_2(text[]) RETURNS int LANGUAGE 'sql' + AS 'SELECT $1[1]::int'; + +CREATE FUNCTION functest_A_3() RETURNS bool LANGUAGE 'sql' + AS 'SELECT false'; + +SELECT proname, prorettype::regtype, proargtypes::regtype[] FROM pg_proc + WHERE oid in ('functest_A_1'::regproc, + 'functest_A_2'::regproc, + 'functest_A_3'::regproc) ORDER BY proname; + +SELECT functest_A_1('abcd', '2020-01-01'); + +SELECT functest_A_2(ARRAY['1', '2', '3']); + +SELECT functest_A_3(); + +CREATE FUNCTION functest_B_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 0'; + +CREATE FUNCTION functest_B_2(int) RETURNS bool LANGUAGE 'sql' + IMMUTABLE AS 'SELECT $1 > 0'; + +CREATE FUNCTION functest_B_3(int) RETURNS bool LANGUAGE 'sql' + STABLE AS 'SELECT $1 = 0'; + +CREATE FUNCTION functest_B_4(int) RETURNS bool LANGUAGE 'sql' + VOLATILE AS 'SELECT $1 < 0'; + +SELECT proname, provolatile FROM pg_proc + WHERE oid in ('functest_B_1'::regproc, + 'functest_B_2'::regproc, + 'functest_B_3'::regproc, + 'functest_B_4'::regproc) ORDER BY proname; + +ALTER FUNCTION functest_B_2(int) VOLATILE; + +ALTER FUNCTION functest_B_3(int) COST 100; + +SELECT proname, provolatile FROM pg_proc + WHERE oid in ('functest_B_1'::regproc, + 'functest_B_2'::regproc, + 'functest_B_3'::regproc, + 'functest_B_4'::regproc) ORDER BY proname; + +CREATE FUNCTION functest_C_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 0'; + +CREATE FUNCTION functest_C_2(int) RETURNS bool LANGUAGE 'sql' + SECURITY DEFINER AS 'SELECT $1 = 0'; + +CREATE FUNCTION functest_C_3(int) RETURNS bool LANGUAGE 'sql' + SECURITY INVOKER AS 'SELECT $1 < 0'; + +SELECT proname, prosecdef FROM pg_proc + WHERE oid in ('functest_C_1'::regproc, + 'functest_C_2'::regproc, + 'functest_C_3'::regproc) ORDER BY proname; + +ALTER FUNCTION functest_C_1(int) IMMUTABLE; + +ALTER FUNCTION functest_C_2(int) SECURITY INVOKER; + +ALTER FUNCTION functest_C_3(int) SECURITY DEFINER; + +SELECT proname, prosecdef FROM pg_proc + WHERE oid in ('functest_C_1'::regproc, + 'functest_C_2'::regproc, + 'functest_C_3'::regproc) ORDER BY proname; + +CREATE FUNCTION functest_E_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 100'; + +CREATE FUNCTION functest_E_2(int) RETURNS bool LANGUAGE 'sql' + LEAKPROOF AS 'SELECT $1 > 100'; + +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname; + +ALTER FUNCTION functest_E_1(int) LEAKPROOF; + +ALTER FUNCTION functest_E_2(int) STABLE; + +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname; + +ALTER FUNCTION functest_E_2(int) NOT LEAKPROOF; + +SELECT proname, proleakproof FROM pg_proc + WHERE oid in ('functest_E_1'::regproc, + 'functest_E_2'::regproc) ORDER BY proname; + +ALTER FUNCTION functest_E_1(int) OWNER TO regress_unpriv_user; + +ALTER FUNCTION functest_E_2(int) OWNER TO regress_unpriv_user; + +SET SESSION AUTHORIZATION regress_unpriv_user; + +SET search_path TO temp_func_test, public; + +ALTER FUNCTION functest_E_1(int) NOT LEAKPROOF; + +ALTER FUNCTION functest_E_2(int) LEAKPROOF; + +CREATE FUNCTION functest_E_3(int) RETURNS bool LANGUAGE 'sql' + LEAKPROOF AS 'SELECT $1 < 200'; + +RESET SESSION AUTHORIZATION; + +CREATE FUNCTION functest_F_1(int) RETURNS bool LANGUAGE 'sql' + AS 'SELECT $1 > 50'; + +CREATE FUNCTION functest_F_2(int) RETURNS bool LANGUAGE 'sql' + CALLED ON NULL INPUT AS 'SELECT $1 = 50'; + +CREATE FUNCTION functest_F_3(int) RETURNS bool LANGUAGE 'sql' + RETURNS NULL ON NULL INPUT AS 'SELECT $1 < 50'; + +CREATE FUNCTION functest_F_4(int) RETURNS bool LANGUAGE 'sql' + STRICT AS 'SELECT $1 = 50'; + +SELECT proname, proisstrict FROM pg_proc + WHERE oid in ('functest_F_1'::regproc, + 'functest_F_2'::regproc, + 'functest_F_3'::regproc, + 'functest_F_4'::regproc) ORDER BY proname; + +ALTER FUNCTION functest_F_1(int) IMMUTABLE; + +ALTER FUNCTION functest_F_2(int) STRICT; + +ALTER FUNCTION functest_F_3(int) CALLED ON NULL INPUT; + +SELECT proname, proisstrict FROM pg_proc + WHERE oid in ('functest_F_1'::regproc, + 'functest_F_2'::regproc, + 'functest_F_3'::regproc, + 'functest_F_4'::regproc) ORDER BY proname; + +SELECT pg_get_functiondef('functest_A_1'::regproc); + +SELECT pg_get_functiondef('functest_B_3'::regproc); + +SELECT pg_get_functiondef('functest_C_3'::regproc); + +SELECT pg_get_functiondef('functest_F_2'::regproc); + +CREATE FUNCTION functest_S_1(a text, b date) RETURNS boolean + LANGUAGE SQL + RETURN a = 'abcd' AND b > '2001-01-01'; + +CREATE FUNCTION functest_S_2(a text[]) RETURNS int + RETURN a[1]::int; + +CREATE FUNCTION functest_S_3() RETURNS boolean + RETURN false; + +END; + +SELECT a = 'abcd' AND b > '2001-01-01'; + +END; + +SELECT 1; + +SELECT false; + +END; + +CREATE TABLE functest1 (i int); + +INSERT INTO functest1 SELECT a + $2; + +END; + +CREATE FUNCTION functest_S_xxx(x int) RETURNS int + LANGUAGE SQL + AS $$ SELECT x * 2 $$ + RETURN x * 3; + +CREATE FUNCTION functest_S_xx(x anyarray) RETURNS anyelement + LANGUAGE SQL + RETURN x[1]; + +CREATE FUNCTION functest_S_xx(x date) RETURNS boolean + LANGUAGE SQL + RETURN x > 1; + +select case when x % 2 = 0 then true else false end; + +END; + +SELECT functest_S_1('abcd', '2020-01-01'); + +SELECT functest_S_2(ARRAY['1', '2', '3']); + +SELECT functest_S_3(); + +SELECT functest_S_10('abcd', '2020-01-01'); + +SELECT functest_S_13(); + +SELECT pg_get_functiondef('functest_S_1'::regproc); + +SELECT pg_get_functiondef('functest_S_2'::regproc); + +SELECT pg_get_functiondef('functest_S_3'::regproc); + +SELECT pg_get_functiondef('functest_S_3a'::regproc); + +SELECT pg_get_functiondef('functest_S_10'::regproc); + +SELECT pg_get_functiondef('functest_S_13'::regproc); + +SELECT pg_get_functiondef('functest_S_15'::regproc); + +SELECT pg_get_functiondef('functest_S_16'::regproc); + +DROP TABLE functest1 CASCADE; + +CREATE TABLE functest3 (a int); + +INSERT INTO functest3 VALUES (1), (2); + +CREATE VIEW functestv3 AS SELECT * FROM functest3; + +CREATE FUNCTION functest_S_14() RETURNS bigint + RETURN (SELECT count(*) FROM functestv3); + +SELECT functest_S_14(); + +DROP TABLE functest3 CASCADE; + +CREATE FUNCTION functest_IS_1(a int, b int default 1, c text default 'foo') + RETURNS int + LANGUAGE SQL + AS 'SELECT $1 + $2'; + +CREATE FUNCTION functest_IS_2(out a int, b int default 1) + RETURNS int + LANGUAGE SQL + AS 'SELECT $1'; + +CREATE FUNCTION functest_IS_3(a int default 1, out b int) + RETURNS int + LANGUAGE SQL + AS 'SELECT $1'; + +SELECT routine_name, ordinal_position, parameter_name, parameter_default + FROM information_schema.parameters JOIN information_schema.routines USING (specific_schema, specific_name) + WHERE routine_schema = 'temp_func_test' AND routine_name ~ '^functest_is_' + ORDER BY 1, 2; + +DROP FUNCTION functest_IS_1(int, int, text), functest_IS_2(int), functest_IS_3(int); + +CREATE FUNCTION functest_IS_4a() RETURNS int LANGUAGE SQL AS 'SELECT 1'; + +CREATE FUNCTION functest_IS_4b(x int DEFAULT functest_IS_4a()) RETURNS int LANGUAGE SQL AS 'SELECT x'; + +CREATE SEQUENCE functest1; + +CREATE FUNCTION functest_IS_5(x int DEFAULT nextval('functest1')) + RETURNS int + LANGUAGE SQL + AS 'SELECT x'; + +CREATE FUNCTION functest_IS_6() + RETURNS int + LANGUAGE SQL + RETURN nextval('functest1'); + +CREATE TABLE functest2 (a int, b int); + +CREATE FUNCTION functest_IS_7() + RETURNS int + LANGUAGE SQL + RETURN (SELECT count(a) FROM functest2); + +SELECT r0.routine_name, r1.routine_name + FROM information_schema.routine_routine_usage rru + JOIN information_schema.routines r0 ON r0.specific_name = rru.specific_name + JOIN information_schema.routines r1 ON r1.specific_name = rru.routine_name + WHERE r0.routine_schema = 'temp_func_test' AND + r1.routine_schema = 'temp_func_test' + ORDER BY 1, 2; + +SELECT routine_name, sequence_name FROM information_schema.routine_sequence_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2; + +SELECT routine_name, table_name, column_name FROM information_schema.routine_column_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2; + +SELECT routine_name, table_name FROM information_schema.routine_table_usage + WHERE routine_schema = 'temp_func_test' + ORDER BY 1, 2; + +DROP FUNCTION functest_IS_4a CASCADE; + +DROP SEQUENCE functest1 CASCADE; + +DROP TABLE functest2 CASCADE; + +CREATE FUNCTION functest_B_2(bigint) RETURNS bool LANGUAGE 'sql' + IMMUTABLE AS 'SELECT $1 > 0'; + +DROP FUNCTION functest_b_1; + +DROP FUNCTION functest_b_1; + +DROP FUNCTION functest_b_2; + +CREATE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL AS 'SELECT $1'; + +CREATE OR REPLACE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL WINDOW AS 'SELECT $1'; + +CREATE OR REPLACE PROCEDURE functest1(a int) LANGUAGE SQL AS 'SELECT $1'; + +DROP FUNCTION functest1(a int); + +CREATE FUNCTION functest_srf0() RETURNS SETOF int +LANGUAGE SQL +AS $$ SELECT i FROM generate_series(1, 100) i $$; + +SELECT functest_srf0() LIMIT 5; + +CREATE TABLE functest3 (a int); + +INSERT INTO functest3 VALUES (1), (2), (3); + +CREATE FUNCTION functest_sri1() RETURNS SETOF int +LANGUAGE SQL +STABLE +AS ' + SELECT * FROM functest3; +'; + +SELECT * FROM functest_sri1(); + +SELECT * FROM functest_sri1(); + +SELECT * FROM functest3; + +END; + +SELECT * FROM functest_sri2(); + +SELECT * FROM functest_sri2(); + +DROP TABLE functest3 CASCADE; + +CREATE FUNCTION voidtest1(a int) RETURNS VOID LANGUAGE SQL AS +$$ SELECT a + 1 $$; + +SELECT voidtest1(42); + +CREATE FUNCTION voidtest2(a int, b int) RETURNS VOID LANGUAGE SQL AS +$$ SELECT voidtest1(a + b) $$; + +SELECT voidtest2(11,22); + +SELECT voidtest2(11,22); + +CREATE TEMP TABLE sometable(f1 int); + +CREATE FUNCTION voidtest3(a int) RETURNS VOID LANGUAGE SQL AS +$$ INSERT INTO sometable VALUES(a + 1) $$; + +SELECT voidtest3(17); + +CREATE FUNCTION voidtest4(a int) RETURNS VOID LANGUAGE SQL AS +$$ INSERT INTO sometable VALUES(a - 1) RETURNING f1 $$; + +SELECT voidtest4(39); + +TABLE sometable; + +CREATE FUNCTION voidtest5(a int) RETURNS SETOF VOID LANGUAGE SQL AS +$$ SELECT generate_series(1, a) $$ STABLE; + +SELECT * FROM voidtest5(3); + +SET check_function_bodies TO off; + +CREATE FUNCTION create_and_insert() RETURNS VOID LANGUAGE sql AS $$ + create table ddl_test (f1 int); + insert into ddl_test values (1.2); +$$; + +SELECT create_and_insert(); + +TABLE ddl_test; + +CREATE FUNCTION alter_and_insert() RETURNS VOID LANGUAGE sql AS $$ + alter table ddl_test alter column f1 type numeric; + insert into ddl_test values (1.2); +$$; + +SELECT alter_and_insert(); + +TABLE ddl_test; + +RESET check_function_bodies; + +CREATE FUNCTION double_append(anyarray, anyelement) RETURNS SETOF anyarray +LANGUAGE SQL IMMUTABLE AS +$$ SELECT array_append($1, $2) || array_append($1, $2) $$; + +SELECT double_append(array_append(ARRAY[q1], q2), q3) + FROM (VALUES(1,2,3), (4,5,6)) v(q1,q2,q3); + +CREATE FUNCTION part_hashint4_error(value int4, seed int8) RETURNS int8 +LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE AS +$$ SELECT value + seed + random()::int/0 $$; + +CREATE OPERATOR CLASS part_test_int4_ops_bad FOR TYPE int4 USING hash AS + FUNCTION 2 part_hashint4_error(int4, int8); + +CREATE TABLE pt(i int) PARTITION BY hash (i part_test_int4_ops_bad); + +CREATE TABLE p1 PARTITION OF pt FOR VALUES WITH (modulus 4, remainder 0); + +INSERT INTO pt VALUES (1); + +INSERT INTO pt VALUES (1); + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT ''not an integer'';'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'not even SQL'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT 1, 2, 3;'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT $2;'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'a', 'b'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS ''; + +SET check_function_bodies = off; + +CREATE FUNCTION test1 (anyelement) RETURNS anyarray LANGUAGE SQL + AS ''; + +SELECT test1(0); + +RESET check_function_bodies; + +DROP SCHEMA temp_func_test CASCADE; + +DROP USER regress_unpriv_user; + +RESET search_path; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_index_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_index_60.sql new file mode 100644 index 000000000..db9ad116f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_index_60.sql @@ -0,0 +1,1588 @@ +CREATE INDEX onek_unique1 ON onek USING btree(unique1 int4_ops); + +CREATE INDEX IF NOT EXISTS onek_unique1 ON onek USING btree(unique1 int4_ops); + +CREATE INDEX onek_unique2 ON onek USING btree(unique2 int4_ops); + +CREATE INDEX onek_hundred ON onek USING btree(hundred int4_ops); + +CREATE INDEX onek_stringu1 ON onek USING btree(stringu1 name_ops); + +CREATE INDEX tenk1_unique1 ON tenk1 USING btree(unique1 int4_ops); + +CREATE INDEX tenk1_unique2 ON tenk1 USING btree(unique2 int4_ops); + +CREATE INDEX tenk1_hundred ON tenk1 USING btree(hundred int4_ops); + +CREATE INDEX tenk1_thous_tenthous ON tenk1 (thousand, tenthous); + +CREATE INDEX tenk2_unique1 ON tenk2 USING btree(unique1 int4_ops); + +CREATE INDEX tenk2_unique2 ON tenk2 USING btree(unique2 int4_ops); + +CREATE INDEX tenk2_hundred ON tenk2 USING btree(hundred int4_ops); + +CREATE INDEX rix ON road USING btree (name text_ops); + +CREATE INDEX iix ON ihighway USING btree (name text_ops); + +CREATE INDEX six ON shighway USING btree (name text_ops); + +COMMENT ON INDEX six_wrong IS 'bad index'; + +COMMENT ON INDEX six IS 'good index'; + +COMMENT ON INDEX six IS NULL; + +CREATE INDEX onek2_u1_prtl ON onek2 USING btree(unique1 int4_ops) + where unique1 < 20 or unique1 > 980; + +CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops) + where stringu1 < 'B'; + +CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops) + where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K'; + +CREATE TABLE slow_emp4000 ( + home_base box +); + +CREATE TABLE fast_emp4000 ( + home_base box +); + +COPY slow_emp4000 FROM 'filename'; + +INSERT INTO fast_emp4000 SELECT * FROM slow_emp4000; + +ANALYZE slow_emp4000; + +ANALYZE fast_emp4000; + +CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base); + +CREATE TEMP TABLE point_tbl AS SELECT * FROM public.point_tbl; + +INSERT INTO POINT_TBL(f1) VALUES (NULL); + +CREATE INDEX gpointind ON point_tbl USING gist (f1); + +CREATE TEMP TABLE gpolygon_tbl AS + SELECT polygon(home_base) AS f1 FROM slow_emp4000; + +INSERT INTO gpolygon_tbl VALUES ( '(1000,0,0,1000)' ); + +INSERT INTO gpolygon_tbl VALUES ( '(0,1000,1000,1000)' ); + +CREATE TEMP TABLE gcircle_tbl AS + SELECT circle(home_base) AS f1 FROM slow_emp4000; + +CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1); + +CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1); + +SET enable_seqscan = ON; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = OFF; + +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0]; + +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box; + +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; + +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon; + +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle; + +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)'; + +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1; + +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)'; + +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; + +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl WHERE f1 IS NULL; + +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; + +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; + +SET enable_seqscan = OFF; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = OFF; + +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0]; + +SELECT * FROM fast_emp4000 + WHERE home_base <@ '(200,200),(2000,1000)'::box + ORDER BY (home_base[0])[0]; + +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box; + +SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box; + +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; + +SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL; + +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon; + +SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon; + +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle; + +SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle; + +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)'; + +SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)'; + +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1; + +SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1; + +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)'; + +SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)'; + +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>'; + +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 <<| '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 |>> '(0.0, 0.0)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; + +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; + +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl WHERE f1 IS NULL; + +SELECT * FROM point_tbl WHERE f1 IS NULL; + +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; + +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; + +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; + +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; + +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x; + +SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x; + +SET enable_seqscan = OFF; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = ON; + +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +CREATE TABLE array_index_op_test ( + seqno int4, + i int4[], + t text[] +); + +COPY array_index_op_test FROM 'filename'; + +ANALYZE array_index_op_test; + +SELECT * FROM array_index_op_test WHERE i = '{NULL}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i @> '{NULL}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i && '{NULL}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i <@ '{NULL}' ORDER BY seqno; + +SET enable_seqscan = OFF; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = ON; + +CREATE INDEX intarrayidx ON array_index_op_test USING gin (i); + +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i @> '{17}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i && '{17}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i @> '{32,17}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i && '{32,17}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i = '{47,77}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i = '{}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i @> '{}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i && '{}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i <@ '{}' ORDER BY seqno; + +CREATE INDEX textarrayidx ON array_index_op_test USING gin (t); + +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t = '{AAAAAAAAAA646,A87088}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t @> '{}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t && '{}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t <@ '{}' ORDER BY seqno; + +DROP INDEX intarrayidx, textarrayidx; + +CREATE INDEX botharrayidx ON array_index_op_test USING gin (i, t); + +SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAA80240}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t && '{AAAAAAA80240}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i @> '{32}' AND t && '{AAAAAAA80240}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE i && '{32}' AND t @> '{AAAAAAA80240}' ORDER BY seqno; + +SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +CREATE TABLE array_gin_test (a int[]); + +INSERT INTO array_gin_test SELECT ARRAY[1, g%5, g] FROM generate_series(1, 10000) g; + +CREATE INDEX array_gin_test_idx ON array_gin_test USING gin (a); + +SELECT COUNT(*) FROM array_gin_test WHERE a @> '{2}'; + +DROP TABLE array_gin_test; + +CREATE INDEX gin_relopts_test ON array_index_op_test USING gin (i) + WITH (FASTUPDATE=on, GIN_PENDING_LIST_LIMIT=128); + +CREATE UNLOGGED TABLE unlogged_hash_table (id int4); + +CREATE INDEX unlogged_hash_index ON unlogged_hash_table USING hash (id int4_ops); + +DROP TABLE unlogged_hash_table; + +SET maintenance_work_mem = '1MB'; + +CREATE INDEX hash_tuplesort_idx ON tenk1 USING hash (stringu1 name_ops) WITH (fillfactor = 10); + +SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'; + +SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'; + +SET enable_seqscan = off; + +SELECT COUNT(*) FROM tenk1 WHERE stringu1 = 'TVAAAA' OR stringu1 = 'TVAAAB'; + +RESET enable_seqscan; + +DROP INDEX hash_tuplesort_idx; + +RESET maintenance_work_mem; + +CREATE TABLE unique_tbl (i int, t text); + +CREATE UNIQUE INDEX unique_idx1 ON unique_tbl (i) NULLS DISTINCT; + +CREATE UNIQUE INDEX unique_idx2 ON unique_tbl (i) NULLS NOT DISTINCT; + +INSERT INTO unique_tbl VALUES (1, 'one'); + +INSERT INTO unique_tbl VALUES (2, 'two'); + +INSERT INTO unique_tbl VALUES (3, 'three'); + +INSERT INTO unique_tbl VALUES (4, 'four'); + +INSERT INTO unique_tbl VALUES (5, 'one'); + +INSERT INTO unique_tbl (t) VALUES ('six'); + +INSERT INTO unique_tbl (t) VALUES ('seven'); + +DROP INDEX unique_idx1, unique_idx2; + +INSERT INTO unique_tbl (t) VALUES ('seven'); + +CREATE UNIQUE INDEX unique_idx3 ON unique_tbl (i) NULLS DISTINCT; + +CREATE UNIQUE INDEX unique_idx4 ON unique_tbl (i) NULLS NOT DISTINCT; + +DELETE FROM unique_tbl WHERE t = 'seven'; + +CREATE UNIQUE INDEX unique_idx4 ON unique_tbl (i) NULLS NOT DISTINCT; + +SELECT pg_get_indexdef('unique_idx3'::regclass); + +SELECT pg_get_indexdef('unique_idx4'::regclass); + +DROP TABLE unique_tbl; + +CREATE TABLE func_index_heap (f1 text, f2 text); + +CREATE UNIQUE INDEX func_index_index on func_index_heap (textcat(f1,f2)); + +INSERT INTO func_index_heap VALUES('ABC','DEF'); + +INSERT INTO func_index_heap VALUES('AB','CDEFG'); + +INSERT INTO func_index_heap VALUES('QWE','RTY'); + +INSERT INTO func_index_heap VALUES('ABCD', 'EF'); + +INSERT INTO func_index_heap VALUES('QWERTY'); + +DROP TABLE func_index_heap; + +CREATE TABLE func_index_heap (f1 text, f2 text); + +CREATE UNIQUE INDEX func_index_index on func_index_heap ((f1 || f2) text_ops); + +INSERT INTO func_index_heap VALUES('ABC','DEF'); + +INSERT INTO func_index_heap VALUES('AB','CDEFG'); + +INSERT INTO func_index_heap VALUES('QWE','RTY'); + +INSERT INTO func_index_heap VALUES('ABCD', 'EF'); + +INSERT INTO func_index_heap VALUES('QWERTY'); + +create index on func_index_heap ((f1 || f2), (row(f1, f2))); + +CREATE TABLE covering_index_heap (f1 int, f2 int, f3 text); + +CREATE UNIQUE INDEX covering_index_index on covering_index_heap (f1,f2) INCLUDE(f3); + +INSERT INTO covering_index_heap VALUES(1,1,'AAA'); + +INSERT INTO covering_index_heap VALUES(1,2,'AAA'); + +INSERT INTO covering_index_heap VALUES(1,2,'BBB'); + +INSERT INTO covering_index_heap VALUES(1,4,'AAA'); + +CREATE UNIQUE INDEX covering_pkey on covering_index_heap (f1,f2) INCLUDE(f3); + +ALTER TABLE covering_index_heap ADD CONSTRAINT covering_pkey PRIMARY KEY USING INDEX +covering_pkey; + +DROP TABLE covering_index_heap; + +CREATE TABLE concur_heap (f1 text, f2 text); + +CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap(f2,f1); + +CREATE INDEX CONCURRENTLY IF NOT EXISTS concur_index1 ON concur_heap(f2,f1); + +INSERT INTO concur_heap VALUES ('a','b'); + +INSERT INTO concur_heap VALUES ('b','b'); + +CREATE UNIQUE INDEX CONCURRENTLY concur_index2 ON concur_heap(f1); + +CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS concur_index2 ON concur_heap(f1); + +INSERT INTO concur_heap VALUES ('b','x'); + +CREATE UNIQUE INDEX CONCURRENTLY concur_index3 ON concur_heap(f2); + +CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a'; + +CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x'; + +CREATE INDEX CONCURRENTLY on concur_heap((f2||f1)); + +BEGIN; + +CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap(f1); + +COMMIT; + +CREATE FUNCTION predicate_stable() RETURNS bool IMMUTABLE +LANGUAGE plpgsql AS $$ +BEGIN + EXECUTE 'SELECT txid_current()'; + RETURN true; +END; $$; + +CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap (f1) + WHERE predicate_stable(); + +DROP INDEX concur_index8; + +DROP FUNCTION predicate_stable(); + +BEGIN; + +CREATE INDEX std_index on concur_heap(f2); + +COMMIT; + +VACUUM FULL concur_heap; + +REINDEX TABLE concur_heap; + +DELETE FROM concur_heap WHERE f1 = 'b'; + +VACUUM FULL concur_heap; + +REINDEX TABLE concur_heap; + +CREATE TEMP TABLE concur_temp (f1 int, f2 text) + ON COMMIT PRESERVE ROWS; + +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); + +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); + +DROP INDEX CONCURRENTLY concur_temp_ind; + +DROP TABLE concur_temp; + +BEGIN; + +CREATE TEMP TABLE concur_temp (f1 int, f2 text) + ON COMMIT DROP; + +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); + +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); + +COMMIT; + +INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); + +CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); + +DROP INDEX CONCURRENTLY concur_temp_ind; + +DROP TABLE concur_temp; + +DROP INDEX CONCURRENTLY "concur_index2"; + +DROP INDEX CONCURRENTLY IF EXISTS "concur_index2"; + +DROP INDEX CONCURRENTLY "concur_index2", "concur_index3"; + +BEGIN; + +DROP INDEX CONCURRENTLY "concur_index5"; + +ROLLBACK; + +DROP INDEX CONCURRENTLY IF EXISTS "concur_index3"; + +DROP INDEX CONCURRENTLY "concur_index4"; + +DROP INDEX CONCURRENTLY "concur_index5"; + +DROP INDEX CONCURRENTLY "concur_index1"; + +DROP INDEX CONCURRENTLY "concur_heap_expr_idx"; + +DROP TABLE concur_heap; + +CREATE TABLE cwi_test( a int , b varchar(10), c char); + +INSERT INTO cwi_test VALUES(1, 2), (3, 4), (5, 6); + +CREATE UNIQUE INDEX cwi_uniq_idx ON cwi_test(a , b); + +ALTER TABLE cwi_test ADD primary key USING INDEX cwi_uniq_idx; + +CREATE UNIQUE INDEX cwi_uniq2_idx ON cwi_test(b , a); + +ALTER TABLE cwi_test DROP CONSTRAINT cwi_uniq_idx, + ADD CONSTRAINT cwi_replaced_pkey PRIMARY KEY + USING INDEX cwi_uniq2_idx; + +DROP INDEX cwi_replaced_pkey; + +CREATE UNIQUE INDEX cwi_uniq3_idx ON cwi_test(a desc); + +ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq3_idx; + +CREATE UNIQUE INDEX cwi_uniq4_idx ON cwi_test(b collate "POSIX"); + +ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq4_idx; + +DROP TABLE cwi_test; + +CREATE TABLE cwi_test(a int) PARTITION BY hash (a); + +create unique index on cwi_test (a); + +alter table cwi_test add primary key using index cwi_test_a_idx ; + +DROP TABLE cwi_test; + +CREATE TABLE cwi_test(a int, b int); + +CREATE UNIQUE INDEX cwi_a_nnd ON cwi_test (a) NULLS NOT DISTINCT; + +ALTER TABLE cwi_test ADD PRIMARY KEY USING INDEX cwi_a_nnd; + +DROP TABLE cwi_test; + +CREATE TABLE syscol_table (a INT); + +CREATE INDEX ON syscol_table (ctid); + +CREATE INDEX ON syscol_table ((ctid >= '(1000,0)')); + +CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)'; + +DROP TABLE syscol_table; + +CREATE TABLE onek_with_null AS SELECT unique1, unique2 FROM onek; + +INSERT INTO onek_with_null(unique1, unique2) +VALUES (NULL, -1), (NULL, 2_147_483_647), (NULL, NULL), + (100, NULL), (500, NULL); + +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2,unique1); + +SET enable_seqscan = OFF; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = ON; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; + +SELECT unique1, unique2 FROM onek_with_null WHERE unique1 = 500 ORDER BY unique2 DESC, unique1 DESC LIMIT 1; + +DROP INDEX onek_nulltest; + +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc,unique1); + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IN (-1, 0, 1); + +SELECT unique1, unique2 FROM onek_with_null WHERE unique1 = 500 ORDER BY unique2 DESC, unique1 DESC LIMIT 1; + +DROP INDEX onek_nulltest; + +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc nulls last,unique1); + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; + +SELECT unique1, unique2 FROM onek_with_null WHERE unique1 = 500 ORDER BY unique2 DESC, unique1 DESC LIMIT 1; + +DROP INDEX onek_nulltest; + +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 nulls first,unique1); + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; + +SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; + +SELECT unique1, unique2 FROM onek_with_null WHERE unique1 = 500 ORDER BY unique2 DESC, unique1 DESC LIMIT 1; + +DROP INDEX onek_nulltest; + +CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2); + +SET enable_seqscan = OFF; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = OFF; + +SELECT unique1, unique2 FROM onek_with_null + ORDER BY unique2 LIMIT 2; + +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 + ORDER BY unique2 LIMIT 2; + +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= 0 + ORDER BY unique2 LIMIT 2; + +SELECT unique1, unique2 FROM onek_with_null + ORDER BY unique2 DESC LIMIT 5; + +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 + ORDER BY unique2 DESC LIMIT 3; + +SELECT unique1, unique2 FROM onek_with_null WHERE unique2 < 999 + ORDER BY unique2 DESC LIMIT 2; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +DROP TABLE onek_with_null; + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42 OR tenthous = 0); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42 OR tenthous = 0); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = (SELECT 1 + 2) OR tenthous = 42); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = (SELECT 1 + 2) OR tenthous = 42); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42 OR tenthous IS NULL); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1::int2 OR tenthous::int2 = 3::int8 OR tenthous = 42::int8); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1::int2 OR tenthous::int2 = 3::int8 OR tenthous::int2 = 42::int8); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1::int2 OR tenthous = 3::int8 OR tenthous = 42::int8); + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99); + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); + +SELECT * FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1::numeric OR tenthous = 3::int4 OR tenthous = 42::numeric); + +SELECT * FROM tenk1 + WHERE tenthous = 1::numeric OR tenthous = 3::int4 OR tenthous = 42::numeric; + +SELECT count(*) FROM tenk1 t1 + WHERE t1.thousand = 42 OR t1.thousand = (SELECT t2.tenthous FROM tenk1 t2 WHERE t2.thousand = t1.tenthous + 1 LIMIT 1); + +SELECT count(*) FROM tenk1 t1 + WHERE t1.thousand = 42 OR t1.thousand = (SELECT t2.tenthous FROM tenk1 t2 WHERE t2.thousand = t1.tenthous + 1 LIMIT 1); + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99); + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99); + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand < 42 OR thousand < 99 OR 43 > thousand OR 42 > thousand); + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand < 42 OR thousand < 99 OR 43 > thousand OR 42 > thousand); + +SELECT count(*) FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3) OR thousand = 41; + +SELECT count(*) FROM tenk1 + WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3) OR thousand = 41; + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99 OR tenthous < 2) OR thousand = 41; + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 99 OR tenthous < 2) OR thousand = 41; + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2); + +SELECT count(*) FROM tenk1 + WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2); + +SELECT count(*) FROM tenk1, tenk2 + WHERE tenk1.hundred = 42 AND (tenk2.thousand = 42 OR tenk1.thousand = 41 OR tenk2.tenthous = 2) AND + tenk2.hundred = tenk1.hundred; + +SELECT count(*) FROM tenk1, tenk2 + WHERE tenk1.hundred = 42 AND (tenk2.thousand = 42 OR tenk2.thousand = 41 OR tenk2.tenthous = 2) AND + tenk2.hundred = tenk1.hundred; + +SELECT count(*) FROM tenk1 JOIN tenk2 ON + tenk1.hundred = 42 AND (tenk2.thousand = 42 OR tenk2.thousand = 41 OR tenk2.tenthous = 2) AND + tenk2.hundred = tenk1.hundred; + +SELECT count(*) FROM tenk1 LEFT JOIN tenk2 ON + tenk1.hundred = 42 AND (tenk2.thousand = 42 OR tenk2.thousand = 41 OR tenk2.tenthous = 2) AND + tenk2.hundred = tenk1.hundred; + +CREATE TABLE dupindexcols AS + SELECT unique1 as id, stringu2::text as f1 FROM tenk1; + +CREATE INDEX dupindexcols_i ON dupindexcols (f1, id, f1 text_pattern_ops); + +ANALYZE dupindexcols; + +SELECT count(*) FROM dupindexcols + WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX'; + +SELECT count(*) FROM dupindexcols + WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX'; + +SELECT unique1 FROM tenk1 +WHERE unique1 IN (1,42,7) +ORDER BY unique1; + +SELECT unique1 FROM tenk1 +WHERE unique1 IN (1,42,7) +ORDER BY unique1; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand DESC, tenthous DESC; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 2 AND tenthous IN (1001,3000) +ORDER BY thousand DESC, tenthous DESC; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand > 995 and tenthous in (998, 999) +ORDER BY thousand desc; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand > 995 and tenthous in (998, 999) +ORDER BY thousand desc; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = ANY('{7, 8, 9}'); + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = ANY('{7, 8, 9}'); + +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') and unique1 = ANY('{33, 44}'::bigint[]); + +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{7, 14, 22}') and unique1 = ANY('{33, 44}'::bigint[]); + +SELECT unique1 FROM tenk1 WHERE unique1 = ANY(NULL); + +SELECT unique1 FROM tenk1 WHERE unique1 = ANY(NULL); + +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{NULL,NULL,NULL}'); + +SELECT unique1 FROM tenk1 WHERE unique1 = ANY('{NULL,NULL,NULL}'); + +SELECT unique1 FROM tenk1 WHERE unique1 IS NULL AND unique1 IS NULL; + +SELECT unique1 FROM tenk1 WHERE unique1 IS NULL AND unique1 IS NULL; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 1; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 1; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 12345; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 = 12345; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 >= 42; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 >= 42; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 > 42; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 > 42; + +SELECT unique1 FROM tenk1 WHERE unique1 > 9996 and unique1 >= 9999; + +SELECT unique1 FROM tenk1 WHERE unique1 > 9996 and unique1 >= 9999; + +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 <= 3; + +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 <= 3; + +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 < (-1)::bigint; + +SELECT unique1 FROM tenk1 WHERE unique1 < 3 and unique1 < (-1)::bigint; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 < (-1)::bigint; + +SELECT unique1 FROM tenk1 WHERE unique1 IN (1, 42, 7) and unique1 < (-1)::bigint; + +SELECT unique1 FROM tenk1 WHERE (thousand, tenthous) > (NULL, 5); + +SELECT unique1 FROM tenk1 WHERE (thousand, tenthous) > (NULL, 5); + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand > -1 and thousand >= 0 AND tenthous = 3000 +ORDER BY thousand; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand > -1 and thousand >= 0 AND tenthous = 3000 +ORDER BY thousand; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 3 and thousand <= 2 AND tenthous = 1001 +ORDER BY thousand; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand < 3 and thousand <= 2 AND tenthous = 1001 +ORDER BY thousand; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand > -1 AND tenthous IN (1001,3000) +ORDER BY thousand limit 2; + +SELECT thousand, tenthous FROM tenk1 +WHERE thousand > -1 AND tenthous IN (1001,3000) +ORDER BY thousand limit 2; + +select * from tenk1 where (thousand, tenthous) in ((1,1001), (null,null)); + +create temp table boolindex (b bool, i int, unique(b, i), junk float); + +select * from boolindex order by b, i limit 10; + +select * from boolindex where b order by i limit 10; + +select * from boolindex where b = true order by i desc limit 10; + +select * from boolindex where not b order by i limit 10; + +select * from boolindex where b is true order by i desc limit 10; + +select * from boolindex where b is false order by i desc limit 10; + +CREATE TABLE reindex_verbose(id integer primary key); + +REINDEX (VERBOSE) TABLE reindex_verbose; + +DROP TABLE reindex_verbose; + +CREATE TABLE concur_reindex_tab (c1 int); + +REINDEX TABLE concur_reindex_tab; + +REINDEX (CONCURRENTLY) TABLE concur_reindex_tab; + +ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; + +CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1); + +CREATE INDEX concur_reindex_ind2 ON concur_reindex_tab(c2); + +CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab(abs(c1)); + +CREATE INDEX concur_reindex_ind4 ON concur_reindex_tab(c1, c1, c2); + +ALTER TABLE concur_reindex_tab ADD PRIMARY KEY USING INDEX concur_reindex_ind1; + +CREATE TABLE concur_reindex_tab2 (c1 int REFERENCES concur_reindex_tab); + +INSERT INTO concur_reindex_tab VALUES (1, 'a'); + +INSERT INTO concur_reindex_tab VALUES (2, 'a'); + +CREATE TABLE concur_reindex_tab3 (c1 int, c2 int4range, EXCLUDE USING gist (c2 WITH &&)); + +INSERT INTO concur_reindex_tab3 VALUES (3, '[1,2]'); + +REINDEX INDEX CONCURRENTLY concur_reindex_tab3_c2_excl; + +REINDEX TABLE CONCURRENTLY concur_reindex_tab3; + +INSERT INTO concur_reindex_tab3 VALUES (4, '[2,4]'); + +CREATE MATERIALIZED VIEW concur_reindex_matview AS SELECT * FROM concur_reindex_tab; + +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype +FROM pg_depend +WHERE classid = 'pg_class'::regclass AND + objid in ('concur_reindex_tab'::regclass, + 'concur_reindex_ind1'::regclass, + 'concur_reindex_ind2'::regclass, + 'concur_reindex_ind3'::regclass, + 'concur_reindex_ind4'::regclass, + 'concur_reindex_matview'::regclass) + ORDER BY 1, 2; + +REINDEX INDEX CONCURRENTLY concur_reindex_ind1; + +REINDEX TABLE CONCURRENTLY concur_reindex_tab; + +REINDEX TABLE CONCURRENTLY concur_reindex_matview; + +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype +FROM pg_depend +WHERE classid = 'pg_class'::regclass AND + objid in ('concur_reindex_tab'::regclass, + 'concur_reindex_ind1'::regclass, + 'concur_reindex_ind2'::regclass, + 'concur_reindex_ind3'::regclass, + 'concur_reindex_ind4'::regclass, + 'concur_reindex_matview'::regclass) + ORDER BY 1, 2; + +CREATE TABLE testcomment (i int); + +CREATE INDEX testcomment_idx1 ON testcomment (i); + +COMMENT ON INDEX testcomment_idx1 IS 'test comment'; + +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); + +REINDEX TABLE testcomment; + +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); + +REINDEX TABLE CONCURRENTLY testcomment ; + +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); + +DROP TABLE testcomment; + +CREATE TABLE concur_clustered(i int); + +CREATE INDEX concur_clustered_i_idx ON concur_clustered(i); + +ALTER TABLE concur_clustered CLUSTER ON concur_clustered_i_idx; + +REINDEX TABLE CONCURRENTLY concur_clustered; + +SELECT indexrelid::regclass, indisclustered FROM pg_index + WHERE indrelid = 'concur_clustered'::regclass; + +DROP TABLE concur_clustered; + +CREATE TABLE concur_replident(i int NOT NULL); + +CREATE UNIQUE INDEX concur_replident_i_idx ON concur_replident(i); + +ALTER TABLE concur_replident REPLICA IDENTITY + USING INDEX concur_replident_i_idx; + +SELECT indexrelid::regclass, indisreplident FROM pg_index + WHERE indrelid = 'concur_replident'::regclass; + +REINDEX TABLE CONCURRENTLY concur_replident; + +SELECT indexrelid::regclass, indisreplident FROM pg_index + WHERE indrelid = 'concur_replident'::regclass; + +DROP TABLE concur_replident; + +CREATE TABLE concur_appclass_tab(i tsvector, j tsvector, k tsvector); + +CREATE INDEX concur_appclass_ind on concur_appclass_tab + USING gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500')); + +CREATE INDEX concur_appclass_ind_2 on concur_appclass_tab + USING gist (k tsvector_ops (siglen='300'), j tsvector_ops); + +REINDEX TABLE CONCURRENTLY concur_appclass_tab; + +DROP TABLE concur_appclass_tab; + +CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1); + +CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2); + +CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (1); + +CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (2); + +CREATE TABLE concur_reindex_part_10 PARTITION OF concur_reindex_part + FOR VALUES FROM (10) TO (20) PARTITION BY list (c2); + +CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1); + +CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1); + +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0; + +CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1); + +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10; + +CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1); + +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1; + +CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1); + +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2; + +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype +FROM pg_depend +WHERE classid = 'pg_class'::regclass AND + objid in ('concur_reindex_part'::regclass, + 'concur_reindex_part_0'::regclass, + 'concur_reindex_part_0_1'::regclass, + 'concur_reindex_part_0_2'::regclass, + 'concur_reindex_part_index'::regclass, + 'concur_reindex_part_index_0'::regclass, + 'concur_reindex_part_index_0_1'::regclass, + 'concur_reindex_part_index_0_2'::regclass) + ORDER BY 1, 2; + +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1; + +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2; + +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1; + +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2; + +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid,refobjid,refobjsubid) as objref, + deptype +FROM pg_depend +WHERE classid = 'pg_class'::regclass AND + objid in ('concur_reindex_part'::regclass, + 'concur_reindex_part_0'::regclass, + 'concur_reindex_part_0_1'::regclass, + 'concur_reindex_part_0_2'::regclass, + 'concur_reindex_part_index'::regclass, + 'concur_reindex_part_index_0'::regclass, + 'concur_reindex_part_index_0_1'::regclass, + 'concur_reindex_part_index_0_2'::regclass) + ORDER BY 1, 2; + +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + +REINDEX TABLE concur_reindex_part_index; + +REINDEX TABLE CONCURRENTLY concur_reindex_part_index; + +REINDEX TABLE concur_reindex_part_index_10; + +REINDEX TABLE CONCURRENTLY concur_reindex_part_index_10; + +BEGIN; + +REINDEX INDEX concur_reindex_part_index; + +ROLLBACK; + +CREATE OR REPLACE FUNCTION create_relfilenode_part(relname text, indname text) + RETURNS VOID AS + $func$ + BEGIN + EXECUTE format(' + CREATE TABLE %I AS + SELECT oid, relname, relfilenode, relkind, reltoastrelid + FROM pg_class + WHERE oid IN + (SELECT relid FROM pg_partition_tree(''%I''));', + relname, indname); + END + $func$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION compare_relfilenode_part(tabname text) + RETURNS TABLE (relname name, relkind "char", state text) AS + $func$ + BEGIN + RETURN QUERY EXECUTE + format( + 'SELECT b.relname, + b.relkind, + CASE WHEN a.relfilenode = b.relfilenode THEN ''relfilenode is unchanged'' + ELSE ''relfilenode has changed'' END + -- Do not join with OID here as CONCURRENTLY changes it. + FROM %I b JOIN pg_class a ON b.relname = a.relname + ORDER BY 1;', tabname); + END + $func$ LANGUAGE plpgsql; + +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index'); + +REINDEX INDEX concur_reindex_part_index; + +SELECT * FROM compare_relfilenode_part('reindex_index_status'); + +DROP TABLE reindex_index_status; + +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index'); + +REINDEX INDEX CONCURRENTLY concur_reindex_part_index; + +SELECT * FROM compare_relfilenode_part('reindex_index_status'); + +DROP TABLE reindex_index_status; + +REINDEX INDEX concur_reindex_part; + +REINDEX INDEX CONCURRENTLY concur_reindex_part; + +REINDEX INDEX concur_reindex_part_10; + +REINDEX INDEX CONCURRENTLY concur_reindex_part_10; + +BEGIN; + +REINDEX TABLE concur_reindex_part; + +ROLLBACK; + +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index'); + +REINDEX TABLE concur_reindex_part; + +SELECT * FROM compare_relfilenode_part('reindex_index_status'); + +DROP TABLE reindex_index_status; + +SELECT create_relfilenode_part('reindex_index_status', 'concur_reindex_part_index'); + +REINDEX TABLE CONCURRENTLY concur_reindex_part; + +SELECT * FROM compare_relfilenode_part('reindex_index_status'); + +DROP TABLE reindex_index_status; + +DROP FUNCTION create_relfilenode_part; + +DROP FUNCTION compare_relfilenode_part; + +DROP TABLE concur_reindex_part; + +BEGIN; + +REINDEX TABLE CONCURRENTLY concur_reindex_tab; + +COMMIT; + +REINDEX TABLE CONCURRENTLY pg_class; + +REINDEX INDEX CONCURRENTLY pg_class_oid_index; + +REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1262; + +REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1262_index; + +REINDEX SYSTEM CONCURRENTLY postgres; + +REINDEX (CONCURRENTLY) SYSTEM postgres; + +REINDEX (CONCURRENTLY) SYSTEM; + +REINDEX SCHEMA CONCURRENTLY pg_catalog; + +REINDEX DATABASE not_current_database; + +DROP MATERIALIZED VIEW concur_reindex_matview; + +DROP TABLE concur_reindex_tab, concur_reindex_tab2, concur_reindex_tab3; + +CREATE TABLE concur_reindex_tab4 (c1 int); + +INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2); + +CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1); + +REINDEX INDEX CONCURRENTLY concur_reindex_ind5; + +DROP INDEX concur_reindex_ind5_ccnew; + +DELETE FROM concur_reindex_tab4 WHERE c1 = 1; + +REINDEX TABLE CONCURRENTLY concur_reindex_tab4; + +REINDEX INDEX CONCURRENTLY concur_reindex_ind5; + +DROP TABLE concur_reindex_tab4; + +CREATE TABLE concur_exprs_tab (c1 int , c2 boolean); + +INSERT INTO concur_exprs_tab (c1, c2) VALUES (1369652450, FALSE), + (414515746, TRUE), + (897778963, FALSE); + +CREATE UNIQUE INDEX concur_exprs_index_expr + ON concur_exprs_tab ((c1::text COLLATE "C")); + +CREATE UNIQUE INDEX concur_exprs_index_pred ON concur_exprs_tab (c1) + WHERE (c1::text > 500000000::text COLLATE "C"); + +CREATE UNIQUE INDEX concur_exprs_index_pred_2 + ON concur_exprs_tab ((1 / c1)) + WHERE ('-H') >= (c2::TEXT) COLLATE "C"; + +ALTER INDEX concur_exprs_index_expr ALTER COLUMN 1 SET STATISTICS 100; + +ANALYZE concur_exprs_tab; + +SELECT starelid::regclass, count(*) FROM pg_statistic WHERE starelid IN ( + 'concur_exprs_index_expr'::regclass, + 'concur_exprs_index_pred'::regclass, + 'concur_exprs_index_pred_2'::regclass) + GROUP BY starelid ORDER BY starelid::regclass::text; + +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); + +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); + +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); + +REINDEX TABLE CONCURRENTLY concur_exprs_tab; + +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); + +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); + +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); + +ALTER TABLE concur_exprs_tab ALTER c2 TYPE TEXT; + +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); + +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); + +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); + +SELECT starelid::regclass, count(*) FROM pg_statistic WHERE starelid IN ( + 'concur_exprs_index_expr'::regclass, + 'concur_exprs_index_pred'::regclass, + 'concur_exprs_index_pred_2'::regclass) + GROUP BY starelid ORDER BY starelid::regclass::text; + +SELECT attrelid::regclass, attnum, attstattarget + FROM pg_attribute WHERE attrelid IN ( + 'concur_exprs_index_expr'::regclass, + 'concur_exprs_index_pred'::regclass, + 'concur_exprs_index_pred_2'::regclass) + ORDER BY attrelid::regclass::text, attnum; + +DROP TABLE concur_exprs_tab; + +CREATE TEMP TABLE concur_temp_tab_1 (c1 int, c2 text) + ON COMMIT PRESERVE ROWS; + +INSERT INTO concur_temp_tab_1 VALUES (1, 'foo'), (2, 'bar'); + +CREATE INDEX concur_temp_ind_1 ON concur_temp_tab_1(c2); + +REINDEX TABLE CONCURRENTLY concur_temp_tab_1; + +REINDEX INDEX CONCURRENTLY concur_temp_ind_1; + +BEGIN; + +REINDEX INDEX CONCURRENTLY concur_temp_ind_1; + +COMMIT; + +CREATE INDEX concur_temp_ind_2 ON concur_temp_tab_2(c2); + +REINDEX TABLE CONCURRENTLY concur_temp_tab_2; + +REINDEX INDEX CONCURRENTLY concur_temp_ind_2; + +BEGIN; + +CREATE TEMP TABLE concur_temp_tab_3 (c1 int, c2 text) + ON COMMIT PRESERVE ROWS; + +INSERT INTO concur_temp_tab_3 VALUES (1, 'foo'), (2, 'bar'); + +CREATE INDEX concur_temp_ind_3 ON concur_temp_tab_3(c2); + +REINDEX INDEX CONCURRENTLY concur_temp_ind_3; + +COMMIT; + +CREATE TABLE reindex_temp_before AS +SELECT oid, relname, relfilenode, relkind, reltoastrelid + FROM pg_class + WHERE relname IN ('concur_temp_ind_1', 'concur_temp_ind_2'); + +SELECT pg_my_temp_schema()::regnamespace as temp_schema_name ; + +SELECT b.relname, + b.relkind, + CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' + ELSE 'relfilenode has changed' END + FROM reindex_temp_before b JOIN pg_class a ON b.oid = a.oid + ORDER BY 1; + +DROP TABLE concur_temp_tab_1, concur_temp_tab_2, reindex_temp_before; + +SELECT * FROM tenk1 WHERE unique1 < 1 OR hundred < 2; + +SELECT * FROM tenk1 WHERE unique1 < 1 OR unique1 < 3 OR hundred < 2; + +CREATE TABLE bitmap_split_or (a int NOT NULL, b int NOT NULL, c int NOT NULL); + +INSERT INTO bitmap_split_or (SELECT 1, 1, i FROM generate_series(1, 1000) i); + +INSERT INTO bitmap_split_or (select i, 2, 2 FROM generate_series(1, 1000) i); + +VACUUM ANALYZE bitmap_split_or; + +CREATE INDEX t_b_partial_1_idx ON bitmap_split_or (b) WHERE a = 1; + +CREATE INDEX t_b_partial_2_idx ON bitmap_split_or (b) WHERE a = 2; + +SELECT * FROM bitmap_split_or WHERE (a = 1 OR a = 2) AND b = 2; + +DROP INDEX t_b_partial_1_idx; + +DROP INDEX t_b_partial_2_idx; + +CREATE INDEX t_a_b_idx ON bitmap_split_or (a, b); + +CREATE INDEX t_b_c_idx ON bitmap_split_or (b, c); + +CREATE STATISTICS t_a_b_stat (mcv) ON a, b FROM bitmap_split_or; + +CREATE STATISTICS t_b_c_stat (mcv) ON b, c FROM bitmap_split_or; + +ANALYZE bitmap_split_or; + +SELECT * FROM bitmap_split_or t1, bitmap_split_or t2 +WHERE t1.a = t2.b OR t1.a = 2; + +SELECT * FROM bitmap_split_or WHERE a = 1 AND (b = 1 OR b = 2) AND c = 2; + +DROP TABLE bitmap_split_or; + +REINDEX SCHEMA schema_to_reindex; + +CREATE SCHEMA schema_to_reindex; + +SET search_path = 'schema_to_reindex'; + +CREATE TABLE table1(col1 SERIAL PRIMARY KEY); + +INSERT INTO table1 SELECT generate_series(1,400); + +CREATE TABLE table2(col1 SERIAL PRIMARY KEY, col2 TEXT NOT NULL); + +INSERT INTO table2 SELECT generate_series(1,400), 'abc'; + +CREATE INDEX ON table2(col2); + +CREATE MATERIALIZED VIEW matview AS SELECT col1 FROM table2; + +CREATE INDEX ON matview(col1); + +CREATE VIEW view AS SELECT col2 FROM table2; + +CREATE TABLE reindex_before AS +SELECT oid, relname, relfilenode, relkind, reltoastrelid + FROM pg_class + where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); + +INSERT INTO reindex_before +SELECT oid, 'pg_toast_TABLE', relfilenode, relkind, reltoastrelid +FROM pg_class WHERE oid IN + (SELECT reltoastrelid FROM reindex_before WHERE reltoastrelid > 0); + +INSERT INTO reindex_before +SELECT oid, 'pg_toast_TABLE_index', relfilenode, relkind, reltoastrelid +FROM pg_class where oid in + (select indexrelid from pg_index where indrelid in + (select reltoastrelid from reindex_before where reltoastrelid > 0)); + +REINDEX SCHEMA schema_to_reindex; + +CREATE TABLE reindex_after AS SELECT oid, relname, relfilenode, relkind + FROM pg_class + where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); + +SELECT b.relname, + b.relkind, + CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' + ELSE 'relfilenode has changed' END + FROM reindex_before b JOIN pg_class a ON b.oid = a.oid + ORDER BY 1; + +REINDEX SCHEMA schema_to_reindex; + +BEGIN; + +REINDEX SCHEMA schema_to_reindex; + +END; + +REINDEX SCHEMA CONCURRENTLY schema_to_reindex; + +CREATE ROLE regress_reindexuser NOLOGIN; + +SET SESSION ROLE regress_reindexuser; + +REINDEX SCHEMA schema_to_reindex; + +RESET ROLE; + +GRANT USAGE ON SCHEMA pg_toast TO regress_reindexuser; + +SET SESSION ROLE regress_reindexuser; + +REINDEX TABLE pg_toast.pg_toast_1262; + +REINDEX INDEX pg_toast.pg_toast_1262_index; + +RESET ROLE; + +REVOKE USAGE ON SCHEMA pg_toast FROM regress_reindexuser; + +DROP ROLE regress_reindexuser; + +DROP SCHEMA schema_to_reindex CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_index_spgist_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_index_spgist_60.sql new file mode 100644 index 000000000..aa222d6d4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_index_spgist_60.sql @@ -0,0 +1,444 @@ +CREATE TABLE quad_point_tbl AS + SELECT point(unique1,unique2) AS p FROM tenk1; + +INSERT INTO quad_point_tbl + SELECT '(333.0,400.0)'::point FROM generate_series(1,1000); + +INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL); + +CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p); + +CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl; + +CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops); + +CREATE TABLE radix_text_tbl AS + SELECT name AS t FROM road WHERE name !~ '^[0-9]'; + +INSERT INTO radix_text_tbl + SELECT 'P0123456789abcdef' FROM generate_series(1,1000); + +INSERT INTO radix_text_tbl VALUES ('P0123456789abcde'); + +INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF'); + +CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t); + +SET enable_seqscan = ON; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = OFF; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM quad_point_tbl; + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +CREATE TEMP TABLE quad_point_tbl_ord_seq1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; + +CREATE TEMP TABLE quad_point_tbl_ord_seq2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +CREATE TEMP TABLE quad_point_tbl_ord_seq3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +SET enable_seqscan = OFF; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = OFF; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM quad_point_tbl; + +SELECT count(*) FROM quad_point_tbl; + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; + +CREATE TEMP TABLE quad_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; + +SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN quad_point_tbl_ord_idx1 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +CREATE TEMP TABLE quad_point_tbl_ord_idx2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN quad_point_tbl_ord_idx2 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; + +CREATE TEMP TABLE quad_point_tbl_ord_idx3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN quad_point_tbl_ord_idx3 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl; + +CREATE TEMP TABLE kd_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl; + +SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN kd_point_tbl_ord_idx1 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +CREATE TEMP TABLE kd_point_tbl_ord_idx2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN kd_point_tbl_ord_idx2 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM kd_point_tbl WHERE p IS NOT NULL; + +CREATE TEMP TABLE kd_point_tbl_ord_idx3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM kd_point_tbl WHERE p IS NOT NULL; + +SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN kd_point_tbl_ord_idx3 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +SET extra_float_digits = 0; + +CREATE INDEX ON quad_point_tbl_ord_seq1 USING spgist(p) INCLUDE(dist); + +SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10; + +SELECT p, dist FROM quad_point_tbl_ord_seq1 ORDER BY p <-> '0,0' LIMIT 10; + +RESET extra_float_digits; + +SELECT (SELECT p FROM kd_point_tbl ORDER BY p <-> pt, p <-> '0,0' LIMIT 1) +FROM (VALUES (point '1,2'), (NULL), ('1234,5678')) pts(pt); + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth'); + +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth'); + +SET enable_seqscan = OFF; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = ON; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM quad_point_tbl; + +SELECT count(*) FROM quad_point_tbl; + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p <<| '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p |>> '(5000, 4000)'; + +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth'); + +SELECT count(*) FROM radix_text_tbl WHERE starts_with(t, 'Worth'); + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_misc_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_misc_60.sql new file mode 100644 index 000000000..7dac1e456 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_misc_60.sql @@ -0,0 +1,235 @@ +CREATE TABLE a_star ( + class char, + a int4 +); + +CREATE TABLE b_star ( + b text +) INHERITS (a_star); + +CREATE TABLE c_star ( + c name +) INHERITS (a_star); + +CREATE TABLE d_star ( + d float8 +) INHERITS (b_star, c_star); + +CREATE TABLE e_star ( + e int2 +) INHERITS (c_star); + +CREATE TABLE f_star ( + f polygon +) INHERITS (e_star); + +INSERT INTO a_star (class, a) VALUES ('a', 1); + +INSERT INTO a_star (class, a) VALUES ('a', 2); + +INSERT INTO a_star (class) VALUES ('a'); + +INSERT INTO b_star (class, a, b) VALUES ('b', 3, 'mumble'::text); + +INSERT INTO b_star (class, a) VALUES ('b', 4); + +INSERT INTO b_star (class, b) VALUES ('b', 'bumble'::text); + +INSERT INTO b_star (class) VALUES ('b'); + +INSERT INTO c_star (class, a, c) VALUES ('c', 5, 'hi mom'::name); + +INSERT INTO c_star (class, a) VALUES ('c', 6); + +INSERT INTO c_star (class, c) VALUES ('c', 'hi paul'::name); + +INSERT INTO c_star (class) VALUES ('c'); + +INSERT INTO d_star (class, a, b, c, d) + VALUES ('d', 7, 'grumble'::text, 'hi sunita'::name, '0.0'::float8); + +INSERT INTO d_star (class, a, b, c) + VALUES ('d', 8, 'stumble'::text, 'hi koko'::name); + +INSERT INTO d_star (class, a, b, d) + VALUES ('d', 9, 'rumble'::text, '1.1'::float8); + +INSERT INTO d_star (class, a, c, d) + VALUES ('d', 10, 'hi kristin'::name, '10.01'::float8); + +INSERT INTO d_star (class, b, c, d) + VALUES ('d', 'crumble'::text, 'hi boris'::name, '100.001'::float8); + +INSERT INTO d_star (class, a, b) + VALUES ('d', 11, 'fumble'::text); + +INSERT INTO d_star (class, a, c) + VALUES ('d', 12, 'hi avi'::name); + +INSERT INTO d_star (class, a, d) + VALUES ('d', 13, '1000.0001'::float8); + +INSERT INTO d_star (class, b, c) + VALUES ('d', 'tumble'::text, 'hi andrew'::name); + +INSERT INTO d_star (class, b, d) + VALUES ('d', 'humble'::text, '10000.00001'::float8); + +INSERT INTO d_star (class, c, d) + VALUES ('d', 'hi ginger'::name, '100000.000001'::float8); + +INSERT INTO d_star (class, a) VALUES ('d', 14); + +INSERT INTO d_star (class, b) VALUES ('d', 'jumble'::text); + +INSERT INTO d_star (class, c) VALUES ('d', 'hi jolly'::name); + +INSERT INTO d_star (class, d) VALUES ('d', '1000000.0000001'::float8); + +INSERT INTO d_star (class) VALUES ('d'); + +INSERT INTO e_star (class, a, c, e) + VALUES ('e', 15, 'hi carol'::name, '-1'::int2); + +INSERT INTO e_star (class, a, c) + VALUES ('e', 16, 'hi bob'::name); + +INSERT INTO e_star (class, a, e) + VALUES ('e', 17, '-2'::int2); + +INSERT INTO e_star (class, c, e) + VALUES ('e', 'hi michelle'::name, '-3'::int2); + +INSERT INTO e_star (class, a) + VALUES ('e', 18); + +INSERT INTO e_star (class, c) + VALUES ('e', 'hi elisa'::name); + +INSERT INTO e_star (class, e) + VALUES ('e', '-4'::int2); + +INSERT INTO f_star (class, a, c, e, f) + VALUES ('f', 19, 'hi claire'::name, '-5'::int2, '(1,3),(2,4)'::polygon); + +INSERT INTO f_star (class, a, c, e) + VALUES ('f', 20, 'hi mike'::name, '-6'::int2); + +INSERT INTO f_star (class, a, c, f) + VALUES ('f', 21, 'hi marcel'::name, '(11,44),(22,55),(33,66)'::polygon); + +INSERT INTO f_star (class, a, e, f) + VALUES ('f', 22, '-7'::int2, '(111,555),(222,666),(333,777),(444,888)'::polygon); + +INSERT INTO f_star (class, c, e, f) + VALUES ('f', 'hi keith'::name, '-8'::int2, + '(1111,3333),(2222,4444)'::polygon); + +INSERT INTO f_star (class, a, c) + VALUES ('f', 24, 'hi marc'::name); + +INSERT INTO f_star (class, a, e) + VALUES ('f', 25, '-9'::int2); + +INSERT INTO f_star (class, a, f) + VALUES ('f', 26, '(11111,33333),(22222,44444)'::polygon); + +INSERT INTO f_star (class, c, e) + VALUES ('f', 'hi allison'::name, '-10'::int2); + +INSERT INTO f_star (class, c, f) + VALUES ('f', 'hi jeff'::name, + '(111111,333333),(222222,444444)'::polygon); + +INSERT INTO f_star (class, e, f) + VALUES ('f', '-11'::int2, '(1111111,3333333),(2222222,4444444)'::polygon); + +INSERT INTO f_star (class, a) VALUES ('f', 27); + +INSERT INTO f_star (class, c) VALUES ('f', 'hi carl'::name); + +INSERT INTO f_star (class, e) VALUES ('f', '-12'::int2); + +INSERT INTO f_star (class, f) + VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon); + +INSERT INTO f_star (class) VALUES ('f'); + +ANALYZE a_star; + +ANALYZE b_star; + +ANALYZE c_star; + +ANALYZE d_star; + +ANALYZE e_star; + +ANALYZE f_star; + +SELECT * FROM a_star*; + +SELECT * + FROM b_star* x + WHERE x.b = text 'bumble' or x.a < 3; + +SELECT class, a + FROM c_star* x + WHERE x.c ~ text 'hi'; + +SELECT class, b, c + FROM d_star* x + WHERE x.a < 100; + +SELECT class, c FROM e_star* x WHERE x.c NOTNULL; + +SELECT * FROM f_star* x WHERE x.c ISNULL; + +SELECT sum(a) FROM a_star*; + +SELECT class, sum(a) FROM a_star* GROUP BY class ORDER BY class; + +ALTER TABLE f_star RENAME COLUMN f TO ff; + +ALTER TABLE e_star* RENAME COLUMN e TO ee; + +ALTER TABLE d_star* RENAME COLUMN d TO dd; + +ALTER TABLE c_star* RENAME COLUMN c TO cc; + +ALTER TABLE b_star* RENAME COLUMN b TO bb; + +ALTER TABLE a_star* RENAME COLUMN a TO aa; + +SELECT class, aa + FROM a_star* x + WHERE aa ISNULL; + +ALTER TABLE a_star RENAME COLUMN aa TO foo; + +SELECT class, foo + FROM a_star* x + WHERE x.foo >= 2; + +ALTER TABLE a_star RENAME COLUMN foo TO aa; + +SELECT * + from a_star* + WHERE aa < 1000; + +ALTER TABLE f_star ADD COLUMN f int4; + +UPDATE f_star SET f = 10; + +ALTER TABLE e_star* ADD COLUMN e int4; + +SELECT * FROM e_star*; + +ALTER TABLE a_star* ADD COLUMN a text; + +SELECT relname, reltoastrelid <> 0 AS has_toast_table + FROM pg_class + WHERE oid::regclass IN ('a_star', 'c_star') + ORDER BY 1; + +SELECT class, aa, a FROM a_star*; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_operator_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_operator_60.sql new file mode 100644 index 000000000..87a5ff17f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_operator_60.sql @@ -0,0 +1,300 @@ +CREATE OPERATOR ## ( + leftarg = path, + rightarg = path, + function = path_inter, + commutator = ## +); + +CREATE OPERATOR @#@ ( + rightarg = int8, -- prefix + procedure = factorial +); + +CREATE OPERATOR #%# ( + leftarg = int8, -- fail, postfix is no longer supported + procedure = factorial +); + +SELECT @#@ 24; + +select @@##@@ 24; + +set search_path = pg_catalog; + +select @#@ 24; + +reset search_path; + +select @#@ 24.0; + +COMMENT ON OPERATOR ###### (NONE, int4) IS 'bad prefix'; + +COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad postfix'; + +COMMENT ON OPERATOR ###### (int4, int8) IS 'bad infix'; + +DROP OPERATOR ###### (NONE, int4); + +DROP OPERATOR ###### (int4, NONE); + +DROP OPERATOR ###### (int4, int8); + +CREATE OPERATOR !=- ( + rightarg = int8, + procedure = factorial +); + +SELECT !=- 10; + +SELECT 2 !=/**/ 1, 2 !=/**/ 2; + +SELECT 2 !=-- comment to be removed by psql + 1; + +DO $$ -- use DO to protect -- from psql + declare r boolean; + begin + execute $e$ select 2 !=-- comment + 1 $e$ into r; + raise info 'r = %', r; + end; +$$; + +SELECT true<>-1 BETWEEN 1 AND 1; + +SELECT false<>/**/1 BETWEEN 1 AND 1; + +SELECT false<=-1 BETWEEN 1 AND 1; + +SELECT false>=-1 BETWEEN 1 AND 1; + +SELECT 2<=/**/3, 3>=/**/2, 2<>/**/3; + +SELECT 3<=/**/2, 2>=/**/3, 2<>/**/2; + +BEGIN TRANSACTION; + +CREATE ROLE regress_rol_op1; + +CREATE SCHEMA schema_op1; + +GRANT USAGE ON SCHEMA schema_op1 TO PUBLIC; + +REVOKE USAGE ON SCHEMA schema_op1 FROM regress_rol_op1; + +SET ROLE regress_rol_op1; + +CREATE OPERATOR schema_op1.#*# ( + rightarg = int8, + procedure = factorial +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OPERATOR #*# ( + leftarg = SETOF int8, + procedure = factorial +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OPERATOR #*# ( + rightarg = SETOF int8, + procedure = factorial +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OR REPLACE FUNCTION fn_op2(boolean, boolean) +RETURNS boolean AS $$ + SELECT NULL::BOOLEAN; +$$ LANGUAGE sql IMMUTABLE; + +CREATE OPERATOR === ( + LEFTARG = boolean, + RIGHTARG = boolean, + PROCEDURE = fn_op2, + COMMUTATOR = ===, + NEGATOR = !==, + RESTRICT = contsel, + JOIN = contjoinsel, + SORT1, SORT2, LTCMP, GTCMP, HASHES, MERGES +); + +ROLLBACK; + +CREATE OPERATOR #@%# ( + rightarg = int8, + procedure = factorial, + invalid_att = int8 +); + +CREATE OPERATOR #@%# ( + procedure = factorial +); + +CREATE OPERATOR #@%# ( + rightarg = int8 +); + +BEGIN TRANSACTION; + +CREATE ROLE regress_rol_op3; + +CREATE TYPE type_op3 AS ENUM ('new', 'open', 'closed'); + +CREATE FUNCTION fn_op3(type_op3, int8) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE; + +REVOKE USAGE ON TYPE type_op3 FROM regress_rol_op3; + +REVOKE USAGE ON TYPE type_op3 FROM PUBLIC; + +SET ROLE regress_rol_op3; + +CREATE OPERATOR #*# ( + leftarg = type_op3, + rightarg = int8, + procedure = fn_op3 +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE ROLE regress_rol_op4; + +CREATE TYPE type_op4 AS ENUM ('new', 'open', 'closed'); + +CREATE FUNCTION fn_op4(int8, type_op4) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE; + +REVOKE USAGE ON TYPE type_op4 FROM regress_rol_op4; + +REVOKE USAGE ON TYPE type_op4 FROM PUBLIC; + +SET ROLE regress_rol_op4; + +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = type_op4, + procedure = fn_op4 +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE ROLE regress_rol_op5; + +CREATE TYPE type_op5 AS ENUM ('new', 'open', 'closed'); + +CREATE FUNCTION fn_op5(int8, int8) +RETURNS int8 AS $$ + SELECT NULL::int8; +$$ LANGUAGE sql IMMUTABLE; + +REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM regress_rol_op5; + +REVOKE EXECUTE ON FUNCTION fn_op5(int8, int8) FROM PUBLIC; + +SET ROLE regress_rol_op5; + +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = int8, + procedure = fn_op5 +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE ROLE regress_rol_op6; + +CREATE TYPE type_op6 AS ENUM ('new', 'open', 'closed'); + +CREATE FUNCTION fn_op6(int8, int8) +RETURNS type_op6 AS $$ + SELECT NULL::type_op6; +$$ LANGUAGE sql IMMUTABLE; + +REVOKE USAGE ON TYPE type_op6 FROM regress_rol_op6; + +REVOKE USAGE ON TYPE type_op6 FROM PUBLIC; + +SET ROLE regress_rol_op6; + +CREATE OPERATOR #*# ( + leftarg = int8, + rightarg = int8, + procedure = fn_op6 +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + negator = === +); + +ROLLBACK; + +BEGIN TRANSACTION; + +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + commutator = ===!!! +); + +CREATE OPERATOR ===!!! ( + leftarg = integer, + rightarg = integer, + procedure = int4ne, + negator = ===!!! +); + +ROLLBACK; + +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + commutator = = +); + +CREATE OPERATOR === ( + leftarg = integer, + rightarg = integer, + procedure = int4eq, + negator = <> +); + +CREATE OPERATOR === +( + "Leftarg" = box, + "Rightarg" = box, + "Procedure" = area_equal_function, + "Commutator" = ===, + "Negator" = !==, + "Restrict" = area_restriction_function, + "Join" = area_join_function, + "Hashes", + "Merges" +); diff --git a/crates/pgt_pretty_print/tests/data/multi/create_procedure_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_procedure_60.sql new file mode 100644 index 000000000..515a958e6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_procedure_60.sql @@ -0,0 +1,279 @@ +CALL nonexistent(); + +CALL random(); + +CREATE FUNCTION cp_testfunc1(a int) RETURNS int LANGUAGE SQL AS $$ SELECT a $$; + +CREATE TABLE cp_test (a int, b text); + +CREATE PROCEDURE ptest1(x text) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES (1, x); +$$; + +SELECT pg_get_functiondef('ptest1'::regproc); + +SELECT ptest1('x'); + +CALL ptest1('a'); + +CALL ptest1('xy' || 'zzy'); + +CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1)); + +SELECT * FROM cp_test ORDER BY b COLLATE "C"; + +INSERT INTO cp_test VALUES (1, x); + +END; + +SELECT pg_get_functiondef('ptest1s'::regproc); + +CALL ptest1s('b'); + +SELECT * FROM cp_test ORDER BY b COLLATE "C"; + +CREATE TABLE x (a int); + +END; + +CREATE PROCEDURE ptest2() +LANGUAGE SQL +AS $$ +SELECT 5; +$$; + +CALL ptest2(); + +TRUNCATE cp_test; + +CREATE PROCEDURE ptest3(y text) +LANGUAGE SQL +AS $$ +CALL ptest1(y); +CALL ptest1($1); +$$; + +CALL ptest3('b'); + +SELECT * FROM cp_test; + +CREATE PROCEDURE ptest4a(INOUT a int, INOUT b int) +LANGUAGE SQL +AS $$ +SELECT 1, 2; +$$; + +CALL ptest4a(NULL, NULL); + +CREATE PROCEDURE ptest4b(INOUT b int, INOUT a int) +LANGUAGE SQL +AS $$ +CALL ptest4a(a, b); -- error, not supported +$$; + +CREATE PROCEDURE ptest4c(INOUT comp int8_tbl) +LANGUAGE SQL +AS $$ +SELECT ROW(1, 2); +$$; + +CALL ptest4c(NULL); + +DROP PROCEDURE ptest4a, ptest4c; + +CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int default 100) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES(a, b); +INSERT INTO cp_test VALUES(c, b); +$$; + +TRUNCATE cp_test; + +CALL ptest5(10, 'Hello', 20); + +CALL ptest5(10, 'Hello'); + +CALL ptest5(10, b => 'Hello'); + +CALL ptest5(b => 'Hello', a => 10); + +SELECT * FROM cp_test; + +CREATE PROCEDURE ptest6(a int, b anyelement) +LANGUAGE SQL +AS $$ +SELECT NULL::int; +$$; + +CALL ptest6(1, 2); + +CREATE PROCEDURE ptest6a(inout a anyelement, out b anyelement) +LANGUAGE SQL +AS $$ +SELECT $1, $1; +$$; + +CALL ptest6a(1, null); + +CALL ptest6a(1.1, null); + +CREATE PROCEDURE ptest6b(a anyelement, out b anyelement, out c anyarray) +LANGUAGE SQL +AS $$ +SELECT $1, array[$1]; +$$; + +CALL ptest6b(1, null, null); + +CALL ptest6b(1.1, null, null); + +CREATE PROCEDURE ptest6c(inout a anyelement, inout b anyelement) +LANGUAGE SQL +AS $$ +SELECT $1, 1; +$$; + +CALL ptest6c(1, null); + +CALL ptest6c(1.1, null); + +CREATE PROCEDURE ptest7(a text, b text) +LANGUAGE SQL +AS $$ +SELECT a = b; +$$; + +CALL ptest7(least('a', 'b'), 'a'); + +CREATE PROCEDURE ptest8(x text) +BEGIN ATOMIC +END; + +SELECT pg_get_functiondef('ptest8'::regproc); + +CALL ptest8(''); + +CREATE PROCEDURE ptest9(OUT a int) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES (1, 'a'); +SELECT 1; +$$; + +CALL ptest9(NULL); + +CALL ptest9(1/0); + +CALL ptest9(1./0.); + +CREATE PROCEDURE ptest10(OUT a int, IN b int, IN c int) +LANGUAGE SQL AS $$ SELECT b - c $$; + +CALL ptest10(null, 7, 4); + +CALL ptest10(a => null, b => 8, c => 2); + +CALL ptest10(null, 7, c => 2); + +CALL ptest10(null, c => 4, b => 11); + +CALL ptest10(b => 8, c => 2, a => 0); + +CREATE PROCEDURE ptest11(a OUT int, VARIADIC b int[]) LANGUAGE SQL + AS $$ SELECT b[1] + b[2] $$; + +CALL ptest11(null, 11, 12, 13); + +CREATE PROCEDURE ptest10(IN a int, IN b int, IN c int) +LANGUAGE SQL AS $$ SELECT a + b - c $$; + +drop procedure ptest10; + +drop procedure ptest10(int, int, int); + +begin; + +drop procedure ptest10(out int, int, int); + +drop procedure ptest10(int, int, int); + +rollback; + +begin; + +drop procedure ptest10(in int, int, int); + +drop procedure ptest10(int, int, int); + +rollback; + +CALL version(); + +CALL sum(1); + +CREATE PROCEDURE ptestx() LANGUAGE SQL WINDOW AS $$ INSERT INTO cp_test VALUES (1, 'a') $$; + +CREATE PROCEDURE ptestx() LANGUAGE SQL STRICT AS $$ INSERT INTO cp_test VALUES (1, 'a') $$; + +CREATE PROCEDURE ptestx(a VARIADIC int[], b OUT int) LANGUAGE SQL + AS $$ SELECT a[1] $$; + +CREATE PROCEDURE ptestx(a int DEFAULT 42, b OUT int) LANGUAGE SQL + AS $$ SELECT a $$; + +ALTER PROCEDURE ptest1(text) STRICT; + +ALTER FUNCTION ptest1(text) VOLATILE; + +ALTER PROCEDURE cp_testfunc1(int) VOLATILE; + +ALTER PROCEDURE nonexistent() VOLATILE; + +DROP FUNCTION ptest1(text); + +DROP PROCEDURE cp_testfunc1(int); + +DROP PROCEDURE nonexistent(); + +CREATE USER regress_cp_user1; + +GRANT INSERT ON cp_test TO regress_cp_user1; + +REVOKE EXECUTE ON PROCEDURE ptest1(text) FROM PUBLIC; + +SET ROLE regress_cp_user1; + +CALL ptest1('a'); + +RESET ROLE; + +GRANT EXECUTE ON PROCEDURE ptest1(text) TO regress_cp_user1; + +SET ROLE regress_cp_user1; + +CALL ptest1('a'); + +RESET ROLE; + +ALTER ROUTINE cp_testfunc1(int) RENAME TO cp_testfunc1a; + +ALTER ROUTINE cp_testfunc1a RENAME TO cp_testfunc1; + +ALTER ROUTINE ptest1(text) RENAME TO ptest1a; + +ALTER ROUTINE ptest1a RENAME TO ptest1; + +DROP ROUTINE cp_testfunc1(int); + +DROP PROCEDURE ptest1; + +DROP PROCEDURE ptest1s; + +DROP PROCEDURE ptest2; + +DROP TABLE cp_test; + +DROP USER regress_cp_user1; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_role_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_role_60.sql new file mode 100644 index 000000000..88e3c92aa --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_role_60.sql @@ -0,0 +1,277 @@ +CREATE ROLE regress_role_super SUPERUSER; + +CREATE ROLE regress_role_admin CREATEDB CREATEROLE REPLICATION BYPASSRLS; + +GRANT CREATE ON DATABASE regression TO regress_role_admin WITH GRANT OPTION; + +CREATE ROLE regress_role_limited_admin CREATEROLE; + +CREATE ROLE regress_role_normal; + +SET SESSION AUTHORIZATION regress_role_limited_admin; + +CREATE ROLE regress_nosuch_superuser SUPERUSER; + +CREATE ROLE regress_nosuch_replication_bypassrls REPLICATION BYPASSRLS; + +CREATE ROLE regress_nosuch_replication REPLICATION; + +CREATE ROLE regress_nosuch_bypassrls BYPASSRLS; + +CREATE ROLE regress_nosuch_createdb CREATEDB; + +CREATE ROLE regress_role_limited; + +ALTER ROLE regress_role_limited SUPERUSER; + +ALTER ROLE regress_role_limited REPLICATION; + +ALTER ROLE regress_role_limited CREATEDB; + +ALTER ROLE regress_role_limited BYPASSRLS; + +DROP ROLE regress_role_limited; + +SET SESSION AUTHORIZATION regress_role_admin; + +CREATE ROLE regress_replication_bypassrls REPLICATION BYPASSRLS; + +CREATE ROLE regress_replication REPLICATION; + +CREATE ROLE regress_bypassrls BYPASSRLS; + +CREATE ROLE regress_createdb CREATEDB; + +ALTER ROLE regress_replication NOREPLICATION; + +ALTER ROLE regress_replication REPLICATION; + +ALTER ROLE regress_bypassrls NOBYPASSRLS; + +ALTER ROLE regress_bypassrls BYPASSRLS; + +ALTER ROLE regress_createdb NOCREATEDB; + +ALTER ROLE regress_createdb CREATEDB; + +ALTER ROLE regress_createdb SUPERUSER; + +ALTER ROLE regress_createdb NOSUPERUSER; + +CREATE ROLE regress_createrole CREATEROLE NOINHERIT; + +GRANT CREATE ON DATABASE regression TO regress_createrole WITH GRANT OPTION; + +CREATE ROLE regress_login LOGIN; + +CREATE ROLE regress_inherit INHERIT; + +CREATE ROLE regress_connection_limit CONNECTION LIMIT 5; + +CREATE ROLE regress_encrypted_password ENCRYPTED PASSWORD 'foo'; + +CREATE ROLE regress_password_null PASSWORD NULL; + +CREATE ROLE regress_noiseword SYSID 12345; + +CREATE ROLE regress_nosuch_super IN ROLE regress_role_super; + +CREATE ROLE regress_nosuch_dbowner IN ROLE pg_database_owner; + +CREATE ROLE regress_inroles ROLE + regress_role_super, regress_createdb, regress_createrole, regress_login, + regress_inherit, regress_connection_limit, regress_encrypted_password, regress_password_null; + +CREATE ROLE regress_nosuch_recursive ROLE regress_nosuch_recursive; + +CREATE ROLE regress_adminroles ADMIN + regress_role_super, regress_createdb, regress_createrole, regress_login, + regress_inherit, regress_connection_limit, regress_encrypted_password, regress_password_null; + +CREATE ROLE regress_nosuch_admin_recursive ADMIN regress_nosuch_admin_recursive; + +SET SESSION AUTHORIZATION regress_createrole; + +CREATE DATABASE regress_nosuch_db; + +CREATE ROLE regress_plainrole; + +CREATE ROLE regress_rolecreator CREATEROLE; + +CREATE ROLE regress_hasprivs CREATEROLE LOGIN INHERIT CONNECTION LIMIT 5; + +COMMENT ON ROLE regress_hasprivs IS 'some comment'; + +ALTER ROLE regress_hasprivs RENAME TO regress_tenant; + +ALTER ROLE regress_tenant NOINHERIT NOLOGIN CONNECTION LIMIT 7; + +COMMENT ON ROLE regress_role_normal IS 'some comment'; + +ALTER ROLE regress_role_normal RENAME TO regress_role_abnormal; + +ALTER ROLE regress_role_normal NOINHERIT NOLOGIN CONNECTION LIMIT 7; + +SET SESSION AUTHORIZATION regress_tenant; + +CREATE TABLE tenant_table (i integer); + +CREATE INDEX tenant_idx ON tenant_table(i); + +CREATE VIEW tenant_view AS SELECT * FROM pg_catalog.pg_class; + +REVOKE ALL PRIVILEGES ON tenant_table FROM PUBLIC; + +SET SESSION AUTHORIZATION regress_createrole; + +DROP INDEX tenant_idx; + +ALTER TABLE tenant_table ADD COLUMN t text; + +DROP TABLE tenant_table; + +ALTER VIEW tenant_view OWNER TO regress_role_admin; + +DROP VIEW tenant_view; + +CREATE SCHEMA regress_tenant_schema AUTHORIZATION regress_tenant; + +REASSIGN OWNED BY regress_tenant TO regress_createrole; + +SET createrole_self_grant = 'set, inherit'; + +CREATE ROLE regress_tenant2; + +GRANT CREATE ON DATABASE regression TO regress_tenant2; + +SET SESSION AUTHORIZATION regress_tenant2; + +CREATE TABLE tenant2_table (i integer); + +REVOKE ALL PRIVILEGES ON tenant2_table FROM PUBLIC; + +SET SESSION AUTHORIZATION regress_createrole; + +CREATE SCHEMA regress_tenant2_schema AUTHORIZATION regress_tenant2; + +ALTER SCHEMA regress_tenant2_schema OWNER TO regress_createrole; + +ALTER TABLE tenant2_table OWNER TO regress_createrole; + +ALTER TABLE tenant2_table OWNER TO regress_tenant2; + +REVOKE INHERIT OPTION FOR regress_tenant2 FROM regress_createrole; + +ALTER SCHEMA regress_tenant2_schema OWNER TO regress_tenant2; + +ALTER TABLE tenant2_table OWNER TO regress_createrole; + +GRANT regress_tenant2 TO regress_createrole WITH INHERIT TRUE, SET FALSE; + +ALTER TABLE tenant2_table OWNER TO regress_createrole; + +ALTER TABLE tenant2_table OWNER TO regress_tenant2; + +DROP TABLE tenant2_table; + +CREATE ROLE regress_read_all_data IN ROLE pg_read_all_data; + +CREATE ROLE regress_write_all_data IN ROLE pg_write_all_data; + +CREATE ROLE regress_monitor IN ROLE pg_monitor; + +CREATE ROLE regress_read_all_settings IN ROLE pg_read_all_settings; + +CREATE ROLE regress_read_all_stats IN ROLE pg_read_all_stats; + +CREATE ROLE regress_stat_scan_tables IN ROLE pg_stat_scan_tables; + +CREATE ROLE regress_read_server_files IN ROLE pg_read_server_files; + +CREATE ROLE regress_write_server_files IN ROLE pg_write_server_files; + +CREATE ROLE regress_execute_server_program IN ROLE pg_execute_server_program; + +CREATE ROLE regress_signal_backend IN ROLE pg_signal_backend; + +DROP ROLE regress_tenant; + +SET SESSION AUTHORIZATION regress_role_admin; + +DROP ROLE regress_nosuch_superuser; + +DROP ROLE regress_nosuch_replication_bypassrls; + +DROP ROLE regress_nosuch_replication; + +DROP ROLE regress_nosuch_bypassrls; + +DROP ROLE regress_nosuch_super; + +DROP ROLE regress_nosuch_dbowner; + +DROP ROLE regress_nosuch_recursive; + +DROP ROLE regress_nosuch_admin_recursive; + +DROP ROLE regress_plainrole; + +REVOKE CREATE ON DATABASE regression FROM regress_createrole CASCADE; + +DROP ROLE regress_replication_bypassrls; + +DROP ROLE regress_replication; + +DROP ROLE regress_bypassrls; + +DROP ROLE regress_createdb; + +DROP ROLE regress_createrole; + +DROP ROLE regress_login; + +DROP ROLE regress_inherit; + +DROP ROLE regress_connection_limit; + +DROP ROLE regress_encrypted_password; + +DROP ROLE regress_password_null; + +DROP ROLE regress_noiseword; + +DROP ROLE regress_inroles; + +DROP ROLE regress_adminroles; + +DROP ROLE regress_role_super; + +DROP ROLE regress_role_admin; + +DROP ROLE regress_rolecreator; + +RESET SESSION AUTHORIZATION; + +REVOKE CREATE ON DATABASE regression FROM regress_role_admin CASCADE; + +DROP INDEX tenant_idx; + +DROP TABLE tenant_table; + +DROP VIEW tenant_view; + +DROP SCHEMA regress_tenant2_schema; + +DROP ROLE regress_tenant, regress_tenant; + +DROP ROLE regress_tenant2; + +DROP ROLE regress_rolecreator; + +DROP ROLE regress_role_admin; + +DROP ROLE regress_role_limited_admin; + +DROP ROLE regress_role_super; + +DROP ROLE regress_role_normal; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_schema_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_schema_60.sql new file mode 100644 index 000000000..678d5fec8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_schema_60.sql @@ -0,0 +1,92 @@ +CREATE ROLE regress_create_schema_role SUPERUSER; + +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + +CREATE SEQUENCE schema_not_existing.seq; + +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + +CREATE TABLE schema_not_existing.tab (id int); + +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + +CREATE VIEW schema_not_existing.view AS SELECT 1; + +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + +CREATE INDEX ON schema_not_existing.tab (id); + +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + +CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func(); + +SET ROLE regress_create_schema_role; + +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + +CREATE SEQUENCE schema_not_existing.seq; + +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + +CREATE TABLE schema_not_existing.tab (id int); + +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + +CREATE VIEW schema_not_existing.view AS SELECT 1; + +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + +CREATE INDEX ON schema_not_existing.tab (id); + +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + +CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func(); + +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + +CREATE SEQUENCE schema_not_existing.seq; + +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + +CREATE TABLE schema_not_existing.tab (id int); + +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + +CREATE VIEW schema_not_existing.view AS SELECT 1; + +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + +CREATE INDEX ON schema_not_existing.tab (id); + +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + +CREATE TRIGGER schema_trig BEFORE INSERT ON schema_not_existing.tab + EXECUTE FUNCTION schema_trig.no_func(); + +RESET ROLE; + +CREATE SCHEMA AUTHORIZATION regress_create_schema_role + +CREATE TABLE regress_create_schema_role.tab (id int); + +DROP SCHEMA regress_create_schema_role CASCADE; + +SET ROLE regress_create_schema_role; + +CREATE SCHEMA AUTHORIZATION CURRENT_ROLE + +CREATE TABLE regress_create_schema_role.tab (id int); + +DROP SCHEMA regress_create_schema_role CASCADE; + +CREATE SCHEMA regress_schema_1 AUTHORIZATION CURRENT_ROLE + +CREATE TABLE regress_schema_1.tab (id int); + +DROP SCHEMA regress_schema_1 CASCADE; + +RESET ROLE; + +DROP ROLE regress_create_schema_role; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_table_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_table_60.sql new file mode 100644 index 000000000..ae5a4fa3d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_table_60.sql @@ -0,0 +1,797 @@ +CREATE TABLE unknowntab ( + u unknown -- fail +); + +CREATE TYPE unknown_comptype AS ( + u unknown -- fail +); + +CREATE TABLE tas_case WITH ("Fillfactor" = 10) AS SELECT 1 a; + +CREATE UNLOGGED TABLE unlogged1 (a int primary key); + +CREATE TEMPORARY TABLE unlogged2 (a int primary key); + +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname; + +REINDEX INDEX unlogged1_pkey; + +REINDEX INDEX unlogged2_pkey; + +SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname; + +DROP TABLE unlogged2; + +INSERT INTO unlogged1 VALUES (42); + +CREATE UNLOGGED TABLE public.unlogged2 (a int primary key); + +CREATE UNLOGGED TABLE pg_temp.unlogged3 (a int primary key); + +CREATE TABLE pg_temp.implicitly_temp (a int primary key); + +CREATE TEMP TABLE explicitly_temp (a int primary key); + +CREATE TEMP TABLE pg_temp.doubly_temp (a int primary key); + +CREATE TEMP TABLE public.temp_to_perm (a int primary key); + +DROP TABLE unlogged1, public.unlogged2; + +CREATE UNLOGGED TABLE unlogged1 (a int) PARTITION BY RANGE (a); + +CREATE TABLE unlogged1 (a int) PARTITION BY RANGE (a); + +ALTER TABLE unlogged1 SET LOGGED; + +ALTER TABLE unlogged1 SET UNLOGGED; + +DROP TABLE unlogged1; + +CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; + +CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; + +CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; + +DROP TABLE as_select1; + +PREPARE select1 AS SELECT 1 as a; + +CREATE TABLE as_select1 AS EXECUTE select1; + +CREATE TABLE as_select1 AS EXECUTE select1; + +SELECT * FROM as_select1; + +CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1; + +DROP TABLE as_select1; + +DEALLOCATE select1; + +SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);' +FROM generate_series(1, 1100) g(i) + +INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col'); + +SELECT firstc, lastc FROM extra_wide_table; + +CREATE TABLE withoid() WITH (oids); + +CREATE TABLE withoid() WITH (oids = true); + +CREATE TEMP TABLE withoutoid() WITHOUT OIDS; + +DROP TABLE withoutoid; + +CREATE TEMP TABLE withoutoid() WITH (oids = false); + +DROP TABLE withoutoid; + +CREATE TEMP TABLE relation_filenode_check(c1 int); + +SELECT relpersistence, + pg_filenode_relation (reltablespace, pg_relation_filenode(oid)) + FROM pg_class + WHERE relname = 'relation_filenode_check'; + +DROP TABLE relation_filenode_check; + +CREATE TABLE default_expr_column (id int DEFAULT (id)); + +CREATE TABLE default_expr_column (id int DEFAULT (bar.id)); + +CREATE TABLE default_expr_agg_column (id int DEFAULT (avg(id))); + +CREATE TABLE default_expr_non_column (a int DEFAULT (avg(non_existent))); + +CREATE TABLE default_expr_agg (a int DEFAULT (avg(1))); + +CREATE TABLE default_expr_agg (a int DEFAULT (select 1)); + +CREATE TABLE default_expr_agg (a int DEFAULT (generate_series(1,3))); + +BEGIN; + +CREATE TABLE remember_create_subid (c int); + +SAVEPOINT q; + +DROP TABLE remember_create_subid; + +ROLLBACK TO q; + +COMMIT; + +DROP TABLE remember_create_subid; + +CREATE TABLE remember_node_subid (c int); + +BEGIN; + +ALTER TABLE remember_node_subid ALTER c TYPE bigint; + +SAVEPOINT q; + +DROP TABLE remember_node_subid; + +ROLLBACK TO q; + +COMMIT; + +DROP TABLE remember_node_subid; + +CREATE TABLE partitioned ( + a int +) INHERITS (some_table) PARTITION BY LIST (a); + +CREATE TABLE partitioned ( + a1 int, + a2 int +) PARTITION BY LIST (a1, a2); + +CREATE FUNCTION retset (a int) RETURNS SETOF int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE; + +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (retset(a)); + +DROP FUNCTION retset(int); + +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE ((avg(a))); + +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE ((avg(a) OVER (PARTITION BY b))); + +CREATE TABLE partitioned ( + a int +) PARTITION BY LIST ((a LIKE (SELECT 1))); + +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE ((42)); + +CREATE FUNCTION const_func () RETURNS int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE; + +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (const_func()); + +DROP FUNCTION const_func(); + +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (b); + +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (xmin); + +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (((a, b))); + +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (a, ('unknown')); + +CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL; + +CREATE TABLE partitioned ( + a int +) PARTITION BY RANGE (immut_func(a)); + +DROP FUNCTION immut_func(int); + +CREATE TABLE partitioned ( + a point +) PARTITION BY LIST (a); + +CREATE TABLE partitioned ( + a point +) PARTITION BY LIST (a point_ops); + +CREATE TABLE partitioned ( + a point +) PARTITION BY RANGE (a); + +CREATE TABLE partitioned ( + a point +) PARTITION BY RANGE (a point_ops); + +CREATE TABLE partitioned ( + a int, + CONSTRAINT check_a CHECK (a > 0) NO INHERIT +) PARTITION BY RANGE (a); + +CREATE FUNCTION plusone(a int) RETURNS INT AS $$ SELECT a+1; $$ LANGUAGE SQL; + +CREATE TABLE partitioned ( + a int, + b int, + c text, + d text +) PARTITION BY RANGE (a oid_ops, plusone(b), c collate "default", d collate "C"); + +SELECT relkind FROM pg_class WHERE relname = 'partitioned'; + +DROP FUNCTION plusone(int); + +CREATE TABLE partitioned2 ( + a int, + b text +) PARTITION BY RANGE ((a+1), substr(b, 1, 5)); + +CREATE TABLE fail () INHERITS (partitioned2); + +INSERT INTO partitioned2 VALUES (1, 'hello'); + +CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO (100, 'ccccc'); + +DROP TABLE partitioned, partitioned2; + +create table partitioned (a int, b int) + partition by list ((row(a, b)::partitioned)); + +create table partitioned1 + partition of partitioned for values in ('(1,2)'::partitioned); + +create table partitioned2 + partition of partitioned for values in ('(2,4)'::partitioned); + +select * from partitioned where row(a,b)::partitioned = '(1,2)'::partitioned; + +drop table partitioned; + +create table partitioned (a int, b int) + partition by list ((partitioned)); + +create table partitioned1 + partition of partitioned for values in ('(1,2)'); + +create table partitioned2 + partition of partitioned for values in ('(2,4)'); + +select * from partitioned where partitioned = '(1,2)'::partitioned; + +drop table partitioned; + +create domain intdom1 as int; + +create table partitioned ( + a intdom1, + b text +) partition by range (a); + +alter table partitioned drop column a; + +drop domain intdom1; + +drop domain intdom1 cascade; + +table partitioned; + +create domain intdom1 as int; + +create table partitioned ( + a intdom1, + b text +) partition by range (plusone(a)); + +alter table partitioned drop column a; + +drop domain intdom1; + +drop domain intdom1 cascade; + +table partitioned; + +CREATE TABLE list_parted ( + a int +) PARTITION BY LIST (a); + +CREATE TABLE part_p1 PARTITION OF list_parted FOR VALUES IN ('1'); + +CREATE TABLE part_p2 PARTITION OF list_parted FOR VALUES IN (2); + +CREATE TABLE part_p3 PARTITION OF list_parted FOR VALUES IN ((2+1)); + +CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (null); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename.somename); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (a); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(a)); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(somename)); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(1)); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((select 1)); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (generate_series(4, 6)); + +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((1+1) collate "POSIX"); + +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES FROM (1) TO (2); + +CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1); + +CREATE TABLE part_default PARTITION OF list_parted DEFAULT; + +CREATE TABLE fail_default_part PARTITION OF list_parted DEFAULT; + +CREATE TABLE bools ( + a bool +) PARTITION BY LIST (a); + +CREATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1); + +DROP TABLE bools; + +CREATE TABLE moneyp ( + a money +) PARTITION BY LIST (a); + +CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10); + +CREATE TABLE moneyp_11 PARTITION OF moneyp FOR VALUES IN ('11'); + +CREATE TABLE moneyp_12 PARTITION OF moneyp FOR VALUES IN (to_char(12, '99')::int); + +DROP TABLE moneyp; + +CREATE TABLE bigintp ( + a bigint +) PARTITION BY LIST (a); + +CREATE TABLE bigintp_10 PARTITION OF bigintp FOR VALUES IN (10); + +CREATE TABLE bigintp_10_2 PARTITION OF bigintp FOR VALUES IN ('10'); + +DROP TABLE bigintp; + +CREATE TABLE range_parted ( + a date +) PARTITION BY RANGE (a); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename) TO ('2019-01-01'); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename.somename) TO ('2019-01-01'); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (a) TO ('2019-01-01'); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(a)) TO ('2019-01-01'); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(somename)) TO ('2019-01-01'); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max('2019-02-01'::date)) TO ('2019-01-01'); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM ((select 1)) TO ('2019-01-01'); + +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (generate_series(1, 3)) TO ('2019-01-01'); + +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES IN ('a'); + +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1); + +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('z'); + +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM ('a') TO ('z', 1); + +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES FROM (null) TO (maxvalue); + +CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES WITH (MODULUS 10, REMAINDER 1); + +CREATE TABLE hash_parted ( + a int +) PARTITION BY HASH (a); + +CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 0); + +CREATE TABLE hpart_2 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 50, REMAINDER 1); + +CREATE TABLE hpart_3 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 200, REMAINDER 2); + +CREATE TABLE hpart_4 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 10, REMAINDER 3); + +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 25, REMAINDER 3); + +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 150, REMAINDER 3); + +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES WITH (MODULUS 100, REMAINDER 3); + +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES FROM ('a', 1) TO ('z'); + +CREATE TABLE fail_part PARTITION OF hash_parted FOR VALUES IN (1000); + +CREATE TABLE fail_default_part PARTITION OF hash_parted DEFAULT; + +CREATE TABLE unparted ( + a int +); + +CREATE TABLE fail_part PARTITION OF unparted FOR VALUES IN ('a'); + +CREATE TABLE fail_part PARTITION OF unparted FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +DROP TABLE unparted; + +CREATE TEMP TABLE temp_parted ( + a int +) PARTITION BY LIST (a); + +CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a'); + +DROP TABLE temp_parted; + +CREATE TABLE list_parted2 ( + a varchar +) PARTITION BY LIST (a); + +CREATE TABLE part_null_z PARTITION OF list_parted2 FOR VALUES IN (null, 'z'); + +CREATE TABLE part_ab PARTITION OF list_parted2 FOR VALUES IN ('a', 'b'); + +CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT; + +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN (null); + +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('b', 'c'); + +INSERT INTO list_parted2 VALUES('X'); + +CREATE TABLE fail_part PARTITION OF list_parted2 FOR VALUES IN ('W', 'X', 'Y'); + +CREATE TABLE range_parted2 ( + a int +) PARTITION BY RANGE (a); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (0); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (1) TO (1); + +CREATE TABLE part0 PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (1); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (minvalue) TO (2); + +CREATE TABLE part1 PARTITION OF range_parted2 FOR VALUES FROM (1) TO (10); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (-1) TO (1); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (9) TO (maxvalue); + +CREATE TABLE part2 PARTITION OF range_parted2 FOR VALUES FROM (20) TO (30); + +CREATE TABLE part3 PARTITION OF range_parted2 FOR VALUES FROM (30) TO (40); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (30); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (10) TO (50); + +CREATE TABLE range2_default PARTITION OF range_parted2 DEFAULT; + +CREATE TABLE fail_default_part PARTITION OF range_parted2 DEFAULT; + +INSERT INTO range_parted2 VALUES (85); + +CREATE TABLE fail_part PARTITION OF range_parted2 FOR VALUES FROM (80) TO (90); + +CREATE TABLE part4 PARTITION OF range_parted2 FOR VALUES FROM (90) TO (100); + +CREATE TABLE range_parted3 ( + a int, + b int +) PARTITION BY RANGE (a, (b+1)); + +CREATE TABLE part00 PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, maxvalue); + +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (0, minvalue) TO (0, 1); + +CREATE TABLE part10 PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, 1); + +CREATE TABLE part11 PARTITION OF range_parted3 FOR VALUES FROM (1, 1) TO (1, 10); + +CREATE TABLE part12 PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, maxvalue); + +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, 10) TO (1, 20); + +CREATE TABLE range3_default PARTITION OF range_parted3 DEFAULT; + +CREATE TABLE fail_part PARTITION OF range_parted3 FOR VALUES FROM (1, minvalue) TO (1, maxvalue); + +CREATE TABLE hash_parted2 ( + a varchar +) PARTITION BY HASH (a); + +CREATE TABLE h2part_1 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 4, REMAINDER 2); + +CREATE TABLE h2part_2 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 0); + +CREATE TABLE h2part_3 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 4); + +CREATE TABLE h2part_4 PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 5); + +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 0, REMAINDER 1); + +CREATE TABLE fail_part PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 8, REMAINDER 8); + +CREATE TABLE parted ( + a text, + b int NOT NULL DEFAULT 0, + CONSTRAINT check_a CHECK (length(a) > 0) +) PARTITION BY LIST (a); + +CREATE TABLE part_a PARTITION OF parted FOR VALUES IN ('a'); + +SELECT attname, attislocal, attinhcount FROM pg_attribute + WHERE attrelid = 'part_a'::regclass and attnum > 0 + ORDER BY attnum; + +CREATE TABLE part_b PARTITION OF parted ( + b NOT NULL, + b DEFAULT 1, + b CHECK (b >= 0), + CONSTRAINT check_a CHECK (length(a) > 0) +) FOR VALUES IN ('b'); + +CREATE TABLE part_b PARTITION OF parted ( + b NOT NULL DEFAULT 1, + CONSTRAINT check_a CHECK (length(a) > 0), + CONSTRAINT check_b CHECK (b >= 0) +) FOR VALUES IN ('b'); + +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname; + +ALTER TABLE parted ADD CONSTRAINT check_b CHECK (b >= 0); + +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname; + +ALTER TABLE part_b DROP CONSTRAINT check_a; + +ALTER TABLE part_b DROP CONSTRAINT check_b; + +ALTER TABLE parted DROP CONSTRAINT check_a, DROP CONSTRAINT check_b; + +SELECT conname, conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY coninhcount DESC, conname; + +CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c); + +CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b)); + +CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10); + +create table parted_notnull_inh_test (a int default 1, b int not null default 0) partition by list (a); + +create table parted_notnull_inh_test1 partition of parted_notnull_inh_test (a not null, b default 1) for values in (1); + +insert into parted_notnull_inh_test (b) values (null); + +drop table parted_notnull_inh_test; + +create table parted_boolean_col (a bool, b text) partition by list(a); + +create table parted_boolean_less partition of parted_boolean_col + for values in ('foo' < 'bar'); + +create table parted_boolean_greater partition of parted_boolean_col + for values in ('foo' > 'bar'); + +drop table parted_boolean_col; + +create table parted_collate_must_match (a text collate "C", b text collate "C") + partition by range (a); + +create table parted_collate_must_match1 partition of parted_collate_must_match + (a collate "POSIX") for values from ('a') to ('m'); + +create table parted_collate_must_match2 partition of parted_collate_must_match + (b collate "POSIX") for values from ('m') to ('z'); + +drop table parted_collate_must_match; + +create table test_part_coll_posix (a text) partition by range (a collate "POSIX"); + +create table test_part_coll partition of test_part_coll_posix for values from ('a' collate "C") to ('g'); + +create table test_part_coll2 partition of test_part_coll_posix for values from ('g') to ('m'); + +create table test_part_coll_cast partition of test_part_coll_posix for values from (name 'm' collate "C") to ('s'); + +create table test_part_coll_cast2 partition of test_part_coll_posix for values from (name 's') to ('z'); + +drop table test_part_coll_posix; + +CREATE TABLE range_parted4 (a int, b int, c int) PARTITION BY RANGE (abs(a), abs(b), c); + +CREATE TABLE unbounded_range_part PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, MINVALUE, MINVALUE) TO (MAXVALUE, MAXVALUE, MAXVALUE); + +DROP TABLE unbounded_range_part; + +CREATE TABLE range_parted4_1 PARTITION OF range_parted4 FOR VALUES FROM (MINVALUE, MINVALUE, MINVALUE) TO (1, MAXVALUE, MAXVALUE); + +CREATE TABLE range_parted4_2 PARTITION OF range_parted4 FOR VALUES FROM (3, 4, 5) TO (6, 7, MAXVALUE); + +CREATE TABLE range_parted4_3 PARTITION OF range_parted4 FOR VALUES FROM (6, 8, MINVALUE) TO (9, MAXVALUE, MAXVALUE); + +DROP TABLE range_parted4; + +CREATE FUNCTION my_int4_sort(int4,int4) RETURNS int LANGUAGE sql + AS $$ SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$; + +CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4,int4), OPERATOR 2 <= (int4,int4), + OPERATOR 3 = (int4,int4), OPERATOR 4 >= (int4,int4), + OPERATOR 5 > (int4,int4), FUNCTION 1 my_int4_sort(int4,int4); + +CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops); + +CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000); + +INSERT INTO partkey_t VALUES (100); + +INSERT INTO partkey_t VALUES (200); + +DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3; + +DROP TABLE partkey_t, hash_parted, hash_parted2; + +DROP OPERATOR CLASS test_int4_ops USING btree; + +DROP FUNCTION my_int4_sort(int4,int4); + +CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a); + +COMMENT ON TABLE parted_col_comment IS 'Am partitioned table'; + +COMMENT ON COLUMN parted_col_comment.a IS 'Partition key'; + +SELECT obj_description('parted_col_comment'::regclass); + +DROP TABLE parted_col_comment; + +CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a) WITH (fillfactor=100); + +CREATE TABLE arrlp (a int[]) PARTITION BY LIST (a); + +CREATE TABLE arrlp12 PARTITION OF arrlp FOR VALUES IN ('{1}', '{2}'); + +DROP TABLE arrlp; + +create table boolspart (a bool) partition by list (a); + +create table boolspart_t partition of boolspart for values in (true); + +create table boolspart_f partition of boolspart for values in (false); + +drop table boolspart; + +create table perm_parted (a int) partition by list (a); + +create temporary table temp_parted (a int) partition by list (a); + +create table perm_part partition of temp_parted default; + +create temp table temp_part partition of perm_parted default; + +create temp table temp_part partition of temp_parted default; + +drop table perm_parted cascade; + +drop table temp_parted cascade; + +create table tab_part_create (a int) partition by list (a); + +create or replace function func_part_create() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_create_1 partition of tab_part_create for values in (1)'; + return null; + end $$; + +create trigger trig_part_create before insert on tab_part_create + for each statement execute procedure func_part_create(); + +insert into tab_part_create values (1); + +drop table tab_part_create; + +drop function func_part_create(); + +create table volatile_partbound_test (partkey timestamp) partition by range (partkey); + +create table volatile_partbound_test1 partition of volatile_partbound_test for values from (minvalue) to (current_timestamp); + +create table volatile_partbound_test2 partition of volatile_partbound_test for values from (current_timestamp) to (maxvalue); + +insert into volatile_partbound_test values (current_timestamp); + +select tableoid::regclass from volatile_partbound_test; + +drop table volatile_partbound_test; + +create table defcheck (a int, b int) partition by list (b); + +create table defcheck_def (a int, c int, b int); + +alter table defcheck_def drop c; + +alter table defcheck attach partition defcheck_def default; + +alter table defcheck_def add check (b <= 0 and b is not null); + +create table defcheck_1 partition of defcheck for values in (1, null); + +insert into defcheck_def values (0, 0); + +create table defcheck_0 partition of defcheck for values in (0); + +drop table defcheck; + +create table part_column_drop ( + useless_1 int, + id int, + useless_2 int, + d int, + b int, + useless_3 int +) partition by range (id); + +alter table part_column_drop drop column useless_1; + +alter table part_column_drop drop column useless_2; + +alter table part_column_drop drop column useless_3; + +create index part_column_drop_b_pred on part_column_drop(b) where b = 1; + +create index part_column_drop_b_expr on part_column_drop((b = 1)); + +create index part_column_drop_d_pred on part_column_drop(d) where d = 2; + +create index part_column_drop_d_expr on part_column_drop((d = 2)); + +create table part_column_drop_1_10 partition of + part_column_drop for values from (1) to (10); + +drop table part_column_drop; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_table_like_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_table_like_60.sql new file mode 100644 index 000000000..4ecbcd2d4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_table_like_60.sql @@ -0,0 +1,340 @@ +CREATE TABLE inhx (xx text DEFAULT 'text'); + +CREATE TABLE ctla (aa TEXT); + +CREATE TABLE ctlb (bb TEXT) INHERITS (ctla); + +CREATE TABLE foo (LIKE nonexistent); + +CREATE TABLE inhe (ee text, LIKE inhx) inherits (ctlb); + +INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4'); + +SELECT * FROM inhe; + +SELECT * FROM inhx; + +SELECT * FROM ctlb; + +SELECT * FROM ctla; + +CREATE TABLE inhf (LIKE inhx, LIKE inhx); + +CREATE TABLE inhf (LIKE inhx INCLUDING DEFAULTS INCLUDING CONSTRAINTS); + +INSERT INTO inhf DEFAULT VALUES; + +SELECT * FROM inhf; + +ALTER TABLE inhx add constraint foo CHECK (xx = 'text'); + +ALTER TABLE inhx ADD PRIMARY KEY (xx); + +CREATE TABLE inhg (LIKE inhx); + +INSERT INTO inhg VALUES ('foo'); + +DROP TABLE inhg; + +CREATE TABLE inhg (x text, LIKE inhx INCLUDING CONSTRAINTS, y text); + +INSERT INTO inhg VALUES ('x', 'text', 'y'); + +INSERT INTO inhg VALUES ('x', 'text', 'y'); + +INSERT INTO inhg VALUES ('x', 'foo', 'y'); + +SELECT * FROM inhg; + +DROP TABLE inhg; + +CREATE TABLE test_like_id_1 (a bigint GENERATED ALWAYS AS IDENTITY, b text); + +INSERT INTO test_like_id_1 (b) VALUES ('b1'); + +SELECT * FROM test_like_id_1; + +CREATE TABLE test_like_id_2 (LIKE test_like_id_1); + +INSERT INTO test_like_id_2 (b) VALUES ('b2'); + +SELECT * FROM test_like_id_2; + +CREATE TABLE test_like_id_3 (LIKE test_like_id_1 INCLUDING IDENTITY); + +INSERT INTO test_like_id_3 (b) VALUES ('b3'); + +SELECT * FROM test_like_id_3; + +DROP TABLE test_like_id_1, test_like_id_2, test_like_id_3; + +INSERT INTO test_like_gen_1 (a) VALUES (1); + +SELECT * FROM test_like_gen_1; + +CREATE TABLE test_like_gen_2 (LIKE test_like_gen_1); + +INSERT INTO test_like_gen_2 (a) VALUES (1); + +SELECT * FROM test_like_gen_2; + +CREATE TABLE test_like_gen_3 (LIKE test_like_gen_1 INCLUDING GENERATED); + +INSERT INTO test_like_gen_3 (a) VALUES (1); + +SELECT * FROM test_like_gen_3; + +DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3; + +CREATE TABLE test_like_4 (b int DEFAULT 42, + c int GENERATED ALWAYS AS (a * 2) STORED, + a int CHECK (a > 0)); + +CREATE TABLE test_like_4a (LIKE test_like_4); + +CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS); + +CREATE TABLE test_like_4c (LIKE test_like_4 INCLUDING GENERATED); + +CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERATED); + +INSERT INTO test_like_4a (a) VALUES(11); + +SELECT a, b, c FROM test_like_4a; + +INSERT INTO test_like_4b (a) VALUES(11); + +SELECT a, b, c FROM test_like_4b; + +INSERT INTO test_like_4c (a) VALUES(11); + +SELECT a, b, c FROM test_like_4c; + +INSERT INTO test_like_4d (a) VALUES(11); + +SELECT a, b, c FROM test_like_4d; + +CREATE TABLE test_like_5 (x point, y point, z point); + +CREATE TABLE test_like_5x (p int CHECK (p > 0), + q int GENERATED ALWAYS AS (p * 2) STORED); + +CREATE TABLE test_like_5c (LIKE test_like_4 INCLUDING ALL) + INHERITS (test_like_5, test_like_5x); + +CREATE TABLE test_like_6 (a int, c text, b text); + +CREATE STATISTICS ext_stat ON (a || b) FROM test_like_6; + +ALTER TABLE test_like_6 DROP COLUMN c; + +CREATE TABLE test_like_6c (LIKE test_like_6 INCLUDING ALL); + +DROP TABLE test_like_4, test_like_4a, test_like_4b, test_like_4c, test_like_4d; + +DROP TABLE test_like_5, test_like_5x, test_like_5c; + +DROP TABLE test_like_6, test_like_6c; + +CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text); + +INSERT INTO inhg VALUES (5, 10); + +INSERT INTO inhg VALUES (20, 10); + +DROP TABLE inhg; + +CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, PRIMARY KEY(x)); + +CREATE TABLE inhz (xx text DEFAULT 'text', yy int UNIQUE); + +CREATE UNIQUE INDEX inhz_xx_idx on inhz (xx) WHERE xx <> 'test'; + +CREATE TABLE inhg (x text UNIQUE, LIKE inhz INCLUDING INDEXES); + +INSERT INTO inhg (xx, yy, x) VALUES ('test', 5, 10); + +INSERT INTO inhg (xx, yy, x) VALUES ('test', 10, 15); + +INSERT INTO inhg (xx, yy, x) VALUES ('foo', 10, 15); + +DROP TABLE inhg; + +DROP TABLE inhz; + +CREATE TABLE inhz (x text REFERENCES inhz, LIKE inhx INCLUDING INDEXES); + +DROP TABLE inhz; + +ALTER TABLE ctlt1 ADD CONSTRAINT cc CHECK (length(b) > 100) NOT VALID; + +CREATE INDEX ctlt1_b_key ON ctlt1 (b); + +CREATE INDEX ctlt1_fnidx ON ctlt1 ((a || b)); + +CREATE STATISTICS ctlt1_a_b_stat ON a,b FROM ctlt1; + +CREATE STATISTICS ctlt1_expr_stat ON (a || b) FROM ctlt1; + +COMMENT ON STATISTICS ctlt1_a_b_stat IS 'ab stats'; + +COMMENT ON STATISTICS ctlt1_expr_stat IS 'ab expr stats'; + +COMMENT ON COLUMN ctlt1.a IS 'A'; + +COMMENT ON COLUMN ctlt1.b IS 'B'; + +COMMENT ON CONSTRAINT ctlt1_a_check ON ctlt1 IS 't1_a_check'; + +COMMENT ON INDEX ctlt1_pkey IS 'index pkey'; + +COMMENT ON INDEX ctlt1_b_key IS 'index b_key'; + +ALTER TABLE ctlt1 ALTER COLUMN a SET STORAGE MAIN; + +CREATE TABLE ctlt2 (c text NOT NULL); + +ALTER TABLE ctlt2 ALTER COLUMN c SET STORAGE EXTERNAL; + +COMMENT ON COLUMN ctlt2.c IS 'C'; + +COMMENT ON CONSTRAINT ctlt2_c_not_null ON ctlt2 IS 't2_c_not_null'; + +CREATE TABLE ctlt3 (a text CHECK (length(a) < 5), c text CHECK (length(c) < 7)); + +ALTER TABLE ctlt3 ALTER COLUMN c SET STORAGE EXTERNAL; + +ALTER TABLE ctlt3 ALTER COLUMN a SET STORAGE MAIN; + +CREATE INDEX ctlt3_fnidx ON ctlt3 ((a || c)); + +COMMENT ON COLUMN ctlt3.a IS 'A3'; + +COMMENT ON COLUMN ctlt3.c IS 'C'; + +COMMENT ON CONSTRAINT ctlt3_a_check ON ctlt3 IS 't3_a_check'; + +CREATE TABLE ctlt4 (a text, c text); + +ALTER TABLE ctlt4 ALTER COLUMN c SET STORAGE EXTERNAL; + +CREATE TABLE ctlt12_storage (LIKE ctlt1 INCLUDING STORAGE, LIKE ctlt2 INCLUDING STORAGE); + +CREATE TABLE ctlt12_comments (LIKE ctlt1 INCLUDING COMMENTS, LIKE ctlt2 INCLUDING COMMENTS); + +SELECT conname, description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt12_comments'::regclass; + +CREATE TABLE ctlt1_inh (LIKE ctlt1 INCLUDING CONSTRAINTS INCLUDING COMMENTS) INHERITS (ctlt1); + +SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt1_inh'::regclass; + +CREATE TABLE ctlt13_inh () INHERITS (ctlt1, ctlt3); + +CREATE TABLE ctlt13_like (LIKE ctlt3 INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING COMMENTS INCLUDING STORAGE) INHERITS (ctlt1); + +SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt13_like'::regclass; + +CREATE TABLE ctlt_all (LIKE ctlt1 INCLUDING ALL); + +SELECT c.relname, objsubid, description FROM pg_description, pg_index i, pg_class c WHERE classoid = 'pg_class'::regclass AND objoid = i.indexrelid AND c.oid = i.indexrelid AND i.indrelid = 'ctlt_all'::regclass ORDER BY c.relname, objsubid; + +SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s WHERE classoid = 'pg_statistic_ext'::regclass AND objoid = s.oid AND s.stxrelid = 'ctlt_all'::regclass ORDER BY s.stxname, objsubid; + +CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4); + +CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1); + +CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL); + +DROP TABLE public.pg_attrdef; + +BEGIN; + +CREATE SCHEMA ctl_schema; + +SET LOCAL search_path = ctl_schema, public; + +CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL); + +ROLLBACK; + +DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE; + +COMMENT ON CONSTRAINT noinh_con_copy_b_not_null ON noinh_con_copy IS 'not null b'; + +COMMENT ON CONSTRAINT noinh_con_copy_c_not_null ON noinh_con_copy IS 'not null c no inherit'; + +CREATE TABLE noinh_con_copy1 (LIKE noinh_con_copy INCLUDING CONSTRAINTS INCLUDING COMMENTS); + +SELECT conname, description +FROM pg_description, pg_constraint c +WHERE classoid = 'pg_constraint'::regclass +AND objoid = c.oid AND c.conrelid = 'noinh_con_copy1'::regclass +ORDER BY conname COLLATE "C"; + +CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL) + PARTITION BY LIST (a); + +DROP TABLE noinh_con_copy, noinh_con_copy1; + +CREATE TABLE ctlt4 (a int, b text); + +CREATE SEQUENCE ctlseq1; + +CREATE TABLE ctlt10 (LIKE ctlseq1); + +CREATE VIEW ctlv1 AS SELECT * FROM ctlt4; + +CREATE TABLE ctlt11 (LIKE ctlv1); + +CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL); + +CREATE TYPE ctlty1 AS (a int, b text); + +CREATE TABLE ctlt12 (LIKE ctlty1); + +DROP SEQUENCE ctlseq1; + +DROP TYPE ctlty1; + +DROP VIEW ctlv1; + +DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12; + +CREATE FOREIGN DATA WRAPPER ctl_dummy; + +CREATE SERVER ctl_s0 FOREIGN DATA WRAPPER ctl_dummy; + +CREATE TABLE ctl_table(a int PRIMARY KEY, + b varchar COMPRESSION pglz, + c int GENERATED ALWAYS AS (a * 2) STORED, + d bigint GENERATED ALWAYS AS IDENTITY, + e int DEFAULT 1); + +CREATE INDEX ctl_table_a_key ON ctl_table(a); + +COMMENT ON COLUMN ctl_table.b IS 'Column b'; + +CREATE STATISTICS ctl_table_stat ON a,b FROM ctl_table; + +ALTER TABLE ctl_table ADD CONSTRAINT foo CHECK (b = 'text'); + +ALTER TABLE ctl_table ALTER COLUMN b SET STORAGE MAIN; + +CREATE FOREIGN TABLE ctl_foreign_table1(LIKE ctl_table EXCLUDING ALL) SERVER ctl_s0; + +SELECT attname, attcompression FROM pg_attribute + WHERE attrelid = 'ctl_foreign_table1'::regclass and attnum > 0 ORDER BY attnum; + +CREATE FOREIGN TABLE ctl_foreign_table2(LIKE ctl_table INCLUDING ALL) SERVER ctl_s0; + +SELECT attname, attcompression FROM pg_attribute + WHERE attrelid = 'ctl_foreign_table2'::regclass and attnum > 0 ORDER BY attnum; + +DROP TABLE ctl_table; + +DROP FOREIGN TABLE ctl_foreign_table1; + +DROP FOREIGN TABLE ctl_foreign_table2; + +DROP FOREIGN DATA WRAPPER ctl_dummy CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_type_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_type_60.sql new file mode 100644 index 000000000..46a2f21dd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_type_60.sql @@ -0,0 +1,279 @@ +CREATE FUNCTION widget_in(cstring) + RETURNS widget + AS 'regresslib' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION widget_out(widget) + RETURNS cstring + AS 'regresslib' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION int44in(cstring) + RETURNS city_budget + AS 'regresslib' + LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION int44out(city_budget) + RETURNS cstring + AS 'regresslib' + LANGUAGE C STRICT IMMUTABLE; + +CREATE TYPE widget ( + internallength = 24, + input = widget_in, + output = widget_out, + typmod_in = numerictypmodin, + typmod_out = numerictypmodout, + alignment = double +); + +CREATE TYPE city_budget ( + internallength = 16, + input = int44in, + output = int44out, + element = int4, + category = 'x', -- just to verify the system will take it + preferred = true -- ditto +); + +CREATE TYPE shell; + +CREATE TYPE shell; + +DROP TYPE shell; + +DROP TYPE shell; + +CREATE TYPE myshell; + +CREATE TYPE int42; + +CREATE TYPE text_w_default; + +CREATE FUNCTION int42_in(cstring) + RETURNS int42 + AS 'int4in' + LANGUAGE internal STRICT IMMUTABLE; + +CREATE FUNCTION int42_out(int42) + RETURNS cstring + AS 'int4out' + LANGUAGE internal STRICT IMMUTABLE; + +CREATE FUNCTION text_w_default_in(cstring) + RETURNS text_w_default + AS 'textin' + LANGUAGE internal STRICT IMMUTABLE; + +CREATE FUNCTION text_w_default_out(text_w_default) + RETURNS cstring + AS 'textout' + LANGUAGE internal STRICT IMMUTABLE; + +CREATE TYPE int42 ( + internallength = 4, + input = int42_in, + output = int42_out, + alignment = int4, + default = 42, + passedbyvalue +); + +CREATE TYPE text_w_default ( + internallength = variable, + input = text_w_default_in, + output = text_w_default_out, + alignment = int4, + default = 'zippo' +); + +CREATE TABLE default_test (f1 text_w_default, f2 int42); + +INSERT INTO default_test DEFAULT VALUES; + +SELECT * FROM default_test; + +CREATE TYPE bogus_type; + +CREATE TYPE bogus_type ( + "Internallength" = 4, + "Input" = int42_in, + "Output" = int42_out, + "Alignment" = int4, + "Default" = 42, + "Passedbyvalue" +); + +CREATE TYPE bogus_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32); + +DROP TYPE bogus_type; + +CREATE TYPE bogus_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32); + +CREATE TYPE default_test_row AS (f1 text_w_default, f2 int42); + +CREATE FUNCTION get_default_test() RETURNS SETOF default_test_row AS ' + SELECT * FROM default_test; +' LANGUAGE SQL; + +SELECT * FROM get_default_test(); + +COMMENT ON TYPE bad IS 'bad comment'; + +COMMENT ON TYPE default_test_row IS 'good comment'; + +COMMENT ON TYPE default_test_row IS NULL; + +COMMENT ON COLUMN default_test_row.nope IS 'bad comment'; + +COMMENT ON COLUMN default_test_row.f1 IS 'good comment'; + +COMMENT ON COLUMN default_test_row.f1 IS NULL; + +CREATE TYPE text_w_default; + +DROP TYPE default_test_row CASCADE; + +DROP TABLE default_test; + +CREATE TYPE base_type; + +CREATE FUNCTION base_fn_in(cstring) RETURNS base_type AS 'boolin' + LANGUAGE internal IMMUTABLE STRICT; + +CREATE FUNCTION base_fn_out(base_type) RETURNS cstring AS 'boolout' + LANGUAGE internal IMMUTABLE STRICT; + +CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out); + +DROP FUNCTION base_fn_in(cstring); + +DROP FUNCTION base_fn_out(base_type); + +DROP TYPE base_type; + +DROP TYPE base_type CASCADE; + +CREATE TEMP TABLE mytab (foo widget(42,13,7)); + +CREATE TEMP TABLE mytab (foo widget(42,13)); + +SELECT format_type(atttypid,atttypmod) FROM pg_attribute +WHERE attrelid = 'mytab'::regclass AND attnum > 0; + +INSERT INTO mytab VALUES ('(1,2,3)'), ('(-44,5.5,12)'); + +TABLE mytab; + +select format_type('varchar'::regtype, 42); + +select format_type('bpchar'::regtype, null); + +select format_type('bpchar'::regtype, -1); + +SELECT pg_input_is_valid('(1,2,3)', 'widget'); + +SELECT pg_input_is_valid('(1,2)', 'widget'); + +SELECT pg_input_is_valid('{"(1,2,3)"}', 'widget[]'); + +SELECT pg_input_is_valid('{"(1,2)"}', 'widget[]'); + +SELECT pg_input_is_valid('("(1,2,3)")', 'mytab'); + +SELECT pg_input_is_valid('("(1,2)")', 'mytab'); + +CREATE FUNCTION pt_in_widget(point, widget) + RETURNS bool + AS 'regresslib' + LANGUAGE C STRICT; + +CREATE OPERATOR <% ( + leftarg = point, + rightarg = widget, + procedure = pt_in_widget, + commutator = >% , + negator = >=% +); + +SELECT point '(1,2)' <% widget '(0,0,3)' AS t, + point '(1,2)' <% widget '(0,0,1)' AS f; + +CREATE TABLE city ( + name name, + location box, + budget city_budget +); + +INSERT INTO city VALUES +('Podunk', '(1,2),(3,4)', '100,127,1000'), +('Gotham', '(1000,34),(1100,334)', '123456,127,-1000,6789'); + +TABLE city; + +CREATE TYPE myvarchar; + +CREATE FUNCTION myvarcharin(cstring, oid, integer) RETURNS myvarchar +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharin'; + +CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring +LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout'; + +CREATE FUNCTION myvarcharsend(myvarchar) RETURNS bytea +LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharsend'; + +CREATE FUNCTION myvarcharrecv(internal, oid, integer) RETURNS myvarchar +LANGUAGE internal STABLE PARALLEL SAFE STRICT AS 'varcharrecv'; + +ALTER TYPE myvarchar SET (storage = extended); + +CREATE TYPE myvarchar ( + input = myvarcharin, + output = myvarcharout, + alignment = integer, + storage = main +); + +CREATE DOMAIN myvarchardom AS myvarchar; + +ALTER TYPE myvarchar SET (storage = plain); + +ALTER TYPE myvarchar SET (storage = extended); + +ALTER TYPE myvarchar SET ( + send = myvarcharsend, + receive = myvarcharrecv, + typmod_in = varchartypmodin, + typmod_out = varchartypmodout, + -- these are bogus, but it's safe as long as we don't use the type: + analyze = ts_typanalyze, + subscript = raw_array_subscript_handler +); + +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = 'myvarchar'; + +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = '_myvarchar'; + +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = 'myvarchardom'; + +SELECT typinput, typoutput, typreceive, typsend, typmodin, typmodout, + typanalyze, typsubscript, typstorage +FROM pg_type WHERE typname = '_myvarchardom'; + +DROP FUNCTION myvarcharsend(myvarchar); + +DROP TYPE myvarchar; + +DROP TYPE myvarchar CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/create_view_60.sql b/crates/pgt_pretty_print/tests/data/multi/create_view_60.sql new file mode 100644 index 000000000..16c962d63 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/create_view_60.sql @@ -0,0 +1,847 @@ +CREATE FUNCTION interpt_pp(path, path) + RETURNS point + AS 'regresslib' + LANGUAGE C STRICT; + +CREATE TABLE real_city ( + pop int4, + cname text, + outline path +); + +COPY real_city FROM 'filename'; + +ANALYZE real_city; + +SELECT * + INTO TABLE ramp + FROM ONLY road + WHERE name ~ '.*Ramp'; + +CREATE VIEW street AS + SELECT r.name, r.thepath, c.cname AS cname + FROM ONLY road r, real_city c + WHERE c.outline ?# r.thepath; + +CREATE VIEW iexit AS + SELECT ih.name, ih.thepath, + interpt_pp(ih.thepath, r.thepath) AS exit + FROM ihighway ih, ramp r + WHERE ih.thepath ?# r.thepath; + +CREATE VIEW toyemp AS + SELECT name, age, location, 12*salary AS annualsal + FROM emp; + +COMMENT ON VIEW noview IS 'no view'; + +COMMENT ON VIEW toyemp IS 'is a view'; + +COMMENT ON VIEW toyemp IS NULL; + +CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20)); + +CREATE VIEW key_dependent_view AS + SELECT * FROM view_base_table GROUP BY key; + +ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey; + +CREATE VIEW key_dependent_view_no_cols AS + SELECT FROM view_base_table GROUP BY key HAVING length(data) > 0; + +CREATE TABLE viewtest_tbl (a int, b int, c numeric(10,1), d text COLLATE "C"); + +CREATE OR REPLACE VIEW viewtest AS + SELECT * FROM viewtest_tbl; + +CREATE OR REPLACE VIEW viewtest AS + SELECT * FROM viewtest_tbl WHERE a > 10; + +SELECT * FROM viewtest; + +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d FROM viewtest_tbl WHERE a > 5 ORDER BY b DESC; + +SELECT * FROM viewtest; + +CREATE OR REPLACE VIEW viewtest AS + SELECT a FROM viewtest_tbl WHERE a <> 20; + +CREATE OR REPLACE VIEW viewtest AS + SELECT 1, * FROM viewtest_tbl; + +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b::numeric, c, d FROM viewtest_tbl; + +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c::numeric(10,2), d FROM viewtest_tbl; + +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d COLLATE "POSIX" FROM viewtest_tbl; + +CREATE OR REPLACE VIEW viewtest AS + SELECT a, b, c, d, 0 AS e FROM viewtest_tbl; + +DROP VIEW viewtest; + +DROP TABLE viewtest_tbl; + +CREATE SCHEMA temp_view_test + +CREATE TABLE base_table (a int, id int) + +CREATE TABLE base_table2 (a int, id int); + +SET search_path TO temp_view_test, public; + +CREATE TEMPORARY TABLE temp_table (a int, id int); + +CREATE VIEW v1 AS SELECT * FROM base_table; + +CREATE VIEW v1_temp AS SELECT * FROM temp_table; + +CREATE TEMP VIEW v2_temp AS SELECT * FROM base_table; + +CREATE VIEW temp_view_test.v2 AS SELECT * FROM base_table; + +CREATE VIEW temp_view_test.v3_temp AS SELECT * FROM temp_table; + +CREATE SCHEMA test_view_schema + +CREATE TEMP VIEW testview AS SELECT 1; + +CREATE VIEW v3 AS + SELECT t1.a AS t1_a, t2.a AS t2_a + FROM base_table t1, base_table2 t2 + WHERE t1.id = t2.id; + +CREATE VIEW v4_temp AS + SELECT t1.a AS t1_a, t2.a AS t2_a + FROM base_table t1, temp_table t2 + WHERE t1.id = t2.id; + +CREATE VIEW v5_temp AS + SELECT t1.a AS t1_a, t2.a AS t2_a, t3.a AS t3_a + FROM base_table t1, base_table2 t2, temp_table t3 + WHERE t1.id = t2.id and t2.id = t3.id; + +CREATE VIEW v4 AS SELECT * FROM base_table WHERE id IN (SELECT id FROM base_table2); + +CREATE VIEW v5 AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM base_table2) t2; + +CREATE VIEW v6 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM base_table2); + +CREATE VIEW v7 AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM base_table2); + +CREATE VIEW v8 AS SELECT * FROM base_table WHERE EXISTS (SELECT 1); + +CREATE VIEW v6_temp AS SELECT * FROM base_table WHERE id IN (SELECT id FROM temp_table); + +CREATE VIEW v7_temp AS SELECT t1.id, t2.a FROM base_table t1, (SELECT * FROM temp_table) t2; + +CREATE VIEW v8_temp AS SELECT * FROM base_table WHERE EXISTS (SELECT 1 FROM temp_table); + +CREATE VIEW v9_temp AS SELECT * FROM base_table WHERE NOT EXISTS (SELECT 1 FROM temp_table); + +CREATE VIEW v10_temp AS SELECT * FROM v7_temp; + +CREATE VIEW v11_temp AS SELECT t1.id, t2.a FROM base_table t1, v10_temp t2; + +CREATE VIEW v12_temp AS SELECT true FROM v11_temp; + +CREATE SEQUENCE seq1; + +CREATE TEMPORARY SEQUENCE seq1_temp; + +CREATE VIEW v9 AS SELECT seq1.is_called FROM seq1; + +CREATE VIEW v13_temp AS SELECT seq1_temp.is_called FROM seq1_temp; + +SELECT relname FROM pg_class + WHERE relname LIKE 'v_' + AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'temp_view_test') + ORDER BY relname; + +SELECT relname FROM pg_class + WHERE relname LIKE 'v%' + AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp%') + ORDER BY relname; + +CREATE SCHEMA testviewschm2; + +SET search_path TO testviewschm2, public; + +CREATE TABLE t1 (num int, name text); + +CREATE TABLE t2 (num2 int, value text); + +CREATE TEMP TABLE tt (num2 int, value text); + +CREATE VIEW nontemp1 AS SELECT * FROM t1 CROSS JOIN t2; + +CREATE VIEW temporal1 AS SELECT * FROM t1 CROSS JOIN tt; + +CREATE VIEW nontemp2 AS SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num2; + +CREATE VIEW temporal2 AS SELECT * FROM t1 INNER JOIN tt ON t1.num = tt.num2; + +CREATE VIEW nontemp3 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2; + +CREATE VIEW temporal3 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2; + +CREATE VIEW nontemp4 AS SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num2 AND t2.value = 'xxx'; + +CREATE VIEW temporal4 AS SELECT * FROM t1 LEFT JOIN tt ON t1.num = tt.num2 AND tt.value = 'xxx'; + +SELECT relname FROM pg_class + WHERE relname LIKE 'nontemp%' + AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'testviewschm2') + ORDER BY relname; + +SELECT relname FROM pg_class + WHERE relname LIKE 'temporal%' + AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname LIKE 'pg_temp%') + ORDER BY relname; + +CREATE TABLE tbl1 ( a int, b int); + +CREATE TABLE tbl2 (c int, d int); + +CREATE TABLE tbl3 (e int, f int); + +CREATE TABLE tbl4 (g int, h int); + +CREATE TEMP TABLE tmptbl (i int, j int); + +CREATE VIEW pubview AS SELECT * FROM tbl1 WHERE tbl1.a +BETWEEN (SELECT d FROM tbl2 WHERE c = 1) AND (SELECT e FROM tbl3 WHERE f = 2) +AND EXISTS (SELECT g FROM tbl4 LEFT JOIN tbl3 ON tbl4.h = tbl3.f); + +SELECT count(*) FROM pg_class where relname = 'pubview' +AND relnamespace IN (SELECT OID FROM pg_namespace WHERE nspname = 'testviewschm2'); + +CREATE VIEW mytempview AS SELECT * FROM tbl1 WHERE tbl1.a +BETWEEN (SELECT d FROM tbl2 WHERE c = 1) AND (SELECT e FROM tbl3 WHERE f = 2) +AND EXISTS (SELECT g FROM tbl4 LEFT JOIN tbl3 ON tbl4.h = tbl3.f) +AND NOT EXISTS (SELECT g FROM tbl4 LEFT JOIN tmptbl ON tbl4.h = tmptbl.j); + +SELECT count(*) FROM pg_class where relname LIKE 'mytempview' +And relnamespace IN (SELECT OID FROM pg_namespace WHERE nspname LIKE 'pg_temp%'); + +CREATE VIEW mysecview1 + AS SELECT * FROM tbl1 WHERE a = 0; + +CREATE VIEW mysecview2 WITH (security_barrier=true) + AS SELECT * FROM tbl1 WHERE a > 0; + +CREATE VIEW mysecview3 WITH (security_barrier=false) + AS SELECT * FROM tbl1 WHERE a < 0; + +CREATE VIEW mysecview4 WITH (security_barrier) + AS SELECT * FROM tbl1 WHERE a <> 0; + +CREATE VIEW mysecview5 WITH (security_barrier=100) -- Error + AS SELECT * FROM tbl1 WHERE a > 100; + +CREATE VIEW mysecview6 WITH (invalid_option) -- Error + AS SELECT * FROM tbl1 WHERE a < 100; + +CREATE VIEW mysecview7 WITH (security_invoker=true) + AS SELECT * FROM tbl1 WHERE a = 100; + +CREATE VIEW mysecview8 WITH (security_invoker=false, security_barrier=true) + AS SELECT * FROM tbl1 WHERE a > 100; + +CREATE VIEW mysecview9 WITH (security_invoker) + AS SELECT * FROM tbl1 WHERE a < 100; + +CREATE VIEW mysecview10 WITH (security_invoker=100) -- Error + AS SELECT * FROM tbl1 WHERE a <> 100; + +SELECT relname, relkind, reloptions FROM pg_class + WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, + 'mysecview3'::regclass, 'mysecview4'::regclass, + 'mysecview7'::regclass, 'mysecview8'::regclass, + 'mysecview9'::regclass) + ORDER BY relname; + +CREATE OR REPLACE VIEW mysecview1 + AS SELECT * FROM tbl1 WHERE a = 256; + +CREATE OR REPLACE VIEW mysecview2 + AS SELECT * FROM tbl1 WHERE a > 256; + +CREATE OR REPLACE VIEW mysecview3 WITH (security_barrier=true) + AS SELECT * FROM tbl1 WHERE a < 256; + +CREATE OR REPLACE VIEW mysecview4 WITH (security_barrier=false) + AS SELECT * FROM tbl1 WHERE a <> 256; + +CREATE OR REPLACE VIEW mysecview7 + AS SELECT * FROM tbl1 WHERE a > 256; + +CREATE OR REPLACE VIEW mysecview8 WITH (security_invoker=true) + AS SELECT * FROM tbl1 WHERE a < 256; + +CREATE OR REPLACE VIEW mysecview9 WITH (security_invoker=false, security_barrier=true) + AS SELECT * FROM tbl1 WHERE a <> 256; + +SELECT relname, relkind, reloptions FROM pg_class + WHERE oid in ('mysecview1'::regclass, 'mysecview2'::regclass, + 'mysecview3'::regclass, 'mysecview4'::regclass, + 'mysecview7'::regclass, 'mysecview8'::regclass, + 'mysecview9'::regclass) + ORDER BY relname; + +CREATE VIEW unspecified_types AS + SELECT 42 as i, 42.5 as num, 'foo' as u, 'foo'::unknown as u2, null as n; + +SELECT * FROM unspecified_types; + +CREATE VIEW tt1 AS + SELECT * FROM ( + VALUES + ('abc'::varchar(3), '0123456789', 42, 'abcd'::varchar(4)), + ('0123456789', 'abc'::varchar(3), 42.12, 'abc'::varchar(4)) + ) vv(a,b,c,d); + +SELECT * FROM tt1; + +SELECT a::varchar(3) FROM tt1; + +DROP VIEW tt1; + +CREATE TABLE tt1 (f1 int, f2 int, f3 text); + +CREATE TABLE tx1 (x1 int, x2 int, x3 text); + +CREATE TABLE temp_view_test.tt1 (y1 int, f2 int, f3 text); + +CREATE VIEW aliased_view_1 AS + select * from tt1 + where exists (select 1 from tx1 where tt1.f1 = tx1.x1); + +CREATE VIEW aliased_view_2 AS + select * from tt1 a1 + where exists (select 1 from tx1 where a1.f1 = tx1.x1); + +CREATE VIEW aliased_view_3 AS + select * from tt1 + where exists (select 1 from tx1 a2 where tt1.f1 = a2.x1); + +CREATE VIEW aliased_view_4 AS + select * from temp_view_test.tt1 + where exists (select 1 from tt1 where temp_view_test.tt1.y1 = tt1.f1); + +ALTER TABLE tx1 RENAME TO a1; + +ALTER TABLE tt1 RENAME TO a2; + +ALTER TABLE a1 RENAME TO tt1; + +ALTER TABLE a2 RENAME TO tx1; + +ALTER TABLE tx1 SET SCHEMA temp_view_test; + +ALTER TABLE temp_view_test.tt1 RENAME TO tmp1; + +ALTER TABLE temp_view_test.tmp1 SET SCHEMA testviewschm2; + +ALTER TABLE tmp1 RENAME TO tx1; + +create view aliased_order_by as +select x1 as x2, x2 as x1, x3 from tt1 + order by x2; + +alter view aliased_order_by rename column x1 to x0; + +alter view aliased_order_by rename column x3 to x1; + +create view view_of_joins as +select * from + (select * from (tbl1 cross join tbl2) same) ss, + (tbl3 cross join tbl4) same; + +create table tbl1a (a int, c int); + +create view view_of_joins_2a as select * from tbl1 join tbl1a using (a); + +create view view_of_joins_2b as select * from tbl1 join tbl1a using (a) as x; + +create view view_of_joins_2c as select * from (tbl1 join tbl1a using (a)) as y; + +create view view_of_joins_2d as select * from (tbl1 join tbl1a using (a) as x) as y; + +select pg_get_viewdef('view_of_joins_2a', true); + +select pg_get_viewdef('view_of_joins_2b', true); + +select pg_get_viewdef('view_of_joins_2c', true); + +select pg_get_viewdef('view_of_joins_2d', true); + +create table tt2 (a int, b int, c int); + +create table tt3 (ax int8, b int2, c numeric); + +create table tt4 (ay int, b int, q int); + +create view v1 as select * from tt2 natural join tt3; + +create view v1a as select * from (tt2 natural join tt3) j; + +create view v2 as select * from tt2 join tt3 using (b,c) join tt4 using (b); + +create view v2a as select * from (tt2 join tt3 using (b,c) join tt4 using (b)) j; + +create view v3 as select * from tt2 join tt3 using (b,c) full join tt4 using (b); + +select pg_get_viewdef('v1', true); + +select pg_get_viewdef('v1a', true); + +select pg_get_viewdef('v2', true); + +select pg_get_viewdef('v2a', true); + +select pg_get_viewdef('v3', true); + +alter table tt2 add column d int; + +alter table tt2 add column e int; + +select pg_get_viewdef('v1', true); + +select pg_get_viewdef('v1a', true); + +select pg_get_viewdef('v2', true); + +select pg_get_viewdef('v2a', true); + +select pg_get_viewdef('v3', true); + +alter table tt3 rename c to d; + +select pg_get_viewdef('v1', true); + +select pg_get_viewdef('v1a', true); + +select pg_get_viewdef('v2', true); + +select pg_get_viewdef('v2a', true); + +select pg_get_viewdef('v3', true); + +alter table tt3 add column c int; + +alter table tt3 add column e int; + +select pg_get_viewdef('v1', true); + +select pg_get_viewdef('v1a', true); + +select pg_get_viewdef('v2', true); + +select pg_get_viewdef('v2a', true); + +select pg_get_viewdef('v3', true); + +alter table tt2 drop column d; + +select pg_get_viewdef('v1', true); + +select pg_get_viewdef('v1a', true); + +select pg_get_viewdef('v2', true); + +select pg_get_viewdef('v2a', true); + +select pg_get_viewdef('v3', true); + +create table tt5 (a int, b int); + +create table tt6 (c int, d int); + +create view vv1 as select * from (tt5 cross join tt6) j(aa,bb,cc,dd); + +select pg_get_viewdef('vv1', true); + +alter table tt5 add column c int; + +select pg_get_viewdef('vv1', true); + +alter table tt5 add column cc int; + +select pg_get_viewdef('vv1', true); + +alter table tt5 drop column c; + +select pg_get_viewdef('vv1', true); + +create view v4 as select * from v1; + +alter view v1 rename column a to x; + +select pg_get_viewdef('v1', true); + +select pg_get_viewdef('v4', true); + +create table tt7 (x int, xx int, y int); + +alter table tt7 drop column xx; + +create table tt8 (x int, z int); + +create view vv2 as +select * from (values(1,2,3,4,5)) v(a,b,c,d,e) +union all +select * from tt7 full join tt8 using (x), tt8 tt8x; + +select pg_get_viewdef('vv2', true); + +create view vv3 as +select * from (values(1,2,3,4,5,6)) v(a,b,c,x,e,f) +union all +select * from + tt7 full join tt8 using (x), + tt7 tt7x full join tt8 tt8x using (x); + +select pg_get_viewdef('vv3', true); + +create view vv4 as +select * from (values(1,2,3,4,5,6,7)) v(a,b,c,x,e,f,g) +union all +select * from + tt7 full join tt8 using (x), + tt7 tt7x full join tt8 tt8x using (x) full join tt8 tt8y using (x); + +select pg_get_viewdef('vv4', true); + +alter table tt7 add column zz int; + +alter table tt7 add column z int; + +alter table tt7 drop column zz; + +alter table tt8 add column z2 int; + +select pg_get_viewdef('vv2', true); + +select pg_get_viewdef('vv3', true); + +select pg_get_viewdef('vv4', true); + +create table tt7a (x date, xx int, y int); + +alter table tt7a drop column xx; + +create table tt8a (x timestamptz, z int); + +create view vv2a as +select * from (values(now(),2,3,now(),5)) v(a,b,c,d,e) +union all +select * from tt7a left join tt8a using (x), tt8a tt8ax; + +select pg_get_viewdef('vv2a', true); + +create table tt9 (x int, xx int, y int); + +create table tt10 (x int, z int); + +create view vv5 as select x,y,z from tt9 join tt10 using(x); + +select pg_get_viewdef('vv5', true); + +alter table tt9 drop column xx; + +select pg_get_viewdef('vv5', true); + +create table tt11 (x int, y int); + +create table tt12 (x int, z int); + +create table tt13 (z int, q int); + +create view vv6 as select x,y,z,q from + (tt11 join tt12 using(x)) join tt13 using(z); + +select pg_get_viewdef('vv6', true); + +alter table tt11 add column z int; + +select pg_get_viewdef('vv6', true); + +create table tt14t (f1 text, f2 text, f3 text, f4 text); + +insert into tt14t values('foo', 'bar', 'baz', '42'); + +alter table tt14t drop column f2; + +create function tt14f() returns setof tt14t as +$$ +declare + rec1 record; +begin + for rec1 in select * from tt14t + loop + return next rec1; + end loop; +end; +$$ +language plpgsql; + +create view tt14v as select t.* from tt14f() t; + +select pg_get_viewdef('tt14v', true); + +select * from tt14v; + +alter table tt14t drop column f3; + +begin; + +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'tt14v'::regclass and rulename = '_RETURN') + and refobjsubid = 3 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype; + +alter table tt14t drop column f3; + +select pg_get_viewdef('tt14v', true); + +select * from tt14v; + +select f1, f4 from tt14v; + +select * from tt14v; + +rollback; + +alter table tt14t alter column f4 type integer using f4::integer; + +begin; + +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'tt14v'::regclass and rulename = '_RETURN') + and refobjsubid = 4 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype; + +alter table tt14t alter column f4 type integer using f4::integer; + +select pg_get_viewdef('tt14v', true); + +select f1, f3 from tt14v; + +select * from tt14v; + +rollback; + +drop view tt14v; + +create view tt14v as select t.f1, t.f4 from tt14f() t; + +select pg_get_viewdef('tt14v', true); + +select * from tt14v; + +alter table tt14t drop column f3; + +select pg_get_viewdef('tt14v', true); + +select * from tt14v; + +select * from tt14v; + +create type nestedcomposite as (x int8_tbl); + +create view tt15v as select row(i)::nestedcomposite from int8_tbl i; + +select * from tt15v; + +select pg_get_viewdef('tt15v', true); + +select row(i.*::int8_tbl)::nestedcomposite from int8_tbl i; + +create view tt16v as select * from int8_tbl i, lateral(values(i)) ss; + +select * from tt16v; + +select pg_get_viewdef('tt16v', true); + +select * from int8_tbl i, lateral(values(i.*::int8_tbl)) ss; + +create view tt17v as select * from int8_tbl i where i in (values(i)); + +select * from tt17v; + +select pg_get_viewdef('tt17v', true); + +select * from int8_tbl i where i.* in (values(i.*::int8_tbl)); + +create table tt15v_log(o tt15v, n tt15v, incr bool); + +create rule updlog as on update to tt15v do also + insert into tt15v_log values(old, new, row(old,old) < row(new,new)); + +create view tt18v as + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy + union all + select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz; + +select pg_get_viewdef('tt18v', true); + +select * from tt18v; + +select 'foo'::text = any(array['abc','def','foo']::text[]); + +select 'foo'::text = any((select array['abc','def','foo']::text[])); + +select 'foo'::text = any((select array['abc','def','foo']::text[])::text[]); + +create view tt19v as +select 'foo'::text = any(array['abc','def','foo']::text[]) c1, + 'foo'::text = any((select array['abc','def','foo']::text[])::text[]) c2; + +select pg_get_viewdef('tt19v', true); + +create view tt20v as +select * from + coalesce(1,2) as c, + collation for ('x'::text) col, + current_date as d, + localtimestamp(3) as t, + cast(1+2 as int4) as i4, + cast(1+2 as int8) as i8; + +select pg_get_viewdef('tt20v', true); + +create view tt201v as +select + ('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz, + extract(day from now()) as extr, + (now(), '1 day'::interval) overlaps + (current_timestamp(2), '1 day'::interval) as o, + 'foo' is normalized isn, + 'foo' is nfkc normalized isnn, + normalize('foo') as n, + normalize('foo', nfkd) as nfkd, + overlay('foo' placing 'bar' from 2) as ovl, + overlay('foo' placing 'bar' from 2 for 3) as ovl2, + position('foo' in 'foobar') as p, + substring('foo' from 2 for 3) as s, + substring('foo' similar 'f' escape '#') as ss, + substring('foo' from 'oo') as ssf, -- historically-permitted abuse + trim(' ' from ' foo ') as bt, + trim(leading ' ' from ' foo ') as lt, + trim(trailing ' foo ') as rt, + trim(E'\\000'::bytea from E'\\000Tom\\000'::bytea) as btb, + trim(leading E'\\000'::bytea from E'\\000Tom\\000'::bytea) as ltb, + trim(trailing E'\\000'::bytea from E'\\000Tom\\000'::bytea) as rtb, + CURRENT_DATE as cd, + (select * from CURRENT_DATE) as cd2, + CURRENT_TIME as ct, + (select * from CURRENT_TIME) as ct2, + CURRENT_TIME (1) as ct3, + (select * from CURRENT_TIME (1)) as ct4, + CURRENT_TIMESTAMP as ct5, + (select * from CURRENT_TIMESTAMP) as ct6, + CURRENT_TIMESTAMP (1) as ct7, + (select * from CURRENT_TIMESTAMP (1)) as ct8, + LOCALTIME as lt1, + (select * from LOCALTIME) as lt2, + LOCALTIME (1) as lt3, + (select * from LOCALTIME (1)) as lt4, + LOCALTIMESTAMP as lt5, + (select * from LOCALTIMESTAMP) as lt6, + LOCALTIMESTAMP (1) as lt7, + (select * from LOCALTIMESTAMP (1)) as lt8, + CURRENT_CATALOG as ca, + (select * from CURRENT_CATALOG) as ca2, + CURRENT_ROLE as cr, + (select * from CURRENT_ROLE) as cr2, + CURRENT_SCHEMA as cs, + (select * from CURRENT_SCHEMA) as cs2, + CURRENT_USER as cu, + (select * from CURRENT_USER) as cu2, + USER as us, + (select * from USER) as us2, + SESSION_USER seu, + (select * from SESSION_USER) as seu2, + SYSTEM_USER as su, + (select * from SYSTEM_USER) as su2; + +select pg_get_viewdef('tt201v', true); + +create view tt21v as +select * from tt5 natural inner join tt6; + +select pg_get_viewdef('tt21v', true); + +create view tt22v as +select * from tt5 natural left join tt6; + +select pg_get_viewdef('tt22v', true); + +create view tt23v (col_a, col_b) as +select q1 as other_name1, q2 as other_name2 from int8_tbl +union +select 42, 43; + +select pg_get_viewdef('tt23v', true); + +select pg_get_ruledef(oid, true) from pg_rewrite + where ev_class = 'tt23v'::regclass and ev_type = '1'; + +select (r).column2 as col_a, (rr).column2 as col_b from + cte join (select rr from (values(1,7),(3,8)) rr limit 2) ss + on (r).column1 = (rr).column1; + +select pg_get_viewdef('tt24v', true); + +select (k).word from cte; + +select pg_get_viewdef('tt25v', true); + +select * from tt24v; + +select (r).column2 from (select r from (values(1,2),(3,4)) r limit 1) ss; + +create view tt26v as +select x + y + z as c1, + (x * y) + z as c2, + x + (y * z) as c3, + (x + y) * z as c4, + x * (y + z) as c5, + x + (y + z) as c6, + x + (y # z) as c7, + (x > y) AND (y > z OR x > z) as c8, + (x > y) OR (y > z AND NOT (x > z)) as c9, + (x,y) <> ALL (values(1,2),(3,4)) as c10, + (x,y) <= ANY (values(1,2),(3,4)) as c11 +from (values(1,2,3)) v(x,y,z); + +select pg_get_viewdef('tt26v', true); + +create table tt27v_tbl (a int); + +create view tt27v as select a from tt27v_tbl; + +set restrict_nonsystem_relation_kind to 'view'; + +select a from tt27v where a > 0; + +insert into tt27v values (1); + +select viewname from pg_views where viewname = 'tt27v'; + +reset restrict_nonsystem_relation_kind; + +DROP SCHEMA temp_view_test CASCADE; + +DROP SCHEMA testviewschm2 CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/database_60.sql b/crates/pgt_pretty_print/tests/data/multi/database_60.sql new file mode 100644 index 000000000..7dac1ecbb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/database_60.sql @@ -0,0 +1,34 @@ +CREATE DATABASE regression_tbd + ENCODING utf8 LC_COLLATE "C" LC_CTYPE "C" TEMPLATE template0; + +ALTER DATABASE regression_tbd RENAME TO regression_utf8; + +ALTER DATABASE regression_utf8 SET TABLESPACE regress_tblspace; + +ALTER DATABASE regression_utf8 SET TABLESPACE pg_default; + +ALTER DATABASE regression_utf8 CONNECTION_LIMIT 123; + +BEGIN; + +UPDATE pg_database +SET datacl = array_fill(makeaclitem(10, 10, 'USAGE', false), ARRAY[5e5::int]) +WHERE datname = 'regression_utf8'; + +ALTER DATABASE regression_utf8 RENAME TO regression_rename_rolled_back; + +ROLLBACK; + +CREATE ROLE regress_datdba_before; + +CREATE ROLE regress_datdba_after; + +ALTER DATABASE regression_utf8 OWNER TO regress_datdba_before; + +REASSIGN OWNED BY regress_datdba_before TO regress_datdba_after; + +DROP DATABASE regression_utf8; + +DROP ROLE regress_datdba_before; + +DROP ROLE regress_datdba_after; diff --git a/crates/pgt_pretty_print/tests/data/multi/date_60.sql b/crates/pgt_pretty_print/tests/data/multi/date_60.sql new file mode 100644 index 000000000..f2ded87eb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/date_60.sql @@ -0,0 +1,557 @@ +CREATE TABLE DATE_TBL (f1 date); + +INSERT INTO DATE_TBL VALUES ('1957-04-09'); + +INSERT INTO DATE_TBL VALUES ('1957-06-13'); + +INSERT INTO DATE_TBL VALUES ('1996-02-28'); + +INSERT INTO DATE_TBL VALUES ('1996-02-29'); + +INSERT INTO DATE_TBL VALUES ('1996-03-01'); + +INSERT INTO DATE_TBL VALUES ('1996-03-02'); + +INSERT INTO DATE_TBL VALUES ('1997-02-28'); + +INSERT INTO DATE_TBL VALUES ('1997-02-29'); + +INSERT INTO DATE_TBL VALUES ('1997-03-01'); + +INSERT INTO DATE_TBL VALUES ('1997-03-02'); + +INSERT INTO DATE_TBL VALUES ('2000-04-01'); + +INSERT INTO DATE_TBL VALUES ('2000-04-02'); + +INSERT INTO DATE_TBL VALUES ('2000-04-03'); + +INSERT INTO DATE_TBL VALUES ('2038-04-08'); + +INSERT INTO DATE_TBL VALUES ('2039-04-09'); + +INSERT INTO DATE_TBL VALUES ('2040-04-10'); + +INSERT INTO DATE_TBL VALUES ('2040-04-10 BC'); + +SELECT f1 FROM DATE_TBL; + +SELECT f1 FROM DATE_TBL WHERE f1 < '2000-01-01'; + +SELECT f1 FROM DATE_TBL + WHERE f1 BETWEEN '2000-01-01' AND '2001-01-01'; + +SET datestyle TO iso; + +SET datestyle TO ymd; + +SELECT date 'January 8, 1999'; + +SELECT date '1999-01-08'; + +SELECT date '1999-01-18'; + +SELECT date '1/8/1999'; + +SELECT date '1/18/1999'; + +SELECT date '18/1/1999'; + +SELECT date '01/02/03'; + +SELECT date '19990108'; + +SELECT date '990108'; + +SELECT date '1999.008'; + +SELECT date 'J2451187'; + +SELECT date 'January 8, 99 BC'; + +SELECT date '99-Jan-08'; + +SELECT date '1999-Jan-08'; + +SELECT date '08-Jan-99'; + +SELECT date '08-Jan-1999'; + +SELECT date 'Jan-08-99'; + +SELECT date 'Jan-08-1999'; + +SELECT date '99-08-Jan'; + +SELECT date '1999-08-Jan'; + +SELECT date '99 Jan 08'; + +SELECT date '1999 Jan 08'; + +SELECT date '08 Jan 99'; + +SELECT date '08 Jan 1999'; + +SELECT date 'Jan 08 99'; + +SELECT date 'Jan 08 1999'; + +SELECT date '99 08 Jan'; + +SELECT date '1999 08 Jan'; + +SELECT date '99-01-08'; + +SELECT date '1999-01-08'; + +SELECT date '08-01-99'; + +SELECT date '08-01-1999'; + +SELECT date '01-08-99'; + +SELECT date '01-08-1999'; + +SELECT date '99-08-01'; + +SELECT date '1999-08-01'; + +SELECT date '99 01 08'; + +SELECT date '1999 01 08'; + +SELECT date '08 01 99'; + +SELECT date '08 01 1999'; + +SELECT date '01 08 99'; + +SELECT date '01 08 1999'; + +SELECT date '99 08 01'; + +SELECT date '1999 08 01'; + +SET datestyle TO dmy; + +SELECT date 'January 8, 1999'; + +SELECT date '1999-01-08'; + +SELECT date '1999-01-18'; + +SELECT date '1/8/1999'; + +SELECT date '1/18/1999'; + +SELECT date '18/1/1999'; + +SELECT date '01/02/03'; + +SELECT date '19990108'; + +SELECT date '990108'; + +SELECT date '1999.008'; + +SELECT date 'J2451187'; + +SELECT date 'January 8, 99 BC'; + +SELECT date '99-Jan-08'; + +SELECT date '1999-Jan-08'; + +SELECT date '08-Jan-99'; + +SELECT date '08-Jan-1999'; + +SELECT date 'Jan-08-99'; + +SELECT date 'Jan-08-1999'; + +SELECT date '99-08-Jan'; + +SELECT date '1999-08-Jan'; + +SELECT date '99 Jan 08'; + +SELECT date '1999 Jan 08'; + +SELECT date '08 Jan 99'; + +SELECT date '08 Jan 1999'; + +SELECT date 'Jan 08 99'; + +SELECT date 'Jan 08 1999'; + +SELECT date '99 08 Jan'; + +SELECT date '1999 08 Jan'; + +SELECT date '99-01-08'; + +SELECT date '1999-01-08'; + +SELECT date '08-01-99'; + +SELECT date '08-01-1999'; + +SELECT date '01-08-99'; + +SELECT date '01-08-1999'; + +SELECT date '99-08-01'; + +SELECT date '1999-08-01'; + +SELECT date '99 01 08'; + +SELECT date '1999 01 08'; + +SELECT date '08 01 99'; + +SELECT date '08 01 1999'; + +SELECT date '01 08 99'; + +SELECT date '01 08 1999'; + +SELECT date '99 08 01'; + +SELECT date '1999 08 01'; + +SET datestyle TO mdy; + +SELECT date 'January 8, 1999'; + +SELECT date '1999-01-08'; + +SELECT date '1999-01-18'; + +SELECT date '1/8/1999'; + +SELECT date '1/18/1999'; + +SELECT date '18/1/1999'; + +SELECT date '01/02/03'; + +SELECT date '19990108'; + +SELECT date '990108'; + +SELECT date '1999.008'; + +SELECT date 'J2451187'; + +SELECT date 'January 8, 99 BC'; + +SELECT date '99-Jan-08'; + +SELECT date '1999-Jan-08'; + +SELECT date '08-Jan-99'; + +SELECT date '08-Jan-1999'; + +SELECT date 'Jan-08-99'; + +SELECT date 'Jan-08-1999'; + +SELECT date '99-08-Jan'; + +SELECT date '1999-08-Jan'; + +SELECT date '99 Jan 08'; + +SELECT date '1999 Jan 08'; + +SELECT date '08 Jan 99'; + +SELECT date '08 Jan 1999'; + +SELECT date 'Jan 08 99'; + +SELECT date 'Jan 08 1999'; + +SELECT date '99 08 Jan'; + +SELECT date '1999 08 Jan'; + +SELECT date '99-01-08'; + +SELECT date '1999-01-08'; + +SELECT date '08-01-99'; + +SELECT date '08-01-1999'; + +SELECT date '01-08-99'; + +SELECT date '01-08-1999'; + +SELECT date '99-08-01'; + +SELECT date '1999-08-01'; + +SELECT date '99 01 08'; + +SELECT date '1999 01 08'; + +SELECT date '08 01 99'; + +SELECT date '08 01 1999'; + +SELECT date '01 08 99'; + +SELECT date '01 08 1999'; + +SELECT date '99 08 01'; + +SELECT date '1999 08 01'; + +SELECT date '4714-11-24 BC'; + +SELECT date '4714-11-23 BC'; + +SELECT date '5874897-12-31'; + +SELECT date '5874898-01-01'; + +SELECT pg_input_is_valid('now', 'date'); + +SELECT pg_input_is_valid('garbage', 'date'); + +SELECT pg_input_is_valid('6874898-01-01', 'date'); + +SELECT * FROM pg_input_error_info('garbage', 'date'); + +SELECT * FROM pg_input_error_info('6874898-01-01', 'date'); + +RESET datestyle; + +SELECT f1 - date '2000-01-01' AS "Days From 2K" FROM DATE_TBL; + +SELECT f1 - date 'epoch' AS "Days From Epoch" FROM DATE_TBL; + +SELECT date 'yesterday' - date 'today' AS "One day"; + +SELECT date 'today' - date 'tomorrow' AS "One day"; + +SELECT date 'yesterday' - date 'tomorrow' AS "Two days"; + +SELECT date 'tomorrow' - date 'today' AS "One day"; + +SELECT date 'today' - date 'yesterday' AS "One day"; + +SELECT date 'tomorrow' - date 'yesterday' AS "Two days"; + +SELECT f1 as "date", + date_part('year', f1) AS year, + date_part('month', f1) AS month, + date_part('day', f1) AS day, + date_part('quarter', f1) AS quarter, + date_part('decade', f1) AS decade, + date_part('century', f1) AS century, + date_part('millennium', f1) AS millennium, + date_part('isoyear', f1) AS isoyear, + date_part('week', f1) AS week, + date_part('dow', f1) AS dow, + date_part('isodow', f1) AS isodow, + date_part('doy', f1) AS doy, + date_part('julian', f1) AS julian, + date_part('epoch', f1) AS epoch + FROM date_tbl; + +SELECT EXTRACT(EPOCH FROM DATE '1970-01-01'); + +SELECT EXTRACT(CENTURY FROM DATE '0101-12-31 BC'); + +SELECT EXTRACT(CENTURY FROM DATE '0100-12-31 BC'); + +SELECT EXTRACT(CENTURY FROM DATE '0001-12-31 BC'); + +SELECT EXTRACT(CENTURY FROM DATE '0001-01-01'); + +SELECT EXTRACT(CENTURY FROM DATE '0001-01-01 AD'); + +SELECT EXTRACT(CENTURY FROM DATE '1900-12-31'); + +SELECT EXTRACT(CENTURY FROM DATE '1901-01-01'); + +SELECT EXTRACT(CENTURY FROM DATE '2000-12-31'); + +SELECT EXTRACT(CENTURY FROM DATE '2001-01-01'); + +SELECT EXTRACT(CENTURY FROM CURRENT_DATE)>=21 AS True; + +SELECT EXTRACT(MILLENNIUM FROM DATE '0001-12-31 BC'); + +SELECT EXTRACT(MILLENNIUM FROM DATE '0001-01-01 AD'); + +SELECT EXTRACT(MILLENNIUM FROM DATE '1000-12-31'); + +SELECT EXTRACT(MILLENNIUM FROM DATE '1001-01-01'); + +SELECT EXTRACT(MILLENNIUM FROM DATE '2000-12-31'); + +SELECT EXTRACT(MILLENNIUM FROM DATE '2001-01-01'); + +SELECT EXTRACT(MILLENNIUM FROM CURRENT_DATE); + +SELECT EXTRACT(DECADE FROM DATE '1994-12-25'); + +SELECT EXTRACT(DECADE FROM DATE '0010-01-01'); + +SELECT EXTRACT(DECADE FROM DATE '0009-12-31'); + +SELECT EXTRACT(DECADE FROM DATE '0001-01-01 BC'); + +SELECT EXTRACT(DECADE FROM DATE '0002-12-31 BC'); + +SELECT EXTRACT(DECADE FROM DATE '0011-01-01 BC'); + +SELECT EXTRACT(DECADE FROM DATE '0012-12-31 BC'); + +SELECT EXTRACT(MICROSECONDS FROM DATE '2020-08-11'); + +SELECT EXTRACT(MILLISECONDS FROM DATE '2020-08-11'); + +SELECT EXTRACT(SECOND FROM DATE '2020-08-11'); + +SELECT EXTRACT(MINUTE FROM DATE '2020-08-11'); + +SELECT EXTRACT(HOUR FROM DATE '2020-08-11'); + +SELECT EXTRACT(DAY FROM DATE '2020-08-11'); + +SELECT EXTRACT(MONTH FROM DATE '2020-08-11'); + +SELECT EXTRACT(YEAR FROM DATE '2020-08-11'); + +SELECT EXTRACT(YEAR FROM DATE '2020-08-11 BC'); + +SELECT EXTRACT(DECADE FROM DATE '2020-08-11'); + +SELECT EXTRACT(CENTURY FROM DATE '2020-08-11'); + +SELECT EXTRACT(MILLENNIUM FROM DATE '2020-08-11'); + +SELECT EXTRACT(ISOYEAR FROM DATE '2020-08-11'); + +SELECT EXTRACT(ISOYEAR FROM DATE '2020-08-11 BC'); + +SELECT EXTRACT(QUARTER FROM DATE '2020-08-11'); + +SELECT EXTRACT(WEEK FROM DATE '2020-08-11'); + +SELECT EXTRACT(DOW FROM DATE '2020-08-11'); + +SELECT EXTRACT(DOW FROM DATE '2020-08-16'); + +SELECT EXTRACT(ISODOW FROM DATE '2020-08-11'); + +SELECT EXTRACT(ISODOW FROM DATE '2020-08-16'); + +SELECT EXTRACT(DOY FROM DATE '2020-08-11'); + +SELECT EXTRACT(TIMEZONE FROM DATE '2020-08-11'); + +SELECT EXTRACT(TIMEZONE_M FROM DATE '2020-08-11'); + +SELECT EXTRACT(TIMEZONE_H FROM DATE '2020-08-11'); + +SELECT EXTRACT(EPOCH FROM DATE '2020-08-11'); + +SELECT EXTRACT(JULIAN FROM DATE '2020-08-11'); + +SELECT DATE_TRUNC('MILLENNIUM', TIMESTAMP '1970-03-20 04:30:00.00000'); + +SELECT DATE_TRUNC('MILLENNIUM', DATE '1970-03-20'); + +SELECT DATE_TRUNC('CENTURY', TIMESTAMP '1970-03-20 04:30:00.00000'); + +SELECT DATE_TRUNC('CENTURY', DATE '1970-03-20'); + +SELECT DATE_TRUNC('CENTURY', DATE '2004-08-10'); + +SELECT DATE_TRUNC('CENTURY', DATE '0002-02-04'); + +SELECT DATE_TRUNC('CENTURY', DATE '0055-08-10 BC'); + +SELECT DATE_TRUNC('DECADE', DATE '1993-12-25'); + +SELECT DATE_TRUNC('DECADE', DATE '0004-12-25'); + +SELECT DATE_TRUNC('DECADE', DATE '0002-12-31 BC'); + +select 'infinity'::date, '-infinity'::date; + +select 'infinity'::date > 'today'::date as t; + +select '-infinity'::date < 'today'::date as t; + +select isfinite('infinity'::date), isfinite('-infinity'::date), isfinite('today'::date); + +select 'infinity'::date = '+infinity'::date as t; + +SELECT EXTRACT(DAY FROM DATE 'infinity'); + +SELECT EXTRACT(DAY FROM DATE '-infinity'); + +SELECT EXTRACT(DAY FROM DATE 'infinity'); + +SELECT EXTRACT(MONTH FROM DATE 'infinity'); + +SELECT EXTRACT(QUARTER FROM DATE 'infinity'); + +SELECT EXTRACT(WEEK FROM DATE 'infinity'); + +SELECT EXTRACT(DOW FROM DATE 'infinity'); + +SELECT EXTRACT(ISODOW FROM DATE 'infinity'); + +SELECT EXTRACT(DOY FROM DATE 'infinity'); + +SELECT EXTRACT(EPOCH FROM DATE 'infinity'); + +SELECT EXTRACT(EPOCH FROM DATE '-infinity'); + +SELECT EXTRACT(YEAR FROM DATE 'infinity'); + +SELECT EXTRACT(DECADE FROM DATE 'infinity'); + +SELECT EXTRACT(CENTURY FROM DATE 'infinity'); + +SELECT EXTRACT(MILLENNIUM FROM DATE 'infinity'); + +SELECT EXTRACT(JULIAN FROM DATE 'infinity'); + +SELECT EXTRACT(ISOYEAR FROM DATE 'infinity'); + +SELECT EXTRACT(EPOCH FROM DATE 'infinity'); + +SELECT EXTRACT(MICROSEC FROM DATE 'infinity'); + +select make_date(2013, 7, 15); + +select make_date(-44, 3, 15); + +select make_time(8, 20, 0.0); + +select make_date(0, 7, 15); + +select make_date(2013, 2, 30); + +select make_date(2013, 13, 1); + +select make_date(2013, 11, -1); + +SELECT make_date(-2147483648, 1, 1); + +select make_time(10, 55, 100.1); + +select make_time(24, 0, 2.1); diff --git a/crates/pgt_pretty_print/tests/data/multi/dbsize_60.sql b/crates/pgt_pretty_print/tests/data/multi/dbsize_60.sql new file mode 100644 index 000000000..c4c5d76dc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/dbsize_60.sql @@ -0,0 +1,78 @@ +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10::bigint), (1000::bigint), (1000000::bigint), + (1000000000::bigint), (1000000000000::bigint), + (1000000000000000::bigint)) x(size); + +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10::numeric), (1000::numeric), (1000000::numeric), + (1000000000::numeric), (1000000000000::numeric), + (1000000000000000::numeric), + (10.5::numeric), (1000.5::numeric), (1000000.5::numeric), + (1000000000.5::numeric), (1000000000000.5::numeric), + (1000000000000000.5::numeric)) x(size); + +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::bigint), (10240::bigint), + (10485247::bigint), (10485248::bigint), + (10736893951::bigint), (10736893952::bigint), + (10994579406847::bigint), (10994579406848::bigint), + (11258449312612351::bigint), (11258449312612352::bigint)) x(size); + +SELECT size, pg_size_pretty(size), pg_size_pretty(-1 * size) FROM + (VALUES (10239::numeric), (10240::numeric), + (10485247::numeric), (10485248::numeric), + (10736893951::numeric), (10736893952::numeric), + (10994579406847::numeric), (10994579406848::numeric), + (11258449312612351::numeric), (11258449312612352::numeric), + (11528652096115048447::numeric), (11528652096115048448::numeric)) x(size); + +SELECT pg_size_pretty('-9223372036854775808'::bigint), + pg_size_pretty('9223372036854775807'::bigint); + +SELECT size, pg_size_bytes(size) FROM + (VALUES ('1'), ('123bytes'), ('256 B'), ('1kB'), ('1MB'), (' 1 GB'), ('1.5 GB '), + ('1TB'), ('3000 TB'), ('1e6 MB'), ('99 PB')) x(size); + +SELECT size, pg_size_bytes(size) FROM + (VALUES ('1'), ('123bYteS'), ('1kb'), ('1mb'), (' 1 Gb'), ('1.5 gB '), + ('1tb'), ('3000 tb'), ('1e6 mb'), ('99 pb')) x(size); + +SELECT size, pg_size_bytes(size) FROM + (VALUES ('-1'), ('-123bytes'), ('-1kb'), ('-1mb'), (' -1 Gb'), ('-1.5 gB '), + ('-1tb'), ('-3000 TB'), ('-10e-1 MB'), ('-99 PB')) x(size); + +SELECT size, pg_size_bytes(size) FROM + (VALUES ('-1.'), ('-1.kb'), ('-1. kb'), ('-0. gb'), + ('-.1'), ('-.1kb'), ('-.1 kb'), ('-.0 gb')) x(size); + +SELECT pg_size_bytes('1 AB'); + +SELECT pg_size_bytes('1 AB A'); + +SELECT pg_size_bytes('1 AB A '); + +SELECT pg_size_bytes('9223372036854775807.9'); + +SELECT pg_size_bytes('1e100'); + +SELECT pg_size_bytes('1e1000000000000000000'); + +SELECT pg_size_bytes('1 byte'); + +SELECT pg_size_bytes(''); + +SELECT pg_size_bytes('kb'); + +SELECT pg_size_bytes('..'); + +SELECT pg_size_bytes('-.'); + +SELECT pg_size_bytes('-.kb'); + +SELECT pg_size_bytes('-. kb'); + +SELECT pg_size_bytes('.+912'); + +SELECT pg_size_bytes('+912+ kB'); + +SELECT pg_size_bytes('++123 kB'); diff --git a/crates/pgt_pretty_print/tests/data/multi/delete_60.sql b/crates/pgt_pretty_print/tests/data/multi/delete_60.sql new file mode 100644 index 000000000..10cf12a2a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/delete_60.sql @@ -0,0 +1,23 @@ +CREATE TABLE delete_test ( + id SERIAL PRIMARY KEY, + a INT, + b text +); + +INSERT INTO delete_test (a) VALUES (10); + +INSERT INTO delete_test (a, b) VALUES (50, repeat('x', 10000)); + +INSERT INTO delete_test (a) VALUES (100); + +DELETE FROM delete_test AS dt WHERE dt.a > 75; + +DELETE FROM delete_test dt WHERE delete_test.a > 25; + +SELECT id, a, char_length(b) FROM delete_test; + +DELETE FROM delete_test WHERE a > 25; + +SELECT id, a, char_length(b) FROM delete_test; + +DROP TABLE delete_test; diff --git a/crates/pgt_pretty_print/tests/data/multi/dependency_60.sql b/crates/pgt_pretty_print/tests/data/multi/dependency_60.sql new file mode 100644 index 000000000..15b185a46 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/dependency_60.sql @@ -0,0 +1,127 @@ +CREATE USER regress_dep_user; + +CREATE USER regress_dep_user2; + +CREATE USER regress_dep_user3; + +CREATE GROUP regress_dep_group; + +CREATE TABLE deptest (f1 serial primary key, f2 text); + +GRANT SELECT ON TABLE deptest TO GROUP regress_dep_group; + +GRANT ALL ON TABLE deptest TO regress_dep_user, regress_dep_user2; + +DROP USER regress_dep_user; + +DROP GROUP regress_dep_group; + +REVOKE SELECT ON deptest FROM GROUP regress_dep_group; + +DROP GROUP regress_dep_group; + +REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, MAINTAIN ON deptest FROM regress_dep_user; + +DROP USER regress_dep_user; + +REVOKE TRIGGER ON deptest FROM regress_dep_user; + +DROP USER regress_dep_user; + +REVOKE ALL ON deptest FROM regress_dep_user2; + +DROP USER regress_dep_user2; + +ALTER TABLE deptest OWNER TO regress_dep_user3; + +DROP USER regress_dep_user3; + +DROP TABLE deptest; + +DROP USER regress_dep_user3; + +CREATE USER regress_dep_user0; + +CREATE USER regress_dep_user1; + +CREATE USER regress_dep_user2; + +SET SESSION AUTHORIZATION regress_dep_user0; + +DROP OWNED BY regress_dep_user1; + +DROP OWNED BY regress_dep_user0, regress_dep_user2; + +REASSIGN OWNED BY regress_dep_user0 TO regress_dep_user1; + +REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user0; + +DROP OWNED BY regress_dep_user0; + +CREATE TABLE deptest1 (f1 int unique); + +GRANT ALL ON deptest1 TO regress_dep_user1 WITH GRANT OPTION; + +SET SESSION AUTHORIZATION regress_dep_user1; + +CREATE TABLE deptest (a serial primary key, b text); + +GRANT ALL ON deptest1 TO regress_dep_user2; + +RESET SESSION AUTHORIZATION; + +DROP OWNED BY regress_dep_user1; + +GRANT ALL ON deptest1 TO regress_dep_user1; + +GRANT CREATE ON DATABASE regression TO regress_dep_user1; + +SET SESSION AUTHORIZATION regress_dep_user1; + +CREATE SCHEMA deptest; + +CREATE TABLE deptest (a serial primary key, b text); + +ALTER DEFAULT PRIVILEGES FOR ROLE regress_dep_user1 IN SCHEMA deptest + GRANT ALL ON TABLES TO regress_dep_user2; + +CREATE FUNCTION deptest_func() RETURNS void LANGUAGE plpgsql + AS $$ BEGIN END; $$; + +CREATE TYPE deptest_enum AS ENUM ('red'); + +CREATE TYPE deptest_range AS RANGE (SUBTYPE = int4); + +CREATE TABLE deptest2 (f1 int); + +CREATE SEQUENCE ss1; + +ALTER TABLE deptest2 ALTER f1 SET DEFAULT nextval('ss1'); + +ALTER SEQUENCE ss1 OWNED BY deptest2.f1; + +CREATE TYPE deptest_t AS (a int); + +SELECT typowner = relowner +FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t'; + +RESET SESSION AUTHORIZATION; + +REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user2; + +SELECT typowner = relowner +FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t'; + +DROP USER regress_dep_user1; + +DROP OWNED BY regress_dep_user1; + +DROP USER regress_dep_user1; + +DROP USER regress_dep_user2; + +DROP OWNED BY regress_dep_user2, regress_dep_user0; + +DROP USER regress_dep_user2; + +DROP USER regress_dep_user0; diff --git a/crates/pgt_pretty_print/tests/data/multi/domain_60.sql b/crates/pgt_pretty_print/tests/data/multi/domain_60.sql new file mode 100644 index 000000000..47f4142a1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/domain_60.sql @@ -0,0 +1,1039 @@ +create domain domaindroptest int4; + +comment on domain domaindroptest is 'About to drop this..'; + +create domain dependenttypetest domaindroptest; + +drop domain domaindroptest; + +drop domain domaindroptest cascade; + +drop domain domaindroptest cascade; + +create domain d_fail as no_such_type; + +create domain d_fail as int constraint cc REFERENCES this_table_not_exists(i); + +create domain d_fail as int4 not null null; + +create domain d_fail as int4 not null default 3 default 3; + +create domain d_fail int4 DEFAULT 3 + 'h'; + +create domain d_fail int4 collate "C"; + +create domain d_fail as anyelement; + +create domain d_fail as int4 unique; + +create domain d_fail as int4 PRIMARY key; + +create domain d_fail as int4 constraint cc generated by default as identity; + +create domain d_fail as int4 constraint cc check (values > 1) no inherit; + +create domain d_fail as int4 constraint cc check (values > 1) deferrable; + +create domain domainvarchar varchar(5); + +create domain domainnumeric numeric(8,2); + +create domain domainint4 int4; + +create domain domaintext text; + +SELECT cast('123456' as domainvarchar); + +SELECT cast('12345' as domainvarchar); + +create table basictest + ( testint4 domainint4 + , testtext domaintext + , testvarchar domainvarchar + , testnumeric domainnumeric + ); + +INSERT INTO basictest values ('88', 'haha', 'short', '123.12'); + +INSERT INTO basictest values ('88', 'haha', 'short text', '123.12'); + +INSERT INTO basictest values ('88', 'haha', 'short', '123.1212'); + +select * from basictest; + +select testtext || testvarchar as concat, testnumeric + 42 as sum +from basictest; + +select pg_typeof(coalesce(4::domainint4, 7)); + +select pg_typeof(coalesce(4::domainint4, 7::domainint4)); + +drop table basictest; + +drop domain domainvarchar restrict; + +drop domain domainnumeric restrict; + +drop domain domainint4 restrict; + +drop domain domaintext; + +create domain positiveint int4 check(value > 0); + +create domain weirdfloat float8 check((1 / value) < 10); + +select pg_input_is_valid('1', 'positiveint'); + +select pg_input_is_valid('junk', 'positiveint'); + +select pg_input_is_valid('-1', 'positiveint'); + +select * from pg_input_error_info('junk', 'positiveint'); + +select * from pg_input_error_info('-1', 'positiveint'); + +select * from pg_input_error_info('junk', 'weirdfloat'); + +select * from pg_input_error_info('0.01', 'weirdfloat'); + +select * from pg_input_error_info('0', 'weirdfloat'); + +drop domain positiveint; + +drop domain weirdfloat; + +create domain domainint4arr int4[1]; + +create domain domainchar4arr varchar(4)[2][3]; + +create table domarrtest + ( testint4arr domainint4arr + , testchar4arr domainchar4arr + ); + +INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"}}'); + +INSERT INTO domarrtest values ('{{2,2},{2,2}}', '{{"a","b"}}'); + +INSERT INTO domarrtest values ('{2,2}', '{{"a","b"},{"c","d"},{"e","f"}}'); + +INSERT INTO domarrtest values ('{2,2}', '{{"a"},{"c"}}'); + +INSERT INTO domarrtest values (NULL, '{{"a","b","c"},{"d","e","f"}}'); + +INSERT INTO domarrtest values (NULL, '{{"toolong","b","c"},{"d","e","f"}}'); + +INSERT INTO domarrtest (testint4arr[1], testint4arr[3]) values (11,22); + +select * from domarrtest; + +select testint4arr[1], testchar4arr[2:2] from domarrtest; + +select array_dims(testint4arr), array_dims(testchar4arr) from domarrtest; + +select * from domarrtest; + +update domarrtest set + testint4arr[1] = testint4arr[1] + 1, + testint4arr[3] = testint4arr[3] - 1 +where testchar4arr is null; + +select * from domarrtest where testchar4arr is null; + +drop table domarrtest; + +drop domain domainint4arr restrict; + +drop domain domainchar4arr restrict; + +create domain dia as int[]; + +select '{1,2,3}'::dia; + +select array_dims('{1,2,3}'::dia); + +select pg_typeof('{1,2,3}'::dia); + +select pg_typeof('{1,2,3}'::dia || 42); + +drop domain dia; + +create type comptype as (r float8, i float8); + +create domain dcomptype as comptype; + +create table dcomptable (d1 dcomptype unique); + +insert into dcomptable values (row(1,2)::dcomptype); + +insert into dcomptable values (row(3,4)::comptype); + +insert into dcomptable values (row(1,2)::dcomptype); + +insert into dcomptable (d1.r) values(11); + +select * from dcomptable; + +select (d1).r, (d1).i, (d1).* from dcomptable; + +update dcomptable set d1.r = (d1).r + 1 where (d1).i > 0; + +select * from dcomptable; + +alter domain dcomptype add constraint c1 check ((value).r <= (value).i); + +alter domain dcomptype add constraint c2 check ((value).r > (value).i); + +select row(2,1)::dcomptype; + +insert into dcomptable values (row(1,2)::comptype); + +insert into dcomptable values (row(2,1)::comptype); + +insert into dcomptable (d1.r) values(99); + +insert into dcomptable (d1.r, d1.i) values(99, 100); + +insert into dcomptable (d1.r, d1.i) values(100, 99); + +update dcomptable set d1.r = (d1).r + 1 where (d1).i > 0; + +update dcomptable set d1.r = (d1).r - 1, d1.i = (d1).i + 1 where (d1).i > 0; + +select * from dcomptable; + +update dcomptable set d1.r = (d1).r - 1, d1.i = (d1).i + 1 where (d1).i > 0; + +create rule silly as on delete to dcomptable do instead + update dcomptable set d1.r = (d1).r - 1, d1.i = (d1).i + 1 where (d1).i > 0; + +create function makedcomp(r float8, i float8) returns dcomptype +as 'select row(r, i)' language sql; + +select makedcomp(1,2); + +select makedcomp(2,1); + +select * from makedcomp(1,2) m; + +select m, m is not null from makedcomp(1,2) m; + +drop function makedcomp(float8, float8); + +drop table dcomptable; + +drop type comptype cascade; + +create type comptype as (r float8, i float8); + +create domain dcomptype as comptype; + +alter domain dcomptype add constraint c1 check ((value).r > 0); + +comment on constraint c1 on domain dcomptype is 'random commentary'; + +select row(0,1)::dcomptype; + +alter type comptype alter attribute r type varchar; + +alter type comptype alter attribute r type bigint; + +alter type comptype drop attribute r; + +alter type comptype drop attribute i; + +select conname, obj_description(oid, 'pg_constraint') from pg_constraint + where contypid = 'dcomptype'::regtype; + +drop type comptype cascade; + +create type comptype as (r float8, i float8); + +create domain dcomptypea as comptype[]; + +create table dcomptable (d1 dcomptypea unique); + +insert into dcomptable values (array[row(1,2)]::dcomptypea); + +insert into dcomptable values (array[row(3,4), row(5,6)]::comptype[]); + +insert into dcomptable values (array[row(7,8)::comptype, row(9,10)::comptype]); + +insert into dcomptable values (array[row(1,2)]::dcomptypea); + +insert into dcomptable (d1[1]) values(row(9,10)); + +insert into dcomptable (d1[1].r) values(11); + +select * from dcomptable; + +select d1[2], d1[1].r, d1[1].i from dcomptable; + +update dcomptable set d1[2] = row(d1[2].i, d1[2].r); + +select * from dcomptable; + +update dcomptable set d1[1].r = d1[1].r + 1 where d1[1].i > 0; + +select * from dcomptable; + +alter domain dcomptypea add constraint c1 check (value[1].r <= value[1].i); + +alter domain dcomptypea add constraint c2 check (value[1].r > value[1].i); + +select array[row(2,1)]::dcomptypea; + +insert into dcomptable values (array[row(1,2)]::comptype[]); + +insert into dcomptable values (array[row(2,1)]::comptype[]); + +insert into dcomptable (d1[1].r) values(99); + +insert into dcomptable (d1[1].r, d1[1].i) values(99, 100); + +insert into dcomptable (d1[1].r, d1[1].i) values(100, 99); + +update dcomptable set d1[1].r = d1[1].r + 1 where d1[1].i > 0; + +update dcomptable set d1[1].r = d1[1].r - 1, d1[1].i = d1[1].i + 1 + where d1[1].i > 0; + +select * from dcomptable; + +update dcomptable set d1[1].r = d1[1].r - 1, d1[1].i = d1[1].i + 1 + where d1[1].i > 0; + +create rule silly as on delete to dcomptable do instead + update dcomptable set d1[1].r = d1[1].r - 1, d1[1].i = d1[1].i + 1 + where d1[1].i > 0; + +drop table dcomptable; + +drop type comptype cascade; + +create domain posint as int check (value > 0); + +create table pitable (f1 posint[]); + +insert into pitable values(array[42]); + +insert into pitable values(array[-1]); + +insert into pitable values('{0}'); + +update pitable set f1[1] = f1[1] + 1; + +update pitable set f1[1] = 0; + +select * from pitable; + +drop table pitable; + +create domain vc4 as varchar(4); + +create table vc4table (f1 vc4[]); + +insert into vc4table values(array['too long']); + +insert into vc4table values(array['too long']::vc4[]); + +select * from vc4table; + +drop table vc4table; + +drop type vc4; + +create domain dposinta as posint[]; + +create table dposintatable (f1 dposinta[]); + +insert into dposintatable values(array[array[42]]); + +insert into dposintatable values(array[array[42]::posint[]]); + +insert into dposintatable values(array[array[42]::dposinta]); + +select f1, f1[1], (f1[1])[1] from dposintatable; + +select pg_typeof(f1) from dposintatable; + +select pg_typeof(f1[1]) from dposintatable; + +select pg_typeof(f1[1][1]) from dposintatable; + +select pg_typeof((f1[1])[1]) from dposintatable; + +update dposintatable set f1[2] = array[99]; + +select f1, f1[1], (f1[2])[1] from dposintatable; + +update dposintatable set f1[2][1] = array[97]; + +drop table dposintatable; + +drop domain posint cascade; + +create type comptype as (cf1 int, cf2 int); + +create domain dcomptype as comptype check ((value).cf1 > 0); + +create table dcomptable (f1 dcomptype[]); + +insert into dcomptable values (null); + +update dcomptable set f1[1].cf2 = 5; + +table dcomptable; + +update dcomptable set f1[1].cf1 = -1; + +update dcomptable set f1[1].cf1 = 1; + +table dcomptable; + +alter domain dcomptype drop constraint dcomptype_check; + +update dcomptable set f1[1].cf1 = -1; + +table dcomptable; + +drop table dcomptable; + +drop type comptype cascade; + +create domain dnotnull varchar(15) NOT NULL; + +create domain dnull varchar(15); + +create domain dcheck varchar(15) NOT NULL CHECK (VALUE = 'a' OR VALUE = 'c' OR VALUE = 'd'); + +create table nulltest + ( col1 dnotnull + , col2 dnotnull NULL -- NOT NULL in the domain cannot be overridden + , col3 dnull NOT NULL + , col4 dnull + , col5 dcheck CHECK (col5 IN ('c', 'd')) + ); + +INSERT INTO nulltest DEFAULT VALUES; + +INSERT INTO nulltest values ('a', 'b', 'c', 'd', 'c'); + +insert into nulltest values ('a', 'b', 'c', 'd', NULL); + +insert into nulltest values ('a', 'b', 'c', 'd', 'a'); + +INSERT INTO nulltest values (NULL, 'b', 'c', 'd', 'd'); + +INSERT INTO nulltest values ('a', NULL, 'c', 'd', 'c'); + +INSERT INTO nulltest values ('a', 'b', NULL, 'd', 'c'); + +INSERT INTO nulltest values ('a', 'b', 'c', NULL, 'd'); + +select * from nulltest; + +SELECT cast('1' as dnotnull); + +SELECT cast(NULL as dnotnull); + +SELECT cast(cast(NULL as dnull) as dnotnull); + +SELECT cast(col4 as dnotnull) from nulltest; + +drop table nulltest; + +drop domain dnotnull restrict; + +drop domain dnull restrict; + +drop domain dcheck restrict; + +create domain ddef1 int4 DEFAULT 3; + +create domain ddef2 oid DEFAULT '12'; + +create domain ddef3 text DEFAULT 5; + +create sequence ddef4_seq; + +create domain ddef4 int4 DEFAULT nextval('ddef4_seq'); + +create domain ddef5 numeric(8,2) NOT NULL DEFAULT '12.12'; + +create table defaulttest + ( col1 ddef1 + , col2 ddef2 + , col3 ddef3 + , col4 ddef4 PRIMARY KEY + , col5 ddef1 NOT NULL DEFAULT NULL + , col6 ddef2 DEFAULT '88' + , col7 ddef4 DEFAULT 8000 + , col8 ddef5 + ); + +insert into defaulttest(col4) values(0); + +alter table defaulttest alter column col5 drop default; + +insert into defaulttest default values; + +alter table defaulttest alter column col5 set default null; + +insert into defaulttest(col4) values(0); + +alter table defaulttest alter column col5 drop default; + +insert into defaulttest default values; + +insert into defaulttest default values; + +select * from defaulttest; + +drop table defaulttest cascade; + +create domain dnotnulltest integer; + +create table domnotnull +( col1 dnotnulltest +, col2 dnotnulltest +); + +insert into domnotnull default values; + +alter domain dnotnulltest set not null; + +update domnotnull set col1 = 5; + +alter domain dnotnulltest set not null; + +update domnotnull set col2 = 6; + +alter domain dnotnulltest set not null; + +update domnotnull set col1 = null; + +alter domain dnotnulltest drop not null; + +update domnotnull set col1 = null; + +update domnotnull set col1 = 5; + +alter domain dnotnulltest add constraint dnotnulltest_notnull not null; + +update domnotnull set col1 = null; + +select conname, pg_get_constraintdef(oid) from pg_constraint + where contypid = 'dnotnulltest'::regtype; + +alter domain dnotnulltest drop constraint dnotnulltest_notnull; + +update domnotnull set col1 = null; + +drop domain dnotnulltest cascade; + +create table domdeftest (col1 ddef1); + +insert into domdeftest default values; + +select * from domdeftest; + +alter domain ddef1 set default '42'; + +insert into domdeftest default values; + +select * from domdeftest; + +alter domain ddef1 drop default; + +insert into domdeftest default values; + +select * from domdeftest; + +drop table domdeftest; + +create domain con as integer; + +create table domcontest (col1 con); + +insert into domcontest values (1); + +insert into domcontest values (2); + +alter domain con add constraint t check (VALUE < 1); + +alter domain con add constraint t check (VALUE < 34); + +alter domain con add check (VALUE > 0); + +insert into domcontest values (-5); + +insert into domcontest values (42); + +insert into domcontest values (5); + +alter domain con drop constraint t; + +insert into domcontest values (-5); + +insert into domcontest values (42); + +alter domain con drop constraint nonexistent; + +alter domain con drop constraint if exists nonexistent; + +create domain connotnull integer; + +create table domconnotnulltest +( col1 connotnull +, col2 connotnull +); + +insert into domconnotnulltest default values; + +alter domain connotnull add not null; + +update domconnotnulltest set col1 = 5; + +alter domain connotnull add not null; + +update domconnotnulltest set col2 = 6; + +alter domain connotnull add constraint constr1 not null; + +select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n'; + +alter domain connotnull add constraint constr1bis not null; + +select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n'; + +update domconnotnulltest set col1 = null; + +alter domain connotnull drop constraint constr1; + +update domconnotnulltest set col1 = null; + +drop domain connotnull cascade; + +drop table domconnotnulltest; + +create domain things AS INT; + +CREATE TABLE thethings (stuff things); + +INSERT INTO thethings (stuff) VALUES (55); + +ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11); + +ALTER DOMAIN things ADD CONSTRAINT meow CHECK (VALUE < 11) NOT VALID; + +ALTER DOMAIN things VALIDATE CONSTRAINT meow; + +UPDATE thethings SET stuff = 10; + +ALTER DOMAIN things VALIDATE CONSTRAINT meow; + +create table domtab (col1 integer); + +create domain dom as integer; + +create view domview as select cast(col1 as dom) from domtab; + +insert into domtab (col1) values (null); + +insert into domtab (col1) values (5); + +select * from domview; + +alter domain dom set not null; + +select * from domview; + +alter domain dom drop not null; + +select * from domview; + +alter domain dom add constraint domchkgt6 check(value > 6); + +select * from domview; + +alter domain dom drop constraint domchkgt6 restrict; + +select * from domview; + +drop domain ddef1 restrict; + +drop domain ddef2 restrict; + +drop domain ddef3 restrict; + +drop domain ddef4 restrict; + +drop domain ddef5 restrict; + +drop sequence ddef4_seq; + +create domain vchar4 varchar(4); + +create domain dinter vchar4 check (substring(VALUE, 1, 1) = 'x'); + +create domain dtop dinter check (substring(VALUE, 2, 1) = '1'); + +select 'x123'::dtop; + +select 'x1234'::dtop; + +select 'y1234'::dtop; + +select 'y123'::dtop; + +select 'yz23'::dtop; + +select 'xz23'::dtop; + +create temp table dtest(f1 dtop); + +insert into dtest values('x123'); + +insert into dtest values('x1234'); + +insert into dtest values('y1234'); + +insert into dtest values('y123'); + +insert into dtest values('yz23'); + +insert into dtest values('xz23'); + +drop table dtest; + +drop domain vchar4 cascade; + +create domain str_domain as text not null; + +create table domain_test (a int, b int); + +insert into domain_test values (1, 2); + +insert into domain_test values (1, 2); + +alter table domain_test add column c str_domain; + +create domain int_domain1 as int constraint nn1 not null constraint nn2 not null; + +create domain str_domain2 as text check (value <> 'foo') default 'foo'; + +alter table domain_test add column d str_domain2; + +create domain pos_int as int4 check (value > 0) not null; + +prepare s1 as select $1::pos_int = 10 as "is_ten"; + +execute s1(10); + +execute s1(0); + +execute s1(NULL); + +create function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int; +begin + return p1; +end$$ language plpgsql; + +select doubledecrement(3); + +create or replace function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int := 0; +begin + return p1; +end$$ language plpgsql; + +select doubledecrement(3); + +create or replace function doubledecrement(p1 pos_int) returns pos_int as $$ +declare v pos_int := 1; +begin + v := p1 - 1; + return v - 1; +end$$ language plpgsql; + +select doubledecrement(null); + +select doubledecrement(0); + +select doubledecrement(1); + +select doubledecrement(2); + +select doubledecrement(3); + +create domain posint as int4; + +create type ddtest1 as (f1 posint); + +create table ddtest2(f1 ddtest1); + +insert into ddtest2 values(row(-1)); + +alter domain posint add constraint c1 check(value >= 0); + +drop table ddtest2; + +create table ddtest2(f1 ddtest1[]); + +insert into ddtest2 values('{(-1)}'); + +alter domain posint add constraint c1 check(value >= 0); + +drop table ddtest2; + +create domain ddtest1d as ddtest1; + +create table ddtest2(f1 ddtest1d); + +insert into ddtest2 values('(-1)'); + +alter domain posint add constraint c1 check(value >= 0); + +drop table ddtest2; + +drop domain ddtest1d; + +create domain ddtest1d as ddtest1[]; + +create table ddtest2(f1 ddtest1d); + +insert into ddtest2 values('{(-1)}'); + +alter domain posint add constraint c1 check(value >= 0); + +drop table ddtest2; + +drop domain ddtest1d; + +create type rposint as range (subtype = posint); + +create table ddtest2(f1 rposint); + +insert into ddtest2 values('(-1,3]'); + +alter domain posint add constraint c1 check(value >= 0); + +drop table ddtest2; + +drop type rposint; + +alter domain posint add constraint c1 check(value >= 0); + +create domain posint2 as posint check (value % 2 = 0); + +create table ddtest2(f1 posint2); + +insert into ddtest2 values(11); + +insert into ddtest2 values(-2); + +insert into ddtest2 values(2); + +alter domain posint add constraint c2 check(value >= 10); + +alter domain posint add constraint c2 check(value > 0); + +drop table ddtest2; + +drop type ddtest1; + +drop domain posint cascade; + +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x numeric(4,2)[1]; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql; + +select array_elem_check(121.00); + +select array_elem_check(1.23456); + +create domain mynums as numeric(4,2)[1]; + +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x mynums; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql; + +select array_elem_check(121.00); + +select array_elem_check(1.23456); + +create domain mynums2 as mynums; + +create or replace function array_elem_check(numeric) returns numeric as $$ +declare + x mynums2; +begin + x[1] := $1; + return x[1]; +end$$ language plpgsql; + +select array_elem_check(121.00); + +select array_elem_check(1.23456); + +drop function array_elem_check(numeric); + +create domain orderedpair as int[2] check (value[1] < value[2]); + +select array[1,2]::orderedpair; + +select array[2,1]::orderedpair; + +create temp table op (f1 orderedpair); + +insert into op values (array[1,2]); + +insert into op values (array[2,1]); + +update op set f1[2] = 3; + +update op set f1[2] = 0; + +select * from op; + +create or replace function array_elem_check(int) returns int as $$ +declare + x orderedpair := '{1,2}'; +begin + x[2] := $1; + return x[2]; +end$$ language plpgsql; + +select array_elem_check(3); + +select array_elem_check(-1); + +drop function array_elem_check(int); + +create domain di as int; + +create function dom_check(int) returns di as $$ +declare d di; +begin + d := $1::di; + return d; +end +$$ language plpgsql immutable; + +select dom_check(0); + +alter domain di add constraint pos check (value > 0); + +select dom_check(0); + +alter domain di drop constraint pos; + +select dom_check(0); + +create or replace function dom_check(int) returns di as $$ +declare d di; +begin + d := $1; + return d; +end +$$ language plpgsql immutable; + +select dom_check(0); + +alter domain di add constraint pos check (value > 0); + +select dom_check(0); + +alter domain di drop constraint pos; + +select dom_check(0); + +drop function dom_check(int); + +drop domain di; + +create function sql_is_distinct_from(anyelement, anyelement) +returns boolean language sql +as 'select $1 is distinct from $2 limit 1'; + +create domain inotnull int + check (sql_is_distinct_from(value, null)); + +select 1::inotnull; + +select null::inotnull; + +create table dom_table (x inotnull); + +insert into dom_table values ('1'); + +insert into dom_table values (1); + +insert into dom_table values (null); + +drop table dom_table; + +drop domain inotnull; + +drop function sql_is_distinct_from(anyelement, anyelement); + +create domain testdomain1 as int; + +alter domain testdomain1 rename to testdomain2; + +alter type testdomain2 rename to testdomain3; + +drop domain testdomain3; + +create domain testdomain1 as int constraint unsigned check (value > 0); + +alter domain testdomain1 rename constraint unsigned to unsigned_foo; + +alter domain testdomain1 drop constraint unsigned_foo; + +drop domain testdomain1; + +create domain mytext as text; + +create domain mytext_child_1 as mytext; + +select pg_basetype('mytext'::regtype); + +select pg_basetype('mytext_child_1'::regtype); + +select pg_basetype(1); + +drop domain mytext cascade; + +CREATE DOMAIN constraint_enforced_dom AS int; + +DROP DOMAIN constraint_enforced_dom; + +SELECT * FROM information_schema.column_domain_usage + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY domain_name; + +SELECT * FROM information_schema.domain_constraints + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY constraint_name; + +SELECT * FROM information_schema.domains + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things') + ORDER BY domain_name; + +SELECT * FROM information_schema.check_constraints + WHERE (constraint_schema, constraint_name) + IN (SELECT constraint_schema, constraint_name + FROM information_schema.domain_constraints + WHERE domain_name IN ('con', 'dom', 'pos_int', 'things')) + ORDER BY constraint_name; diff --git a/crates/pgt_pretty_print/tests/data/multi/drop_if_exists_60.sql b/crates/pgt_pretty_print/tests/data/multi/drop_if_exists_60.sql new file mode 100644 index 000000000..1abc120c3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/drop_if_exists_60.sql @@ -0,0 +1,331 @@ +DROP TABLE test_exists; + +DROP TABLE IF EXISTS test_exists; + +CREATE TABLE test_exists (a int, b text); + +DROP VIEW test_view_exists; + +DROP VIEW IF EXISTS test_view_exists; + +CREATE VIEW test_view_exists AS select * from test_exists; + +DROP VIEW IF EXISTS test_view_exists; + +DROP VIEW test_view_exists; + +DROP INDEX test_index_exists; + +DROP INDEX IF EXISTS test_index_exists; + +CREATE INDEX test_index_exists on test_exists(a); + +DROP INDEX IF EXISTS test_index_exists; + +DROP INDEX test_index_exists; + +DROP SEQUENCE test_sequence_exists; + +DROP SEQUENCE IF EXISTS test_sequence_exists; + +CREATE SEQUENCE test_sequence_exists; + +DROP SEQUENCE IF EXISTS test_sequence_exists; + +DROP SEQUENCE test_sequence_exists; + +DROP SCHEMA test_schema_exists; + +DROP SCHEMA IF EXISTS test_schema_exists; + +CREATE SCHEMA test_schema_exists; + +DROP SCHEMA IF EXISTS test_schema_exists; + +DROP SCHEMA test_schema_exists; + +DROP TYPE test_type_exists; + +DROP TYPE IF EXISTS test_type_exists; + +CREATE type test_type_exists as (a int, b text); + +DROP TYPE IF EXISTS test_type_exists; + +DROP TYPE test_type_exists; + +DROP DOMAIN test_domain_exists; + +DROP DOMAIN IF EXISTS test_domain_exists; + +CREATE domain test_domain_exists as int not null check (value > 0); + +DROP DOMAIN IF EXISTS test_domain_exists; + +DROP DOMAIN test_domain_exists; + +CREATE USER regress_test_u1; + +CREATE ROLE regress_test_r1; + +CREATE GROUP regress_test_g1; + +DROP USER regress_test_u2; + +DROP USER IF EXISTS regress_test_u1, regress_test_u2; + +DROP USER regress_test_u1; + +DROP ROLE regress_test_r2; + +DROP ROLE IF EXISTS regress_test_r1, regress_test_r2; + +DROP ROLE regress_test_r1; + +DROP GROUP regress_test_g2; + +DROP GROUP IF EXISTS regress_test_g1, regress_test_g2; + +DROP GROUP regress_test_g1; + +DROP COLLATION IF EXISTS test_collation_exists; + +DROP CONVERSION test_conversion_exists; + +DROP CONVERSION IF EXISTS test_conversion_exists; + +CREATE CONVERSION test_conversion_exists + FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8; + +DROP CONVERSION test_conversion_exists; + +DROP TEXT SEARCH PARSER test_tsparser_exists; + +DROP TEXT SEARCH PARSER IF EXISTS test_tsparser_exists; + +DROP TEXT SEARCH DICTIONARY test_tsdict_exists; + +DROP TEXT SEARCH DICTIONARY IF EXISTS test_tsdict_exists; + +CREATE TEXT SEARCH DICTIONARY test_tsdict_exists ( + Template=ispell, + DictFile=ispell_sample, + AffFile=ispell_sample +); + +DROP TEXT SEARCH DICTIONARY test_tsdict_exists; + +DROP TEXT SEARCH TEMPLATE test_tstemplate_exists; + +DROP TEXT SEARCH TEMPLATE IF EXISTS test_tstemplate_exists; + +DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists; + +DROP TEXT SEARCH CONFIGURATION IF EXISTS test_tsconfig_exists; + +CREATE TEXT SEARCH CONFIGURATION test_tsconfig_exists (COPY=english); + +DROP TEXT SEARCH CONFIGURATION test_tsconfig_exists; + +DROP EXTENSION test_extension_exists; + +DROP EXTENSION IF EXISTS test_extension_exists; + +DROP FUNCTION test_function_exists(); + +DROP FUNCTION IF EXISTS test_function_exists(); + +DROP FUNCTION test_function_exists(int, text, int[]); + +DROP FUNCTION IF EXISTS test_function_exists(int, text, int[]); + +DROP AGGREGATE test_aggregate_exists(*); + +DROP AGGREGATE IF EXISTS test_aggregate_exists(*); + +DROP AGGREGATE test_aggregate_exists(int); + +DROP AGGREGATE IF EXISTS test_aggregate_exists(int); + +DROP OPERATOR @#@ (int, int); + +DROP OPERATOR IF EXISTS @#@ (int, int); + +CREATE OPERATOR @#@ + (leftarg = int8, rightarg = int8, procedure = int8xor); + +DROP OPERATOR @#@ (int8, int8); + +DROP LANGUAGE test_language_exists; + +DROP LANGUAGE IF EXISTS test_language_exists; + +DROP CAST (text AS text); + +DROP CAST IF EXISTS (text AS text); + +DROP TRIGGER test_trigger_exists ON test_exists; + +DROP TRIGGER IF EXISTS test_trigger_exists ON test_exists; + +DROP TRIGGER test_trigger_exists ON no_such_table; + +DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_table; + +DROP TRIGGER test_trigger_exists ON no_such_schema.no_such_table; + +DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_schema.no_such_table; + +CREATE TRIGGER test_trigger_exists + BEFORE UPDATE ON test_exists + FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); + +DROP TRIGGER test_trigger_exists ON test_exists; + +DROP RULE test_rule_exists ON test_exists; + +DROP RULE IF EXISTS test_rule_exists ON test_exists; + +DROP RULE test_rule_exists ON no_such_table; + +DROP RULE IF EXISTS test_rule_exists ON no_such_table; + +DROP RULE test_rule_exists ON no_such_schema.no_such_table; + +DROP RULE IF EXISTS test_rule_exists ON no_such_schema.no_such_table; + +CREATE RULE test_rule_exists AS ON INSERT TO test_exists + DO INSTEAD + INSERT INTO test_exists VALUES (NEW.a, NEW.b || NEW.a::text); + +DROP RULE test_rule_exists ON test_exists; + +DROP FOREIGN DATA WRAPPER test_fdw_exists; + +DROP FOREIGN DATA WRAPPER IF EXISTS test_fdw_exists; + +DROP SERVER test_server_exists; + +DROP SERVER IF EXISTS test_server_exists; + +DROP OPERATOR CLASS test_operator_class USING btree; + +DROP OPERATOR CLASS IF EXISTS test_operator_class USING btree; + +DROP OPERATOR CLASS test_operator_class USING no_such_am; + +DROP OPERATOR CLASS IF EXISTS test_operator_class USING no_such_am; + +DROP OPERATOR FAMILY test_operator_family USING btree; + +DROP OPERATOR FAMILY IF EXISTS test_operator_family USING btree; + +DROP OPERATOR FAMILY test_operator_family USING no_such_am; + +DROP OPERATOR FAMILY IF EXISTS test_operator_family USING no_such_am; + +DROP ACCESS METHOD no_such_am; + +DROP ACCESS METHOD IF EXISTS no_such_am; + +DROP TABLE IF EXISTS test_exists; + +DROP TABLE test_exists; + +DROP AGGREGATE IF EXISTS no_such_schema.foo(int); + +DROP AGGREGATE IF EXISTS foo(no_such_type); + +DROP AGGREGATE IF EXISTS foo(no_such_schema.no_such_type); + +DROP CAST IF EXISTS (INTEGER AS no_such_type2); + +DROP CAST IF EXISTS (no_such_type1 AS INTEGER); + +DROP CAST IF EXISTS (INTEGER AS no_such_schema.bar); + +DROP CAST IF EXISTS (no_such_schema.foo AS INTEGER); + +DROP COLLATION IF EXISTS no_such_schema.foo; + +DROP CONVERSION IF EXISTS no_such_schema.foo; + +DROP DOMAIN IF EXISTS no_such_schema.foo; + +DROP FOREIGN TABLE IF EXISTS no_such_schema.foo; + +DROP FUNCTION IF EXISTS no_such_schema.foo(); + +DROP FUNCTION IF EXISTS foo(no_such_type); + +DROP FUNCTION IF EXISTS foo(no_such_schema.no_such_type); + +DROP INDEX IF EXISTS no_such_schema.foo; + +DROP MATERIALIZED VIEW IF EXISTS no_such_schema.foo; + +DROP OPERATOR IF EXISTS no_such_schema.+ (int, int); + +DROP OPERATOR IF EXISTS + (no_such_type, no_such_type); + +DROP OPERATOR IF EXISTS + (no_such_schema.no_such_type, no_such_schema.no_such_type); + +DROP OPERATOR IF EXISTS # (NONE, no_such_schema.no_such_type); + +DROP OPERATOR CLASS IF EXISTS no_such_schema.widget_ops USING btree; + +DROP OPERATOR FAMILY IF EXISTS no_such_schema.float_ops USING btree; + +DROP RULE IF EXISTS foo ON no_such_schema.bar; + +DROP SEQUENCE IF EXISTS no_such_schema.foo; + +DROP TABLE IF EXISTS no_such_schema.foo; + +DROP TEXT SEARCH CONFIGURATION IF EXISTS no_such_schema.foo; + +DROP TEXT SEARCH DICTIONARY IF EXISTS no_such_schema.foo; + +DROP TEXT SEARCH PARSER IF EXISTS no_such_schema.foo; + +DROP TEXT SEARCH TEMPLATE IF EXISTS no_such_schema.foo; + +DROP TRIGGER IF EXISTS foo ON no_such_schema.bar; + +DROP TYPE IF EXISTS no_such_schema.foo; + +DROP VIEW IF EXISTS no_such_schema.foo; + +CREATE FUNCTION test_ambiguous_funcname(int) returns int as $$ select $1; $$ language sql; + +CREATE FUNCTION test_ambiguous_funcname(text) returns text as $$ select $1; $$ language sql; + +DROP FUNCTION test_ambiguous_funcname; + +DROP FUNCTION IF EXISTS test_ambiguous_funcname; + +DROP FUNCTION test_ambiguous_funcname(int); + +DROP FUNCTION test_ambiguous_funcname(text); + +CREATE PROCEDURE test_ambiguous_procname(int) as $$ begin end; $$ language plpgsql; + +CREATE PROCEDURE test_ambiguous_procname(text) as $$ begin end; $$ language plpgsql; + +DROP PROCEDURE test_ambiguous_procname; + +DROP PROCEDURE IF EXISTS test_ambiguous_procname; + +DROP ROUTINE IF EXISTS test_ambiguous_procname; + +DROP PROCEDURE test_ambiguous_procname(int); + +DROP PROCEDURE test_ambiguous_procname(text); + +drop database test_database_exists (force); + +drop database test_database_exists + +drop database if exists test_database_exists (force); + +drop database if exists test_database_exists diff --git a/crates/pgt_pretty_print/tests/data/multi/drop_operator_60.sql b/crates/pgt_pretty_print/tests/data/multi/drop_operator_60.sql new file mode 100644 index 000000000..cc62cfa14 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/drop_operator_60.sql @@ -0,0 +1,56 @@ +CREATE OPERATOR === ( + PROCEDURE = int8eq, + LEFTARG = bigint, + RIGHTARG = bigint, + COMMUTATOR = === +); + +CREATE OPERATOR !== ( + PROCEDURE = int8ne, + LEFTARG = bigint, + RIGHTARG = bigint, + NEGATOR = ===, + COMMUTATOR = !== +); + +DROP OPERATOR !==(bigint, bigint); + +SELECT ctid, oprcom +FROM pg_catalog.pg_operator fk +WHERE oprcom != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom); + +SELECT ctid, oprnegate +FROM pg_catalog.pg_operator fk +WHERE oprnegate != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate); + +DROP OPERATOR ===(bigint, bigint); + +CREATE OPERATOR <| ( + PROCEDURE = int8lt, + LEFTARG = bigint, + RIGHTARG = bigint +); + +CREATE OPERATOR |> ( + PROCEDURE = int8gt, + LEFTARG = bigint, + RIGHTARG = bigint, + NEGATOR = <|, + COMMUTATOR = <| +); + +DROP OPERATOR |>(bigint, bigint); + +SELECT ctid, oprcom +FROM pg_catalog.pg_operator fk +WHERE oprcom != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprcom); + +SELECT ctid, oprnegate +FROM pg_catalog.pg_operator fk +WHERE oprnegate != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_operator pk WHERE pk.oid = fk.oprnegate); + +DROP OPERATOR <|(bigint, bigint); diff --git a/crates/pgt_pretty_print/tests/data/multi/enum_60.sql b/crates/pgt_pretty_print/tests/data/multi/enum_60.sql new file mode 100644 index 000000000..b1839a996 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/enum_60.sql @@ -0,0 +1,371 @@ +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); + +SELECT COUNT(*) FROM pg_enum WHERE enumtypid = 'rainbow'::regtype; + +SELECT 'red'::rainbow; + +SELECT 'mauve'::rainbow; + +SELECT pg_input_is_valid('red', 'rainbow'); + +SELECT pg_input_is_valid('mauve', 'rainbow'); + +SELECT * FROM pg_input_error_info('mauve', 'rainbow'); + +SELECT * FROM pg_input_error_info(repeat('too_long', 32), 'rainbow'); + +CREATE TYPE dup_enum AS ENUM ('foo','bar','foo'); + +CREATE TYPE planets AS ENUM ( 'venus', 'earth', 'mars' ); + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2; + +ALTER TYPE planets ADD VALUE 'uranus'; + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2; + +ALTER TYPE planets ADD VALUE 'mercury' BEFORE 'venus'; + +ALTER TYPE planets ADD VALUE 'saturn' BEFORE 'uranus'; + +ALTER TYPE planets ADD VALUE 'jupiter' AFTER 'mars'; + +ALTER TYPE planets ADD VALUE 'neptune' AFTER 'uranus'; + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY 2; + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'planets'::regtype +ORDER BY enumlabel::planets; + +ALTER TYPE planets ADD VALUE + 'plutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutoplutopluto'; + +ALTER TYPE planets ADD VALUE 'pluto' AFTER 'zeus'; + +ALTER TYPE planets ADD VALUE 'mercury'; + +ALTER TYPE planets ADD VALUE IF NOT EXISTS 'mercury'; + +SELECT enum_last(NULL::planets); + +ALTER TYPE planets ADD VALUE IF NOT EXISTS 'pluto'; + +SELECT enum_last(NULL::planets); + +create type insenum as enum ('L1', 'L2'); + +alter type insenum add value 'i1' before 'L2'; + +alter type insenum add value 'i2' before 'L2'; + +alter type insenum add value 'i3' before 'L2'; + +alter type insenum add value 'i4' before 'L2'; + +alter type insenum add value 'i5' before 'L2'; + +alter type insenum add value 'i6' before 'L2'; + +alter type insenum add value 'i7' before 'L2'; + +alter type insenum add value 'i8' before 'L2'; + +alter type insenum add value 'i9' before 'L2'; + +alter type insenum add value 'i10' before 'L2'; + +alter type insenum add value 'i11' before 'L2'; + +alter type insenum add value 'i12' before 'L2'; + +alter type insenum add value 'i13' before 'L2'; + +alter type insenum add value 'i14' before 'L2'; + +alter type insenum add value 'i15' before 'L2'; + +alter type insenum add value 'i16' before 'L2'; + +alter type insenum add value 'i17' before 'L2'; + +alter type insenum add value 'i18' before 'L2'; + +alter type insenum add value 'i19' before 'L2'; + +alter type insenum add value 'i20' before 'L2'; + +alter type insenum add value 'i21' before 'L2'; + +alter type insenum add value 'i22' before 'L2'; + +alter type insenum add value 'i23' before 'L2'; + +alter type insenum add value 'i24' before 'L2'; + +alter type insenum add value 'i25' before 'L2'; + +alter type insenum add value 'i26' before 'L2'; + +alter type insenum add value 'i27' before 'L2'; + +alter type insenum add value 'i28' before 'L2'; + +alter type insenum add value 'i29' before 'L2'; + +alter type insenum add value 'i30' before 'L2'; + +SELECT enumlabel, + case when enumsortorder > 20 then null else enumsortorder end as so +FROM pg_enum +WHERE enumtypid = 'insenum'::regtype +ORDER BY enumsortorder; + +CREATE TABLE enumtest (col rainbow); + +INSERT INTO enumtest values ('red'), ('orange'), ('yellow'), ('green'); + +SELECT * FROM enumtest; + +SELECT * FROM enumtest WHERE col = 'orange'; + +SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col; + +SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col; + +SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col; + +SELECT * FROM enumtest WHERE col < 'green' ORDER BY col; + +SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col; + +SELECT 'red'::rainbow::text || 'hithere'; + +SELECT 'red'::text::rainbow = 'red'::rainbow; + +SELECT min(col) FROM enumtest; + +SELECT max(col) FROM enumtest; + +SELECT max(col) FROM enumtest WHERE col < 'green'; + +SET enable_seqscan = off; + +SET enable_bitmapscan = off; + +CREATE UNIQUE INDEX enumtest_btree ON enumtest USING btree (col); + +SELECT * FROM enumtest WHERE col = 'orange'; + +SELECT * FROM enumtest WHERE col <> 'orange' ORDER BY col; + +SELECT * FROM enumtest WHERE col > 'yellow' ORDER BY col; + +SELECT * FROM enumtest WHERE col >= 'yellow' ORDER BY col; + +SELECT * FROM enumtest WHERE col < 'green' ORDER BY col; + +SELECT * FROM enumtest WHERE col <= 'green' ORDER BY col; + +SELECT min(col) FROM enumtest; + +SELECT max(col) FROM enumtest; + +SELECT max(col) FROM enumtest WHERE col < 'green'; + +DROP INDEX enumtest_btree; + +CREATE INDEX enumtest_hash ON enumtest USING hash (col); + +SELECT * FROM enumtest WHERE col = 'orange'; + +DROP INDEX enumtest_hash; + +RESET enable_seqscan; + +RESET enable_bitmapscan; + +CREATE DOMAIN rgb AS rainbow CHECK (VALUE IN ('red', 'green', 'blue')); + +SELECT 'red'::rgb; + +SELECT 'purple'::rgb; + +SELECT 'purple'::rainbow::rgb; + +DROP DOMAIN rgb; + +SELECT '{red,green,blue}'::rainbow[]; + +SELECT ('{red,green,blue}'::rainbow[])[2]; + +SELECT 'red' = ANY ('{red,green,blue}'::rainbow[]); + +SELECT 'yellow' = ANY ('{red,green,blue}'::rainbow[]); + +SELECT 'red' = ALL ('{red,green,blue}'::rainbow[]); + +SELECT 'red' = ALL ('{red,red}'::rainbow[]); + +SELECT enum_first(NULL::rainbow); + +SELECT enum_last('green'::rainbow); + +SELECT enum_range(NULL::rainbow); + +SELECT enum_range('orange'::rainbow, 'green'::rainbow); + +SELECT enum_range(NULL, 'green'::rainbow); + +SELECT enum_range('orange'::rainbow, NULL); + +SELECT enum_range(NULL::rainbow, NULL); + +CREATE FUNCTION echo_me(anyenum) RETURNS text AS $$ +BEGIN +RETURN $1::text || 'omg'; +END +$$ LANGUAGE plpgsql; + +SELECT echo_me('red'::rainbow); + +CREATE FUNCTION echo_me(rainbow) RETURNS text AS $$ +BEGIN +RETURN $1::text || 'wtf'; +END +$$ LANGUAGE plpgsql; + +SELECT echo_me('red'::rainbow); + +DROP FUNCTION echo_me(anyenum); + +SELECT echo_me('red'); + +DROP FUNCTION echo_me(rainbow); + +CREATE TABLE enumtest_parent (id rainbow PRIMARY KEY); + +CREATE TABLE enumtest_child (parent rainbow REFERENCES enumtest_parent); + +INSERT INTO enumtest_parent VALUES ('red'); + +INSERT INTO enumtest_child VALUES ('red'); + +INSERT INTO enumtest_child VALUES ('blue'); + +DELETE FROM enumtest_parent; + +CREATE TYPE bogus AS ENUM('good', 'bad', 'ugly'); + +CREATE TABLE enumtest_bogus_child(parent bogus REFERENCES enumtest_parent); + +DROP TYPE bogus; + +ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson'; + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'rainbow'::regtype +ORDER BY 2; + +ALTER TYPE rainbow RENAME VALUE 'red' TO 'crimson'; + +ALTER TYPE rainbow RENAME VALUE 'blue' TO 'green'; + +CREATE TYPE bogus AS ENUM('good'); + +BEGIN; + +ALTER TYPE bogus ADD VALUE 'new'; + +SAVEPOINT x; + +SELECT 'new'::bogus; + +ROLLBACK TO x; + +SELECT enum_first(null::bogus); + +SELECT enum_last(null::bogus); + +ROLLBACK TO x; + +SELECT enum_range(null::bogus); + +ROLLBACK TO x; + +COMMIT; + +SELECT 'new'::bogus; + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'bogus'::regtype +ORDER BY 2; + +BEGIN; + +ALTER TYPE bogus RENAME TO bogon; + +ALTER TYPE bogon ADD VALUE 'bad'; + +SELECT 'bad'::bogon; + +ROLLBACK; + +BEGIN; + +ALTER TYPE bogus RENAME VALUE 'good' to 'bad'; + +SELECT 'bad'::bogus; + +ROLLBACK; + +DROP TYPE bogus; + +BEGIN; + +CREATE TYPE bogus AS ENUM('good','bad','ugly'); + +ALTER TYPE bogus RENAME TO bogon; + +select enum_range(null::bogon); + +ROLLBACK; + +BEGIN; + +CREATE TYPE bogus AS ENUM('good'); + +ALTER TYPE bogus RENAME TO bogon; + +ALTER TYPE bogon ADD VALUE 'bad'; + +ALTER TYPE bogon ADD VALUE 'ugly'; + +select enum_range(null::bogon); + +ROLLBACK; + +DROP TABLE enumtest_child; + +DROP TABLE enumtest_parent; + +DROP TABLE enumtest; + +DROP TYPE rainbow; + +SELECT COUNT(*) FROM pg_type WHERE typname = 'rainbow'; + +SELECT * FROM pg_enum WHERE NOT EXISTS + (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid); diff --git a/crates/pgt_pretty_print/tests/data/multi/equivclass_60.sql b/crates/pgt_pretty_print/tests/data/multi/equivclass_60.sql new file mode 100644 index 000000000..1a3df4458 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/equivclass_60.sql @@ -0,0 +1,302 @@ +create type int8alias1; + +create function int8alias1in(cstring) returns int8alias1 + strict immutable language internal as 'int8in'; + +create function int8alias1out(int8alias1) returns cstring + strict immutable language internal as 'int8out'; + +create type int8alias1 ( + input = int8alias1in, + output = int8alias1out, + like = int8 +); + +create type int8alias2; + +create function int8alias2in(cstring) returns int8alias2 + strict immutable language internal as 'int8in'; + +create function int8alias2out(int8alias2) returns cstring + strict immutable language internal as 'int8out'; + +create type int8alias2 ( + input = int8alias2in, + output = int8alias2out, + like = int8 +); + +create cast (int8 as int8alias1) without function; + +create cast (int8 as int8alias2) without function; + +create cast (int8alias1 as int8) without function; + +create cast (int8alias2 as int8) without function; + +create function int8alias1eq(int8alias1, int8alias1) returns bool + strict immutable language internal as 'int8eq'; + +create operator = ( + procedure = int8alias1eq, + leftarg = int8alias1, rightarg = int8alias1, + commutator = =, + restrict = eqsel, join = eqjoinsel, + merges +); + +alter operator family integer_ops using btree add + operator 3 = (int8alias1, int8alias1); + +create function int8alias2eq(int8alias2, int8alias2) returns bool + strict immutable language internal as 'int8eq'; + +create operator = ( + procedure = int8alias2eq, + leftarg = int8alias2, rightarg = int8alias2, + commutator = =, + restrict = eqsel, join = eqjoinsel, + merges +); + +alter operator family integer_ops using btree add + operator 3 = (int8alias2, int8alias2); + +create function int8alias1eq(int8, int8alias1) returns bool + strict immutable language internal as 'int8eq'; + +create operator = ( + procedure = int8alias1eq, + leftarg = int8, rightarg = int8alias1, + restrict = eqsel, join = eqjoinsel, + merges +); + +alter operator family integer_ops using btree add + operator 3 = (int8, int8alias1); + +create function int8alias1eq(int8alias1, int8alias2) returns bool + strict immutable language internal as 'int8eq'; + +create operator = ( + procedure = int8alias1eq, + leftarg = int8alias1, rightarg = int8alias2, + restrict = eqsel, join = eqjoinsel, + merges +); + +alter operator family integer_ops using btree add + operator 3 = (int8alias1, int8alias2); + +create function int8alias1lt(int8alias1, int8alias1) returns bool + strict immutable language internal as 'int8lt'; + +create operator < ( + procedure = int8alias1lt, + leftarg = int8alias1, rightarg = int8alias1 +); + +alter operator family integer_ops using btree add + operator 1 < (int8alias1, int8alias1); + +create function int8alias1cmp(int8, int8alias1) returns int + strict immutable language internal as 'btint8cmp'; + +alter operator family integer_ops using btree add + function 1 int8alias1cmp (int8, int8alias1); + +create table ec0 (ff int8 primary key, f1 int8, f2 int8); + +create table ec1 (ff int8 primary key, f1 int8alias1, f2 int8alias2); + +create table ec2 (xf int8 primary key, x1 int8alias1, x2 int8alias2); + +set enable_hashjoin = off; + +set enable_mergejoin = off; + +select * from ec0 where ff = f1 and f1 = '42'::int8; + +select * from ec0 where ff = f1 and f1 = '42'::int8alias1; + +select * from ec1 where ff = f1 and f1 = '42'::int8alias1; + +select * from ec1 where ff = f1 and f1 = '42'::int8alias2; + +select * from ec1, ec2 where ff = x1 and ff = '42'::int8; + +select * from ec1, ec2 where ff = x1 and ff = '42'::int8alias1; + +select * from ec1, ec2 where ff = x1 and '42'::int8 = x1; + +select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias1; + +select * from ec1, ec2 where ff = x1 and x1 = '42'::int8alias2; + +create unique index ec1_expr1 on ec1((ff + 1)); + +create unique index ec1_expr2 on ec1((ff + 2 + 1)); + +create unique index ec1_expr3 on ec1((ff + 3 + 1)); + +create unique index ec1_expr4 on ec1((ff + 4)); + +select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8; + +select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8 and ec1.ff = ec1.f1; + +select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss2 + where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8; + +set enable_mergejoin = on; + +set enable_nestloop = off; + +select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss2 + where ss1.x = ec1.f1 and ss1.x = ss2.x and ec1.ff = 42::int8; + +set enable_nestloop = on; + +set enable_mergejoin = off; + +drop index ec1_expr3; + +select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8; + +set enable_mergejoin = on; + +set enable_nestloop = off; + +select * from ec1, + (select ff + 1 as x from + (select ff + 2 as ff from ec1 + union all + select ff + 3 as ff from ec1) ss0 + union all + select ff + 4 as x from ec1) as ss1 + where ss1.x = ec1.f1 and ec1.ff = 42::int8; + +set enable_nestloop = on; + +set enable_mergejoin = off; + +alter table ec1 enable row level security; + +create policy p1 on ec1 using (f1 < '5'::int8alias1); + +create user regress_user_ectest; + +grant select on ec0 to regress_user_ectest; + +grant select on ec1 to regress_user_ectest; + +select * from ec0 a, ec1 b + where a.ff = b.ff and a.ff = 43::bigint::int8alias1; + +set session authorization regress_user_ectest; + +select * from ec0 a, ec1 b + where a.ff = b.ff and a.ff = 43::bigint::int8alias1; + +reset session authorization; + +revoke select on ec0 from regress_user_ectest; + +revoke select on ec1 from regress_user_ectest; + +drop user regress_user_ectest; + +select * from tenk1 where unique1 = unique1 and unique2 = unique2; + +set enable_mergejoin to off; + +select * from ec0 m join ec0 n on m.ff = n.ff + join ec1 p on m.ff + n.ff = p.f1; + +select * from ec0 m join ec0 n on m.ff = n.ff + join ec1 p on p.f1::int8 = (m.ff + n.ff)::int8alias1; + +reset enable_mergejoin; + +select * from tenk1 where unique1 = unique1 or unique2 = unique2; + +create temp table undername (f1 name, f2 int); + +create temp view overview as + select f1::information_schema.sql_identifier as sqli, f2 from undername; + +select * from overview where sqli = 'foo' order by sqli; + +begin; + +create table tbl_nocom(a int8, b int8alias1); + +set enable_hashjoin to off; + +set enable_mergejoin to on; + +select * from tbl_nocom t1 full join tbl_nocom t2 on t2.a = t1.b; + +alter operator = (int8, int8alias1) set (hashes); + +alter operator family integer_ops using hash add + operator 1 = (int8, int8alias1); + +create function hashint8alias1(int8alias1) returns int + strict immutable language internal as 'hashint8'; + +alter operator family integer_ops using hash add + function 1 hashint8alias1(int8alias1); + +set enable_hashjoin to on; + +set enable_mergejoin to off; + +select * from tbl_nocom t1 full join tbl_nocom t2 on t2.a = t1.b; + +abort; diff --git a/crates/pgt_pretty_print/tests/data/multi/errors_60.sql b/crates/pgt_pretty_print/tests/data/multi/errors_60.sql new file mode 100644 index 000000000..4a69bae6a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/errors_60.sql @@ -0,0 +1,93 @@ +select 1; + +select; + +select * from nonesuch; + +select nonesuch from pg_database; + +select * from pg_database where nonesuch = pg_database.datname; + +select * from pg_database where pg_database.datname = nonesuch; + +select distinct on (foobar) * from pg_database; + +select null from pg_database group by datname for update; + +select null from pg_database group by grouping sets (()) for update; + +delete from nonesuch; + +drop table nonesuch; + +alter table nonesuch rename to newnonesuch; + +alter table nonesuch rename to stud_emp; + +alter table stud_emp rename to student; + +alter table stud_emp rename to stud_emp; + +alter table nonesuchrel rename column nonesuchatt to newnonesuchatt; + +alter table emp rename column nonesuchatt to newnonesuchatt; + +alter table emp rename column salary to manager; + +alter table emp rename column salary to ctid; + +abort; + +end; + +create aggregate newavg2 (sfunc = int4pl, + basetype = int4, + stype = int4, + finalfunc = int2um, + initcond = '0'); + +create aggregate newcnt1 (sfunc = int4inc, + stype = int4, + initcond = '0'); + +drop index nonesuch; + +drop aggregate newcnt (nonesuch); + +drop aggregate nonesuch (int4); + +drop aggregate newcnt (float4); + +drop function nonesuch(); + +drop type nonesuch; + +drop operator === (int4, int4); + +drop operator = (nonesuch, int4); + +drop operator = (int4, nonesuch); + +drop rule nonesuch on noplace; + +select 1/0; + +select 1::int8/0; + +select 1/0::int8; + +select 1::int2/0; + +select 1/0::int2; + +select 1::numeric/0; + +select 1/0::numeric; + +select 1::float8/0; + +select 1/0::float8; + +select 1::float4/0; + +select 1/0::float4; diff --git a/crates/pgt_pretty_print/tests/data/multi/event_trigger_60.sql b/crates/pgt_pretty_print/tests/data/multi/event_trigger_60.sql new file mode 100644 index 000000000..d345dfe0c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/event_trigger_60.sql @@ -0,0 +1,712 @@ +create event trigger regress_event_trigger + on ddl_command_start + execute procedure pg_backend_pid(); + +create function test_event_trigger() returns event_trigger as $$ +BEGIN + RAISE NOTICE 'test_event_trigger: % %', tg_event, tg_tag; +END +$$ language plpgsql; + +SELECT test_event_trigger(); + +create function test_event_trigger_arg(name text) +returns event_trigger as $$ BEGIN RETURN 1; END $$ language plpgsql; + +create function test_event_trigger_sql() returns event_trigger as $$ +SELECT 1 $$ language sql; + +create event trigger regress_event_trigger on elephant_bootstrap + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger on ddl_command_start + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger_end on ddl_command_end + execute function test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when food in ('sandwich') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('sandwich') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table', 'create skunkcabbage') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('DROP EVENT TRIGGER') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE ROLE') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE DATABASE') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('CREATE TABLESPACE') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table') and tag in ('CREATE FUNCTION') + execute procedure test_event_trigger(); + +create event trigger regress_event_trigger2 on ddl_command_start + when tag in ('create table', 'CREATE FUNCTION') + execute procedure test_event_trigger(); + +comment on event trigger regress_event_trigger is 'test comment'; + +create role regress_evt_user; + +set role regress_evt_user; + +create event trigger regress_event_trigger_noperms on ddl_command_start + execute procedure test_event_trigger(); + +reset role; + +alter event trigger regress_event_trigger disable; + +create table event_trigger_fire1 (a int); + +alter event trigger regress_event_trigger enable; + +set session_replication_role = replica; + +create table event_trigger_fire2 (a int); + +alter event trigger regress_event_trigger enable replica; + +create table event_trigger_fire3 (a int); + +alter event trigger regress_event_trigger enable always; + +create table event_trigger_fire4 (a int); + +reset session_replication_role; + +create table event_trigger_fire5 (a int); + +create function f1() returns int +language plpgsql +as $$ +begin + create table event_trigger_fire6 (a int); + return 0; +end $$; + +select f1(); + +create procedure p1() +language plpgsql +as $$ +begin + create table event_trigger_fire7 (a int); +end $$; + +call p1(); + +alter event trigger regress_event_trigger disable; + +drop table event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5, event_trigger_fire6, event_trigger_fire7; + +drop routine f1(), p1(); + +grant all on table event_trigger_fire1 to public; + +comment on table event_trigger_fire1 is 'here is a comment'; + +revoke all on table event_trigger_fire1 from public; + +drop table event_trigger_fire1; + +create foreign data wrapper useless; + +create server useless_server foreign data wrapper useless; + +create user mapping for regress_evt_user server useless_server; + +alter default privileges for role regress_evt_user + revoke delete on tables from regress_evt_user; + +alter event trigger regress_event_trigger owner to regress_evt_user; + +alter role regress_evt_user superuser; + +alter event trigger regress_event_trigger owner to regress_evt_user; + +alter event trigger regress_event_trigger rename to regress_event_trigger2; + +alter event trigger regress_event_trigger rename to regress_event_trigger3; + +drop event trigger regress_event_trigger; + +drop role regress_evt_user; + +drop event trigger if exists regress_event_trigger2; + +drop event trigger if exists regress_event_trigger2; + +drop event trigger regress_event_trigger3; + +drop event trigger regress_event_trigger_end; + +CREATE SCHEMA schema_one authorization regress_evt_user; + +CREATE SCHEMA schema_two authorization regress_evt_user; + +CREATE SCHEMA audit_tbls authorization regress_evt_user; + +CREATE TEMP TABLE a_temp_tbl (); + +SET SESSION AUTHORIZATION regress_evt_user; + +CREATE TABLE schema_one.table_one(a int); + +CREATE TABLE schema_one."table two"(a int); + +CREATE TABLE schema_one.table_three(a int); + +CREATE TABLE audit_tbls.schema_one_table_two(the_value text); + +CREATE TABLE schema_two.table_two(a int); + +CREATE TABLE schema_two.table_three(a int, b text); + +CREATE TABLE audit_tbls.schema_two_table_three(the_value text); + +CREATE OR REPLACE FUNCTION schema_two.add(int, int) RETURNS int LANGUAGE plpgsql + CALLED ON NULL INPUT + AS $$ BEGIN RETURN coalesce($1,0) + coalesce($2,0); END; $$; + +CREATE AGGREGATE schema_two.newton + (BASETYPE = int, SFUNC = schema_two.add, STYPE = int); + +RESET SESSION AUTHORIZATION; + +CREATE TABLE undroppable_objs ( + object_type text, + object_identity text +); + +INSERT INTO undroppable_objs VALUES +('table', 'schema_one.table_three'), +('table', 'audit_tbls.schema_two_table_three'); + +CREATE TABLE dropped_objects ( + object_type text, + schema_name text, + object_name text, + object_identity text, + address_names text[], + address_args text[], + is_temporary bool, + original bool, + normal bool +); + +CREATE OR REPLACE FUNCTION undroppable() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + PERFORM 1 FROM pg_tables WHERE tablename = 'undroppable_objs'; + IF NOT FOUND THEN + RAISE NOTICE 'table undroppable_objs not found, skipping'; + RETURN; + END IF; + FOR obj IN + SELECT * FROM pg_event_trigger_dropped_objects() JOIN + undroppable_objs USING (object_type, object_identity) + LOOP + RAISE EXCEPTION 'object % of type % cannot be dropped', + obj.object_identity, obj.object_type; + END LOOP; +END; +$$; + +CREATE EVENT TRIGGER undroppable ON sql_drop + EXECUTE PROCEDURE undroppable(); + +CREATE OR REPLACE FUNCTION test_evtrig_dropped_objects() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + IF obj.object_type = 'table' THEN + EXECUTE format('DROP TABLE IF EXISTS audit_tbls.%I', + format('%s_%s', obj.schema_name, obj.object_name)); + END IF; + + INSERT INTO dropped_objects + (object_type, schema_name, object_name, + object_identity, address_names, address_args, + is_temporary, original, normal) VALUES + (obj.object_type, obj.schema_name, obj.object_name, + obj.object_identity, obj.address_names, obj.address_args, + obj.is_temporary, obj.original, obj.normal); + END LOOP; +END +$$; + +CREATE EVENT TRIGGER regress_event_trigger_drop_objects ON sql_drop + WHEN TAG IN ('drop table', 'drop function', 'drop view', + 'drop owned', 'drop schema', 'alter table') + EXECUTE PROCEDURE test_evtrig_dropped_objects(); + +ALTER TABLE schema_one.table_one DROP COLUMN a; + +DROP SCHEMA schema_one, schema_two CASCADE; + +DELETE FROM undroppable_objs WHERE object_identity = 'audit_tbls.schema_two_table_three'; + +DROP SCHEMA schema_one, schema_two CASCADE; + +DELETE FROM undroppable_objs WHERE object_identity = 'schema_one.table_three'; + +DROP SCHEMA schema_one, schema_two CASCADE; + +SELECT * FROM dropped_objects + WHERE schema_name IS NULL OR schema_name <> 'pg_toast'; + +DROP OWNED BY regress_evt_user; + +SELECT * FROM dropped_objects WHERE object_type = 'schema'; + +DROP ROLE regress_evt_user; + +DROP EVENT TRIGGER regress_event_trigger_drop_objects; + +DROP EVENT TRIGGER undroppable; + +CREATE OR REPLACE FUNCTION event_trigger_report_dropped() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r record; +BEGIN + FOR r IN SELECT * from pg_event_trigger_dropped_objects() + LOOP + IF NOT r.normal AND NOT r.original THEN + CONTINUE; + END IF; + RAISE NOTICE 'NORMAL: orig=% normal=% istemp=% type=% identity=% schema=% name=% addr=% args=%', + r.original, r.normal, r.is_temporary, r.object_type, + r.object_identity, r.schema_name, r.object_name, + r.address_names, r.address_args; + END LOOP; +END; $$; + +CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop + EXECUTE PROCEDURE event_trigger_report_dropped(); + +CREATE OR REPLACE FUNCTION event_trigger_report_end() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r RECORD; +BEGIN + FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + RAISE NOTICE 'END: command_tag=% type=% identity=%', + r.command_tag, r.object_type, r.object_identity; + END LOOP; +END; $$; + +CREATE EVENT TRIGGER regress_event_trigger_report_end ON ddl_command_end + EXECUTE PROCEDURE event_trigger_report_end(); + +CREATE SCHEMA evttrig + +CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL) + +CREATE INDEX one_idx ON one (col_b) + +CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42) + +CREATE TABLE id (col_d int NOT NULL GENERATED ALWAYS AS IDENTITY); + +CREATE TABLE evttrig.parted ( + id int PRIMARY KEY) + PARTITION BY RANGE (id); + +CREATE TABLE evttrig.part_1_10 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (1) TO (10); + +CREATE TABLE evttrig.part_10_20 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (10) TO (20) PARTITION BY RANGE (id); + +CREATE TABLE evttrig.part_10_15 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (10) TO (15); + +CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (15) TO (20); + +ALTER TABLE evttrig.two DROP COLUMN col_c; + +ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT; + +ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey; + +ALTER TABLE evttrig.one DROP COLUMN col_c; + +ALTER TABLE evttrig.id ALTER COLUMN col_d SET DATA TYPE bigint; + +ALTER TABLE evttrig.id ALTER COLUMN col_d DROP IDENTITY, + ALTER COLUMN col_d SET DATA TYPE int; + +DROP INDEX evttrig.one_idx; + +DROP SCHEMA evttrig CASCADE; + +DROP TABLE a_temp_tbl; + +CREATE OR REPLACE FUNCTION event_trigger_report_dropped() + RETURNS event_trigger + LANGUAGE plpgsql +AS $$ +DECLARE r record; +BEGIN + FOR r IN SELECT * from pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE 'DROP: orig=% normal=% istemp=% type=% identity=% schema=% name=% addr=% args=%', + r.original, r.normal, r.is_temporary, r.object_type, + r.object_identity, r.schema_name, r.object_name, + r.address_names, r.address_args; + END LOOP; +END; $$; + +CREATE FUNCTION event_trigger_dummy_trigger() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + RETURN new; +END; $$; + +CREATE TABLE evtrg_nontemp_table (f1 int primary key, f2 int default 42); + +CREATE TRIGGER evtrg_nontemp_trig + BEFORE INSERT ON evtrg_nontemp_table + EXECUTE FUNCTION event_trigger_dummy_trigger(); + +CREATE POLICY evtrg_nontemp_pol ON evtrg_nontemp_table USING (f2 > 0); + +DROP TABLE evtrg_nontemp_table; + +CREATE TEMP TABLE a_temp_tbl (f1 int primary key, f2 int default 42); + +CREATE TRIGGER a_temp_trig + BEFORE INSERT ON a_temp_tbl + EXECUTE FUNCTION event_trigger_dummy_trigger(); + +CREATE POLICY a_temp_pol ON a_temp_tbl USING (f2 > 0); + +DROP TABLE a_temp_tbl; + +DROP FUNCTION event_trigger_dummy_trigger(); + +CREATE OPERATOR CLASS evttrigopclass FOR TYPE int USING btree AS STORAGE int; + +DROP EVENT TRIGGER regress_event_trigger_report_dropped; + +DROP EVENT TRIGGER regress_event_trigger_report_end; + +select pg_event_trigger_table_rewrite_oid(); + +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE EXCEPTION 'rewrites not allowed'; +END; +$$; + +create event trigger no_rewrite_allowed on table_rewrite + execute procedure test_evtrig_no_rewrite(); + +create table rewriteme (id serial primary key, foo float, bar timestamptz); + +insert into rewriteme + select x * 1.001 from generate_series(1, 500) as t(x); + +alter table rewriteme alter column foo type numeric; + +alter table rewriteme add column baz int default 0; + +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'Table ''%'' is being rewritten (reason = %)', + pg_event_trigger_table_rewrite_oid()::regclass, + pg_event_trigger_table_rewrite_reason(); +END; +$$; + +alter table rewriteme + add column onemore int default 0, + add column another int default -1, + alter column foo type numeric(10,4); + +CREATE MATERIALIZED VIEW heapmv USING heap AS SELECT 1 AS a; + +ALTER MATERIALIZED VIEW heapmv SET ACCESS METHOD heap2; + +DROP MATERIALIZED VIEW heapmv; + +alter table rewriteme alter column foo type numeric(12,4); + +begin; + +set timezone to 'UTC'; + +alter table rewriteme alter column bar type timestamp; + +set timezone to '0'; + +alter table rewriteme alter column bar type timestamptz; + +set timezone to 'Europe/London'; + +alter table rewriteme alter column bar type timestamp; + +rollback; + +CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'Table is being rewritten (reason = %)', + pg_event_trigger_table_rewrite_reason(); +END; +$$; + +create type rewritetype as (a int); + +create table rewritemetoo1 of rewritetype; + +create table rewritemetoo2 of rewritetype; + +alter type rewritetype alter attribute a type text cascade; + +create table rewritemetoo3 (a rewritetype); + +alter type rewritetype alter attribute a type varchar cascade; + +drop table rewriteme; + +drop event trigger no_rewrite_allowed; + +drop function test_evtrig_no_rewrite(); + +CREATE OR REPLACE FUNCTION reindex_start_command() +RETURNS event_trigger AS $$ +BEGIN + RAISE NOTICE 'REINDEX START: % %', tg_event, tg_tag; +END; +$$ LANGUAGE plpgsql; + +CREATE EVENT TRIGGER regress_reindex_start ON ddl_command_start + WHEN TAG IN ('REINDEX') + EXECUTE PROCEDURE reindex_start_command(); + +CREATE FUNCTION reindex_end_command() +RETURNS event_trigger AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() + LOOP + RAISE NOTICE 'REINDEX END: command_tag=% type=% identity=%', + obj.command_tag, obj.object_type, obj.object_identity; + END LOOP; +END; +$$ LANGUAGE plpgsql; + +CREATE EVENT TRIGGER regress_reindex_end ON ddl_command_end + WHEN TAG IN ('REINDEX') + EXECUTE PROCEDURE reindex_end_command(); + +CREATE FUNCTION reindex_end_command_snap() RETURNS EVENT_TRIGGER + AS $$ BEGIN PERFORM 1; END $$ LANGUAGE plpgsql; + +CREATE EVENT TRIGGER regress_reindex_end_snap ON ddl_command_end + EXECUTE FUNCTION reindex_end_command_snap(); + +CREATE TABLE concur_reindex_tab (c1 int); + +CREATE INDEX concur_reindex_ind ON concur_reindex_tab (c1); + +REINDEX INDEX concur_reindex_ind; + +REINDEX TABLE concur_reindex_tab; + +REINDEX INDEX CONCURRENTLY concur_reindex_ind; + +REINDEX TABLE CONCURRENTLY concur_reindex_tab; + +ALTER EVENT TRIGGER regress_reindex_start DISABLE; + +REINDEX INDEX concur_reindex_ind; + +REINDEX INDEX CONCURRENTLY concur_reindex_ind; + +DROP INDEX concur_reindex_ind; + +REINDEX TABLE concur_reindex_tab; + +REINDEX TABLE CONCURRENTLY concur_reindex_tab; + +CREATE SCHEMA concur_reindex_schema; + +REINDEX SCHEMA concur_reindex_schema; + +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema; + +CREATE TABLE concur_reindex_schema.tab (a int); + +CREATE INDEX ind ON concur_reindex_schema.tab (a); + +REINDEX SCHEMA concur_reindex_schema; + +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema; + +DROP INDEX concur_reindex_schema.ind; + +REINDEX SCHEMA concur_reindex_schema; + +REINDEX SCHEMA CONCURRENTLY concur_reindex_schema; + +DROP SCHEMA concur_reindex_schema CASCADE; + +CREATE TABLE concur_reindex_part (id int) PARTITION BY RANGE (id); + +REINDEX TABLE concur_reindex_part; + +REINDEX TABLE CONCURRENTLY concur_reindex_part; + +CREATE TABLE concur_reindex_child PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10); + +REINDEX TABLE concur_reindex_part; + +REINDEX TABLE CONCURRENTLY concur_reindex_part; + +CREATE INDEX concur_reindex_partidx ON concur_reindex_part (id); + +REINDEX INDEX concur_reindex_partidx; + +REINDEX INDEX CONCURRENTLY concur_reindex_partidx; + +REINDEX TABLE concur_reindex_part; + +REINDEX TABLE CONCURRENTLY concur_reindex_part; + +DROP TABLE concur_reindex_part; + +DROP EVENT TRIGGER regress_reindex_start; + +DROP EVENT TRIGGER regress_reindex_end; + +DROP EVENT TRIGGER regress_reindex_end_snap; + +DROP FUNCTION reindex_end_command(); + +DROP FUNCTION reindex_end_command_snap(); + +DROP FUNCTION reindex_start_command(); + +DROP TABLE concur_reindex_tab; + +RESET SESSION AUTHORIZATION; + +CREATE TABLE event_trigger_test (a integer, b text); + +CREATE OR REPLACE FUNCTION start_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - ddl_command_start', tg_tag; +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION end_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - ddl_command_end', tg_tag; +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION drop_sql_command() +RETURNS event_trigger AS $$ +BEGIN +RAISE NOTICE '% - sql_drop', tg_tag; +END; +$$ LANGUAGE plpgsql; + +CREATE EVENT TRIGGER start_rls_command ON ddl_command_start + WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE start_command(); + +CREATE EVENT TRIGGER end_rls_command ON ddl_command_end + WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE end_command(); + +CREATE EVENT TRIGGER sql_drop_command ON sql_drop + WHEN TAG IN ('DROP POLICY') EXECUTE PROCEDURE drop_sql_command(); + +CREATE POLICY p1 ON event_trigger_test USING (FALSE); + +ALTER POLICY p1 ON event_trigger_test USING (TRUE); + +ALTER POLICY p1 ON event_trigger_test RENAME TO p2; + +DROP POLICY p2 ON event_trigger_test; + +SELECT + e.evtname, + pg_describe_object('pg_event_trigger'::regclass, e.oid, 0) as descr, + b.type, b.object_names, b.object_args, + pg_identify_object(a.classid, a.objid, a.objsubid) as ident + FROM pg_event_trigger as e, + LATERAL pg_identify_object_as_address('pg_event_trigger'::regclass, e.oid, 0) as b, + LATERAL pg_get_object_address(b.type, b.object_names, b.object_args) as a + ORDER BY e.evtname; + +DROP EVENT TRIGGER start_rls_command; + +DROP EVENT TRIGGER end_rls_command; + +DROP EVENT TRIGGER sql_drop_command; + +CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger +LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE '% dropped %', tg_tag, obj.object_type; + END LOOP; +END; +$$; + +CREATE EVENT TRIGGER test_event_trigger_guc + ON sql_drop + WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc(); + +SET event_triggers = 'on'; + +CREATE POLICY pguc ON event_trigger_test USING (FALSE); + +DROP POLICY pguc ON event_trigger_test; + +CREATE POLICY pguc ON event_trigger_test USING (FALSE); + +SET event_triggers = 'off'; + +DROP POLICY pguc ON event_trigger_test; diff --git a/crates/pgt_pretty_print/tests/data/multi/event_trigger_login_60.sql b/crates/pgt_pretty_print/tests/data/multi/event_trigger_login_60.sql new file mode 100644 index 000000000..2d9229f6b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/event_trigger_login_60.sql @@ -0,0 +1,26 @@ +CREATE TABLE user_logins(id serial, who text); + +GRANT SELECT ON user_logins TO public; + +CREATE FUNCTION on_login_proc() RETURNS event_trigger AS $$ +BEGIN + INSERT INTO user_logins (who) VALUES (SESSION_USER); + RAISE NOTICE 'You are welcome!'; +END; +$$ LANGUAGE plpgsql; + +CREATE EVENT TRIGGER on_login_trigger ON login EXECUTE PROCEDURE on_login_proc(); + +ALTER EVENT TRIGGER on_login_trigger ENABLE ALWAYS; + +SELECT COUNT(*) FROM user_logins; + +SELECT COUNT(*) FROM user_logins; + +SELECT dathasloginevt FROM pg_database WHERE datname= 'DBNAME'; + +DROP TABLE user_logins; + +DROP EVENT TRIGGER on_login_trigger; + +DROP FUNCTION on_login_proc(); diff --git a/crates/pgt_pretty_print/tests/data/multi/explain_60.sql b/crates/pgt_pretty_print/tests/data/multi/explain_60.sql new file mode 100644 index 000000000..3323283fc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/explain_60.sql @@ -0,0 +1,176 @@ +create function explain_filter(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in execute $1 + loop + -- Replace any numeric word with just 'N' + ln := regexp_replace(ln, '-?\m\d+\M', 'N', 'g'); + -- In sort output, the above won't match units-suffixed numbers + ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g'); + -- Ignore text-mode buffers output because it varies depending + -- on the system state + CONTINUE WHEN (ln ~ ' +Buffers: .*'); + -- Ignore text-mode "Planning:" line because whether it's output + -- varies depending on the system state + CONTINUE WHEN (ln = 'Planning:'); + return next ln; + end loop; +end; +$$; + +create function explain_filter_to_json(text) returns jsonb +language plpgsql as +$$ +declare + data text := ''; + ln text; +begin + for ln in execute $1 + loop + -- Replace any numeric word with just '0' + ln := regexp_replace(ln, '\m\d+\M', '0', 'g'); + data := data || ln; + end loop; + return data::jsonb; +end; +$$; + +set jit = off; + +set track_io_timing = off; + +select explain_filter('explain select * from int8_tbl i8'); + +select explain_filter('explain (analyze, buffers off) select * from int8_tbl i8'); + +select explain_filter('explain (analyze, buffers off, verbose) select * from int8_tbl i8'); + +select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8'); + +select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8'); + +select explain_filter('explain (analyze, serialize, buffers, format yaml) select * from int8_tbl i8'); + +select explain_filter('explain (buffers, format text) select * from int8_tbl i8'); + +select explain_filter('explain (buffers, format json) select * from int8_tbl i8'); + +select explain_filter('explain verbose select sum(unique1) over w, sum(unique2) over (w order by hundred), sum(tenthous) over (w order by hundred) from tenk1 window w as (partition by ten)'); + +select explain_filter('explain verbose select sum(unique1) over w1, sum(unique2) over (w1 order by hundred), sum(tenthous) over (w1 order by hundred rows 10 preceding) from tenk1 window w1 as (partition by ten)'); + +set track_io_timing = on; + +select explain_filter('explain (analyze, buffers, format json) select * from int8_tbl i8'); + +set track_io_timing = off; + +begin; + +set local plan_cache_mode = force_generic_plan; + +select true as "OK" + from explain_filter('explain (settings) select * from int8_tbl i8') ln + where ln ~ '^ *Settings: .*plan_cache_mode = ''force_generic_plan'''; + +select explain_filter_to_json('explain (settings, format json) select * from int8_tbl i8') #> '{0,Settings,plan_cache_mode}'; + +rollback; + +select explain_filter('explain (generic_plan) select unique1 from tenk1 where thousand = $1'); + +select explain_filter('explain (analyze, generic_plan) select unique1 from tenk1 where thousand = $1'); + +select explain_filter('explain (memory) select * from int8_tbl i8'); + +select explain_filter('explain (memory, analyze, buffers off) select * from int8_tbl i8'); + +select explain_filter('explain (memory, summary, format yaml) select * from int8_tbl i8'); + +select explain_filter('explain (memory, analyze, format json) select * from int8_tbl i8'); + +prepare int8_query as select * from int8_tbl i8; + +select explain_filter('explain (memory) execute int8_query'); + +create table gen_part ( + key1 integer not null, + key2 integer not null +) partition by list (key1); + +create table gen_part_1 + partition of gen_part for values in (1) + partition by range (key2); + +create table gen_part_1_1 + partition of gen_part_1 for values from (1) to (2); + +create table gen_part_1_2 + partition of gen_part_1 for values from (2) to (3); + +create table gen_part_2 + partition of gen_part for values in (2); + +select explain_filter('explain (generic_plan) select key1, key2 from gen_part where key1 = 1 and key2 = $1'); + +drop table gen_part; + +begin; + +set parallel_setup_cost=0; + +set parallel_tuple_cost=0; + +set min_parallel_table_scan_size=0; + +set max_parallel_workers_per_gather=4; + +select jsonb_pretty( + explain_filter_to_json('explain (analyze, verbose, buffers, format json) + select * from tenk1 order by tenthous') + -- remove "Workers" node of the Seq Scan plan node + #- '{0,Plan,Plans,0,Plans,0,Workers}' + -- remove "Workers" node of the Sort plan node + #- '{0,Plan,Plans,0,Workers}' + -- Also remove its sort-type fields, as those aren't 100% stable + #- '{0,Plan,Plans,0,Sort Method}' + #- '{0,Plan,Plans,0,Sort Space Type}' +); + +rollback; + +create temp table t1(f1 float8); + +create function pg_temp.mysin(float8) returns float8 language plpgsql +as 'begin return sin($1); end'; + +select explain_filter('explain (verbose) select * from t1 where pg_temp.mysin(f1) < 0.5'); + +set compute_query_id = on; + +select explain_filter('explain (verbose) select * from int8_tbl i8'); + +select explain_filter('explain (verbose) declare test_cur cursor for select * from int8_tbl'); + +select explain_filter('explain (verbose) create table test_ctas as select 1'); + +select explain_filter('explain (analyze,buffers off,serialize) select * from int8_tbl i8'); + +select explain_filter('explain (analyze,serialize text,buffers,timing off) select * from int8_tbl i8'); + +select explain_filter('explain (analyze,serialize binary,buffers,timing) select * from int8_tbl i8'); + +select explain_filter('explain (analyze,buffers off,serialize) create temp table explain_temp as select * from int8_tbl i8'); + +select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over() from generate_series(1,10) a(n)'); + +set work_mem to 64; + +select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over() from generate_series(1,2500) a(n)'); + +select explain_filter('explain (analyze,buffers off,costs off) select sum(n) over(partition by m) from (SELECT n < 3 as m, n from generate_series(1,2500) a(n))'); + +reset work_mem; diff --git a/crates/pgt_pretty_print/tests/data/multi/expressions_60.sql b/crates/pgt_pretty_print/tests/data/multi/expressions_60.sql new file mode 100644 index 000000000..efa329cec --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/expressions_60.sql @@ -0,0 +1,194 @@ +SELECT date(now())::text = current_date::text; + +SELECT now()::timetz::text = current_time::text; + +SELECT now()::timetz(4)::text = current_time(4)::text; + +SELECT now()::time::text = localtime::text; + +SELECT now()::time(3)::text = localtime(3)::text; + +SELECT current_timestamp = NOW(); + +SELECT length(current_timestamp::text) >= length(current_timestamp(0)::text); + +SELECT now()::timestamp::text = localtimestamp::text; + +SELECT current_time = current_time(7); + +SELECT current_timestamp = current_timestamp(7); + +SELECT localtime = localtime(7); + +SELECT localtimestamp = localtimestamp(7); + +SELECT current_catalog = current_database(); + +SELECT current_schema; + +SET search_path = 'notme'; + +SELECT current_schema; + +SET search_path = 'pg_catalog'; + +SELECT current_schema; + +RESET search_path; + +begin; + +create table numeric_tbl (f1 numeric(18,3), f2 numeric); + +create view numeric_view as + select + f1, f1::numeric(16,4) as f1164, f1::numeric as f1n, + f2, f2::numeric(16,4) as f2164, f2::numeric as f2n + from numeric_tbl; + +select * from numeric_view; + +create table bpchar_tbl (f1 character(16) unique, f2 bpchar); + +create view bpchar_view as + select + f1, f1::character(14) as f114, f1::bpchar as f1n, + f2, f2::character(14) as f214, f2::bpchar as f2n + from bpchar_tbl; + +select * from bpchar_view + where f1::bpchar = 'foo'; + +rollback; + +select random() IN (1, 4, 8.0); + +select random()::int IN (1, 4, 8.0); + +select '(0,0)'::point in ('(0,0,0,0)'::box, point(0,0)); + +begin; + +create function return_int_input(int) returns int as $$ +begin + return $1; +end; +$$ language plpgsql stable; + +create function return_text_input(text) returns text as $$ +begin + return $1; +end; +$$ language plpgsql stable; + +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1); + +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null); + +select return_int_input(1) in (null, null, null, null, null, null, null, null, null, null, null); + +select return_int_input(1) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null); + +select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1); + +select return_int_input(null::int) in (10, 9, 2, 8, 3, 7, 4, 6, 5, null); + +select return_text_input('a') in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'); + +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1); + +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 0); + +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 2, null); + +select return_int_input(1) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1, null); + +select return_int_input(1) not in (null, null, null, null, null, null, null, null, null, null, null); + +select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, 1); + +select return_int_input(null::int) not in (10, 9, 2, 8, 3, 7, 4, 6, 5, null); + +select return_text_input('a') not in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'); + +rollback; + +begin; + +create type myint; + +create function myintin(cstring) returns myint strict immutable language + internal as 'int4in'; + +create function myintout(myint) returns cstring strict immutable language + internal as 'int4out'; + +create function myinthash(myint) returns integer strict immutable language + internal as 'hashint4'; + +create type myint (input = myintin, output = myintout, like = int4); + +create cast (int4 as myint) without function; + +create cast (myint as int4) without function; + +create function myinteq(myint, myint) returns bool as $$ +begin + if $1 is null and $2 is null then + return true; + else + return $1::int = $2::int; + end if; +end; +$$ language plpgsql immutable; + +create function myintne(myint, myint) returns bool as $$ +begin + return not myinteq($1, $2); +end; +$$ language plpgsql immutable; + +create operator = ( + leftarg = myint, + rightarg = myint, + commutator = =, + negator = <>, + procedure = myinteq, + restrict = eqsel, + join = eqjoinsel, + merges +); + +create operator <> ( + leftarg = myint, + rightarg = myint, + commutator = <>, + negator = =, + procedure = myintne, + restrict = eqsel, + join = eqjoinsel, + merges +); + +create operator class myint_ops +default for type myint using hash as + operator 1 = (myint, myint), + function 1 myinthash(myint); + +create table inttest (a myint); + +insert into inttest values(1::myint),(null); + +select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null); + +select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null); + +select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint,6::myint,7::myint,8::myint,9::myint, null); + +select * from inttest where a in (1::myint,2::myint,3::myint,4::myint,5::myint, null); + +select * from inttest where a not in (1::myint,2::myint,3::myint,4::myint,5::myint, null); + +select * from inttest where a not in (0::myint,2::myint,3::myint,4::myint,5::myint, null); + +rollback; diff --git a/crates/pgt_pretty_print/tests/data/multi/fast_default_60.sql b/crates/pgt_pretty_print/tests/data/multi/fast_default_60.sql new file mode 100644 index 000000000..0d21ee0fd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/fast_default_60.sql @@ -0,0 +1,690 @@ +SET search_path = fast_default; + +CREATE SCHEMA fast_default; + +CREATE TABLE m(id OID); + +INSERT INTO m VALUES (NULL::OID); + +CREATE FUNCTION set(tabname name) RETURNS VOID +AS $$ +BEGIN + UPDATE m + SET id = (SELECT c.relfilenode + FROM pg_class AS c, pg_namespace AS s + WHERE c.relname = tabname + AND c.relnamespace = s.oid + AND s.nspname = 'fast_default'); +END; +$$ LANGUAGE 'plpgsql'; + +CREATE FUNCTION comp() RETURNS TEXT +AS $$ +BEGIN + RETURN (SELECT CASE + WHEN m.id = c.relfilenode THEN 'Unchanged' + ELSE 'Rewritten' + END + FROM m, pg_class AS c, pg_namespace AS s + WHERE c.relname = 't' + AND c.relnamespace = s.oid + AND s.nspname = 'fast_default'); +END; +$$ LANGUAGE 'plpgsql'; + +CREATE FUNCTION log_rewrite() RETURNS event_trigger +LANGUAGE plpgsql as +$func$ + +declare + this_schema text; +begin + select into this_schema relnamespace::regnamespace::text + from pg_class + where oid = pg_event_trigger_table_rewrite_oid(); + if this_schema = 'fast_default' + then + RAISE NOTICE 'rewriting table % for reason %', + pg_event_trigger_table_rewrite_oid()::regclass, + pg_event_trigger_table_rewrite_reason(); + end if; +end; +$func$; + +CREATE TABLE has_volatile AS +SELECT * FROM generate_series(1,10) id; + +CREATE EVENT TRIGGER has_volatile_rewrite + ON table_rewrite + EXECUTE PROCEDURE log_rewrite(); + +ALTER TABLE has_volatile ADD col1 int; + +ALTER TABLE has_volatile ADD col2 int DEFAULT 1; + +ALTER TABLE has_volatile ADD col3 timestamptz DEFAULT current_timestamp; + +ALTER TABLE has_volatile ADD col4 int DEFAULT (random() * 10000)::int; + +ALTER TABLE has_volatile ALTER COLUMN col5 TYPE float8; + +ALTER TABLE has_volatile ALTER COLUMN col5 TYPE numeric; + +ALTER TABLE has_volatile ALTER COLUMN col5 TYPE numeric; + +ALTER TABLE has_volatile ADD col7 int GENERATED ALWAYS AS (55) stored; + +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT 1); + +SELECT set('t'); + +INSERT INTO T VALUES (1), (2); + +ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT 'hello', + ALTER COLUMN c_int SET DEFAULT 2; + +INSERT INTO T VALUES (3), (4); + +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'world', + ALTER COLUMN c_bpchar SET DEFAULT 'dog'; + +INSERT INTO T VALUES (5), (6); + +ALTER TABLE T ADD COLUMN c_date DATE DEFAULT '2016-06-02', + ALTER COLUMN c_text SET DEFAULT 'cat'; + +INSERT INTO T VALUES (7), (8); + +ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP DEFAULT '2016-09-01 12:00:00', + ADD COLUMN c_timestamp_null TIMESTAMP, + ALTER COLUMN c_date SET DEFAULT '2010-01-01'; + +INSERT INTO T VALUES (9), (10); + +ALTER TABLE T ADD COLUMN c_array TEXT[] + DEFAULT '{"This", "is", "the", "real", "world"}', + ALTER COLUMN c_timestamp SET DEFAULT '1970-12-31 11:12:13', + ALTER COLUMN c_timestamp_null SET DEFAULT '2016-09-29 12:00:00'; + +INSERT INTO T VALUES (11), (12); + +ALTER TABLE T ADD COLUMN c_small SMALLINT DEFAULT -5, + ADD COLUMN c_small_null SMALLINT, + ALTER COLUMN c_array + SET DEFAULT '{"This", "is", "no", "fantasy"}'; + +INSERT INTO T VALUES (13), (14); + +ALTER TABLE T ADD COLUMN c_big BIGINT DEFAULT 180000000000018, + ALTER COLUMN c_small SET DEFAULT 9, + ALTER COLUMN c_small_null SET DEFAULT 13; + +INSERT INTO T VALUES (15), (16); + +ALTER TABLE T ADD COLUMN c_num NUMERIC DEFAULT 1.00000000001, + ALTER COLUMN c_big SET DEFAULT -9999999999999999; + +INSERT INTO T VALUES (17), (18); + +ALTER TABLE T ADD COLUMN c_time TIME DEFAULT '12:00:00', + ALTER COLUMN c_num SET DEFAULT 2.000000000000002; + +INSERT INTO T VALUES (19), (20); + +ALTER TABLE T ADD COLUMN c_interval INTERVAL DEFAULT '1 day', + ALTER COLUMN c_time SET DEFAULT '23:59:59'; + +INSERT INTO T VALUES (21), (22); + +ALTER TABLE T ADD COLUMN c_hugetext TEXT DEFAULT repeat('abcdefg',1000), + ALTER COLUMN c_interval SET DEFAULT '3 hours'; + +INSERT INTO T VALUES (23), (24); + +ALTER TABLE T ALTER COLUMN c_interval DROP DEFAULT, + ALTER COLUMN c_hugetext SET DEFAULT repeat('poiuyt', 1000); + +INSERT INTO T VALUES (25), (26); + +ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT, + ALTER COLUMN c_date DROP DEFAULT, + ALTER COLUMN c_text DROP DEFAULT, + ALTER COLUMN c_timestamp DROP DEFAULT, + ALTER COLUMN c_array DROP DEFAULT, + ALTER COLUMN c_small DROP DEFAULT, + ALTER COLUMN c_big DROP DEFAULT, + ALTER COLUMN c_num DROP DEFAULT, + ALTER COLUMN c_time DROP DEFAULT, + ALTER COLUMN c_hugetext DROP DEFAULT; + +INSERT INTO T VALUES (27), (28); + +SELECT pk, c_int, c_bpchar, c_text, c_date, c_timestamp, + c_timestamp_null, c_array, c_small, c_small_null, + c_big, c_num, c_time, c_interval, + c_hugetext = repeat('abcdefg',1000) as c_hugetext_origdef, + c_hugetext = repeat('poiuyt', 1000) as c_hugetext_newdef +FROM T ORDER BY pk; + +SELECT comp(); + +DROP TABLE T; + +CREATE OR REPLACE FUNCTION foo(a INT) RETURNS TEXT AS $$ +DECLARE res TEXT := ''; + i INT; +BEGIN + i := 0; + WHILE (i < a) LOOP + res := res || chr(ascii('a') + i); + i := i + 1; + END LOOP; + RETURN res; +END; $$ LANGUAGE PLPGSQL STABLE; + +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY, c_int INT DEFAULT LENGTH(foo(6))); + +SELECT set('t'); + +INSERT INTO T VALUES (1), (2); + +ALTER TABLE T ADD COLUMN c_bpchar BPCHAR(5) DEFAULT foo(4), + ALTER COLUMN c_int SET DEFAULT LENGTH(foo(8)); + +INSERT INTO T VALUES (3), (4); + +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT foo(6), + ALTER COLUMN c_bpchar SET DEFAULT foo(3); + +INSERT INTO T VALUES (5), (6); + +ALTER TABLE T ADD COLUMN c_date DATE + DEFAULT '2016-06-02'::DATE + LENGTH(foo(10)), + ALTER COLUMN c_text SET DEFAULT foo(12); + +INSERT INTO T VALUES (7), (8); + +ALTER TABLE T ADD COLUMN c_timestamp TIMESTAMP + DEFAULT '2016-09-01'::DATE + LENGTH(foo(10)), + ALTER COLUMN c_date + SET DEFAULT '2010-01-01'::DATE - LENGTH(foo(4)); + +INSERT INTO T VALUES (9), (10); + +ALTER TABLE T ADD COLUMN c_array TEXT[] + DEFAULT ('{"This", "is", "' || foo(4) || + '","the", "real", "world"}')::TEXT[], + ALTER COLUMN c_timestamp + SET DEFAULT '1970-12-31'::DATE + LENGTH(foo(30)); + +INSERT INTO T VALUES (11), (12); + +ALTER TABLE T ALTER COLUMN c_int DROP DEFAULT, + ALTER COLUMN c_array + SET DEFAULT ('{"This", "is", "' || foo(1) || + '", "fantasy"}')::text[]; + +INSERT INTO T VALUES (13), (14); + +ALTER TABLE T ALTER COLUMN c_bpchar DROP DEFAULT, + ALTER COLUMN c_date DROP DEFAULT, + ALTER COLUMN c_text DROP DEFAULT, + ALTER COLUMN c_timestamp DROP DEFAULT, + ALTER COLUMN c_array DROP DEFAULT; + +INSERT INTO T VALUES (15), (16); + +SELECT * FROM T; + +SELECT comp(); + +DROP TABLE T; + +CREATE DOMAIN domain1 AS int DEFAULT 11; + +CREATE DOMAIN domain2 AS int DEFAULT random(min=>10, max=>100); + +CREATE DOMAIN domain3 AS text DEFAULT foo(4); + +CREATE DOMAIN domain4 AS text[] + DEFAULT ('{"This", "is", "' || foo(4) || '","the", "real", "world"}')::TEXT[]; + +CREATE TABLE t2 (a domain1); + +INSERT INTO t2 VALUES (1),(2); + +ALTER TABLE t2 ADD COLUMN b domain1 default 3; + +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum; + +ALTER TABLE t2 ADD COLUMN c domain3 default left(random()::text,3); + +ALTER TABLE t2 ADD COLUMN d domain4; + +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum; + +ALTER TABLE t2 ADD COLUMN e domain2; + +SELECT attnum, attname, atthasmissing, atthasdef, attmissingval +FROM pg_attribute +WHERE attnum > 0 AND attrelid = 't2'::regclass +ORDER BY attnum; + +SELECT a, b, length(c) = 3 as c_ok, d, e >= 10 as e_ok FROM t2; + +DROP TABLE t2; + +DROP DOMAIN domain1; + +DROP DOMAIN domain2; + +DROP DOMAIN domain3; + +DROP DOMAIN domain4; + +DROP FUNCTION foo(INT); + +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY); + +INSERT INTO T VALUES (1); + +SELECT set('t'); + +ALTER TABLE T ADD COLUMN c1 TIMESTAMP DEFAULT now(); + +SELECT comp(); + +ALTER TABLE T ADD COLUMN c2 TIMESTAMP DEFAULT clock_timestamp(); + +SELECT comp(); + +CREATE FUNCTION foolme(timestamptz DEFAULT clock_timestamp()) + RETURNS timestamptz + IMMUTABLE AS 'select $1' LANGUAGE sql; + +ALTER TABLE T ADD COLUMN c3 timestamptz DEFAULT foolme(); + +SELECT attname, atthasmissing, attmissingval FROM pg_attribute + WHERE attrelid = 't'::regclass AND attnum > 0 + ORDER BY attnum; + +DROP TABLE T; + +DROP FUNCTION foolme(timestamptz); + +CREATE TABLE T (pk INT NOT NULL PRIMARY KEY); + +SELECT set('t'); + +INSERT INTO T SELECT * FROM generate_series(1, 10) a; + +ALTER TABLE T ADD COLUMN c_bigint BIGINT NOT NULL DEFAULT -1; + +INSERT INTO T SELECT b, b - 10 FROM generate_series(11, 20) a(b); + +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'hello'; + +INSERT INTO T SELECT b, b - 10, (b + 10)::text FROM generate_series(21, 30) a(b); + +SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1; + +SELECT c_bigint, c_text FROM T WHERE c_bigint = -1 LIMIT 1; + +SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1; + +SELECT c_bigint, c_text FROM T WHERE c_text = 'hello' LIMIT 1; + +SELECT COALESCE(c_bigint, pk), COALESCE(c_text, pk::text) +FROM T +ORDER BY pk LIMIT 10; + +SELECT SUM(c_bigint), MAX(c_text COLLATE "C" ), MIN(c_text COLLATE "C") FROM T; + +SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10; + +SELECT * FROM T ORDER BY c_bigint, c_text, pk LIMIT 10; + +SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10; + +SELECT * FROM T WHERE c_bigint > -1 ORDER BY c_bigint, c_text, pk LIMIT 10; + +DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING *; + +DELETE FROM T WHERE pk BETWEEN 10 AND 20 RETURNING *; + +UPDATE T SET c_text = '"' || c_text || '"' WHERE pk < 10; + +SELECT * FROM T WHERE c_text LIKE '"%"' ORDER BY PK; + +SELECT comp(); + +DROP TABLE T; + +CREATE TABLE T(pk INT NOT NULL PRIMARY KEY); + +SELECT set('t'); + +INSERT INTO T VALUES (1), (2); + +ALTER TABLE T ADD COLUMN c_int INT NOT NULL DEFAULT -1; + +INSERT INTO T VALUES (3), (4); + +ALTER TABLE T ADD COLUMN c_text TEXT DEFAULT 'Hello'; + +INSERT INTO T VALUES (5), (6); + +ALTER TABLE T ALTER COLUMN c_text SET DEFAULT 'world', + ALTER COLUMN c_int SET DEFAULT 1; + +INSERT INTO T VALUES (7), (8); + +SELECT * FROM T ORDER BY pk; + +CREATE INDEX i ON T(c_int, c_text); + +SELECT c_text FROM T WHERE c_int = -1; + +SELECT comp(); + +CREATE TABLE t1 AS +SELECT 1::int AS a , 2::int AS b +FROM generate_series(1,20) q; + +ALTER TABLE t1 ADD COLUMN c text; + +SELECT a, + stddev(cast((SELECT sum(1) FROM generate_series(1,20) x) AS float4)) + OVER (PARTITION BY a,b,c ORDER BY b) + AS z +FROM t1; + +DROP TABLE T; + +CREATE FUNCTION test_trigger() +RETURNS trigger +LANGUAGE plpgsql +AS $$ + +begin + raise notice 'old tuple: %', to_json(OLD)::text; + if TG_OP = 'DELETE' + then + return OLD; + else + return NEW; + end if; +end; + +$$; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,3); + +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; + +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,3); + +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; + +ALTER TABLE t ADD COLUMN y int; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,3); + +ALTER TABLE t ADD COLUMN x int; + +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,3); + +ALTER TABLE t ADD COLUMN x int; + +ALTER TABLE t ADD COLUMN y int; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,NULL); + +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; + +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,NULL); + +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; + +ALTER TABLE t ADD COLUMN y int; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,NULL); + +ALTER TABLE t ADD COLUMN x int; + +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); + +INSERT INTO t (a,b,c) VALUES (1,2,NULL); + +ALTER TABLE t ADD COLUMN x int; + +ALTER TABLE t ADD COLUMN y int; + +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); + +SELECT * FROM t; + +UPDATE t SET y = 2; + +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE leader (a int PRIMARY KEY, b int); + +CREATE TABLE follower (a int REFERENCES leader ON DELETE CASCADE, b int); + +INSERT INTO leader VALUES (1, 1), (2, 2); + +ALTER TABLE leader ADD c int; + +ALTER TABLE leader DROP c; + +DELETE FROM leader; + +CREATE TABLE vtype( a integer); + +INSERT INTO vtype VALUES (1); + +ALTER TABLE vtype ADD COLUMN b DOUBLE PRECISION DEFAULT 0.2; + +ALTER TABLE vtype ADD COLUMN c BOOLEAN DEFAULT true; + +SELECT * FROM vtype; + +ALTER TABLE vtype + ALTER b TYPE text USING b::text, + ALTER c TYPE text USING c::text; + +SELECT * FROM vtype; + +CREATE TABLE vtype2 (a int); + +INSERT INTO vtype2 VALUES (1); + +ALTER TABLE vtype2 ADD COLUMN b varchar(10) DEFAULT 'xxx'; + +ALTER TABLE vtype2 ALTER COLUMN b SET DEFAULT 'yyy'; + +INSERT INTO vtype2 VALUES (2); + +ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20); + +SELECT * FROM vtype2; + +BEGIN; + +CREATE TABLE t(); + +INSERT INTO t DEFAULT VALUES; + +ALTER TABLE t ADD COLUMN a int DEFAULT 1; + +CREATE INDEX ON t(a); + +UPDATE t SET a = NULL; + +SET LOCAL enable_seqscan = true; + +SELECT * FROM t WHERE a IS NULL; + +SET LOCAL enable_seqscan = false; + +SELECT * FROM t WHERE a IS NULL; + +ROLLBACK; + +CREATE FOREIGN DATA WRAPPER dummy; + +CREATE SERVER s0 FOREIGN DATA WRAPPER dummy; + +CREATE FOREIGN TABLE ft1 (c1 integer NOT NULL) SERVER s0; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer DEFAULT 0; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10); + +SELECT count(*) + FROM pg_attribute + WHERE attrelid = 'ft1'::regclass AND + (attmissingval IS NOT NULL OR atthasmissing); + +DROP FOREIGN TABLE ft1; + +DROP SERVER s0; + +DROP FOREIGN DATA WRAPPER dummy; + +DROP TABLE vtype; + +DROP TABLE vtype2; + +DROP TABLE follower; + +DROP TABLE leader; + +DROP FUNCTION test_trigger(); + +DROP TABLE t1; + +DROP FUNCTION set(name); + +DROP FUNCTION comp(); + +DROP TABLE m; + +DROP TABLE has_volatile; + +DROP EVENT TRIGGER has_volatile_rewrite; + +DROP FUNCTION log_rewrite; + +DROP SCHEMA fast_default; + +set search_path = public; + +create table has_fast_default(f1 int); + +insert into has_fast_default values(1); + +alter table has_fast_default add column f2 int default 42; + +table has_fast_default; diff --git a/crates/pgt_pretty_print/tests/data/multi/float4_60.sql b/crates/pgt_pretty_print/tests/data/multi/float4_60.sql new file mode 100644 index 000000000..6ce118f79 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/float4_60.sql @@ -0,0 +1,391 @@ +CREATE TABLE FLOAT4_TBL (f1 float4); + +INSERT INTO FLOAT4_TBL(f1) VALUES (' 0.0'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30 '); + +INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 '); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'::float8); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'::float8); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'::float8); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'::float8); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400'); + +INSERT INTO FLOAT4_TBL(f1) VALUES (''); + +INSERT INTO FLOAT4_TBL(f1) VALUES (' '); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0'); + +INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0'); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5'); + +SELECT pg_input_is_valid('34.5', 'float4'); + +SELECT pg_input_is_valid('xyz', 'float4'); + +SELECT pg_input_is_valid('1e400', 'float4'); + +SELECT * FROM pg_input_error_info('1e400', 'float4'); + +SELECT 'NaN'::float4; + +SELECT 'nan'::float4; + +SELECT ' NAN '::float4; + +SELECT 'infinity'::float4; + +SELECT ' -INFINiTY '::float4; + +SELECT 'N A N'::float4; + +SELECT 'NaN x'::float4; + +SELECT ' INFINITY x'::float4; + +SELECT 'Infinity'::float4 + 100.0; + +SELECT 'Infinity'::float4 / 'Infinity'::float4; + +SELECT '42'::float4 / 'Infinity'::float4; + +SELECT 'nan'::float4 / 'nan'::float4; + +SELECT 'nan'::float4 / '0'::float4; + +SELECT 'nan'::numeric::float4; + +SELECT * FROM FLOAT4_TBL; + +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3'; + +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3'; + +SELECT f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1; + +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3'; + +SELECT f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1; + +SELECT f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3'; + +SELECT f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1 / '0.0' from FLOAT4_TBL f; + +SELECT * FROM FLOAT4_TBL; + +SELECT f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f; + +UPDATE FLOAT4_TBL + SET f1 = FLOAT4_TBL.f1 * '-1' + WHERE FLOAT4_TBL.f1 > '0.0'; + +SELECT * FROM FLOAT4_TBL ORDER BY 1; + +SELECT '32767.4'::float4::int2; + +SELECT '32767.6'::float4::int2; + +SELECT '-32768.4'::float4::int2; + +SELECT '-32768.6'::float4::int2; + +SELECT '2147483520'::float4::int4; + +SELECT '2147483647'::float4::int4; + +SELECT '-2147483648.5'::float4::int4; + +SELECT '-2147483900'::float4::int4; + +SELECT '9223369837831520256'::float4::int8; + +SELECT '9223372036854775807'::float4::int8; + +SELECT '-9223372036854775808.5'::float4::int8; + +SELECT '-9223380000000000000'::float4::int8; + +SELECT float4send('5e-20'::float4); + +SELECT float4send('67e14'::float4); + +SELECT float4send('985e15'::float4); + +SELECT float4send('55895e-16'::float4); + +SELECT float4send('7038531e-32'::float4); + +SELECT float4send('702990899e-20'::float4); + +SELECT float4send('3e-23'::float4); + +SELECT float4send('57e18'::float4); + +SELECT float4send('789e-35'::float4); + +SELECT float4send('2539e-18'::float4); + +SELECT float4send('76173e28'::float4); + +SELECT float4send('887745e-11'::float4); + +SELECT float4send('5382571e-37'::float4); + +SELECT float4send('82381273e-35'::float4); + +SELECT float4send('750486563e-38'::float4); + +SELECT float4send('1.17549435e-38'::float4); + +SELECT float4send('1.1754944e-38'::float4); + +create type xfloat4; + +create function xfloat4in(cstring) returns xfloat4 immutable strict + language internal as 'int4in'; + +create function xfloat4out(xfloat4) returns cstring immutable strict + language internal as 'int4out'; + +create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4); + +create cast (xfloat4 as float4) without function; + +create cast (float4 as xfloat4) without function; + +create cast (xfloat4 as integer) without function; + +create cast (integer as xfloat4) without function; + +with testdata(bits) as (values + -- small subnormals + (x'00000001'), + (x'00000002'), (x'00000003'), + (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'), + (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'), + -- stress values + (x'0053c4f4'), -- 7693e-42 + (x'006c85c4'), -- 996622e-44 + (x'0041ca76'), -- 60419369e-46 + (x'004b7678'), -- 6930161142e-48 + -- taken from upstream testsuite + (x'00000007'), + (x'00424fe2'), + -- borderline between subnormal and normal + (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff')) +select float4send(flt) as ibits, + flt + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + +with testdata(bits) as (values + (x'00000000'), + -- smallest normal values + (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'), + (x'00800006'), + -- small normal values chosen for short vs. long output + (x'008002f1'), (x'008002f2'), (x'008002f3'), + (x'00800e17'), (x'00800e18'), (x'00800e19'), + -- assorted values (random mantissae) + (x'01000001'), (x'01102843'), (x'01a52c98'), + (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'), + (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'), + (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'), + (x'1f850283'), (x'2874a9d6'), + -- values around 5e-08 + (x'3356bf94'), (x'3356bf95'), (x'3356bf96'), + -- around 1e-07 + (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'), + -- around 3e-07 .. 1e-04 + (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'), + (x'350637bc'), (x'350637bd'), (x'350637be'), + (x'35719786'), (x'35719787'), (x'35719788'), + (x'358637bc'), (x'358637bd'), (x'358637be'), + (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'), + (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'), + -- format crossover at 1e-04 + (x'38d1b714'), (x'38d1b715'), (x'38d1b716'), + (x'38d1b717'), (x'38d1b718'), (x'38d1b719'), + (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'), + (x'38d1b71d'), + -- + (x'38dffffe'), (x'38dfffff'), (x'38e00000'), + (x'38efffff'), (x'38f00000'), (x'38f00001'), + (x'3a83126e'), (x'3a83126f'), (x'3a831270'), + (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'), + (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'), + -- chosen to need 9 digits for 3dcccd70 + (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'), + -- + (x'3effffff'), (x'3f000000'), (x'3f000001'), + (x'3f333332'), (x'3f333333'), (x'3f333334'), + -- approach 1.0 with increasing numbers of 9s + (x'3f666665'), (x'3f666666'), (x'3f666667'), + (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'), + (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'), + (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'), + (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'), + (x'3f7fffee'), (x'3f7fffef'), + -- values very close to 1 + (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'), + (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'), + (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'), + (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'), + (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'), + (x'3f7fffff'), + (x'3f800000'), + (x'3f800001'), (x'3f800002'), (x'3f800003'), + (x'3f800004'), (x'3f800005'), (x'3f800006'), + (x'3f800007'), (x'3f800008'), (x'3f800009'), + -- values 1 to 1.1 + (x'3f80000f'), (x'3f800010'), (x'3f800011'), + (x'3f800012'), (x'3f800013'), (x'3f800014'), + (x'3f800017'), (x'3f800018'), (x'3f800019'), + (x'3f80001a'), (x'3f80001b'), (x'3f80001c'), + (x'3f800029'), (x'3f80002a'), (x'3f80002b'), + (x'3f800053'), (x'3f800054'), (x'3f800055'), + (x'3f800346'), (x'3f800347'), (x'3f800348'), + (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'), + (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'), + (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'), + -- + (x'3fc90fdb'), -- pi/2 + (x'402df854'), -- e + (x'40490fdb'), -- pi + -- + (x'409fffff'), (x'40a00000'), (x'40a00001'), + (x'40afffff'), (x'40b00000'), (x'40b00001'), + (x'411fffff'), (x'41200000'), (x'41200001'), + (x'42c7ffff'), (x'42c80000'), (x'42c80001'), + (x'4479ffff'), (x'447a0000'), (x'447a0001'), + (x'461c3fff'), (x'461c4000'), (x'461c4001'), + (x'47c34fff'), (x'47c35000'), (x'47c35001'), + (x'497423ff'), (x'49742400'), (x'49742401'), + (x'4b18967f'), (x'4b189680'), (x'4b189681'), + (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'), + (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'), + (x'501502f8'), (x'501502f9'), (x'501502fa'), + (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'), + -- stress values + (x'1f6c1e4a'), -- 5e-20 + (x'59be6cea'), -- 67e14 + (x'5d5ab6c4'), -- 985e15 + (x'2cc4a9bd'), -- 55895e-16 + (x'15ae43fd'), -- 7038531e-32 + (x'2cf757ca'), -- 702990899e-20 + (x'665ba998'), -- 25933168707e13 + (x'743c3324'), -- 596428896559e20 + -- exercise fixed-point memmoves + (x'47f1205a'), + (x'4640e6ae'), + (x'449a5225'), + (x'42f6e9d5'), + (x'414587dd'), + (x'3f9e064b'), + -- these cases come from the upstream's testsuite + -- BoundaryRoundEven + (x'4c000004'), + (x'50061c46'), + (x'510006a8'), + -- ExactValueRoundEven + (x'48951f84'), + (x'45fd1840'), + -- LotsOfTrailingZeros + (x'39800000'), + (x'3b200000'), + (x'3b900000'), + (x'3bd00000'), + -- Regression + (x'63800000'), + (x'4b000000'), + (x'4b800000'), + (x'4c000001'), + (x'4c800b0d'), + (x'00d24584'), + (x'00d90b88'), + (x'45803f34'), + (x'4f9f24f7'), + (x'3a8722c3'), + (x'5c800041'), + (x'15ae43fd'), + (x'5d4cccfb'), + (x'4c800001'), + (x'57800ed8'), + (x'5f000000'), + (x'700000f0'), + (x'5f23e9ac'), + (x'5e9502f9'), + (x'5e8012b1'), + (x'3c000028'), + (x'60cde861'), + (x'03aa2a50'), + (x'43480000'), + (x'4c000000'), + -- LooksLikePow5 + (x'5D1502F9'), + (x'5D9502F9'), + (x'5E1502F9'), + -- OutputLength + (x'3f99999a'), + (x'3f9d70a4'), + (x'3f9df3b6'), + (x'3f9e0419'), + (x'3f9e0610'), + (x'3f9e064b'), + (x'3f9e0651'), + (x'03d20cfe') +) +select float4send(flt) as ibits, + flt, + flt::text::float4 as r_flt, + float4send(flt::text::float4) as obits, + float4send(flt::text::float4) = float4send(flt) as correct + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + +drop type xfloat4 cascade; diff --git a/crates/pgt_pretty_print/tests/data/multi/float8_60.sql b/crates/pgt_pretty_print/tests/data/multi/float8_60.sql new file mode 100644 index 000000000..a378ab0e7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/float8_60.sql @@ -0,0 +1,592 @@ +CREATE TEMP TABLE FLOAT8_TBL(f1 float8); + +INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 '); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 '); + +INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200'); + +SELECT '10e400'::float8; + +SELECT '-10e400'::float8; + +SELECT '10e-400'::float8; + +SELECT '-10e-400'::float8; + +SELECT float8send('2.2250738585072014E-308'::float8); + +INSERT INTO FLOAT8_TBL(f1) VALUES (''); + +INSERT INTO FLOAT8_TBL(f1) VALUES (' '); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0'); + +INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); + +SELECT pg_input_is_valid('34.5', 'float8'); + +SELECT pg_input_is_valid('xyz', 'float8'); + +SELECT pg_input_is_valid('1e4000', 'float8'); + +SELECT * FROM pg_input_error_info('1e4000', 'float8'); + +SELECT 'NaN'::float8; + +SELECT 'nan'::float8; + +SELECT ' NAN '::float8; + +SELECT 'infinity'::float8; + +SELECT ' -INFINiTY '::float8; + +SELECT 'N A N'::float8; + +SELECT 'NaN x'::float8; + +SELECT ' INFINITY x'::float8; + +SELECT 'Infinity'::float8 + 100.0; + +SELECT 'Infinity'::float8 / 'Infinity'::float8; + +SELECT '42'::float8 / 'Infinity'::float8; + +SELECT 'nan'::float8 / 'nan'::float8; + +SELECT 'nan'::float8 / '0'::float8; + +SELECT 'nan'::numeric::float8; + +SELECT * FROM FLOAT8_TBL; + +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3'; + +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3'; + +SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1; + +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3'; + +SELECT f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1; + +SELECT f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3'; + +SELECT f.f1, f.f1 * '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1, f.f1 + '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1, f.f1 / '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1, f.f1 - '-10' AS x + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0'; + +SELECT f.f1 ^ '2.0' AS square_f1 + FROM FLOAT8_TBL f where f.f1 = '1004.3'; + +SELECT f.f1, @f.f1 AS abs_f1 + FROM FLOAT8_TBL f; + +SELECT f.f1, trunc(f.f1) AS trunc_f1 + FROM FLOAT8_TBL f; + +SELECT f.f1, round(f.f1) AS round_f1 + FROM FLOAT8_TBL f; + +select ceil(f1) as ceil_f1 from float8_tbl f; + +select ceiling(f1) as ceiling_f1 from float8_tbl f; + +select floor(f1) as floor_f1 from float8_tbl f; + +select sign(f1) as sign_f1 from float8_tbl f; + +SET extra_float_digits = 0; + +SELECT sqrt(float8 '64') AS eight; + +SELECT |/ float8 '64' AS eight; + +SELECT f.f1, |/f.f1 AS sqrt_f1 + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0'; + +SELECT power(float8 '144', float8 '0.5'); + +SELECT power(float8 'NaN', float8 '0.5'); + +SELECT power(float8 '144', float8 'NaN'); + +SELECT power(float8 'NaN', float8 'NaN'); + +SELECT power(float8 '-1', float8 'NaN'); + +SELECT power(float8 '1', float8 'NaN'); + +SELECT power(float8 'NaN', float8 '0'); + +SELECT power(float8 'inf', float8 '0'); + +SELECT power(float8 '-inf', float8 '0'); + +SELECT power(float8 '0', float8 'inf'); + +SELECT power(float8 '0', float8 '-inf'); + +SELECT power(float8 '1', float8 'inf'); + +SELECT power(float8 '1', float8 '-inf'); + +SELECT power(float8 '-1', float8 'inf'); + +SELECT power(float8 '-1', float8 '-inf'); + +SELECT power(float8 '0.1', float8 'inf'); + +SELECT power(float8 '-0.1', float8 'inf'); + +SELECT power(float8 '1.1', float8 'inf'); + +SELECT power(float8 '-1.1', float8 'inf'); + +SELECT power(float8 '0.1', float8 '-inf'); + +SELECT power(float8 '-0.1', float8 '-inf'); + +SELECT power(float8 '1.1', float8 '-inf'); + +SELECT power(float8 '-1.1', float8 '-inf'); + +SELECT power(float8 'inf', float8 '-2'); + +SELECT power(float8 'inf', float8 '2'); + +SELECT power(float8 'inf', float8 'inf'); + +SELECT power(float8 'inf', float8 '-inf'); + +SELECT power(float8 '-inf', float8 '-2') = '0'; + +SELECT power(float8 '-inf', float8 '-3'); + +SELECT power(float8 '-inf', float8 '2'); + +SELECT power(float8 '-inf', float8 '3'); + +SELECT power(float8 '-inf', float8 '3.5'); + +SELECT power(float8 '-inf', float8 'inf'); + +SELECT power(float8 '-inf', float8 '-inf'); + +SELECT f.f1, exp(ln(f.f1)) AS exp_ln_f1 + FROM FLOAT8_TBL f + WHERE f.f1 > '0.0'; + +SELECT exp('inf'::float8), exp('-inf'::float8), exp('nan'::float8); + +SELECT ||/ float8 '27' AS three; + +SELECT f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f; + +SELECT * FROM FLOAT8_TBL; + +UPDATE FLOAT8_TBL + SET f1 = FLOAT8_TBL.f1 * '-1' + WHERE FLOAT8_TBL.f1 > '0.0'; + +SELECT f.f1 * '1e200' from FLOAT8_TBL f; + +SELECT f.f1 ^ '1e200' from FLOAT8_TBL f; + +SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5; + +SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ; + +SELECT ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ; + +SELECT exp(f.f1) from FLOAT8_TBL f; + +SELECT f.f1 / '0.0' from FLOAT8_TBL f; + +SELECT * FROM FLOAT8_TBL ORDER BY 1; + +SELECT sinh(float8 '1'); + +SELECT cosh(float8 '1'); + +SELECT tanh(float8 '1'); + +SELECT asinh(float8 '1'); + +SELECT acosh(float8 '2'); + +SELECT atanh(float8 '0.5'); + +SELECT sinh(float8 'infinity'); + +SELECT sinh(float8 '-infinity'); + +SELECT sinh(float8 'nan'); + +SELECT cosh(float8 'infinity'); + +SELECT cosh(float8 '-infinity'); + +SELECT cosh(float8 'nan'); + +SELECT tanh(float8 'infinity'); + +SELECT tanh(float8 '-infinity'); + +SELECT tanh(float8 'nan'); + +SELECT asinh(float8 'infinity'); + +SELECT asinh(float8 '-infinity'); + +SELECT asinh(float8 'nan'); + +SELECT acosh(float8 '-infinity'); + +SELECT acosh(float8 'nan'); + +SELECT atanh(float8 'infinity'); + +SELECT atanh(float8 '-infinity'); + +SELECT atanh(float8 'nan'); + +SET extra_float_digits = -1; + +SELECT x, + erf(x), + erfc(x) +FROM (VALUES (float8 '-infinity'), + (-28), (-6), (-3.4), (-2.1), (-1.1), (-0.45), + (-1.2e-9), (-2.3e-13), (-1.2e-17), (0), + (1.2e-17), (2.3e-13), (1.2e-9), + (0.45), (1.1), (2.1), (3.4), (6), (28), + (float8 'infinity'), (float8 'nan')) AS t(x); + +RESET extra_float_digits; + +SET extra_float_digits = -1; + +SELECT x, + gamma(x), + lgamma(x) +FROM (VALUES (0.5), (1), (2), (3), (4), (5), + (float8 'infinity'), (float8 'nan')) AS t(x); + +SELECT gamma(float8 '-infinity'); + +SELECT lgamma(float8 '-infinity'); + +SELECT gamma(float8 '-1000.5'); + +SELECT lgamma(float8 '-1000.5'); + +SELECT gamma(float8 '-1'); + +SELECT lgamma(float8 '-1'); + +SELECT gamma(float8 '0'); + +SELECT lgamma(float8 '0'); + +SELECT gamma(float8 '1000'); + +SELECT lgamma(float8 '1000'); + +SELECT lgamma(float8 '1e308'); + +RESET extra_float_digits; + +INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400'); + +INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400'); + +DROP TABLE FLOAT8_TBL; + +SELECT * FROM FLOAT8_TBL; + +SELECT '32767.4'::float8::int2; + +SELECT '32767.6'::float8::int2; + +SELECT '-32768.4'::float8::int2; + +SELECT '-32768.6'::float8::int2; + +SELECT '2147483647.4'::float8::int4; + +SELECT '2147483647.6'::float8::int4; + +SELECT '-2147483648.4'::float8::int4; + +SELECT '-2147483648.6'::float8::int4; + +SELECT '9223372036854773760'::float8::int8; + +SELECT '9223372036854775807'::float8::int8; + +SELECT '-9223372036854775808.5'::float8::int8; + +SELECT '-9223372036854780000'::float8::int8; + +SELECT x, + sind(x), + sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact +FROM (VALUES (0), (30), (90), (150), (180), + (210), (270), (330), (360)) AS t(x); + +SELECT x, + cosd(x), + cosd(x) IN (-1,-0.5,0,0.5,1) AS cosd_exact +FROM (VALUES (0), (60), (90), (120), (180), + (240), (270), (300), (360)) AS t(x); + +SELECT x, + tand(x), + tand(x) IN ('-Infinity'::float8,-1,0, + 1,'Infinity'::float8) AS tand_exact, + cotd(x), + cotd(x) IN ('-Infinity'::float8,-1,0, + 1,'Infinity'::float8) AS cotd_exact +FROM (VALUES (0), (45), (90), (135), (180), + (225), (270), (315), (360)) AS t(x); + +SELECT x, + asind(x), + asind(x) IN (-90,-30,0,30,90) AS asind_exact, + acosd(x), + acosd(x) IN (0,60,90,120,180) AS acosd_exact +FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x); + +SELECT x, + atand(x), + atand(x) IN (-90,-45,0,45,90) AS atand_exact +FROM (VALUES ('-Infinity'::float8), (-1), (0), (1), + ('Infinity'::float8)) AS t(x); + +SELECT x, y, + atan2d(y, x), + atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact +FROM (SELECT 10*cosd(a), 10*sind(a) + FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y); + +create type xfloat8; + +create function xfloat8in(cstring) returns xfloat8 immutable strict + language internal as 'int8in'; + +create function xfloat8out(xfloat8) returns cstring immutable strict + language internal as 'int8out'; + +create type xfloat8 (input = xfloat8in, output = xfloat8out, like = no_such_type); + +create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8); + +create cast (xfloat8 as float8) without function; + +create cast (float8 as xfloat8) without function; + +create cast (xfloat8 as bigint) without function; + +create cast (bigint as xfloat8) without function; + +with testdata(bits) as (values + -- small subnormals + (x'0000000000000001'), + (x'0000000000000002'), (x'0000000000000003'), + (x'0000000000001000'), (x'0000000100000000'), + (x'0000010000000000'), (x'0000010100000000'), + (x'0000400000000000'), (x'0000400100000000'), + (x'0000800000000000'), (x'0000800000000001'), + -- these values taken from upstream testsuite + (x'00000000000f4240'), + (x'00000000016e3600'), + (x'0000008cdcdea440'), + -- borderline between subnormal and normal + (x'000ffffffffffff0'), (x'000ffffffffffff1'), + (x'000ffffffffffffe'), (x'000fffffffffffff')) +select float8send(flt) as ibits, + flt + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s; + +with testdata(bits) as (values + (x'0000000000000000'), + -- smallest normal values + (x'0010000000000000'), (x'0010000000000001'), + (x'0010000000000002'), (x'0018000000000000'), + -- + (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'), + (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'), + (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'), + (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'), + (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'), + (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'), + (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'), + (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'), + (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'), + (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'), + -- values very close to 1 + (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'), + (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'), + (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'), + (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'), + (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'), + (x'3fefffffffffffff'), + (x'3ff0000000000000'), + (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'), + (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'), + (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'), + -- + (x'3ff921fb54442d18'), + (x'4005bf0a8b14576a'), + (x'400921fb54442d18'), + -- + (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'), + (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'), + (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'), + (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'), + (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'), + (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'), + (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'), + (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'), + (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'), + (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'), + (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'), + (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'), + (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'), + (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'), + (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'), + (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'), + (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'), + (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'), + (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'), + (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'), + (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'), + (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'), + (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'), + (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'), + (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'), + -- + (x'7feffffffffffffe'), (x'7fefffffffffffff'), + -- round to even tests (+ve) + (x'4350000000000002'), + (x'4350000000002e06'), + (x'4352000000000003'), + (x'4352000000000004'), + (x'4358000000000003'), + (x'4358000000000004'), + (x'435f000000000020'), + -- round to even tests (-ve) + (x'c350000000000002'), + (x'c350000000002e06'), + (x'c352000000000003'), + (x'c352000000000004'), + (x'c358000000000003'), + (x'c358000000000004'), + (x'c35f000000000020'), + -- exercise fixed-point memmoves + (x'42dc12218377de66'), + (x'42a674e79c5fe51f'), + (x'4271f71fb04cb74c'), + (x'423cbe991a145879'), + (x'4206fee0e1a9e061'), + (x'41d26580b487e6b4'), + (x'419d6f34540ca453'), + (x'41678c29dcd6e9dc'), + (x'4132d687e3df217d'), + (x'40fe240c9fcb68c8'), + (x'40c81cd6e63c53d3'), + (x'40934a4584fd0fdc'), + (x'405edd3c07fb4c93'), + (x'4028b0fcd32f7076'), + (x'3ff3c0ca428c59f8'), + -- these cases come from the upstream's testsuite + -- LotsOfTrailingZeros) + (x'3e60000000000000'), + -- Regression + (x'c352bd2668e077c4'), + (x'434018601510c000'), + (x'43d055dc36f24000'), + (x'43e052961c6f8000'), + (x'3ff3c0ca2a5b1d5d'), + -- LooksLikePow5 + (x'4830f0cf064dd592'), + (x'4840f0cf064dd592'), + (x'4850f0cf064dd592'), + -- OutputLength + (x'3ff3333333333333'), + (x'3ff3ae147ae147ae'), + (x'3ff3be76c8b43958'), + (x'3ff3c083126e978d'), + (x'3ff3c0c1fc8f3238'), + (x'3ff3c0c9539b8887'), + (x'3ff3c0ca2a5b1d5d'), + (x'3ff3c0ca4283de1b'), + (x'3ff3c0ca43db770a'), + (x'3ff3c0ca428abd53'), + (x'3ff3c0ca428c1d2b'), + (x'3ff3c0ca428c51f2'), + (x'3ff3c0ca428c58fc'), + (x'3ff3c0ca428c59dd'), + (x'3ff3c0ca428c59f8'), + (x'3ff3c0ca428c59fb'), + -- 32-bit chunking + (x'40112e0be8047a7d'), + (x'40112e0be815a889'), + (x'40112e0be826d695'), + (x'40112e0be83804a1'), + (x'40112e0be84932ad'), + -- MinMaxShift + (x'0040000000000000'), + (x'007fffffffffffff'), + (x'0290000000000000'), + (x'029fffffffffffff'), + (x'4350000000000000'), + (x'435fffffffffffff'), + (x'1330000000000000'), + (x'133fffffffffffff'), + (x'3a6fa7161a4d6e0c') +) +select float8send(flt) as ibits, + flt, + flt::text::float8 as r_flt, + float8send(flt::text::float8) as obits, + float8send(flt::text::float8) = float8send(flt) as correct + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s; + +drop type xfloat8 cascade; diff --git a/crates/pgt_pretty_print/tests/data/multi/foreign_data_60.sql b/crates/pgt_pretty_print/tests/data/multi/foreign_data_60.sql new file mode 100644 index 000000000..c9b9976bf --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/foreign_data_60.sql @@ -0,0 +1,1156 @@ +CREATE FUNCTION test_fdw_handler() + RETURNS fdw_handler + AS 'regresslib', 'test_fdw_handler' + LANGUAGE C; + +SET client_min_messages TO 'warning'; + +DROP ROLE IF EXISTS regress_foreign_data_user, regress_test_role, regress_test_role2, regress_test_role_super, regress_test_indirect, regress_unprivileged_role; + +RESET client_min_messages; + +CREATE ROLE regress_foreign_data_user LOGIN SUPERUSER; + +SET SESSION AUTHORIZATION 'regress_foreign_data_user'; + +CREATE ROLE regress_test_role; + +CREATE ROLE regress_test_role2; + +CREATE ROLE regress_test_role_super SUPERUSER; + +CREATE ROLE regress_test_indirect; + +CREATE ROLE regress_unprivileged_role; + +CREATE FOREIGN DATA WRAPPER dummy; + +COMMENT ON FOREIGN DATA WRAPPER dummy IS 'useless'; + +CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator; + +SELECT fdwname, fdwhandler::regproc, fdwvalidator::regproc, fdwoptions FROM pg_foreign_data_wrapper ORDER BY 1, 2, 3; + +SELECT srvname, srvoptions FROM pg_foreign_server; + +SELECT * FROM pg_user_mapping; + +CREATE FOREIGN DATA WRAPPER foo VALIDATOR bar; + +CREATE FOREIGN DATA WRAPPER foo; + +CREATE FOREIGN DATA WRAPPER foo; + +DROP FOREIGN DATA WRAPPER foo; + +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1'); + +DROP FOREIGN DATA WRAPPER foo; + +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', testing '2'); + +CREATE FOREIGN DATA WRAPPER foo OPTIONS (testing '1', another '2'); + +DROP FOREIGN DATA WRAPPER foo; + +SET ROLE regress_test_role; + +CREATE FOREIGN DATA WRAPPER foo; + +RESET ROLE; + +CREATE FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator; + +CREATE FUNCTION invalid_fdw_handler() RETURNS int LANGUAGE SQL AS 'SELECT 1;'; + +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER invalid_fdw_handler; + +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER invalid_fdw_handler; + +CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler; + +DROP FOREIGN DATA WRAPPER test_fdw; + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (nonexistent 'fdw'); + +ALTER FOREIGN DATA WRAPPER foo VALIDATOR bar; + +ALTER FOREIGN DATA WRAPPER foo NO VALIDATOR; + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '1', b '2'); + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (SET c '4'); + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP c); + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD x '1', DROP x); + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (DROP a, SET b '3', ADD c '4'); + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (a '2'); + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (b '4'); + +SET ROLE regress_test_role; + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5'); + +SET ROLE regress_test_role_super; + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD d '5'); + +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role; + +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_test_role_super; + +ALTER ROLE regress_test_role_super NOSUPERUSER; + +SET ROLE regress_test_role_super; + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (ADD e '6'); + +RESET ROLE; + +ALTER FOREIGN DATA WRAPPER foo RENAME TO foo1; + +ALTER FOREIGN DATA WRAPPER foo1 RENAME TO foo; + +ALTER FOREIGN DATA WRAPPER foo HANDLER invalid_fdw_handler; + +ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler HANDLER anything; + +ALTER FOREIGN DATA WRAPPER foo HANDLER test_fdw_handler; + +DROP FUNCTION invalid_fdw_handler(); + +DROP FOREIGN DATA WRAPPER nonexistent; + +DROP FOREIGN DATA WRAPPER IF EXISTS nonexistent; + +DROP ROLE regress_test_role_super; + +SET ROLE regress_test_role_super; + +DROP FOREIGN DATA WRAPPER foo; + +RESET ROLE; + +DROP ROLE regress_test_role_super; + +CREATE FOREIGN DATA WRAPPER foo; + +CREATE SERVER s1 FOREIGN DATA WRAPPER foo; + +COMMENT ON SERVER s1 IS 'foreign server'; + +CREATE USER MAPPING FOR current_user SERVER s1; + +CREATE USER MAPPING FOR current_user SERVER s1; + +CREATE USER MAPPING IF NOT EXISTS FOR current_user SERVER s1; + +DROP FOREIGN DATA WRAPPER foo; + +SET ROLE regress_test_role; + +DROP FOREIGN DATA WRAPPER foo CASCADE; + +RESET ROLE; + +DROP FOREIGN DATA WRAPPER foo CASCADE; + +CREATE SERVER s1 FOREIGN DATA WRAPPER foo; + +CREATE FOREIGN DATA WRAPPER foo OPTIONS ("test wrapper" 'true'); + +CREATE SERVER s1 FOREIGN DATA WRAPPER foo; + +CREATE SERVER s1 FOREIGN DATA WRAPPER foo; + +CREATE SERVER IF NOT EXISTS s1 FOREIGN DATA WRAPPER foo; + +CREATE SERVER s2 FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b'); + +CREATE SERVER s3 TYPE 'oracle' FOREIGN DATA WRAPPER foo; + +CREATE SERVER s4 TYPE 'oracle' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b'); + +CREATE SERVER s5 VERSION '15.0' FOREIGN DATA WRAPPER foo; + +CREATE SERVER s6 VERSION '16.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b'); + +CREATE SERVER s7 TYPE 'oracle' VERSION '17.0' FOREIGN DATA WRAPPER foo OPTIONS (host 'a', dbname 'b'); + +CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (foo '1'); + +CREATE SERVER s8 FOREIGN DATA WRAPPER postgresql OPTIONS (host 'localhost', dbname 's8db'); + +SET ROLE regress_test_role; + +CREATE SERVER t1 FOREIGN DATA WRAPPER foo; + +RESET ROLE; + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role; + +SET ROLE regress_test_role; + +CREATE SERVER t1 FOREIGN DATA WRAPPER foo; + +RESET ROLE; + +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_test_role; + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_indirect; + +SET ROLE regress_test_role; + +CREATE SERVER t2 FOREIGN DATA WRAPPER foo; + +RESET ROLE; + +GRANT regress_test_indirect TO regress_test_role; + +SET ROLE regress_test_role; + +CREATE SERVER t2 FOREIGN DATA WRAPPER foo; + +RESET ROLE; + +REVOKE regress_test_indirect FROM regress_test_role; + +ALTER SERVER s0 OPTIONS (a '1'); + +ALTER SERVER s1 VERSION '1.0' OPTIONS (servername 's1'); + +ALTER SERVER s2 VERSION '1.1'; + +ALTER SERVER s3 OPTIONS ("tns name" 'orcl', port '1521'); + +GRANT USAGE ON FOREIGN SERVER s1 TO regress_test_role; + +GRANT USAGE ON FOREIGN SERVER s6 TO regress_test_role2 WITH GRANT OPTION; + +SET ROLE regress_test_role; + +ALTER SERVER s1 VERSION '1.1'; + +ALTER SERVER s1 OWNER TO regress_test_role; + +RESET ROLE; + +ALTER SERVER s1 OWNER TO regress_test_role; + +GRANT regress_test_role2 TO regress_test_role; + +SET ROLE regress_test_role; + +ALTER SERVER s1 VERSION '1.1'; + +ALTER SERVER s1 OWNER TO regress_test_role2; + +RESET ROLE; + +ALTER SERVER s8 OPTIONS (foo '1'); + +ALTER SERVER s8 OPTIONS (connect_timeout '30', SET dbname 'db1', DROP host); + +SET ROLE regress_test_role; + +ALTER SERVER s1 OWNER TO regress_test_indirect; + +RESET ROLE; + +GRANT regress_test_indirect TO regress_test_role; + +SET ROLE regress_test_role; + +ALTER SERVER s1 OWNER TO regress_test_indirect; + +RESET ROLE; + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_indirect; + +SET ROLE regress_test_role; + +ALTER SERVER s1 OWNER TO regress_test_indirect; + +RESET ROLE; + +DROP ROLE regress_test_indirect; + +ALTER SERVER s8 RENAME to s8new; + +ALTER SERVER s8new RENAME to s8; + +DROP SERVER nonexistent; + +DROP SERVER IF EXISTS nonexistent; + +SET ROLE regress_test_role; + +DROP SERVER s2; + +DROP SERVER s1; + +RESET ROLE; + +ALTER SERVER s2 OWNER TO regress_test_role; + +SET ROLE regress_test_role; + +DROP SERVER s2; + +RESET ROLE; + +CREATE USER MAPPING FOR current_user SERVER s3; + +DROP SERVER s3; + +DROP SERVER s3 CASCADE; + +CREATE USER MAPPING FOR regress_test_missing_role SERVER s1; + +CREATE USER MAPPING FOR current_user SERVER s1; + +CREATE USER MAPPING FOR current_user SERVER s4; + +CREATE USER MAPPING FOR user SERVER s4; + +CREATE USER MAPPING FOR public SERVER s4 OPTIONS ("this mapping" 'is public'); + +CREATE USER MAPPING FOR user SERVER s8 OPTIONS (username 'test', password 'secret'); + +CREATE USER MAPPING FOR user SERVER s8 OPTIONS (user 'test', password 'secret'); + +ALTER SERVER s5 OWNER TO regress_test_role; + +ALTER SERVER s6 OWNER TO regress_test_indirect; + +SET ROLE regress_test_role; + +CREATE USER MAPPING FOR current_user SERVER s5; + +CREATE USER MAPPING FOR current_user SERVER s6 OPTIONS (username 'test'); + +CREATE USER MAPPING FOR current_user SERVER s7; + +CREATE USER MAPPING FOR public SERVER s8; + +RESET ROLE; + +ALTER SERVER t1 OWNER TO regress_test_indirect; + +SET ROLE regress_test_role; + +CREATE USER MAPPING FOR current_user SERVER t1 OPTIONS (username 'bob', password 'boo'); + +CREATE USER MAPPING FOR public SERVER t1; + +RESET ROLE; + +ALTER USER MAPPING FOR regress_test_missing_role SERVER s4 OPTIONS (gotcha 'true'); + +ALTER USER MAPPING FOR user SERVER ss4 OPTIONS (gotcha 'true'); + +ALTER USER MAPPING FOR public SERVER s5 OPTIONS (gotcha 'true'); + +ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (username 'test'); + +ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (DROP user, SET password 'public'); + +SET ROLE regress_test_role; + +ALTER USER MAPPING FOR current_user SERVER s5 OPTIONS (ADD modified '1'); + +ALTER USER MAPPING FOR public SERVER s4 OPTIONS (ADD modified '1'); + +ALTER USER MAPPING FOR public SERVER t1 OPTIONS (ADD modified '1'); + +RESET ROLE; + +DROP USER MAPPING FOR regress_test_missing_role SERVER s4; + +DROP USER MAPPING FOR user SERVER ss4; + +DROP USER MAPPING FOR public SERVER s7; + +DROP USER MAPPING IF EXISTS FOR regress_test_missing_role SERVER s4; + +DROP USER MAPPING IF EXISTS FOR user SERVER ss4; + +DROP USER MAPPING IF EXISTS FOR public SERVER s7; + +CREATE USER MAPPING FOR public SERVER s8; + +SET ROLE regress_test_role; + +DROP USER MAPPING FOR public SERVER s8; + +RESET ROLE; + +DROP SERVER s7; + +CREATE SCHEMA foreign_schema; + +CREATE SERVER s0 FOREIGN DATA WRAPPER dummy; + +CREATE FOREIGN TABLE ft1 () SERVER no_server; + +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') PRIMARY KEY, + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +CREATE TABLE ref_table (id integer PRIMARY KEY); + +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') REFERENCES ref_table (id), + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +DROP TABLE ref_table; + +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') NOT NULL, + c2 text OPTIONS (param2 'val2', param3 'val3'), + c3 date, + UNIQUE (c3) +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +CREATE FOREIGN TABLE ft1 ( + c1 integer OPTIONS ("param 1" 'val1') NOT NULL, + c2 text OPTIONS (param2 'val2', param3 'val3') CHECK (c2 <> ''), + c3 date, + CHECK (c3 BETWEEN '1994-01-01'::date AND '1994-01-31'::date) +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +COMMENT ON FOREIGN TABLE ft1 IS 'ft1'; + +COMMENT ON COLUMN ft1.c1 IS 'ft1.c1'; + +CREATE INDEX id_ft1_c2 ON ft1 (c2); + +SELECT * FROM ft1; + +SELECT * FROM ft1; + +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); + +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; + +CREATE INDEX ON lt1 (a); + +CREATE UNIQUE INDEX ON lt1 (a); + +ALTER TABLE lt1 ADD PRIMARY KEY (a); + +DROP TABLE lt1; + +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); + +CREATE INDEX ON lt1 (a); + +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; + +CREATE FOREIGN TABLE ft_part2 (a INT) SERVER s0; + +ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000); + +DROP FOREIGN TABLE ft_part1, ft_part2; + +CREATE UNIQUE INDEX ON lt1 (a); + +ALTER TABLE lt1 ADD PRIMARY KEY (a); + +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; + +CREATE FOREIGN TABLE ft_part2 (a INT NOT NULL) SERVER s0; + +ALTER TABLE lt1 ATTACH PARTITION ft_part2 + FOR VALUES FROM (1000) TO (2000); + +DROP TABLE lt1; + +DROP FOREIGN TABLE ft_part2; + +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); + +CREATE INDEX ON lt1 (a); + +CREATE TABLE lt1_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) + PARTITION BY RANGE (a); + +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0; + +CREATE FOREIGN TABLE ft_part_1_2 (a INT) SERVER s0; + +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200); + +CREATE UNIQUE INDEX ON lt1 (a); + +ALTER TABLE lt1 ADD PRIMARY KEY (a); + +DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2; + +CREATE UNIQUE INDEX ON lt1 (a); + +ALTER TABLE lt1 ADD PRIMARY KEY (a); + +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0; + +CREATE FOREIGN TABLE ft_part_1_2 (a INT NOT NULL) SERVER s0; + +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200); + +DROP TABLE lt1; + +DROP FOREIGN TABLE ft_part_1_2; + +COMMENT ON FOREIGN TABLE ft1 IS 'foreign table'; + +COMMENT ON FOREIGN TABLE ft1 IS NULL; + +COMMENT ON COLUMN ft1.c1 IS 'foreign column'; + +COMMENT ON COLUMN ft1.c1 IS NULL; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c4 integer; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c5 integer DEFAULT 0; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c6 integer; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c7 integer NOT NULL; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c8 integer; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c9 integer; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1'); + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c4 SET DEFAULT 0; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c5 DROP DEFAULT; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c6 SET NOT NULL; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 DROP NOT NULL; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10) USING '0'; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE char(10); + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET DATA TYPE text; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN xmin OPTIONS (ADD p1 'v1'); + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2'), + ALTER COLUMN c8 OPTIONS (ADD p1 'v1', ADD p2 'v2'); + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1); + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET STATISTICS 10000; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 SET (n_distinct = 100); + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STATISTICS -1; + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET STORAGE PLAIN; + +CREATE TABLE use_ft1_column_type (x ft1); + +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 SET DATA TYPE integer; + +DROP TABLE use_ft1_column_type; + +ALTER FOREIGN TABLE ft1 ADD PRIMARY KEY (c7); + +ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c9_check CHECK (c9 < 0) NOT VALID; + +ALTER FOREIGN TABLE ft1 ALTER CONSTRAINT ft1_c9_check DEFERRABLE; + +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c9_check; + +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const; + +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const; + +ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role; + +ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@'); + +ALTER FOREIGN TABLE ft1 DROP COLUMN no_column; + +ALTER FOREIGN TABLE ft1 DROP COLUMN IF EXISTS no_column; + +ALTER FOREIGN TABLE ft1 DROP COLUMN c9; + +ALTER FOREIGN TABLE ft1 ADD COLUMN c11 serial; + +ALTER FOREIGN TABLE ft1 SET SCHEMA foreign_schema; + +ALTER FOREIGN TABLE ft1 SET TABLESPACE ts; + +ALTER SEQUENCE foreign_schema.ft1_c11_seq SET SCHEMA public; + +ALTER FOREIGN TABLE foreign_schema.ft1 RENAME c1 TO foreign_column_1; + +ALTER FOREIGN TABLE foreign_schema.ft1 RENAME TO foreign_table_1; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c4 integer; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c6 integer; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c7 integer NOT NULL; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c8 integer; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c9 integer; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ADD COLUMN c10 integer OPTIONS (p1 'v1'); + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c6 SET NOT NULL; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 DROP NOT NULL; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 TYPE char(10); + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 SET DATA TYPE text; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c7 OPTIONS (ADD p1 'v1', ADD p2 'v2'), + ALTER COLUMN c8 OPTIONS (ADD p1 'v1', ADD p2 'v2'); + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 ALTER COLUMN c8 OPTIONS (SET p2 'V2', DROP p1); + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT IF EXISTS no_const; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP CONSTRAINT ft1_c1_check; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OWNER TO regress_test_role; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@'); + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP COLUMN IF EXISTS no_column; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 DROP COLUMN c9; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 SET SCHEMA foreign_schema; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME c1 TO foreign_column_1; + +ALTER FOREIGN TABLE IF EXISTS doesnt_exist_ft1 RENAME TO foreign_table_1; + +SELECT * FROM information_schema.foreign_data_wrappers ORDER BY 1, 2; + +SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3; + +SELECT * FROM information_schema.foreign_servers ORDER BY 1, 2; + +SELECT * FROM information_schema.foreign_server_options ORDER BY 1, 2, 3; + +SELECT * FROM information_schema.user_mappings ORDER BY lower(authorization_identifier), 2, 3; + +SELECT * FROM information_schema.user_mapping_options ORDER BY lower(authorization_identifier), 2, 3, 4; + +SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5; + +SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5; + +SELECT * FROM information_schema.foreign_tables ORDER BY 1, 2, 3; + +SELECT * FROM information_schema.foreign_table_options ORDER BY 1, 2, 3, 4; + +SET ROLE regress_test_role; + +SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4; + +SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5; + +SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') ORDER BY 1, 2, 3, 4, 5; + +DROP USER MAPPING FOR current_user SERVER t1; + +SET ROLE regress_test_role2; + +SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4; + +RESET ROLE; + +SELECT has_foreign_data_wrapper_privilege('regress_test_role', + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE'); + +SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE'); + +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE'); + +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_foreign_data_wrapper WHERE fdwname='foo'), 'USAGE'); + +SELECT has_foreign_data_wrapper_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), 'foo', 'USAGE'); + +SELECT has_foreign_data_wrapper_privilege('foo', 'USAGE'); + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role; + +SELECT has_foreign_data_wrapper_privilege('regress_test_role', 'foo', 'USAGE'); + +SELECT has_server_privilege('regress_test_role', + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE'); + +SELECT has_server_privilege('regress_test_role', 's8', 'USAGE'); + +SELECT has_server_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE'); + +SELECT has_server_privilege( + (SELECT oid FROM pg_foreign_server WHERE srvname='s8'), 'USAGE'); + +SELECT has_server_privilege( + (SELECT oid FROM pg_roles WHERE rolname='regress_test_role'), 's8', 'USAGE'); + +SELECT has_server_privilege('s8', 'USAGE'); + +GRANT USAGE ON FOREIGN SERVER s8 TO regress_test_role; + +SELECT has_server_privilege('regress_test_role', 's8', 'USAGE'); + +REVOKE USAGE ON FOREIGN SERVER s8 FROM regress_test_role; + +GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role; + +DROP USER MAPPING FOR public SERVER s4; + +ALTER SERVER s6 OPTIONS (DROP host, DROP dbname); + +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (DROP username); + +ALTER FOREIGN DATA WRAPPER foo VALIDATOR postgresql_fdw_validator; + +SET ROLE regress_unprivileged_role; + +CREATE FOREIGN DATA WRAPPER foobar; + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true'); + +ALTER FOREIGN DATA WRAPPER foo OWNER TO regress_unprivileged_role; + +DROP FOREIGN DATA WRAPPER foo; + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role; + +CREATE SERVER s9 FOREIGN DATA WRAPPER foo; + +ALTER SERVER s4 VERSION '0.5'; + +ALTER SERVER s4 OWNER TO regress_unprivileged_role; + +DROP SERVER s4; + +GRANT USAGE ON FOREIGN SERVER s4 TO regress_test_role; + +CREATE USER MAPPING FOR public SERVER s4; + +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true'); + +DROP USER MAPPING FOR regress_test_role SERVER s6; + +RESET ROLE; + +GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_unprivileged_role; + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_unprivileged_role WITH GRANT OPTION; + +SET ROLE regress_unprivileged_role; + +CREATE FOREIGN DATA WRAPPER foobar; + +ALTER FOREIGN DATA WRAPPER foo OPTIONS (gotcha 'true'); + +DROP FOREIGN DATA WRAPPER foo; + +GRANT USAGE ON FOREIGN DATA WRAPPER postgresql TO regress_test_role; + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role; + +CREATE SERVER s9 FOREIGN DATA WRAPPER postgresql; + +ALTER SERVER s6 VERSION '0.5'; + +DROP SERVER s6; + +GRANT USAGE ON FOREIGN SERVER s6 TO regress_test_role; + +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role; + +CREATE USER MAPPING FOR public SERVER s6; + +CREATE USER MAPPING FOR public SERVER s9; + +ALTER USER MAPPING FOR regress_test_role SERVER s6 OPTIONS (gotcha 'true'); + +DROP USER MAPPING FOR regress_test_role SERVER s6; + +RESET ROLE; + +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role; + +REVOKE USAGE ON FOREIGN DATA WRAPPER foo FROM regress_unprivileged_role CASCADE; + +SET ROLE regress_unprivileged_role; + +GRANT USAGE ON FOREIGN DATA WRAPPER foo TO regress_test_role; + +CREATE SERVER s10 FOREIGN DATA WRAPPER foo; + +ALTER SERVER s9 VERSION '1.1'; + +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role; + +CREATE USER MAPPING FOR current_user SERVER s9; + +DROP SERVER s9 CASCADE; + +RESET ROLE; + +CREATE SERVER s9 FOREIGN DATA WRAPPER foo; + +GRANT USAGE ON FOREIGN SERVER s9 TO regress_unprivileged_role; + +SET ROLE regress_unprivileged_role; + +ALTER SERVER s9 VERSION '1.2'; + +GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role; + +CREATE USER MAPPING FOR current_user SERVER s9; + +DROP SERVER s9 CASCADE; + +SET ROLE regress_test_role; + +CREATE SERVER s10 FOREIGN DATA WRAPPER foo; + +CREATE USER MAPPING FOR public SERVER s10 OPTIONS (user 'secret'); + +CREATE USER MAPPING FOR regress_unprivileged_role SERVER s10 OPTIONS (user 'secret'); + +RESET ROLE; + +SET ROLE regress_unprivileged_role; + +RESET ROLE; + +DROP SERVER s10 CASCADE; + +CREATE FUNCTION dummy_trigger() RETURNS TRIGGER AS $$ + BEGIN + RETURN NULL; + END +$$ language plpgsql; + +CREATE TRIGGER trigtest_before_stmt BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger(); + +CREATE TRIGGER trigtest_after_stmt AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger(); + +CREATE TRIGGER trigtest_after_stmt_tt AFTER INSERT OR UPDATE OR DELETE -- ERROR +ON foreign_schema.foreign_table_1 +REFERENCING NEW TABLE AS new_table +FOR EACH STATEMENT +EXECUTE PROCEDURE dummy_trigger(); + +CREATE TRIGGER trigtest_before_row BEFORE INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); + +CREATE TRIGGER trigtest_after_row AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); + +CREATE CONSTRAINT TRIGGER trigtest_constraint AFTER INSERT OR UPDATE OR DELETE +ON foreign_schema.foreign_table_1 +FOR EACH ROW +EXECUTE PROCEDURE dummy_trigger(); + +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + DISABLE TRIGGER trigtest_before_stmt; + +ALTER FOREIGN TABLE foreign_schema.foreign_table_1 + ENABLE TRIGGER trigtest_before_stmt; + +DROP TRIGGER trigtest_before_stmt ON foreign_schema.foreign_table_1; + +DROP TRIGGER trigtest_before_row ON foreign_schema.foreign_table_1; + +DROP TRIGGER trigtest_after_stmt ON foreign_schema.foreign_table_1; + +DROP TRIGGER trigtest_after_row ON foreign_schema.foreign_table_1; + +DROP FUNCTION dummy_trigger(); + +CREATE TABLE fd_pt1 ( + c1 integer NOT NULL, + c2 text, + c3 date +); + +CREATE FOREIGN TABLE ft2 () INHERITS (fd_pt1) + SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +DROP FOREIGN TABLE ft2; + +CREATE FOREIGN TABLE ft2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1; + +CREATE TABLE ct3() INHERITS(ft2); + +CREATE FOREIGN TABLE ft3 ( + c1 integer NOT NULL, + c2 text, + c3 date +) INHERITS(ft2) + SERVER s0; + +ALTER TABLE fd_pt1 ADD COLUMN c4 integer; + +ALTER TABLE fd_pt1 ADD COLUMN c5 integer DEFAULT 0; + +ALTER TABLE fd_pt1 ADD COLUMN c6 integer; + +ALTER TABLE fd_pt1 ADD COLUMN c7 integer NOT NULL; + +ALTER TABLE fd_pt1 ADD COLUMN c8 integer; + +ALTER TABLE fd_pt1 ALTER COLUMN c4 SET DEFAULT 0; + +ALTER TABLE fd_pt1 ALTER COLUMN c5 DROP DEFAULT; + +ALTER TABLE fd_pt1 ALTER COLUMN c6 SET NOT NULL; + +ALTER TABLE fd_pt1 ALTER COLUMN c7 DROP NOT NULL; + +ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10) USING '0'; + +ALTER TABLE fd_pt1 ALTER COLUMN c8 TYPE char(10); + +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET DATA TYPE text; + +ALTER TABLE fd_pt1 ALTER COLUMN c1 SET STATISTICS 10000; + +ALTER TABLE fd_pt1 ALTER COLUMN c1 SET (n_distinct = 100); + +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STATISTICS -1; + +ALTER TABLE fd_pt1 ALTER COLUMN c8 SET STORAGE EXTERNAL; + +ALTER TABLE fd_pt1 DROP COLUMN c4; + +ALTER TABLE fd_pt1 DROP COLUMN c5; + +ALTER TABLE fd_pt1 DROP COLUMN c6; + +ALTER TABLE fd_pt1 DROP COLUMN c7; + +ALTER TABLE fd_pt1 DROP COLUMN c8; + +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk1 CHECK (c1 > 0) NO INHERIT; + +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> ''); + +SELECT relname, conname, contype, conislocal, coninhcount, connoinherit + FROM pg_class AS pc JOIN pg_constraint AS pgc ON (conrelid = pc.oid) + WHERE pc.relname = 'fd_pt1' + ORDER BY 1,2; + +DROP FOREIGN TABLE ft2; + +DROP FOREIGN TABLE ft2 CASCADE; + +CREATE FOREIGN TABLE ft2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1; + +ALTER FOREIGN TABLE ft2 ADD CONSTRAINT fd_pt1chk2 CHECK (c2 <> ''); + +ALTER FOREIGN TABLE ft2 INHERIT fd_pt1; + +ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk1 CASCADE; + +ALTER TABLE fd_pt1 DROP CONSTRAINT fd_pt1chk2 CASCADE; + +INSERT INTO fd_pt1 VALUES (1, 'fd_pt1'::text, '1994-01-01'::date); + +ALTER TABLE fd_pt1 ADD CONSTRAINT fd_pt1chk3 CHECK (c2 <> '') NOT VALID; + +ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3; + +ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1; + +ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2; + +ALTER TABLE fd_pt1 RENAME COLUMN c3 TO f3; + +ALTER TABLE fd_pt1 RENAME CONSTRAINT fd_pt1chk3 TO f2_check; + +DROP TABLE fd_pt1 CASCADE; + +IMPORT FOREIGN SCHEMA s1 FROM SERVER s9 INTO public; + +IMPORT FOREIGN SCHEMA s1 LIMIT TO (t1) FROM SERVER s9 INTO public; + +IMPORT FOREIGN SCHEMA s1 EXCEPT (t1) FROM SERVER s9 INTO public; + +IMPORT FOREIGN SCHEMA s1 EXCEPT (t1, t2) FROM SERVER s9 INTO public +OPTIONS (option1 'value1', option2 'value2'); + +DROP FOREIGN TABLE no_table; + +DROP FOREIGN TABLE IF EXISTS no_table; + +DROP FOREIGN TABLE foreign_schema.foreign_table_1; + +REASSIGN OWNED BY regress_test_role TO regress_test_role2; + +DROP OWNED BY regress_test_role2; + +DROP OWNED BY regress_test_role2 CASCADE; + +CREATE TABLE fd_pt2 ( + c1 integer NOT NULL, + c2 text, + c3 date +) PARTITION BY LIST (c1); + +CREATE FOREIGN TABLE fd_pt2_1 PARTITION OF fd_pt2 FOR VALUES IN (1) + SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +DROP FOREIGN TABLE fd_pt2_1; + +CREATE FOREIGN TABLE fd_pt2_1 ( + c1 integer NOT NULL, + c2 text, + c3 date, + c4 char +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); + +DROP FOREIGN TABLE fd_pt2_1; + +CREATE FOREIGN TABLE fd_pt2_1 ( + c1 integer NOT NULL, + c2 text, + c3 date +) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); + +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); + +ALTER TABLE fd_pt2_1 ADD c4 char; + +ALTER TABLE fd_pt2_1 ALTER c3 SET NOT NULL; + +ALTER TABLE fd_pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> ''); + +ALTER TABLE fd_pt2_1 ALTER c1 DROP NOT NULL; + +ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1; + +ALTER TABLE fd_pt2 ALTER c2 SET NOT NULL; + +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); + +ALTER FOREIGN TABLE fd_pt2_1 ALTER c2 SET NOT NULL; + +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); + +ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1; + +ALTER TABLE fd_pt2 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0); + +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); + +ALTER FOREIGN TABLE fd_pt2_1 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0); + +ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); + +DROP FOREIGN TABLE fd_pt2_1; + +DROP TABLE fd_pt2; + +CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a); + +CREATE FOREIGN TABLE foreign_part PARTITION OF temp_parted DEFAULT + SERVER s0; + +CREATE FOREIGN TABLE foreign_part (a int) SERVER s0; + +ALTER TABLE temp_parted ATTACH PARTITION foreign_part DEFAULT; + +DROP FOREIGN TABLE foreign_part; + +DROP TABLE temp_parted; + +DROP SCHEMA foreign_schema CASCADE; + +DROP ROLE regress_test_role; + +DROP SERVER t1 CASCADE; + +DROP USER MAPPING FOR regress_test_role SERVER s6; + +DROP FOREIGN DATA WRAPPER foo CASCADE; + +DROP SERVER s8 CASCADE; + +DROP ROLE regress_test_indirect; + +DROP ROLE regress_test_role; + +DROP ROLE regress_unprivileged_role; + +REVOKE ALL ON FOREIGN DATA WRAPPER postgresql FROM regress_unprivileged_role; + +DROP ROLE regress_unprivileged_role; + +DROP ROLE regress_test_role2; + +DROP FOREIGN DATA WRAPPER postgresql CASCADE; + +DROP FOREIGN DATA WRAPPER dummy CASCADE; + +DROP ROLE regress_foreign_data_user; + +SELECT fdwname, fdwhandler, fdwvalidator, fdwoptions FROM pg_foreign_data_wrapper; + +SELECT srvname, srvoptions FROM pg_foreign_server; + +SELECT * FROM pg_user_mapping; diff --git a/crates/pgt_pretty_print/tests/data/multi/foreign_key_60.sql b/crates/pgt_pretty_print/tests/data/multi/foreign_key_60.sql new file mode 100644 index 000000000..9a655d07e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/foreign_key_60.sql @@ -0,0 +1,2743 @@ +CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ); + +INSERT INTO FKTABLE VALUES (1, 2); + +INSERT INTO FKTABLE VALUES (2, 3); + +SELECT * FROM FKTABLE; + +INSERT INTO PKTABLE VALUES (1, 'Test1'); + +INSERT INTO PKTABLE VALUES (2, 'Test2'); + +INSERT INTO FKTABLE VALUES (3, 4); + +INSERT INTO PKTABLE VALUES (3, 'Test3'); + +INSERT INTO PKTABLE VALUES (4, 'Test4'); + +INSERT INTO PKTABLE VALUES (5, 'Test5'); + +INSERT INTO FKTABLE VALUES (3, 4); + +INSERT INTO FKTABLE VALUES (NULL, 1); + +INSERT INTO FKTABLE VALUES (100, 2); + +SELECT * FROM FKTABLE; + +DELETE FROM PKTABLE WHERE ptest1=1; + +SELECT * FROM FKTABLE; + +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2; + +SELECT * FROM FKTABLE; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ); + +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, CONSTRAINT constrname FOREIGN KEY(ftest1, ftest2) + REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL); + +COMMENT ON CONSTRAINT constrname_wrong ON FKTABLE IS 'fk constraint comment'; + +COMMENT ON CONSTRAINT constrname ON FKTABLE IS 'fk constraint comment'; + +COMMENT ON CONSTRAINT constrname ON FKTABLE IS NULL; + +INSERT INTO PKTABLE VALUES (1, 2, 'Test1'); + +INSERT INTO PKTABLE VALUES (1, 3, 'Test1-2'); + +INSERT INTO PKTABLE VALUES (2, 4, 'Test2'); + +INSERT INTO PKTABLE VALUES (3, 6, 'Test3'); + +INSERT INTO PKTABLE VALUES (4, 8, 'Test4'); + +INSERT INTO PKTABLE VALUES (5, 10, 'Test5'); + +INSERT INTO FKTABLE VALUES (1, 2, 4); + +INSERT INTO FKTABLE VALUES (1, 3, 5); + +INSERT INTO FKTABLE VALUES (2, 4, 8); + +INSERT INTO FKTABLE VALUES (3, 6, 12); + +INSERT INTO FKTABLE VALUES (NULL, NULL, 0); + +INSERT INTO FKTABLE VALUES (100, 2, 4); + +INSERT INTO FKTABLE VALUES (2, 2, 4); + +INSERT INTO FKTABLE VALUES (NULL, 2, 4); + +INSERT INTO FKTABLE VALUES (1, NULL, 4); + +SELECT * FROM FKTABLE; + +DELETE FROM PKTABLE WHERE ptest1=1 and ptest2=2; + +SELECT * FROM FKTABLE; + +DELETE FROM PKTABLE WHERE ptest1=5 and ptest2=10; + +SELECT * FROM FKTABLE; + +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2; + +SELECT * FROM FKTABLE; + +UPDATE FKTABLE SET ftest1 = NULL WHERE ftest1 = 1; + +UPDATE FKTABLE SET ftest1 = 1 WHERE ftest1 = 1; + +ALTER TABLE PKTABLE ALTER COLUMN ptest1 TYPE bigint; + +ALTER TABLE FKTABLE ALTER COLUMN ftest1 TYPE bigint; + +SELECT * FROM PKTABLE; + +SELECT * FROM FKTABLE; + +DROP TABLE PKTABLE CASCADE; + +DROP TABLE FKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ); + +CREATE TABLE FKTABLE ( ftest1 int DEFAULT -1, ftest2 int DEFAULT -2, ftest3 int, CONSTRAINT constrname2 FOREIGN KEY(ftest1, ftest2) + REFERENCES PKTABLE MATCH FULL ON DELETE SET DEFAULT ON UPDATE SET DEFAULT); + +INSERT INTO PKTABLE VALUES (-1, -2, 'The Default!'); + +INSERT INTO PKTABLE VALUES (1, 2, 'Test1'); + +INSERT INTO PKTABLE VALUES (1, 3, 'Test1-2'); + +INSERT INTO PKTABLE VALUES (2, 4, 'Test2'); + +INSERT INTO PKTABLE VALUES (3, 6, 'Test3'); + +INSERT INTO PKTABLE VALUES (4, 8, 'Test4'); + +INSERT INTO PKTABLE VALUES (5, 10, 'Test5'); + +INSERT INTO FKTABLE VALUES (1, 2, 4); + +INSERT INTO FKTABLE VALUES (1, 3, 5); + +INSERT INTO FKTABLE VALUES (2, 4, 8); + +INSERT INTO FKTABLE VALUES (3, 6, 12); + +INSERT INTO FKTABLE VALUES (NULL, NULL, 0); + +INSERT INTO FKTABLE VALUES (100, 2, 4); + +INSERT INTO FKTABLE VALUES (2, 2, 4); + +INSERT INTO FKTABLE VALUES (NULL, 2, 4); + +INSERT INTO FKTABLE VALUES (1, NULL, 4); + +SELECT * FROM FKTABLE; + +DELETE FROM PKTABLE WHERE ptest1=1 and ptest2=2; + +SELECT * FROM FKTABLE; + +DELETE FROM PKTABLE WHERE ptest1=5 and ptest2=10; + +SELECT * FROM FKTABLE; + +UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2; + +SELECT * FROM FKTABLE; + +DROP TABLE PKTABLE; + +DROP TABLE PKTABLE CASCADE; + +DROP TABLE FKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ); + +CREATE TABLE FKTABLE ( ftest1 int REFERENCES PKTABLE MATCH FULL, ftest2 int ); + +INSERT INTO PKTABLE VALUES (1, 'Test1'); + +INSERT INTO PKTABLE VALUES (2, 'Test2'); + +INSERT INTO PKTABLE VALUES (3, 'Test3'); + +INSERT INTO PKTABLE VALUES (4, 'Test4'); + +INSERT INTO PKTABLE VALUES (5, 'Test5'); + +INSERT INTO FKTABLE VALUES (1, 2); + +INSERT INTO FKTABLE VALUES (2, 3); + +INSERT INTO FKTABLE VALUES (3, 4); + +INSERT INTO FKTABLE VALUES (NULL, 1); + +INSERT INTO FKTABLE VALUES (100, 2); + +SELECT * FROM FKTABLE; + +SELECT * FROM PKTABLE; + +DELETE FROM PKTABLE WHERE ptest1=1; + +DELETE FROM PKTABLE WHERE ptest1=5; + +SELECT * FROM PKTABLE; + +UPDATE PKTABLE SET ptest1=0 WHERE ptest1=2; + +UPDATE PKTABLE SET ptest1=0 WHERE ptest1=4; + +SELECT * FROM PKTABLE; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, PRIMARY KEY(ptest1, ptest2) ); + +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int ); + +INSERT INTO PKTABLE VALUES (1, 2); + +INSERT INTO FKTABLE VALUES (1, NULL); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) REFERENCES PKTABLE MATCH FULL; + +ALTER TABLE FKTABLE ALTER CONSTRAINT fk_con DEFERRABLE INITIALLY DEFERRED; + +SELECT condeferrable, condeferred, conenforced, convalidated +FROM pg_constraint WHERE conname = 'fk_con'; + +SELECT condeferrable, condeferred, conenforced, convalidated +FROM pg_constraint WHERE conname = 'fk_con'; + +SELECT condeferrable, condeferred, conenforced, convalidated +FROM pg_constraint WHERE conname = 'fk_con'; + +SELECT condeferrable, condeferred, conenforced, convalidated +FROM pg_constraint WHERE conname = 'fk_con'; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); + +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE); + +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1'); + +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2'); + +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3'); + +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4'); + +INSERT INTO FKTABLE VALUES (1, 2, 3, 1); + +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2); + +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3); + +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4); + +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5); + +INSERT INTO FKTABLE VALUES (1, 2, 7, 6); + +SELECT * from FKTABLE; + +UPDATE PKTABLE set ptest2=5 where ptest2=2; + +UPDATE PKTABLE set ptest1=1 WHERE ptest2=3; + +DELETE FROM PKTABLE where ptest1=1 and ptest2=2 and ptest3=3; + +DELETE FROM PKTABLE where ptest1=2; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, UNIQUE(ptest1, ptest2, ptest3) ); + +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE (ptest1, ptest2, ptest3)); + +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1'); + +INSERT INTO PKTABLE VALUES (1, 3, NULL, 'test2'); + +INSERT INTO PKTABLE VALUES (2, NULL, 4, 'test3'); + +INSERT INTO FKTABLE VALUES (1, 2, 3, 1); + +DELETE FROM PKTABLE WHERE ptest1 = 2; + +SELECT * FROM PKTABLE; + +SELECT * FROM FKTABLE; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); + +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE CASCADE ON UPDATE CASCADE); + +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1'); + +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2'); + +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3'); + +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4'); + +INSERT INTO FKTABLE VALUES (1, 2, 3, 1); + +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2); + +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3); + +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4); + +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5); + +INSERT INTO FKTABLE VALUES (1, 2, 7, 6); + +SELECT * from FKTABLE; + +UPDATE PKTABLE set ptest2=5 where ptest2=2; + +UPDATE PKTABLE set ptest1=1 WHERE ptest2=3; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DELETE FROM PKTABLE where ptest1=1 and ptest2=5 and ptest3=3; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DELETE FROM PKTABLE where ptest1=2; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); + +CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE SET DEFAULT ON UPDATE SET NULL); + +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1'); + +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2'); + +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3'); + +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4'); + +INSERT INTO FKTABLE VALUES (1, 2, 3, 1); + +INSERT INTO FKTABLE VALUES (2, 3, 4, 1); + +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2); + +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3); + +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4); + +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5); + +INSERT INTO FKTABLE VALUES (1, 2, 7, 6); + +SELECT * from FKTABLE; + +UPDATE PKTABLE set ptest2=5 where ptest2=2; + +UPDATE PKTABLE set ptest2=2 WHERE ptest2=3 and ptest1=1; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DELETE FROM PKTABLE where ptest1=2 and ptest2=3 and ptest3=4; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DELETE FROM PKTABLE where ptest2=5; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); + +CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int DEFAULT -1, ftest3 int DEFAULT -2, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE + ON DELETE SET NULL ON UPDATE SET DEFAULT); + +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1'); + +INSERT INTO PKTABLE VALUES (1, 3, 3, 'test2'); + +INSERT INTO PKTABLE VALUES (2, 3, 4, 'test3'); + +INSERT INTO PKTABLE VALUES (2, 4, 5, 'test4'); + +INSERT INTO PKTABLE VALUES (2, -1, 5, 'test5'); + +INSERT INTO FKTABLE VALUES (1, 2, 3, 1); + +INSERT INTO FKTABLE VALUES (2, 3, 4, 1); + +INSERT INTO FKTABLE VALUES (2, 4, 5, 1); + +INSERT INTO FKTABLE VALUES (NULL, 2, 3, 2); + +INSERT INTO FKTABLE VALUES (2, NULL, 3, 3); + +INSERT INTO FKTABLE VALUES (NULL, 2, 7, 4); + +INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5); + +INSERT INTO FKTABLE VALUES (1, 2, 7, 6); + +SELECT * from FKTABLE; + +UPDATE PKTABLE set ptest2=5 where ptest2=2; + +UPDATE PKTABLE set ptest1=0, ptest2=-1, ptest3=-2 where ptest2=2; + +UPDATE PKTABLE set ptest2=10 where ptest2=4; + +UPDATE PKTABLE set ptest2=2 WHERE ptest2=3 and ptest1=1; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DELETE FROM PKTABLE where ptest1=2 and ptest2=3 and ptest3=4; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DELETE FROM PKTABLE where ptest2=-1 and ptest3=5; + +SELECT * from PKTABLE; + +SELECT * from FKTABLE; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (tid int, id int, PRIMARY KEY (tid, id)); + +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES PKTABLE ON DELETE SET NULL (bar)); + +CREATE TABLE FKTABLE (tid int, id int, foo int, FOREIGN KEY (tid, id) REFERENCES PKTABLE ON DELETE SET NULL (foo)); + +CREATE TABLE FKTABLE ( + tid int, id int, + fk_id_del_set_null int, + fk_id_del_set_default int DEFAULT 0, + FOREIGN KEY (tid, fk_id_del_set_null) REFERENCES PKTABLE ON DELETE SET NULL (fk_id_del_set_null), + -- this tests handling of duplicate entries in SET DEFAULT column list + FOREIGN KEY (tid, fk_id_del_set_default) REFERENCES PKTABLE ON DELETE SET DEFAULT (fk_id_del_set_default, fk_id_del_set_default) +); + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'fktable'::regclass::oid ORDER BY oid; + +INSERT INTO PKTABLE VALUES (1, 0), (1, 1), (1, 2); + +INSERT INTO FKTABLE VALUES + (1, 1, 1, NULL), + (1, 2, NULL, 2); + +DELETE FROM PKTABLE WHERE id = 1 OR id = 2; + +SELECT * FROM FKTABLE ORDER BY id; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY, someoid oid); + +CREATE TABLE FKTABLE_FAIL1 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest2) REFERENCES PKTABLE); + +CREATE TABLE FKTABLE_FAIL2 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES PKTABLE(ptest2)); + +CREATE TABLE FKTABLE_FAIL3 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (tableoid) REFERENCES PKTABLE(someoid)); + +CREATE TABLE FKTABLE_FAIL4 ( ftest1 oid, CONSTRAINT fkfail1 FOREIGN KEY (ftest1) REFERENCES PKTABLE(tableoid)); + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 int, ptest2 int, UNIQUE(ptest1, ptest2)); + +CREATE TABLE FKTABLE_FAIL1 (ftest1 int REFERENCES pktable(ptest1)); + +DROP TABLE FKTABLE_FAIL1; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY); + +INSERT INTO PKTABLE VALUES(42); + +CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable); + +CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable(ptest1)); + +CREATE TABLE FKTABLE (ftest1 int8 REFERENCES pktable); + +INSERT INTO FKTABLE VALUES(42); + +INSERT INTO FKTABLE VALUES(43); + +UPDATE FKTABLE SET ftest1 = ftest1; + +UPDATE FKTABLE SET ftest1 = ftest1 + 1; + +DROP TABLE FKTABLE; + +CREATE TABLE FKTABLE (ftest1 numeric REFERENCES pktable); + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 numeric PRIMARY KEY); + +INSERT INTO PKTABLE VALUES(42); + +CREATE TABLE FKTABLE (ftest1 int REFERENCES pktable); + +INSERT INTO FKTABLE VALUES(42); + +INSERT INTO FKTABLE VALUES(43); + +UPDATE FKTABLE SET ftest1 = ftest1; + +UPDATE FKTABLE SET ftest1 = ftest1 + 1; + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2)); + +CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable); + +CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2)); + +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable); + +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2)); + +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1)); + +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1)); + +DROP TABLE FKTABLE; + +CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2)); + +DROP TABLE FKTABLE; + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable(ptest1, ptest2)); + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable); + +DROP TABLE PKTABLE; + +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, +ptest4) REFERENCES pktable(ptest2, ptest1)); + +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, +ptest3) REFERENCES pktable(ptest1, ptest2)); + +CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, +ptest3) REFERENCES pktable); + +create table pktable_base (base1 int not null); + +create table pktable (ptest1 int, primary key(base1), unique(base1, ptest1)) inherits (pktable_base); + +create table fktable (ftest1 int references pktable(base1)); + +insert into pktable(base1) values (1); + +insert into pktable(base1) values (2); + +insert into fktable(ftest1) values (3); + +insert into pktable(base1) values (3); + +insert into fktable(ftest1) values (3); + +delete from pktable where base1>2; + +update pktable set base1=base1*4; + +update pktable set base1=base1*4 where base1<3; + +delete from pktable where base1>3; + +drop table fktable; + +delete from pktable; + +create table fktable (ftest1 int, ftest2 int, foreign key(ftest1, ftest2) references pktable(base1, ptest1)); + +insert into pktable(base1, ptest1) values (1, 1); + +insert into pktable(base1, ptest1) values (2, 2); + +insert into fktable(ftest1, ftest2) values (3, 1); + +insert into pktable(base1,ptest1) values (3, 1); + +insert into fktable(ftest1, ftest2) values (3, 1); + +delete from pktable where base1>2; + +update pktable set base1=base1*4; + +update pktable set base1=base1*4 where base1<3; + +delete from pktable where base1>3; + +drop table fktable; + +drop table pktable; + +drop table pktable_base; + +create table pktable_base(base1 int not null, base2 int); + +create table pktable(ptest1 int, ptest2 int, primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(base1, ptest1)) inherits (pktable_base); + +insert into pktable (base1, ptest1, base2, ptest2) values (1, 1, 1, 1); + +insert into pktable (base1, ptest1, base2, ptest2) values (2, 1, 1, 1); + +insert into pktable (base1, ptest1, base2, ptest2) values (2, 2, 2, 1); + +insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2); + +insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2); + +delete from pktable where base1=2; + +update pktable set base1=3 where base1=1; + +delete from pktable where base2=2; + +delete from pktable where base1=2; + +drop table pktable; + +drop table pktable_base; + +create table pktable_base(base1 int not null); + +create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_base); + +create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable); + +create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1)); + +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable); + +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1)); + +create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1)); + +drop table pktable; + +drop table pktable_base; + +create table pktable_base(base1 int not null, base2 int); + +create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(base1, ptest1)) inherits (pktable_base); + +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references + pktable(ptest1, base1)) inherits (pktable_base); + +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references + pktable(base1, ptest1)) inherits (pktable_base); + +create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references + pktable(base1, ptest1)) inherits (pktable_base); + +drop table pktable; + +drop table pktable_base; + +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +); + +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE +); + +INSERT INTO fktable VALUES (5, 10); + +BEGIN; + +SET CONSTRAINTS ALL DEFERRED; + +INSERT INTO fktable VALUES (10, 15); + +INSERT INTO pktable VALUES (15, 0); + +COMMIT; + +DROP TABLE fktable, pktable; + +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +); + +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED +); + +BEGIN; + +INSERT INTO fktable VALUES (100, 200); + +INSERT INTO pktable VALUES (200, 500); + +COMMIT; + +BEGIN; + +SET CONSTRAINTS ALL IMMEDIATE; + +INSERT INTO fktable VALUES (500, 1000); + +COMMIT; + +DROP TABLE fktable, pktable; + +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +); + +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE +); + +BEGIN; + +SET CONSTRAINTS ALL DEFERRED; + +INSERT INTO fktable VALUES (1000, 2000); + +SET CONSTRAINTS ALL IMMEDIATE; + +INSERT INTO pktable VALUES (2000, 3); + +COMMIT; + +DROP TABLE fktable, pktable; + +CREATE TABLE pktable ( + id INT4 PRIMARY KEY, + other INT4 +); + +CREATE TABLE fktable ( + id INT4 PRIMARY KEY, + fk INT4 REFERENCES pktable DEFERRABLE INITIALLY DEFERRED +); + +BEGIN; + +INSERT INTO fktable VALUES (100, 200); + +COMMIT; + +DROP TABLE pktable, fktable; + +CREATE TEMP TABLE pktable ( + id1 INT4 PRIMARY KEY, + id2 VARCHAR(4) UNIQUE, + id3 REAL UNIQUE, + UNIQUE(id1, id2, id3) +); + +CREATE TEMP TABLE fktable ( + x1 INT4 REFERENCES pktable(id1), + x2 VARCHAR(4) REFERENCES pktable(id2), + x3 REAL REFERENCES pktable(id3), + x4 TEXT, + x5 INT2 +); + +ALTER TABLE fktable ADD CONSTRAINT fk_2_3 +FOREIGN KEY (x2) REFERENCES pktable(id3); + +ALTER TABLE fktable ADD CONSTRAINT fk_2_1 +FOREIGN KEY (x2) REFERENCES pktable(id1); + +ALTER TABLE fktable ADD CONSTRAINT fk_3_1 +FOREIGN KEY (x3) REFERENCES pktable(id1); + +ALTER TABLE fktable ADD CONSTRAINT fk_1_2 +FOREIGN KEY (x1) REFERENCES pktable(id2); + +ALTER TABLE fktable ADD CONSTRAINT fk_1_3 +FOREIGN KEY (x1) REFERENCES pktable(id3); + +ALTER TABLE fktable ADD CONSTRAINT fk_4_2 +FOREIGN KEY (x4) REFERENCES pktable(id2); + +ALTER TABLE fktable ADD CONSTRAINT fk_5_1 +FOREIGN KEY (x5) REFERENCES pktable(id1); + +ALTER TABLE fktable ADD CONSTRAINT fk_123_123 +FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id1,id2,id3); + +ALTER TABLE fktable ADD CONSTRAINT fk_213_213 +FOREIGN KEY (x2,x1,x3) REFERENCES pktable(id2,id1,id3); + +ALTER TABLE fktable ADD CONSTRAINT fk_253_213 +FOREIGN KEY (x2,x5,x3) REFERENCES pktable(id2,id1,id3); + +ALTER TABLE fktable ADD CONSTRAINT fk_123_231 +FOREIGN KEY (x1,x2,x3) REFERENCES pktable(id2,id3,id1); + +ALTER TABLE fktable ADD CONSTRAINT fk_241_132 +FOREIGN KEY (x2,x4,x1) REFERENCES pktable(id1,id3,id2); + +DROP TABLE pktable, fktable; + +CREATE TEMP TABLE pktable ( + id int primary key, + other int +); + +CREATE TEMP TABLE fktable ( + id int primary key, + fk int references pktable deferrable initially deferred +); + +INSERT INTO pktable VALUES (5, 10); + +BEGIN; + +INSERT INTO fktable VALUES (0, 20); + +UPDATE fktable SET id = id + 1; + +COMMIT; + +BEGIN; + +INSERT INTO fktable VALUES (0, 20); + +SAVEPOINT savept1; + +UPDATE fktable SET id = id + 1; + +COMMIT; + +BEGIN; + +SAVEPOINT savept1; + +INSERT INTO fktable VALUES (0, 20); + +RELEASE SAVEPOINT savept1; + +UPDATE fktable SET id = id + 1; + +COMMIT; + +BEGIN; + +INSERT INTO fktable VALUES (0, 20); + +SAVEPOINT savept1; + +UPDATE fktable SET id = id + 1; + +ROLLBACK TO savept1; + +COMMIT; + +INSERT INTO fktable VALUES (1, 5); + +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey DEFERRABLE INITIALLY IMMEDIATE; + +BEGIN; + +UPDATE pktable SET id = 10 WHERE id = 5; + +COMMIT; + +BEGIN; + +INSERT INTO fktable VALUES (0, 20); + +COMMIT; + +BEGIN; + +UPDATE pktable SET id = 10 WHERE id = 5; + +INSERT INTO fktable VALUES (0, 20); + +ROLLBACK; + +ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT DEFERRABLE; + +CREATE TEMP TABLE users ( + id INT PRIMARY KEY, + name VARCHAR NOT NULL +); + +INSERT INTO users VALUES (1, 'Jozko'); + +INSERT INTO users VALUES (2, 'Ferko'); + +INSERT INTO users VALUES (3, 'Samko'); + +CREATE TEMP TABLE tasks ( + id INT PRIMARY KEY, + owner INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, + worker INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL, + checked_by INT REFERENCES users ON UPDATE CASCADE ON DELETE SET NULL +); + +INSERT INTO tasks VALUES (1,1,NULL,NULL); + +INSERT INTO tasks VALUES (2,2,2,NULL); + +INSERT INTO tasks VALUES (3,3,3,3); + +SELECT * FROM tasks; + +UPDATE users SET id = 4 WHERE id = 3; + +SELECT * FROM tasks; + +DELETE FROM users WHERE id = 4; + +SELECT * FROM tasks; + +BEGIN; + +UPDATE tasks set id=id WHERE id=2; + +SELECT * FROM tasks; + +DELETE FROM users WHERE id = 2; + +SELECT * FROM tasks; + +COMMIT; + +create temp table selfref ( + a int primary key, + b int, + foreign key (b) references selfref (a) + on update cascade on delete cascade +); + +insert into selfref (a, b) +values + (0, 0), + (1, 1); + +begin; + +update selfref set a = 123 where a = 0; + +select a, b from selfref; + +update selfref set a = 456 where a = 123; + +select a, b from selfref; + +commit; + +create temp table defp (f1 int primary key); + +create temp table defc (f1 int default 0 + references defp on delete set default); + +insert into defp values (0), (1), (2); + +insert into defc values (2); + +select * from defc; + +delete from defp where f1 = 2; + +select * from defc; + +delete from defp where f1 = 0; + +alter table defc alter column f1 set default 1; + +delete from defp where f1 = 0; + +select * from defc; + +delete from defp where f1 = 1; + +create temp table pp (f1 int primary key); + +create temp table cc (f1 int references pp on update no action on delete no action); + +insert into pp values(12); + +insert into pp values(11); + +update pp set f1=f1+1; + +insert into cc values(13); + +update pp set f1=f1+1; + +update pp set f1=f1+1; + +delete from pp where f1 = 13; + +drop table pp, cc; + +create temp table pp (f1 int primary key); + +create temp table cc (f1 int references pp on update restrict on delete restrict); + +insert into pp values(12); + +insert into pp values(11); + +update pp set f1=f1+1; + +insert into cc values(13); + +update pp set f1=f1+1; + +delete from pp where f1 = 13; + +drop table pp, cc; + +create temp table t1 (a integer primary key, b text); + +create temp table t2 (a integer primary key, b integer references t1); + +create rule r1 as on delete to t1 do delete from t2 where t2.b = old.a; + +delete from t1 where a = 1; + +delete from t1 where a = 1; + +create table pktable2 (a int, b int, c int, d int, e int, primary key (d, e)); + +create table fktable2 (d int, e int, foreign key (d, e) references pktable2); + +insert into pktable2 values (1, 2, 3, 4, 5); + +insert into fktable2 values (4, 5); + +delete from pktable2; + +update pktable2 set d = 5; + +drop table pktable2, fktable2; + +create table pktable1 (a int primary key); + +create table pktable2 (a int, b int, primary key (a, b)); + +create table fktable2 ( + a int, + b int, + very_very_long_column_name_to_exceed_63_characters int, + foreign key (very_very_long_column_name_to_exceed_63_characters) references pktable1, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2 +); + +select conname from pg_constraint where conrelid = 'fktable2'::regclass order by conname; + +drop table pktable1, pktable2, fktable2; + +create table pktable2(f1 int primary key); + +create table fktable2(f1 int references pktable2 deferrable initially deferred); + +insert into pktable2 values(1); + +begin; + +insert into fktable2 values(1); + +savepoint x; + +delete from fktable2; + +rollback to x; + +commit; + +begin; + +insert into fktable2 values(2); + +savepoint x; + +delete from fktable2; + +rollback to x; + +commit; + +begin; + +insert into fktable2 values(2); + +alter table fktable2 drop constraint fktable2_f1_fkey; + +commit; + +begin; + +delete from pktable2 where f1 = 1; + +alter table fktable2 drop constraint fktable2_f1_fkey; + +commit; + +drop table pktable2, fktable2; + +create table pktable2 (a float8, b float8, primary key (a, b)); + +create table fktable2 (x float8, y float8, foreign key (x, y) references pktable2 (a, b) on update cascade); + +insert into pktable2 values ('-0', '-0'); + +insert into fktable2 values ('-0', '-0'); + +select * from pktable2; + +select * from fktable2; + +update pktable2 set a = '0' where a = '-0'; + +select * from pktable2; + +select * from fktable2; + +drop table pktable2, fktable2; + +CREATE TABLE fk_notpartitioned_pk (fdrop1 int, a int, fdrop2 int, b int, + PRIMARY KEY (a, b)); + +ALTER TABLE fk_notpartitioned_pk DROP COLUMN fdrop1, DROP COLUMN fdrop2; + +CREATE TABLE fk_partitioned_fk (b int, fdrop1 int, a int) PARTITION BY RANGE (a, b); + +ALTER TABLE fk_partitioned_fk DROP COLUMN fdrop1; + +CREATE TABLE fk_partitioned_fk_1 (fdrop1 int, fdrop2 int, a int, fdrop3 int, b int); + +ALTER TABLE fk_partitioned_fk_1 DROP COLUMN fdrop1, DROP COLUMN fdrop2, DROP COLUMN fdrop3; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR VALUES FROM (0,0) TO (1000,1000); + +CREATE TABLE fk_partitioned_fk_2 (b int, fdrop1 int, fdrop2 int, a int); + +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN fdrop1, DROP COLUMN fdrop2; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FROM (1000,1000) TO (2000,2000); + +CREATE TABLE fk_partitioned_fk_3 (fdrop1 int, fdrop2 int, fdrop3 int, fdrop4 int, b int, a int) + PARTITION BY HASH (a); + +ALTER TABLE fk_partitioned_fk_3 DROP COLUMN fdrop1, DROP COLUMN fdrop2, + DROP COLUMN fdrop3, DROP COLUMN fdrop4; + +CREATE TABLE fk_partitioned_fk_3_0 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, REMAINDER 0); + +CREATE TABLE fk_partitioned_fk_3_1 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, REMAINDER 1); + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 + FOR VALUES FROM (2000,2000) TO (3000,3000); + +ALTER TABLE ONLY fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk; + +INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501); + +INSERT INTO fk_partitioned_fk_1 (a,b) VALUES (500, 501); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (1500, 1501); + +INSERT INTO fk_partitioned_fk_2 (a,b) VALUES (1500, 1501); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502); + +INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2500, 2502); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503); + +INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2501, 2503); + +INSERT INTO fk_notpartitioned_pk VALUES (500, 501), (1500, 1501), + (2500, 2502), (2501, 2503); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (1500, 1501); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503); + +UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501; + +INSERT INTO fk_notpartitioned_pk (a,b) VALUES (2502, 2503); + +UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501; + +UPDATE fk_notpartitioned_pk SET b = 502 WHERE a = 500; + +UPDATE fk_notpartitioned_pk SET b = 1502 WHERE a = 1500; + +UPDATE fk_notpartitioned_pk SET b = 2504 WHERE a = 2500; + +SELECT conname, tgrelid::regclass as tgrel, regexp_replace(tgname, '[0-9]+', 'N') as tgname, tgtype +FROM pg_trigger t JOIN pg_constraint c ON (t.tgconstraint = c.oid) +WHERE tgrelid IN (SELECT relid FROM pg_partition_tree('fk_partitioned_fk'::regclass) + UNION ALL SELECT 'fk_notpartitioned_pk'::regclass) +ORDER BY tgrelid, tgtype; + +SELECT conname, tgrelid::regclass as tgrel, regexp_replace(tgname, '[0-9]+', 'N') as tgname, tgtype +FROM pg_trigger t JOIN pg_constraint c ON (t.tgconstraint = c.oid) +WHERE tgrelid IN (SELECT relid FROM pg_partition_tree('fk_partitioned_fk'::regclass) + UNION ALL SELECT 'fk_notpartitioned_pk'::regclass) +ORDER BY tgrelid, tgtype; + +SELECT conname, tgrelid::regclass as tgrel, regexp_replace(tgname, '[0-9]+', 'N') as tgname, tgtype +FROM pg_trigger t JOIN pg_constraint c ON (t.tgconstraint = c.oid) +WHERE tgrelid IN (SELECT relid FROM pg_partition_tree('fk_partitioned_fk'::regclass) + UNION ALL SELECT 'fk_notpartitioned_pk'::regclass) +ORDER BY tgrelid, tgtype; + +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; + +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk; + +CREATE TABLE fk_notpartitioned_pk (a INT, PRIMARY KEY(a), CHECK (a > 0)); + +CREATE TABLE fk_partitioned_fk (a INT REFERENCES fk_notpartitioned_pk(a) PRIMARY KEY) PARTITION BY RANGE(a); + +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES FROM (MINVALUE) TO (MAXVALUE); + +INSERT INTO fk_notpartitioned_pk VALUES (1); + +INSERT INTO fk_partitioned_fk VALUES (1); + +ALTER TABLE fk_notpartitioned_pk ALTER COLUMN a TYPE bigint; + +DELETE FROM fk_notpartitioned_pk WHERE a = 1; + +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk; + +CREATE TABLE fk_notpartitioned_pk (a int, b int, PRIMARY KEY (a, b)); + +CREATE TABLE fk_partitioned_fk (b int, a int) PARTITION BY RANGE (a, b); + +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk NOT VALID; + +CREATE TABLE fk_partitioned_fk_1 (a int, b int); + +ALTER TABLE fk_partitioned_fk_1 ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_1 FOR VALUES FROM (0,0) TO (1000,1000); + +SELECT conname, convalidated, conrelid::regclass FROM pg_constraint +WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text; + +ALTER TABLE fk_partitioned_fk VALIDATE CONSTRAINT fk_partitioned_fk_a_b_fkey; + +SELECT conname, convalidated, conrelid::regclass FROM pg_constraint +WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text; + +CREATE TABLE fk_partitioned_fk_2 (a int, b int); + +INSERT INTO fk_partitioned_fk_2 VALUES(1000, 1000); + +ALTER TABLE fk_partitioned_fk_2 ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk NOT VALID; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FROM (1000,1000) TO (2000,2000); + +TRUNCATE fk_partitioned_fk_2; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES FROM (1000,1000) TO (2000,2000); + +SELECT conname, convalidated FROM pg_constraint +WHERE conrelid = 'fk_partitioned_fk_2'::regclass ORDER BY oid::regclass::text; + +CREATE TABLE fk_partitioned_fk_3 (a int, b int) PARTITION BY RANGE (a, b); + +ALTER TABLE fk_partitioned_fk_3 ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk NOT VALID; + +CREATE TABLE fk_partitioned_fk_3_1 (a int, b int); + +ALTER TABLE fk_partitioned_fk_3_1 ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk; + +ALTER TABLE fk_partitioned_fk_3 ATTACH PARTITION fk_partitioned_fk_3_1 FOR VALUES FROM (2000,2000) TO (3000,3000); + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES FROM (2000,2000) TO (3000,3000); + +SELECT conname, convalidated, conrelid::regclass FROM pg_constraint +WHERE conrelid::regclass::text like 'fk_partitioned_fk%' ORDER BY oid::regclass::text; + +DROP TABLE fk_partitioned_fk, fk_notpartitioned_pk; + +CREATE TABLE fk_partitioned_pk (a int, b int, PRIMARY KEY (a, b)) PARTITION BY RANGE (a, b); + +CREATE TABLE fk_partitioned_pk_1 PARTITION OF fk_partitioned_pk FOR VALUES FROM (0,0) TO (1000,1000); + +CREATE TABLE fk_partitioned_pk_2 PARTITION OF fk_partitioned_pk FOR VALUES FROM (1000,1000) TO (2000,2000); + +CREATE TABLE fk_notpartitioned_fk (b int, a int); + +INSERT INTO fk_partitioned_pk VALUES(100,100), (1000,1000); + +INSERT INTO fk_notpartitioned_fk VALUES(100,100), (1000,1000); + +ALTER TABLE fk_notpartitioned_fk ADD CONSTRAINT fk_notpartitioned_fk_a_b_fkey + FOREIGN KEY (a, b) REFERENCES fk_partitioned_pk NOT VALID; + +SELECT conname, conenforced, convalidated FROM pg_constraint +WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY oid::regclass::text; + +ALTER TABLE fk_notpartitioned_fk VALIDATE CONSTRAINT fk_notpartitioned_fk_a_b_fkey; + +SELECT conname, conenforced, convalidated FROM pg_constraint +WHERE conrelid = 'fk_notpartitioned_fk'::regclass ORDER BY oid::regclass::text; + +ALTER TABLE fk_partitioned_pk ADD CONSTRAINT selffk FOREIGN KEY (a, b) REFERENCES fk_partitioned_pk NOT VALID; + +CREATE TABLE fk_partitioned_pk_3 PARTITION OF fk_partitioned_pk FOR VALUES FROM (2000,2000) TO (3000,3000) + PARTITION BY RANGE (a); + +CREATE TABLE fk_partitioned_pk_3_1 PARTITION OF fk_partitioned_pk_3 FOR VALUES FROM (2000) TO (2100); + +SELECT conname, conenforced, convalidated FROM pg_constraint +WHERE conrelid = 'fk_partitioned_pk'::regclass AND contype = 'f' +ORDER BY oid::regclass::text; + +ALTER TABLE fk_partitioned_pk_2 VALIDATE CONSTRAINT selffk; + +ALTER TABLE fk_partitioned_pk VALIDATE CONSTRAINT selffk; + +SELECT conname, conenforced, convalidated FROM pg_constraint +WHERE conrelid = 'fk_partitioned_pk'::regclass AND contype = 'f' +ORDER BY oid::regclass::text; + +DROP TABLE fk_notpartitioned_fk, fk_partitioned_pk; + +CREATE TABLE fk_notpartitioned_pk (a int, b int, primary key (a, b)); + +CREATE TABLE fk_partitioned_fk (a int default 2501, b int default 142857) PARTITION BY LIST (a); + +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES IN (NULL,500,501,502); + +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk MATCH SIMPLE + ON DELETE SET NULL ON UPDATE SET NULL; + +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502); + +CREATE TABLE fk_partitioned_fk_3 (a int, b int); + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES IN (2500,2501,2502,2503); + +INSERT INTO fk_partitioned_fk (a, b) VALUES (2502, 2503); + +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503); + +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, NULL); + +INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503); + +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503); + +INSERT INTO fk_partitioned_fk (a,b) VALUES (NULL, NULL); + +INSERT INTO fk_notpartitioned_pk VALUES (1, 2); + +CREATE TABLE fk_partitioned_fk_full (x int, y int) PARTITION BY RANGE (x); + +CREATE TABLE fk_partitioned_fk_full_1 PARTITION OF fk_partitioned_fk_full DEFAULT; + +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL); + +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL; + +TRUNCATE fk_partitioned_fk_full; + +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL; + +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL); + +DROP TABLE fk_partitioned_fk_full; + +SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a; + +UPDATE fk_notpartitioned_pk SET a = a + 1 WHERE a = 2502; + +SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a; + +INSERT INTO fk_partitioned_fk VALUES (2503, 2503); + +SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL; + +DELETE FROM fk_notpartitioned_pk; + +SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL; + +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; + +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET DEFAULT ON UPDATE SET DEFAULT; + +INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503); + +INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503); + +UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502; + +INSERT INTO fk_notpartitioned_pk VALUES (2501, 142857); + +UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502; + +SELECT * FROM fk_partitioned_fk WHERE b = 142857; + +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; + +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET NULL (a); + +BEGIN; + +DELETE FROM fk_notpartitioned_pk WHERE b = 142857; + +SELECT * FROM fk_partitioned_fk WHERE a IS NOT NULL OR b IS NOT NULL ORDER BY a NULLS LAST; + +ROLLBACK; + +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; + +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE SET DEFAULT (a); + +BEGIN; + +DELETE FROM fk_partitioned_fk; + +DELETE FROM fk_notpartitioned_pk; + +INSERT INTO fk_notpartitioned_pk VALUES (500, 100000), (2501, 100000); + +INSERT INTO fk_partitioned_fk VALUES (500, 100000); + +DELETE FROM fk_notpartitioned_pk WHERE a = 500; + +SELECT * FROM fk_partitioned_fk ORDER BY a; + +ROLLBACK; + +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; + +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk + ON DELETE CASCADE ON UPDATE CASCADE; + +UPDATE fk_notpartitioned_pk SET a = 2502 WHERE a = 2501; + +SELECT * FROM fk_partitioned_fk WHERE b = 142857; + +SELECT * FROM fk_partitioned_fk WHERE b = 142857; + +DELETE FROM fk_notpartitioned_pk WHERE b = 142857; + +SELECT * FROM fk_partitioned_fk WHERE a = 142857; + +DROP TABLE fk_partitioned_fk_2; + +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502); + +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_2; + +BEGIN; + +DROP TABLE fk_partitioned_fk; + +ROLLBACK; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); + +DROP TABLE fk_partitioned_fk_2; + +CREATE TABLE fk_partitioned_fk_2 (b int, c text, a int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE CASCADE ON DELETE CASCADE); + +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN c; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); + +DROP TABLE fk_partitioned_fk_2; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); + +BEGIN; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); + +ROLLBACK; + +BEGIN; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); + +ROLLBACK; + +DROP TABLE fk_partitioned_fk_2; + +CREATE TABLE fk_partitioned_fk_4 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE) PARTITION BY RANGE (b, a); + +CREATE TABLE fk_partitioned_fk_4_1 PARTITION OF fk_partitioned_fk_4 FOR VALUES FROM (1,1) TO (100,100); + +CREATE TABLE fk_partitioned_fk_4_2 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE SET NULL); + +ALTER TABLE fk_partitioned_fk_4 ATTACH PARTITION fk_partitioned_fk_4_2 FOR VALUES FROM (100,100) TO (1000,1000); + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502); + +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_4; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502); + +CREATE TABLE fk_partitioned_fk_5 (a int, b int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE) + PARTITION BY RANGE (a); + +CREATE TABLE fk_partitioned_fk_5_1 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk); + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500); + +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10); + +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_5; + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500); + +ALTER TABLE fk_partitioned_fk_5 DETACH PARTITION fk_partitioned_fk_5_1; + +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10); + +CREATE TABLE fk_partitioned_fk_2 (a int, b int) PARTITION BY RANGE (b); + +CREATE TABLE fk_partitioned_fk_2_1 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (0) TO (1000); + +CREATE TABLE fk_partitioned_fk_2_2 PARTITION OF fk_partitioned_fk_2 FOR VALUES FROM (1000) TO (2000); + +INSERT INTO fk_partitioned_fk_2 VALUES (1600, 601), (1600, 1601); + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 + FOR VALUES IN (1600); + +INSERT INTO fk_notpartitioned_pk VALUES (1600, 601), (1600, 1601); + +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 + FOR VALUES IN (1600); + +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY); + +CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_6) PARTITION BY LIST (a); + +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1); + +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6; + +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY); + +CREATE TABLE fk_partitioned_fk_6 (a int, + FOREIGN KEY (a) REFERENCES fk_partitioned_pk_6, + FOREIGN KEY (a) REFERENCES fk_partitioned_pk_6 +) PARTITION BY LIST (a); + +CREATE TABLE fk_partitioned_fk_6_1 PARTITION OF fk_partitioned_fk_6 FOR VALUES IN (1); + +ALTER TABLE fk_partitioned_fk_6 DETACH PARTITION fk_partitioned_fk_6_1; + +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_fk_6_1 FOR VALUES IN (1); + +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6; + +CREATE TABLE fk_partitioned_pk_6 (a int PRIMARY KEY) PARTITION BY list (a); + +CREATE TABLE fk_partitioned_pk_61 PARTITION OF fk_partitioned_pk_6 FOR VALUES IN (1); + +CREATE TABLE fk_partitioned_fk_6 (a int REFERENCES fk_partitioned_pk_61) PARTITION BY LIST (a); + +ALTER TABLE fk_partitioned_fk_6 ATTACH PARTITION fk_partitioned_pk_6 FOR VALUES IN (1); + +DROP TABLE fk_partitioned_pk_6, fk_partitioned_fk_6; + +create role regress_other_partitioned_fk_owner; + +grant references on fk_notpartitioned_pk to regress_other_partitioned_fk_owner; + +set role regress_other_partitioned_fk_owner; + +create table other_partitioned_fk(a int, b int) partition by list (a); + +create table other_partitioned_fk_1 partition of other_partitioned_fk + for values in (2048); + +insert into other_partitioned_fk + select 2048, x from generate_series(1,10) x; + +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b); + +reset role; + +insert into fk_notpartitioned_pk (a, b) + select 2048, x from generate_series(1,10) x; + +set role regress_other_partitioned_fk_owner; + +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b); + +drop table other_partitioned_fk; + +reset role; + +revoke all on fk_notpartitioned_pk from regress_other_partitioned_fk_owner; + +drop role regress_other_partitioned_fk_owner; + +CREATE TABLE parted_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint, + FOREIGN KEY (id_abc) REFERENCES parted_self_fk(id) +) +PARTITION BY RANGE (id); + +CREATE TABLE part1_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +); + +ALTER TABLE parted_self_fk ATTACH PARTITION part1_self_fk FOR VALUES FROM (0) TO (10); + +CREATE TABLE part2_self_fk PARTITION OF parted_self_fk FOR VALUES FROM (10) TO (20); + +CREATE TABLE part3_self_fk ( -- a partitioned partition + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +) PARTITION BY RANGE (id); + +CREATE TABLE part32_self_fk PARTITION OF part3_self_fk FOR VALUES FROM (20) TO (30); + +ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (20) TO (40); + +CREATE TABLE part33_self_fk ( + id bigint NOT NULL PRIMARY KEY, + id_abc bigint +); + +ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40); + +INSERT INTO parted_self_fk VALUES (1, NULL), (2, NULL), (3, NULL); + +INSERT INTO parted_self_fk VALUES (10, 1), (11, 2), (12, 3) RETURNING tableoid::regclass; + +INSERT INTO parted_self_fk VALUES (4, 5); + +DELETE FROM parted_self_fk WHERE id = 1 RETURNING *; + +SELECT cr.relname, co.conname, co.convalidated, + p.conname AS conparent, p.convalidated, cf.relname AS foreignrel +FROM pg_constraint co +JOIN pg_class cr ON cr.oid = co.conrelid +LEFT JOIN pg_class cf ON cf.oid = co.confrelid +LEFT JOIN pg_constraint p ON p.oid = co.conparentid +WHERE co.contype = 'f' AND + cr.oid IN (SELECT relid FROM pg_partition_tree('parted_self_fk')) +ORDER BY cr.relname, co.conname, p.conname; + +ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk; + +INSERT INTO part2_self_fk VALUES (16, 9); + +DELETE FROM parted_self_fk WHERE id = 2 RETURNING *; + +ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20); + +INSERT INTO parted_self_fk VALUES (16, 9); + +DELETE FROM parted_self_fk WHERE id = 3 RETURNING *; + +ALTER TABLE parted_self_fk DETACH PARTITION part2_self_fk; + +ALTER TABLE parted_self_fk ATTACH PARTITION part2_self_fk FOR VALUES FROM (10) TO (20); + +ALTER TABLE parted_self_fk DETACH PARTITION part3_self_fk; + +ALTER TABLE parted_self_fk ATTACH PARTITION part3_self_fk FOR VALUES FROM (30) TO (40); + +ALTER TABLE part3_self_fk DETACH PARTITION part33_self_fk; + +ALTER TABLE part3_self_fk ATTACH PARTITION part33_self_fk FOR VALUES FROM (30) TO (40); + +SELECT cr.relname, co.conname, co.convalidated, + p.conname AS conparent, p.convalidated, cf.relname AS foreignrel +FROM pg_constraint co +JOIN pg_class cr ON cr.oid = co.conrelid +LEFT JOIN pg_class cf ON cf.oid = co.confrelid +LEFT JOIN pg_constraint p ON p.oid = co.conparentid +WHERE co.contype = 'f' AND + cr.oid IN (SELECT relid FROM pg_partition_tree('parted_self_fk')) +ORDER BY cr.relname, co.conname, p.conname; + +create schema fkpart0 + +create table pkey (a int primary key) + +create table fk_part (a int) partition by list (a) + +create table fk_part_1 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (1) + +create table fk_part_23 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (2, 3) + partition by list (a) + +create table fk_part_23_2 partition of fk_part_23 for values in (2); + +alter table fkpart0.fk_part add foreign key (a) references fkpart0.pkey; + +alter table fkpart0.fk_part_1 drop constraint fk_part_1_a_fkey; + +alter table fkpart0.fk_part_23 drop constraint fk_part_23_a_fkey; + +alter table fkpart0.fk_part_23_2 drop constraint fk_part_23_a_fkey; + +create table fkpart0.fk_part_4 partition of fkpart0.fk_part for values in (4); + +alter table fkpart0.fk_part_4 drop constraint fk_part_a_fkey; + +create table fkpart0.fk_part_56 partition of fkpart0.fk_part + for values in (5,6) partition by list (a); + +create table fkpart0.fk_part_56_5 partition of fkpart0.fk_part_56 + for values in (5); + +alter table fkpart0.fk_part_56 drop constraint fk_part_a_fkey; + +alter table fkpart0.fk_part_56_5 drop constraint fk_part_a_fkey; + +create schema fkpart1 + +create table pkey (a int primary key) + +create table fk_part (a int) partition by list (a) + +create table fk_part_1 partition of fk_part for values in (1) partition by list (a) + +create table fk_part_1_1 partition of fk_part_1 for values in (1); + +alter table fkpart1.fk_part add foreign key (a) references fkpart1.pkey; + +insert into fkpart1.fk_part values (1); + +insert into fkpart1.pkey values (1); + +insert into fkpart1.fk_part values (1); + +delete from fkpart1.pkey where a = 1; + +alter table fkpart1.fk_part detach partition fkpart1.fk_part_1; + +create table fkpart1.fk_part_1_2 partition of fkpart1.fk_part_1 for values in (2); + +insert into fkpart1.fk_part_1 values (2); + +delete from fkpart1.pkey where a = 1; + +create schema fkpart2 + +create table pkey (a int primary key) + +create table fk_part (a int, constraint fkey foreign key (a) references fkpart2.pkey) partition by list (a) + +create table fk_part_1 partition of fkpart2.fk_part for values in (1) partition by list (a) + +create table fk_part_1_1 (a int, constraint my_fkey foreign key (a) references fkpart2.pkey); + +alter table fkpart2.fk_part_1 attach partition fkpart2.fk_part_1_1 for values in (1); + +alter table fkpart2.fk_part_1 drop constraint fkey; + +alter table fkpart2.fk_part_1_1 drop constraint my_fkey; + +alter table fkpart2.fk_part detach partition fkpart2.fk_part_1; + +alter table fkpart2.fk_part_1 drop constraint fkey; + +alter table fkpart2.fk_part_1_1 drop constraint my_fkey; + +create schema fkpart3 + +create table pkey (a int primary key) + +create table fk_part (a int, constraint fkey foreign key (a) references fkpart3.pkey deferrable initially immediate) partition by list (a) + +create table fk_part_1 partition of fkpart3.fk_part for values in (1) partition by list (a) + +create table fk_part_1_1 partition of fkpart3.fk_part_1 for values in (1) + +create table fk_part_2 partition of fkpart3.fk_part for values in (2); + +begin; + +set constraints fkpart3.fkey deferred; + +insert into fkpart3.fk_part values (1); + +insert into fkpart3.pkey values (1); + +commit; + +begin; + +set constraints fkpart3.fkey deferred; + +delete from fkpart3.pkey; + +delete from fkpart3.fk_part; + +commit; + +drop schema fkpart0, fkpart1, fkpart2, fkpart3 cascade; + +CREATE SCHEMA fkpart3; + +SET search_path TO fkpart3; + +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a); + +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (0) TO (1000); + +CREATE TABLE pk2 (b int, a int); + +ALTER TABLE pk2 DROP COLUMN b; + +ALTER TABLE pk2 ALTER a SET NOT NULL; + +ALTER TABLE pk ATTACH PARTITION pk2 FOR VALUES FROM (1000) TO (2000); + +CREATE TABLE fk (a int) PARTITION BY RANGE (a); + +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (0) TO (750); + +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk; + +CREATE TABLE fk2 (b int, a int) ; + +ALTER TABLE fk2 DROP COLUMN b; + +ALTER TABLE fk ATTACH PARTITION fk2 FOR VALUES FROM (750) TO (3500); + +CREATE TABLE pk3 PARTITION OF pk FOR VALUES FROM (2000) TO (3000); + +CREATE TABLE pk4 (LIKE pk); + +ALTER TABLE pk ATTACH PARTITION pk4 FOR VALUES FROM (3000) TO (4000); + +CREATE TABLE pk5 (c int, b int, a int NOT NULL) PARTITION BY RANGE (a); + +ALTER TABLE pk5 DROP COLUMN b, DROP COLUMN c; + +CREATE TABLE pk51 PARTITION OF pk5 FOR VALUES FROM (4000) TO (4500); + +CREATE TABLE pk52 PARTITION OF pk5 FOR VALUES FROM (4500) TO (5000); + +ALTER TABLE pk ATTACH PARTITION pk5 FOR VALUES FROM (4000) TO (5000); + +CREATE TABLE fk3 PARTITION OF fk FOR VALUES FROM (3500) TO (5000); + +INSERT into fk VALUES (1); + +INSERT into fk VALUES (1000); + +INSERT into fk VALUES (2000); + +INSERT into fk VALUES (3000); + +INSERT into fk VALUES (4000); + +INSERT into fk VALUES (4500); + +INSERT into pk VALUES (1), (1000), (2000), (3000), (4000), (4500); + +INSERT into fk VALUES (1), (1000), (2000), (3000), (4000), (4500); + +DELETE FROM pk WHERE a = 1; + +DELETE FROM pk WHERE a = 1000; + +DELETE FROM pk WHERE a = 2000; + +DELETE FROM pk WHERE a = 3000; + +DELETE FROM pk WHERE a = 4000; + +DELETE FROM pk WHERE a = 4500; + +UPDATE pk SET a = 2 WHERE a = 1; + +UPDATE pk SET a = 1002 WHERE a = 1000; + +UPDATE pk SET a = 2002 WHERE a = 2000; + +UPDATE pk SET a = 3002 WHERE a = 3000; + +UPDATE pk SET a = 4002 WHERE a = 4000; + +UPDATE pk SET a = 4502 WHERE a = 4500; + +DELETE FROM fk; + +UPDATE pk SET a = 2 WHERE a = 1; + +DELETE FROM pk WHERE a = 2; + +UPDATE pk SET a = 1002 WHERE a = 1000; + +DELETE FROM pk WHERE a = 1002; + +UPDATE pk SET a = 2002 WHERE a = 2000; + +DELETE FROM pk WHERE a = 2002; + +UPDATE pk SET a = 3002 WHERE a = 3000; + +DELETE FROM pk WHERE a = 3002; + +UPDATE pk SET a = 4002 WHERE a = 4000; + +DELETE FROM pk WHERE a = 4002; + +UPDATE pk SET a = 4502 WHERE a = 4500; + +DELETE FROM pk WHERE a = 4502; + +CREATE TABLE ffk (a int, b int REFERENCES pk) PARTITION BY list (a); + +CREATE TABLE ffk1 PARTITION OF ffk FOR VALUES IN (1); + +ALTER TABLE ffk1 ADD FOREIGN KEY (a) REFERENCES pk; + +ALTER TABLE ffk DETACH PARTITION ffk1; + +DROP TABLE ffk, ffk1; + +CREATE SCHEMA fkpart4; + +SET search_path TO fkpart4; + +CREATE TABLE droppk (a int PRIMARY KEY) PARTITION BY RANGE (a); + +CREATE TABLE droppk1 PARTITION OF droppk FOR VALUES FROM (0) TO (1000); + +CREATE TABLE droppk_d PARTITION OF droppk DEFAULT; + +CREATE TABLE droppk2 PARTITION OF droppk FOR VALUES FROM (1000) TO (2000) + PARTITION BY RANGE (a); + +CREATE TABLE droppk21 PARTITION OF droppk2 FOR VALUES FROM (1000) TO (1400); + +CREATE TABLE droppk2_d PARTITION OF droppk2 DEFAULT; + +INSERT into droppk VALUES (1), (1000), (1500), (2000); + +CREATE TABLE dropfk (a int REFERENCES droppk); + +INSERT into dropfk VALUES (1), (1000), (1500), (2000); + +ALTER TABLE droppk DETACH PARTITION droppk_d; + +ALTER TABLE droppk2 DETACH PARTITION droppk2_d; + +ALTER TABLE droppk DETACH PARTITION droppk1; + +ALTER TABLE droppk DETACH PARTITION droppk2; + +ALTER TABLE droppk2 DETACH PARTITION droppk21; + +DROP TABLE droppk_d; + +DROP TABLE droppk2_d; + +DROP TABLE droppk1; + +DROP TABLE droppk2; + +DROP TABLE droppk21; + +DELETE FROM dropfk; + +DROP TABLE droppk_d; + +DROP TABLE droppk2_d; + +DROP TABLE droppk1; + +ALTER TABLE droppk2 DETACH PARTITION droppk21; + +DROP TABLE droppk2; + +CREATE SCHEMA fkpart5; + +SET search_path TO fkpart5; + +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a); + +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1) PARTITION BY LIST (a); + +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1); + +CREATE TABLE fk (a int) PARTITION BY LIST (a); + +CREATE TABLE fk1 PARTITION OF fk FOR VALUES IN (1) PARTITION BY LIST (a); + +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES IN (1); + +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk; + +CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (2); + +CREATE TABLE pk3 (a int NOT NULL) PARTITION BY LIST (a); + +CREATE TABLE pk31 PARTITION OF pk3 FOR VALUES IN (31); + +CREATE TABLE pk32 (b int, a int NOT NULL); + +ALTER TABLE pk32 DROP COLUMN b; + +ALTER TABLE pk3 ATTACH PARTITION pk32 FOR VALUES IN (32); + +ALTER TABLE pk ATTACH PARTITION pk3 FOR VALUES IN (31, 32); + +CREATE TABLE fk2 PARTITION OF fk FOR VALUES IN (2); + +CREATE TABLE fk3 (b int, a int); + +ALTER TABLE fk3 DROP COLUMN b; + +ALTER TABLE fk ATTACH PARTITION fk3 FOR VALUES IN (3); + +SELECT pg_describe_object('pg_constraint'::regclass, oid, 0), confrelid::regclass, + CASE WHEN conparentid <> 0 THEN pg_describe_object('pg_constraint'::regclass, conparentid, 0) ELSE 'TOP' END +FROM pg_catalog.pg_constraint +WHERE conrelid IN (SELECT relid FROM pg_partition_tree('fk')) +ORDER BY conrelid::regclass::text, conname; + +CREATE TABLE fk4 (LIKE fk); + +INSERT INTO fk4 VALUES (50); + +ALTER TABLE fk ATTACH PARTITION fk4 FOR VALUES IN (50); + +CREATE SCHEMA fkpart9; + +SET search_path TO fkpart9; + +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a); + +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1, 2) PARTITION BY LIST (a); + +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1); + +CREATE TABLE pk3 PARTITION OF pk FOR VALUES IN (3); + +CREATE TABLE fk (a int REFERENCES pk DEFERRABLE INITIALLY IMMEDIATE); + +INSERT INTO fk VALUES (1); + +BEGIN; + +SET CONSTRAINTS fk_a_fkey DEFERRED; + +INSERT INTO fk VALUES (1); + +COMMIT; + +BEGIN; + +SET CONSTRAINTS fk_a_fkey DEFERRED; + +INSERT INTO fk VALUES (1); + +INSERT INTO pk VALUES (1); + +COMMIT; + +BEGIN; + +SET CONSTRAINTS fk_a_fkey DEFERRED; + +DELETE FROM pk WHERE a = 1; + +DELETE FROM fk WHERE a = 1; + +COMMIT; + +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)); + +CREATE TABLE ref(f1 int, f2 int, f3 int) + PARTITION BY list(f1); + +CREATE TABLE ref1 PARTITION OF ref FOR VALUES IN (1); + +CREATE TABLE ref2 PARTITION OF ref FOR VALUES in (2); + +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt; + +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED; + +INSERT INTO pt VALUES(1,2,3); + +INSERT INTO ref VALUES(1,2,3); + +BEGIN; + +DELETE FROM pt; + +DELETE FROM ref; + +ABORT; + +DROP TABLE pt, ref; + +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)); + +CREATE TABLE ref(f1 int, f2 int, f3 int) + PARTITION BY list(f1); + +CREATE TABLE ref1_2 PARTITION OF ref FOR VALUES IN (1, 2) PARTITION BY list (f2); + +CREATE TABLE ref1 PARTITION OF ref1_2 FOR VALUES IN (1); + +CREATE TABLE ref2 PARTITION OF ref1_2 FOR VALUES IN (2) PARTITION BY list (f2); + +CREATE TABLE ref22 PARTITION OF ref2 FOR VALUES IN (2); + +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt; + +INSERT INTO pt VALUES(1,2,3); + +INSERT INTO ref VALUES(1,2,3); + +ALTER TABLE ref22 ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY IMMEDIATE; + +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED; + +BEGIN; + +DELETE FROM pt; + +DELETE FROM ref; + +ABORT; + +DROP TABLE pt, ref; + +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) + PARTITION BY LIST(f1); + +CREATE TABLE pt1 PARTITION OF pt FOR VALUES IN (1); + +CREATE TABLE pt2 PARTITION OF pt FOR VALUES IN (2); + +CREATE TABLE ref(f1 int, f2 int, f3 int); + +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt; + +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED; + +INSERT INTO pt VALUES(1,2,3); + +INSERT INTO ref VALUES(1,2,3); + +BEGIN; + +DELETE FROM pt; + +DELETE FROM ref; + +ABORT; + +DROP TABLE pt, ref; + +CREATE TABLE pt(f1 int, f2 int, f3 int, PRIMARY KEY(f1,f2)) + PARTITION BY LIST(f1); + +CREATE TABLE pt1_2 PARTITION OF pt FOR VALUES IN (1, 2) PARTITION BY LIST (f1); + +CREATE TABLE pt1 PARTITION OF pt1_2 FOR VALUES IN (1); + +CREATE TABLE pt2 PARTITION OF pt1_2 FOR VALUES IN (2); + +CREATE TABLE ref(f1 int, f2 int, f3 int); + +ALTER TABLE ref ADD FOREIGN KEY(f1,f2) REFERENCES pt; + +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey_1 + DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE ref ALTER CONSTRAINT ref_f1_f2_fkey + DEFERRABLE INITIALLY DEFERRED; + +INSERT INTO pt VALUES(1,2,3); + +INSERT INTO ref VALUES(1,2,3); + +BEGIN; + +DELETE FROM pt; + +DELETE FROM ref; + +ABORT; + +DROP TABLE pt, ref; + +DROP SCHEMA fkpart9 CASCADE; + +CREATE SCHEMA fkpart6; + +SET search_path TO fkpart6; + +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a); + +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); + +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (1) TO (50); + +CREATE TABLE pk12 PARTITION OF pk1 FOR VALUES FROM (50) TO (100); + +CREATE TABLE fk (a int) PARTITION BY RANGE (a); + +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); + +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); + +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); + +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE CASCADE ON DELETE CASCADE; + +CREATE TABLE fk_d PARTITION OF fk DEFAULT; + +INSERT INTO pk VALUES (1); + +INSERT INTO fk VALUES (1); + +UPDATE pk SET a = 20; + +SELECT tableoid::regclass, * FROM fk; + +DELETE FROM pk WHERE a = 20; + +SELECT tableoid::regclass, * FROM fk; + +DROP TABLE fk; + +TRUNCATE TABLE pk; + +INSERT INTO pk VALUES (20), (50); + +CREATE TABLE fk (a int) PARTITION BY RANGE (a); + +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); + +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); + +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); + +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET NULL ON DELETE SET NULL; + +CREATE TABLE fk_d PARTITION OF fk DEFAULT; + +INSERT INTO fk VALUES (20), (50); + +UPDATE pk SET a = 21 WHERE a = 20; + +DELETE FROM pk WHERE a = 50; + +SELECT tableoid::regclass, * FROM fk; + +DROP TABLE fk; + +TRUNCATE TABLE pk; + +INSERT INTO pk VALUES (20), (30), (50); + +CREATE TABLE fk (id int, a int DEFAULT 50) PARTITION BY RANGE (a); + +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); + +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); + +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); + +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET DEFAULT ON DELETE SET DEFAULT; + +CREATE TABLE fk_d PARTITION OF fk DEFAULT; + +INSERT INTO fk VALUES (1, 20), (2, 30); + +DELETE FROM pk WHERE a = 20 RETURNING *; + +UPDATE pk SET a = 90 WHERE a = 30 RETURNING *; + +SELECT tableoid::regclass, * FROM fk; + +DROP TABLE fk; + +TRUNCATE TABLE pk; + +INSERT INTO pk VALUES (20), (30); + +CREATE TABLE fk (a int DEFAULT 50) PARTITION BY RANGE (a); + +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); + +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); + +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); + +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE RESTRICT ON DELETE RESTRICT; + +CREATE TABLE fk_d PARTITION OF fk DEFAULT; + +INSERT INTO fk VALUES (20), (30); + +DELETE FROM pk WHERE a = 20; + +UPDATE pk SET a = 90 WHERE a = 30; + +SELECT tableoid::regclass, * FROM fk; + +DROP TABLE fk; + +CREATE SCHEMA fkpart7 + +CREATE TABLE pkpart (a int) PARTITION BY LIST (a) + +CREATE TABLE pkpart1 PARTITION OF pkpart FOR VALUES IN (1); + +ALTER TABLE fkpart7.pkpart1 ADD PRIMARY KEY (a); + +ALTER TABLE fkpart7.pkpart ADD PRIMARY KEY (a); + +CREATE TABLE fkpart7.fk (a int REFERENCES fkpart7.pkpart); + +DROP SCHEMA fkpart7 CASCADE; + +CREATE SCHEMA fkpart8 + +CREATE TABLE tbl1(f1 int PRIMARY KEY) + +CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) PARTITION BY RANGE(f1) + +CREATE TABLE tbl2_p1 PARTITION OF tbl2 FOR VALUES FROM (minvalue) TO (maxvalue); + +INSERT INTO fkpart8.tbl1 VALUES(1); + +BEGIN; + +INSERT INTO fkpart8.tbl2 VALUES(1); + +ALTER TABLE fkpart8.tbl2 DROP CONSTRAINT tbl2_f1_fkey; + +COMMIT; + +DROP SCHEMA fkpart8 CASCADE; + +CREATE SCHEMA fkpart9 + +CREATE TABLE pk (a INT PRIMARY KEY) PARTITION BY RANGE (a) + +CREATE TABLE fk ( + fk_a INT REFERENCES pk(a) ON DELETE CASCADE + ) + +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (30) TO (50) PARTITION BY RANGE (a) + +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (30) TO (40); + +INSERT INTO fkpart9.pk VALUES (35); + +INSERT INTO fkpart9.fk VALUES (35); + +DELETE FROM fkpart9.pk WHERE a=35; + +SELECT * FROM fkpart9.pk; + +SELECT * FROM fkpart9.fk; + +DROP SCHEMA fkpart9 CASCADE; + +CREATE SCHEMA fkpart10 + +CREATE TABLE tbl1(f1 int PRIMARY KEY) PARTITION BY RANGE(f1) + +CREATE TABLE tbl1_p1 PARTITION OF tbl1 FOR VALUES FROM (minvalue) TO (1) + +CREATE TABLE tbl1_p2 PARTITION OF tbl1 FOR VALUES FROM (1) TO (maxvalue) + +CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) + +CREATE TABLE tbl3(f1 int PRIMARY KEY) PARTITION BY RANGE(f1) + +CREATE TABLE tbl3_p1 PARTITION OF tbl3 FOR VALUES FROM (minvalue) TO (1) + +CREATE TABLE tbl3_p2 PARTITION OF tbl3 FOR VALUES FROM (1) TO (maxvalue) + +CREATE TABLE tbl4(f1 int REFERENCES tbl3 DEFERRABLE INITIALLY DEFERRED); + +INSERT INTO fkpart10.tbl1 VALUES (0), (1); + +INSERT INTO fkpart10.tbl2 VALUES (0), (1); + +INSERT INTO fkpart10.tbl3 VALUES (-2), (-1), (0); + +INSERT INTO fkpart10.tbl4 VALUES (-2), (-1); + +BEGIN; + +DELETE FROM fkpart10.tbl1 WHERE f1 = 0; + +UPDATE fkpart10.tbl1 SET f1 = 2 WHERE f1 = 1; + +INSERT INTO fkpart10.tbl1 VALUES (0), (1); + +COMMIT; + +BEGIN; + +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0; + +UPDATE fkpart10.tbl3 SET f1 = f1 * -1; + +INSERT INTO fkpart10.tbl1 VALUES (4); + +COMMIT; + +BEGIN; + +UPDATE fkpart10.tbl3 SET f1 = f1 * -1; + +UPDATE fkpart10.tbl3 SET f1 = f1 + 3; + +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0; + +INSERT INTO fkpart10.tbl1 VALUES (0); + +COMMIT; + +BEGIN; + +UPDATE fkpart10.tbl3 SET f1 = f1 * -1; + +UPDATE fkpart10.tbl1 SET f1 = 3 WHERE f1 = 0; + +INSERT INTO fkpart10.tbl1 VALUES (0); + +INSERT INTO fkpart10.tbl3 VALUES (-2), (-1); + +COMMIT; + +CREATE TABLE fkpart10.tbl5(f1 int REFERENCES fkpart10.tbl3); + +INSERT INTO fkpart10.tbl5 VALUES (-2), (-1); + +BEGIN; + +UPDATE fkpart10.tbl3 SET f1 = f1 * -3; + +COMMIT; + +DELETE FROM fkpart10.tbl5; + +INSERT INTO fkpart10.tbl5 VALUES (0); + +BEGIN; + +UPDATE fkpart10.tbl3 SET f1 = f1 * -3; + +COMMIT; + +DROP SCHEMA fkpart10 CASCADE; + +CREATE SCHEMA fkpart11 + +CREATE TABLE pk (a INT PRIMARY KEY, b text) PARTITION BY LIST (a) + +CREATE TABLE fk ( + a INT, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES pk(a) ON UPDATE CASCADE ON DELETE CASCADE + ) + +CREATE TABLE fk_parted ( + a INT PRIMARY KEY, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES pk(a) ON UPDATE CASCADE ON DELETE CASCADE + ) PARTITION BY LIST (a) + +CREATE TABLE fk_another ( + a INT, + CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fk_parted (a) ON UPDATE CASCADE ON DELETE CASCADE + ) + +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1, 2) PARTITION BY LIST (a) + +CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (3) + +CREATE TABLE pk3 PARTITION OF pk FOR VALUES IN (4) + +CREATE TABLE fk1 PARTITION OF fk_parted FOR VALUES IN (1, 2) + +CREATE TABLE fk2 PARTITION OF fk_parted FOR VALUES IN (3) + +CREATE TABLE fk3 PARTITION OF fk_parted FOR VALUES IN (4); + +CREATE TABLE fkpart11.pk11 (b text, a int NOT NULL); + +ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk11 FOR VALUES IN (1); + +CREATE TABLE fkpart11.pk12 (b text, c int, a int NOT NULL); + +ALTER TABLE fkpart11.pk12 DROP c; + +ALTER TABLE fkpart11.pk1 ATTACH PARTITION fkpart11.pk12 FOR VALUES IN (2); + +INSERT INTO fkpart11.pk VALUES (1, 'xxx'), (3, 'yyy'); + +INSERT INTO fkpart11.fk VALUES (1), (3); + +INSERT INTO fkpart11.fk_parted VALUES (1), (3); + +INSERT INTO fkpart11.fk_another VALUES (1), (3); + +UPDATE fkpart11.pk SET a = a + 1 RETURNING tableoid::pg_catalog.regclass, *; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another; + +ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey; + +DELETE FROM fkpart11.fk WHERE a = 4; + +ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk1 (a) ON UPDATE CASCADE ON DELETE CASCADE; + +UPDATE fkpart11.pk SET a = a - 1; + +UPDATE fkpart11.pk1 SET a = a - 1; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.pk; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_parted; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk_another; + +ALTER TABLE fkpart11.fk DROP CONSTRAINT fkey; + +ALTER TABLE fkpart11.fk ADD CONSTRAINT fkey FOREIGN KEY (a) REFERENCES fkpart11.pk11 (a) ON UPDATE CASCADE ON DELETE CASCADE; + +UPDATE fkpart11.pk SET a = a + 1 WHERE a = 1; + +SELECT tableoid::pg_catalog.regclass, * FROM fkpart11.fk; + +DROP TABLE fkpart11.fk; + +CREATE FUNCTION fkpart11.print_row () RETURNS TRIGGER LANGUAGE plpgsql AS $$ + BEGIN + RAISE NOTICE 'TABLE: %, OP: %, OLD: %, NEW: %', TG_RELNAME, TG_OP, OLD, NEW; + RETURN NULL; + END; +$$; + +CREATE TRIGGER trig_upd_pk AFTER UPDATE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row(); + +CREATE TRIGGER trig_del_pk AFTER DELETE ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row(); + +CREATE TRIGGER trig_ins_pk AFTER INSERT ON fkpart11.pk FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row(); + +CREATE CONSTRAINT TRIGGER trig_upd_fk_parted AFTER UPDATE ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row(); + +CREATE CONSTRAINT TRIGGER trig_del_fk_parted AFTER DELETE ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row(); + +CREATE CONSTRAINT TRIGGER trig_ins_fk_parted AFTER INSERT ON fkpart11.fk_parted INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION fkpart11.print_row(); + +UPDATE fkpart11.pk SET a = 3 WHERE a = 4; + +UPDATE fkpart11.pk SET a = 1 WHERE a = 2; + +DROP SCHEMA fkpart11 CASCADE; + +CREATE SCHEMA fkpart12 + +CREATE TABLE fk_p ( id int, jd int, PRIMARY KEY(id, jd)) PARTITION BY list (id) + +CREATE TABLE fk_p_1 PARTITION OF fk_p FOR VALUES IN (1) PARTITION BY list (jd) + +CREATE TABLE fk_p_1_1 PARTITION OF fk_p_1 FOR VALUES IN (1) + +CREATE TABLE fk_p_1_2 (x int, y int, jd int NOT NULL, id int NOT NULL) + +CREATE TABLE fk_p_2 PARTITION OF fk_p FOR VALUES IN (2) PARTITION BY list (jd) + +CREATE TABLE fk_p_2_1 PARTITION OF fk_p_2 FOR VALUES IN (1) + +CREATE TABLE fk_p_2_2 PARTITION OF fk_p_2 FOR VALUES IN (2) + +CREATE TABLE fk_r_1 ( p_jd int NOT NULL, x int, id int PRIMARY KEY, p_id int NOT NULL) + +CREATE TABLE fk_r_2 ( id int PRIMARY KEY, p_id int NOT NULL, p_jd int NOT NULL) PARTITION BY list (id) + +CREATE TABLE fk_r_2_1 PARTITION OF fk_r_2 FOR VALUES IN (2, 1) + +CREATE TABLE fk_r ( id int PRIMARY KEY, p_id int NOT NULL, p_jd int NOT NULL, + FOREIGN KEY (p_id, p_jd) REFERENCES fk_p (id, jd) + ) PARTITION BY list (id); + +SET search_path TO fkpart12; + +ALTER TABLE fk_p_1_2 DROP COLUMN x, DROP COLUMN y; + +ALTER TABLE fk_p_1 ATTACH PARTITION fk_p_1_2 FOR VALUES IN (2); + +ALTER TABLE fk_r_1 DROP COLUMN x; + +INSERT INTO fk_p VALUES (1, 1); + +ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1); + +ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2); + +INSERT INTO fk_r VALUES (1, 1, 1); + +INSERT INTO fk_r VALUES (2, 2, 1); + +ALTER TABLE fk_r DETACH PARTITION fk_r_1; + +ALTER TABLE fk_r DETACH PARTITION fk_r_2; + +INSERT INTO fk_r_1 (id, p_id, p_jd) VALUES (2, 1, 2); + +DELETE FROM fk_p; + +ALTER TABLE fk_r ATTACH PARTITION fk_r_1 FOR VALUES IN (1); + +ALTER TABLE fk_r ATTACH PARTITION fk_r_2 FOR VALUES IN (2); + +DELETE FROM fk_p; + +ALTER TABLE fk_r_1 DROP CONSTRAINT fk_r_p_id_p_jd_fkey; + +ALTER TABLE fk_r DROP CONSTRAINT fk_r_p_id_p_jd_fkey_1; + +ALTER TABLE fk_r_2 DROP CONSTRAINT fk_r_p_id_p_jd_fkey; + +SET client_min_messages TO warning; + +DROP SCHEMA fkpart12 CASCADE; + +RESET client_min_messages; + +RESET search_path; diff --git a/crates/pgt_pretty_print/tests/data/multi/functional_deps_60.sql b/crates/pgt_pretty_print/tests/data/multi/functional_deps_60.sql new file mode 100644 index 000000000..813711060 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/functional_deps_60.sql @@ -0,0 +1,166 @@ +CREATE TEMP TABLE articles ( + id int CONSTRAINT articles_pkey PRIMARY KEY, + keywords text, + title text UNIQUE NOT NULL, + body text UNIQUE, + created date +); + +CREATE TEMP TABLE articles_in_category ( + article_id int, + category_id int, + changed date, + PRIMARY KEY (article_id, category_id) +); + +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id; + +SELECT id, keywords, title, body, created +FROM articles +GROUP BY title; + +SELECT id, keywords, title, body, created +FROM articles +GROUP BY body; + +SELECT id, keywords, title, body, created +FROM articles +GROUP BY keywords; + +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a, articles_in_category AS aic +WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138) +GROUP BY a.id; + +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a, articles_in_category AS aic +WHERE a.id = aic.article_id AND aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id, aic.category_id; + +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY a.id; + +SELECT a.id, a.keywords, a.title, a.body, a.created +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id, aic.category_id; + +SELECT aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.category_id, aic.article_id; + +SELECT aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY aic.article_id; + +CREATE TEMP TABLE products (product_id int, name text, price numeric); + +CREATE TEMP TABLE sales (product_id int, units int); + +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id, p.name, p.price; + +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id; + +ALTER TABLE products ADD PRIMARY KEY (product_id); + +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id; + +CREATE TEMP TABLE node ( + nid SERIAL, + vid integer NOT NULL default '0', + type varchar(32) NOT NULL default '', + title varchar(128) NOT NULL default '', + uid integer NOT NULL default '0', + status integer NOT NULL default '1', + created integer NOT NULL default '0', + -- snip + PRIMARY KEY (nid, vid) +); + +CREATE TEMP TABLE users ( + uid integer NOT NULL default '0', + name varchar(60) NOT NULL default '', + pass varchar(32) NOT NULL default '', + -- snip + PRIMARY KEY (uid), + UNIQUE (name) +); + +SELECT u.uid, u.name FROM node n +INNER JOIN users u ON u.uid = n.uid +WHERE n.type = 'blog' AND n.status = 1 +GROUP BY u.uid, u.name; + +SELECT u.uid, u.name FROM node n +INNER JOIN users u ON u.uid = n.uid +WHERE n.type = 'blog' AND n.status = 1 +GROUP BY u.uid; + +CREATE TEMP VIEW fdv1 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY body; + +CREATE TEMP VIEW fdv1 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id; + +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; + +DROP VIEW fdv1; + +CREATE TEMP VIEW fdv2 AS +SELECT a.id, a.keywords, a.title, aic.category_id, aic.changed +FROM articles AS a JOIN articles_in_category AS aic ON a.id = aic.article_id +WHERE aic.category_id in (14,62,70,53,138) +GROUP BY a.id, aic.category_id, aic.article_id; + +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; + +ALTER TABLE articles_in_category DROP CONSTRAINT articles_in_category_pkey RESTRICT; + +DROP VIEW fdv2; + +CREATE TEMP VIEW fdv3 AS +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id +UNION +SELECT id, keywords, title, body, created +FROM articles +GROUP BY id; + +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; + +DROP VIEW fdv3; + +CREATE TEMP VIEW fdv4 AS +SELECT * FROM articles WHERE title IN (SELECT title FROM articles GROUP BY id); + +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; + +DROP VIEW fdv4; + +PREPARE foo AS + SELECT id, keywords, title, body, created + FROM articles + GROUP BY id; + +EXECUTE foo; + +ALTER TABLE articles DROP CONSTRAINT articles_pkey RESTRICT; + +EXECUTE foo; diff --git a/crates/pgt_pretty_print/tests/data/multi/generated_stored_60.sql b/crates/pgt_pretty_print/tests/data/multi/generated_stored_60.sql new file mode 100644 index 000000000..70332d409 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/generated_stored_60.sql @@ -0,0 +1,899 @@ +CREATE SCHEMA generated_stored_tests; + +GRANT USAGE ON SCHEMA generated_stored_tests TO PUBLIC; + +SET search_path = generated_stored_tests; + +CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED); + +CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); + +SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_schema = 'generated_stored_tests' ORDER BY 1, 2; + +SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage WHERE table_schema = 'generated_stored_tests' ORDER BY 1, 2, 3; + +CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED); + +CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED); + +CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED); + +CREATE TABLE gtest_err_2c (a int PRIMARY KEY, + b int GENERATED ALWAYS AS (num_nulls(gtest_err_2c)) STORED); + +CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED); + +CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED); + +CREATE TABLE gtest2 (a int, b text GENERATED ALWAYS AS (a || ' sec') STORED); + +DROP TABLE gtest2; + +CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED); + +CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED); + +CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED); + +CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED); + +CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED); + +CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED); + +CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED); + +INSERT INTO gtest1 VALUES (1); + +INSERT INTO gtest1 VALUES (2, DEFAULT); + +INSERT INTO gtest1 VALUES (3, 33); + +INSERT INTO gtest1 VALUES (3, 33), (4, 44); + +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, 44); + +INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT); + +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT); + +SELECT * FROM gtest1 ORDER BY a; + +SELECT gtest1 FROM gtest1 ORDER BY a; + +SELECT a, (SELECT gtest1.b) FROM gtest1 ORDER BY a; + +DELETE FROM gtest1 WHERE a >= 3; + +UPDATE gtest1 SET b = DEFAULT WHERE a = 1; + +UPDATE gtest1 SET b = 11 WHERE a = 1; + +SELECT * FROM gtest1 ORDER BY a; + +SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a; + +SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a; + +INSERT INTO gtest1 VALUES (2000000000); + +SELECT * FROM gtest1; + +DELETE FROM gtest1 WHERE a = 2000000000; + +CREATE TABLE gtestx (x int, y int); + +INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3); + +SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a; + +DROP TABLE gtestx; + +SELECT * FROM gtest1 ORDER BY a; + +UPDATE gtest1 SET a = 3 WHERE b = 4 RETURNING old.*, new.*; + +SELECT * FROM gtest1 ORDER BY a; + +DELETE FROM gtest1 WHERE b = 2; + +SELECT * FROM gtest1 ORDER BY a; + +CREATE TABLE gtestm ( + id int PRIMARY KEY, + f1 int, + f2 int, + f3 int GENERATED ALWAYS AS (f1 * 2) STORED, + f4 int GENERATED ALWAYS AS (f2 * 2) STORED +); + +INSERT INTO gtestm VALUES (1, 5, 100); + +SELECT * FROM gtestm ORDER BY id; + +DROP TABLE gtestm; + +CREATE TABLE gtestm ( + a int PRIMARY KEY, + b int GENERATED ALWAYS AS (a * 2) STORED +); + +INSERT INTO gtestm (a) SELECT g FROM generate_series(1, 10) g; + +DROP TABLE gtestm; + +CREATE VIEW gtest1v AS SELECT * FROM gtest1; + +SELECT * FROM gtest1v; + +INSERT INTO gtest1v VALUES (4, 8); + +INSERT INTO gtest1v VALUES (5, DEFAULT); + +INSERT INTO gtest1v VALUES (6, 66), (7, 77); + +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, 77); + +INSERT INTO gtest1v VALUES (6, 66), (7, DEFAULT); + +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, DEFAULT); + +ALTER VIEW gtest1v ALTER COLUMN b SET DEFAULT 100; + +INSERT INTO gtest1v VALUES (8, DEFAULT); + +INSERT INTO gtest1v VALUES (8, DEFAULT), (9, DEFAULT); + +SELECT * FROM gtest1v; + +DELETE FROM gtest1v WHERE a >= 5; + +DROP VIEW gtest1v; + +WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo; + +CREATE TABLE gtest1_1 () INHERITS (gtest1); + +SELECT * FROM gtest1_1; + +INSERT INTO gtest1_1 VALUES (4); + +SELECT * FROM gtest1_1; + +SELECT * FROM gtest1; + +CREATE TABLE gtest_normal (a int, b int); + +CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED) INHERITS (gtest_normal); + +CREATE TABLE gtest_normal_child (a int, b int GENERATED ALWAYS AS (a * 2) STORED); + +ALTER TABLE gtest_normal_child INHERIT gtest_normal; + +DROP TABLE gtest_normal, gtest_normal_child; + +CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1); + +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1); + +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1); + +INSERT INTO gtestx (a, x) VALUES (11, 22); + +SELECT * FROM gtest1; + +SELECT * FROM gtestx; + +CREATE TABLE gtestxx_1 (a int NOT NULL, b int); + +ALTER TABLE gtestxx_1 INHERIT gtest1; + +CREATE TABLE gtestxx_3 (a int NOT NULL, b int GENERATED ALWAYS AS (a * 2) STORED); + +ALTER TABLE gtestxx_3 INHERIT gtest1; + +CREATE TABLE gtestxx_4 (b int GENERATED ALWAYS AS (a * 2) STORED, a int NOT NULL); + +ALTER TABLE gtestxx_4 INHERIT gtest1; + +CREATE TABLE gtesty (x int, b int DEFAULT 55); + +CREATE TABLE gtest1_y () INHERITS (gtest0, gtesty); + +DROP TABLE gtesty; + +CREATE TABLE gtesty (x int, b int); + +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty); + +DROP TABLE gtesty; + +CREATE TABLE gtesty (x int, b int GENERATED ALWAYS AS (x * 22) STORED); + +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty); + +CREATE TABLE gtest1_y (b int GENERATED ALWAYS AS (x + 1) STORED) INHERITS (gtest1, gtesty); + +CREATE TABLE gtestp (f1 int); + +CREATE TABLE gtestc (f2 int GENERATED ALWAYS AS (f1+1) STORED) INHERITS(gtestp); + +INSERT INTO gtestc values(42); + +TABLE gtestc; + +UPDATE gtestp SET f1 = f1 * 10; + +TABLE gtestc; + +DROP TABLE gtestp CASCADE; + +CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED); + +INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL); + +SELECT * FROM gtest3 ORDER BY a; + +UPDATE gtest3 SET a = 22 WHERE a = 2; + +SELECT * FROM gtest3 ORDER BY a; + +CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS (a || '+' || a) STORED); + +INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL); + +SELECT * FROM gtest3a ORDER BY a; + +UPDATE gtest3a SET a = 'bb' WHERE a = 'b'; + +SELECT * FROM gtest3a ORDER BY a; + +TRUNCATE gtest1; + +INSERT INTO gtest1 (a) VALUES (1), (2); + +COPY gtest1 TO stdout; + +COPY gtest1 (a, b) TO stdout; + +SELECT * FROM gtest1 ORDER BY a; + +TRUNCATE gtest3; + +INSERT INTO gtest3 (a) VALUES (1), (2); + +COPY gtest3 TO stdout; + +COPY gtest3 (a, b) TO stdout; + +SELECT * FROM gtest3 ORDER BY a; + +CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED); + +INSERT INTO gtest2 VALUES (1); + +SELECT * FROM gtest2; + +CREATE TABLE gtest_varlena (a varchar, b varchar GENERATED ALWAYS AS (a) STORED); + +INSERT INTO gtest_varlena (a) VALUES('01234567890123456789'); + +INSERT INTO gtest_varlena (a) VALUES(NULL); + +SELECT * FROM gtest_varlena ORDER BY a; + +DROP TABLE gtest_varlena; + +CREATE TYPE double_int as (a int, b int); + +CREATE TABLE gtest4 ( + a int, + b double_int GENERATED ALWAYS AS ((a * 2, a * 3)) STORED +); + +INSERT INTO gtest4 VALUES (1), (6); + +SELECT * FROM gtest4; + +DROP TABLE gtest4; + +DROP TYPE double_int; + +CREATE TABLE gtest_tableoid ( + a int PRIMARY KEY, + b bool GENERATED ALWAYS AS (tableoid = 'gtest_tableoid'::regclass) STORED +); + +INSERT INTO gtest_tableoid VALUES (1), (2); + +ALTER TABLE gtest_tableoid ADD COLUMN + c regclass GENERATED ALWAYS AS (tableoid) STORED; + +SELECT * FROM gtest_tableoid; + +CREATE TABLE gtest10 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); + +ALTER TABLE gtest10 DROP COLUMN b; + +ALTER TABLE gtest10 DROP COLUMN b CASCADE; + +CREATE TABLE gtest10a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); + +ALTER TABLE gtest10a DROP COLUMN b; + +INSERT INTO gtest10a (a) VALUES (1); + +CREATE USER regress_user11; + +CREATE TABLE gtest11 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); + +INSERT INTO gtest11 VALUES (1, 10), (2, 20); + +GRANT SELECT (a, c) ON gtest11 TO regress_user11; + +CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE SQL; + +REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC; + +CREATE TABLE gtest12 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED); + +INSERT INTO gtest12 VALUES (1, 10), (2, 20); + +GRANT SELECT (a, c), INSERT ON gtest12 TO regress_user11; + +SET ROLE regress_user11; + +SELECT a, b FROM gtest11; + +SELECT a, c FROM gtest11; + +SELECT gf1(10); + +INSERT INTO gtest12 VALUES (3, 30), (4, 40); + +SELECT a, c FROM gtest12; + +RESET ROLE; + +DROP FUNCTION gf1(int); + +DROP TABLE gtest11, gtest12; + +DROP FUNCTION gf1(int); + +DROP USER regress_user11; + +CREATE TABLE gtest20 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED CHECK (b < 50)); + +INSERT INTO gtest20 (a) VALUES (10); + +INSERT INTO gtest20 (a) VALUES (30); + +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); + +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); + +CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); + +INSERT INTO gtest20a (a) VALUES (10); + +INSERT INTO gtest20a (a) VALUES (30); + +ALTER TABLE gtest20a ADD CHECK (b < 50); + +ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 50); + +ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 61); + +CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); + +INSERT INTO gtest20b (a) VALUES (10); + +INSERT INTO gtest20b (a) VALUES (30); + +ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID; + +ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; + +CREATE TABLE gtest20c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); + +ALTER TABLE gtest20c ADD CONSTRAINT whole_row_check CHECK (gtest20c IS NOT NULL); + +INSERT INTO gtest20c VALUES (1); + +INSERT INTO gtest20c VALUES (NULL); + +CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); + +INSERT INTO gtest21a (a) VALUES (1); + +INSERT INTO gtest21a (a) VALUES (0); + +CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED); + +ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL; + +INSERT INTO gtest21b (a) VALUES (1); + +INSERT INTO gtest21b (a) VALUES (0); + +ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL; + +INSERT INTO gtest21b (a) VALUES (0); + +CREATE TABLE gtest22a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a / 2) STORED UNIQUE); + +INSERT INTO gtest22a VALUES (2); + +INSERT INTO gtest22a VALUES (3); + +INSERT INTO gtest22a VALUES (4); + +CREATE TABLE gtest22b (a int, b int GENERATED ALWAYS AS (a / 2) STORED, PRIMARY KEY (a, b)); + +INSERT INTO gtest22b VALUES (2); + +INSERT INTO gtest22b VALUES (2); + +CREATE TABLE gtest22c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); + +CREATE INDEX gtest22c_b_idx ON gtest22c (b); + +CREATE INDEX gtest22c_expr_idx ON gtest22c ((b * 3)); + +CREATE INDEX gtest22c_pred_idx ON gtest22c (a) WHERE b > 0; + +INSERT INTO gtest22c VALUES (1), (2), (3); + +SET enable_seqscan TO off; + +SET enable_bitmapscan TO off; + +SELECT * FROM gtest22c WHERE b = 4; + +SELECT * FROM gtest22c WHERE b = 4; + +SELECT * FROM gtest22c WHERE b * 3 = 6; + +SELECT * FROM gtest22c WHERE b * 3 = 6; + +SELECT * FROM gtest22c WHERE a = 1 AND b > 0; + +SELECT * FROM gtest22c WHERE a = 1 AND b > 0; + +ALTER TABLE gtest22c ALTER COLUMN b SET EXPRESSION AS (a * 4); + +ANALYZE gtest22c; + +SELECT * FROM gtest22c WHERE b = 8; + +SELECT * FROM gtest22c WHERE b = 8; + +SELECT * FROM gtest22c WHERE b * 3 = 12; + +SELECT * FROM gtest22c WHERE b * 3 = 12; + +SELECT * FROM gtest22c WHERE a = 1 AND b > 0; + +SELECT * FROM gtest22c WHERE a = 1 AND b > 0; + +RESET enable_seqscan; + +RESET enable_bitmapscan; + +CREATE TABLE gtest23a (x int PRIMARY KEY, y int); + +INSERT INTO gtest23a VALUES (1, 11), (2, 22), (3, 33); + +CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON UPDATE CASCADE); + +CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON DELETE SET NULL); + +CREATE TABLE gtest23b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x)); + +INSERT INTO gtest23b VALUES (1); + +INSERT INTO gtest23b VALUES (5); + +ALTER TABLE gtest23b ALTER COLUMN b SET EXPRESSION AS (a * 5); + +ALTER TABLE gtest23b ALTER COLUMN b SET EXPRESSION AS (a * 1); + +DROP TABLE gtest23b; + +DROP TABLE gtest23a; + +CREATE TABLE gtest23p (x int, y int GENERATED ALWAYS AS (x * 2) STORED, PRIMARY KEY (y)); + +INSERT INTO gtest23p VALUES (1), (2), (3); + +CREATE TABLE gtest23q (a int PRIMARY KEY, b int REFERENCES gtest23p (y)); + +INSERT INTO gtest23q VALUES (1, 2); + +INSERT INTO gtest23q VALUES (2, 5); + +CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10); + +CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * 2) STORED); + +INSERT INTO gtest24 (a) VALUES (4); + +INSERT INTO gtest24 (a) VALUES (6); + +CREATE TYPE gtestdomain1range AS range (subtype = gtestdomain1); + +CREATE TABLE gtest24r (a int PRIMARY KEY, b gtestdomain1range GENERATED ALWAYS AS (gtestdomain1range(a, a + 5)) STORED); + +INSERT INTO gtest24r (a) VALUES (4); + +INSERT INTO gtest24r (a) VALUES (6); + +CREATE DOMAIN gtestdomainnn AS int CHECK (VALUE IS NOT NULL); + +CREATE TABLE gtest24nn (a int, b gtestdomainnn GENERATED ALWAYS AS (a * 2) STORED); + +INSERT INTO gtest24nn (a) VALUES (4); + +INSERT INTO gtest24nn (a) VALUES (NULL); + +CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint); + +CREATE TABLE gtest28 OF gtest_type (f1 WITH OPTIONS GENERATED ALWAYS AS (f2 *2) STORED); + +DROP TYPE gtest_type CASCADE; + +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint) PARTITION BY RANGE (f1); + +CREATE TABLE gtest_child PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 2) STORED +) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); + +CREATE TABLE gtest_child (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); + +DROP TABLE gtest_parent, gtest_child; + +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f1); + +CREATE TABLE gtest_child PARTITION OF gtest_parent + FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); + +CREATE TABLE gtest_child2 PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 22) STORED -- overrides gen expr +) FOR VALUES FROM ('2016-08-01') TO ('2016-09-01'); + +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 DEFAULT 42 -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint DEFAULT 42); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS IDENTITY); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 33) STORED); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1); + +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 2); + +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-08-15', 3); + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +SELECT tableoid::regclass, * FROM gtest_child ORDER BY 1, 2, 3; + +SELECT tableoid::regclass, * FROM gtest_child2 ORDER BY 1, 2, 3; + +SELECT tableoid::regclass, * FROM gtest_child3 ORDER BY 1, 2, 3; + +UPDATE gtest_parent SET f1 = f1 + 60 WHERE f2 = 1; + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +ALTER TABLE ONLY gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 4); + +ALTER TABLE gtest_child ALTER COLUMN f3 SET EXPRESSION AS (f2 * 10); + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +ALTER TABLE gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 2); + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +CREATE TABLE gtest_part_key (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3); + +CREATE TABLE gtest_part_key (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3)); + +CREATE TABLE gtest25 (a int PRIMARY KEY); + +INSERT INTO gtest25 VALUES (3), (4); + +ALTER TABLE gtest25 ADD COLUMN b int GENERATED ALWAYS AS (a * 2) STORED, ALTER COLUMN b SET EXPRESSION AS (a * 3); + +SELECT * FROM gtest25 ORDER BY a; + +ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (b * 4) STORED; + +ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; + +ALTER TABLE gtest25 ADD COLUMN c int DEFAULT 42, + ADD COLUMN x int GENERATED ALWAYS AS (c * 4) STORED; + +ALTER TABLE gtest25 ADD COLUMN d int DEFAULT 101; + +ALTER TABLE gtest25 ALTER COLUMN d SET DATA TYPE float8, + ADD COLUMN y float8 GENERATED ALWAYS AS (d * 4) STORED; + +SELECT * FROM gtest25 ORDER BY a; + +CREATE TABLE gtest27 ( + a int, + b int, + x int GENERATED ALWAYS AS ((a + b) * 2) STORED +); + +INSERT INTO gtest27 (a, b) VALUES (3, 7), (4, 11); + +ALTER TABLE gtest27 ALTER COLUMN a TYPE text; + +ALTER TABLE gtest27 ALTER COLUMN x TYPE numeric; + +SELECT * FROM gtest27; + +ALTER TABLE gtest27 ALTER COLUMN x TYPE boolean USING x <> 0; + +ALTER TABLE gtest27 ALTER COLUMN x DROP DEFAULT; + +ALTER TABLE gtest27 + DROP COLUMN x, + ALTER COLUMN a TYPE bigint, + ALTER COLUMN b TYPE bigint, + ADD COLUMN x bigint GENERATED ALWAYS AS ((a + b) * 2) STORED; + +ALTER TABLE gtest27 + ALTER COLUMN a TYPE float8, + ALTER COLUMN b TYPE float8; + +SELECT * FROM gtest27; + +CREATE TABLE gtest29 ( + a int, + b int GENERATED ALWAYS AS (a * 2) STORED +); + +INSERT INTO gtest29 (a) VALUES (3), (4); + +SELECT * FROM gtest29; + +ALTER TABLE gtest29 ALTER COLUMN a SET EXPRESSION AS (a * 3); + +ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION; + +ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION IF EXISTS; + +ALTER TABLE gtest29 ALTER COLUMN b SET EXPRESSION AS (a * 3); + +SELECT * FROM gtest29; + +ALTER TABLE gtest29 ALTER COLUMN b DROP EXPRESSION; + +INSERT INTO gtest29 (a) VALUES (5); + +INSERT INTO gtest29 (a, b) VALUES (6, 66); + +SELECT * FROM gtest29; + +ALTER TABLE gtest29 DROP COLUMN a; + +CREATE TABLE gtest30 ( + a int, + b int GENERATED ALWAYS AS (a * 2) STORED +); + +CREATE TABLE gtest30_1 () INHERITS (gtest30); + +ALTER TABLE gtest30 ALTER COLUMN b DROP EXPRESSION; + +DROP TABLE gtest30 CASCADE; + +CREATE TABLE gtest30 ( + a int, + b int GENERATED ALWAYS AS (a * 2) STORED +); + +CREATE TABLE gtest30_1 () INHERITS (gtest30); + +ALTER TABLE ONLY gtest30 ALTER COLUMN b DROP EXPRESSION; + +ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; + +CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text); + +CREATE TABLE gtest31_2 (x int, y gtest31_1); + +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; + +ALTER TABLE gtest31_2 ADD CONSTRAINT cc CHECK ((y).b IS NOT NULL); + +ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello1'); + +ALTER TABLE gtest31_2 DROP CONSTRAINT cc; + +CREATE STATISTICS gtest31_2_stat ON ((y).b is not null) FROM gtest31_2; + +ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello2'); + +DROP STATISTICS gtest31_2_stat; + +CREATE INDEX gtest31_2_y_idx ON gtest31_2(((y).b)); + +ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello3'); + +DROP TABLE gtest31_1, gtest31_2; + +CREATE TABLE gtest31_1 (a int, b text GENERATED ALWAYS AS ('hello') STORED, c text) PARTITION BY LIST (a); + +CREATE TABLE gtest31_2 (x int, y gtest31_1); + +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; + +DROP TABLE gtest31_1, gtest31_2; + +CREATE TABLE gtest26 ( + a int PRIMARY KEY, + b int GENERATED ALWAYS AS (a * 2) STORED +); + +CREATE FUNCTION gtest_trigger_func() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + IF tg_op IN ('DELETE', 'UPDATE') THEN + RAISE INFO '%: %: old = %', TG_NAME, TG_WHEN, OLD; + END IF; + IF tg_op IN ('INSERT', 'UPDATE') THEN + RAISE INFO '%: %: new = %', TG_NAME, TG_WHEN, NEW; + END IF; + IF tg_op = 'DELETE' THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; +END +$$; + +CREATE TRIGGER gtest1 BEFORE DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- error + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.* IS NOT NULL) -- error + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26 + FOR EACH ROW + WHEN (NEW.a < 0) + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest3 AFTER DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest4 AFTER INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +INSERT INTO gtest26 (a) VALUES (-2), (0), (3); + +SELECT * FROM gtest26 ORDER BY a; + +UPDATE gtest26 SET a = a * -2; + +SELECT * FROM gtest26 ORDER BY a; + +DELETE FROM gtest26 WHERE a = -6; + +SELECT * FROM gtest26 ORDER BY a; + +DROP TRIGGER gtest1 ON gtest26; + +DROP TRIGGER gtest2 ON gtest26; + +DROP TRIGGER gtest3 ON gtest26; + +CREATE FUNCTION gtest_trigger_func3() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'OK'; + RETURN NEW; +END +$$; + +CREATE TRIGGER gtest11 BEFORE UPDATE OF b ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func3(); + +UPDATE gtest26 SET a = 1 WHERE a = 0; + +DROP TRIGGER gtest11 ON gtest26; + +TRUNCATE gtest26; + +CREATE FUNCTION gtest_trigger_func4() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + NEW.a = 10; + NEW.b = 300; + RETURN NEW; +END; +$$; + +CREATE TRIGGER gtest12_01 BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest12_02 BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func4(); + +CREATE TRIGGER gtest12_03 BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); + +INSERT INTO gtest26 (a) VALUES (1); + +SELECT * FROM gtest26 ORDER BY a; + +UPDATE gtest26 SET a = 11 WHERE a = 10; + +SELECT * FROM gtest26 ORDER BY a; + +CREATE TABLE gtest28a ( + a int, + b int, + c int, + x int GENERATED ALWAYS AS (b * 2) STORED +); + +ALTER TABLE gtest28a DROP COLUMN a; + +CREATE TABLE gtest28b (LIKE gtest28a INCLUDING GENERATED); + +SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's', 'v'); diff --git a/crates/pgt_pretty_print/tests/data/multi/generated_virtual_60.sql b/crates/pgt_pretty_print/tests/data/multi/generated_virtual_60.sql new file mode 100644 index 000000000..e75352624 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/generated_virtual_60.sql @@ -0,0 +1,699 @@ +CREATE SCHEMA generated_virtual_tests; + +GRANT USAGE ON SCHEMA generated_virtual_tests TO PUBLIC; + +SET search_path = generated_virtual_tests; + +SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_schema = 'generated_virtual_tests' ORDER BY 1, 2; + +SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage WHERE table_schema = 'generated_virtual_tests' ORDER BY 1, 2, 3; + +DROP TABLE gtest2; + +INSERT INTO gtest1 VALUES (1); + +INSERT INTO gtest1 VALUES (2, DEFAULT); + +INSERT INTO gtest1 VALUES (3, 33); + +INSERT INTO gtest1 VALUES (3, 33), (4, 44); + +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, 44); + +INSERT INTO gtest1 VALUES (3, 33), (4, DEFAULT); + +INSERT INTO gtest1 VALUES (3, DEFAULT), (4, DEFAULT); + +SELECT * FROM gtest1 ORDER BY a; + +SELECT gtest1 FROM gtest1 ORDER BY a; + +SELECT a, (SELECT gtest1.b) FROM gtest1 ORDER BY a; + +DELETE FROM gtest1 WHERE a >= 3; + +UPDATE gtest1 SET b = DEFAULT WHERE a = 1; + +UPDATE gtest1 SET b = 11 WHERE a = 1; + +SELECT * FROM gtest1 ORDER BY a; + +SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a; + +SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a; + +INSERT INTO gtest1 VALUES (2000000000); + +SELECT * FROM gtest1; + +DELETE FROM gtest1 WHERE a = 2000000000; + +CREATE TABLE gtestx (x int, y int); + +INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3); + +SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a; + +DROP TABLE gtestx; + +SELECT * FROM gtest1 ORDER BY a; + +UPDATE gtest1 SET a = 3 WHERE b = 4 RETURNING old.*, new.*; + +SELECT * FROM gtest1 ORDER BY a; + +DELETE FROM gtest1 WHERE b = 2; + +SELECT * FROM gtest1 ORDER BY a; + +INSERT INTO gtestm VALUES (1, 5, 100); + +SELECT * FROM gtestm ORDER BY id; + +DROP TABLE gtestm; + +INSERT INTO gtestm (a) SELECT g FROM generate_series(1, 10) g; + +DROP TABLE gtestm; + +CREATE VIEW gtest1v AS SELECT * FROM gtest1; + +SELECT * FROM gtest1v; + +INSERT INTO gtest1v VALUES (4, 8); + +INSERT INTO gtest1v VALUES (5, DEFAULT); + +INSERT INTO gtest1v VALUES (6, 66), (7, 77); + +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, 77); + +INSERT INTO gtest1v VALUES (6, 66), (7, DEFAULT); + +INSERT INTO gtest1v VALUES (6, DEFAULT), (7, DEFAULT); + +ALTER VIEW gtest1v ALTER COLUMN b SET DEFAULT 100; + +INSERT INTO gtest1v VALUES (8, DEFAULT); + +INSERT INTO gtest1v VALUES (8, DEFAULT), (9, DEFAULT); + +SELECT * FROM gtest1v; + +DELETE FROM gtest1v WHERE a >= 5; + +DROP VIEW gtest1v; + +WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo; + +CREATE TABLE gtest1_1 () INHERITS (gtest1); + +SELECT * FROM gtest1_1; + +INSERT INTO gtest1_1 VALUES (4); + +SELECT * FROM gtest1_1; + +SELECT * FROM gtest1; + +CREATE TABLE gtest_normal (a int, b int); + +ALTER TABLE gtest_normal_child INHERIT gtest_normal; + +DROP TABLE gtest_normal, gtest_normal_child; + +CREATE TABLE gtestx (x int, b int DEFAULT 10) INHERITS (gtest1); + +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS IDENTITY) INHERITS (gtest1); + +CREATE TABLE gtestx (x int, b int GENERATED ALWAYS AS (a * 22) STORED) INHERITS (gtest1); + +INSERT INTO gtestx (a, x) VALUES (11, 22); + +SELECT * FROM gtest1; + +SELECT * FROM gtestx; + +CREATE TABLE gtestxx_1 (a int NOT NULL, b int); + +ALTER TABLE gtestxx_1 INHERIT gtest1; + +ALTER TABLE gtestxx_3 INHERIT gtest1; + +ALTER TABLE gtestxx_4 INHERIT gtest1; + +CREATE TABLE gtesty (x int, b int DEFAULT 55); + +CREATE TABLE gtest1_y () INHERITS (gtest0, gtesty); + +DROP TABLE gtesty; + +CREATE TABLE gtesty (x int, b int); + +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty); + +DROP TABLE gtesty; + +CREATE TABLE gtest1_y () INHERITS (gtest1, gtesty); + +CREATE TABLE gtestp (f1 int); + +INSERT INTO gtestc values(42); + +TABLE gtestc; + +UPDATE gtestp SET f1 = f1 * 10; + +TABLE gtestc; + +DROP TABLE gtestp CASCADE; + +INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL); + +SELECT * FROM gtest3 ORDER BY a; + +UPDATE gtest3 SET a = 22 WHERE a = 2; + +SELECT * FROM gtest3 ORDER BY a; + +INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL); + +SELECT * FROM gtest3a ORDER BY a; + +UPDATE gtest3a SET a = 'bb' WHERE a = 'b'; + +SELECT * FROM gtest3a ORDER BY a; + +TRUNCATE gtest1; + +INSERT INTO gtest1 (a) VALUES (1), (2); + +COPY gtest1 TO stdout; + +COPY gtest1 (a, b) TO stdout; + +SELECT * FROM gtest1 ORDER BY a; + +TRUNCATE gtest3; + +INSERT INTO gtest3 (a) VALUES (1), (2); + +COPY gtest3 TO stdout; + +COPY gtest3 (a, b) TO stdout; + +SELECT * FROM gtest3 ORDER BY a; + +INSERT INTO gtest2 VALUES (1); + +SELECT * FROM gtest2; + +INSERT INTO gtest_varlena (a) VALUES('01234567890123456789'); + +INSERT INTO gtest_varlena (a) VALUES(NULL); + +SELECT * FROM gtest_varlena ORDER BY a; + +DROP TABLE gtest_varlena; + +CREATE TYPE double_int as (a int, b int); + +DROP TYPE double_int; + +INSERT INTO gtest_tableoid VALUES (1), (2); + +SELECT * FROM gtest_tableoid; + +ALTER TABLE gtest10 DROP COLUMN b; + +ALTER TABLE gtest10 DROP COLUMN b CASCADE; + +ALTER TABLE gtest10a DROP COLUMN b; + +INSERT INTO gtest10a (a) VALUES (1); + +CREATE USER regress_user11; + +INSERT INTO gtest11 VALUES (1, 10), (2, 20); + +GRANT SELECT (a, c) ON gtest11 TO regress_user11; + +CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE SQL; + +REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC; + +SET ROLE regress_user11; + +SELECT a, b FROM gtest11; + +SELECT a, c FROM gtest11; + +SELECT gf1(10); + +RESET ROLE; + +DROP TABLE gtest11; + +DROP FUNCTION gf1(int); + +DROP USER regress_user11; + +INSERT INTO gtest20 (a) VALUES (10); + +INSERT INTO gtest20 (a) VALUES (30); + +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 100); + +ALTER TABLE gtest20 ALTER COLUMN b SET EXPRESSION AS (a * 3); + +INSERT INTO gtest20a (a) VALUES (10); + +INSERT INTO gtest20a (a) VALUES (30); + +ALTER TABLE gtest20a ADD CHECK (b < 50); + +ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 50); + +ALTER TABLE gtest20a ADD COLUMN c float8 DEFAULT random() CHECK (b < 61); + +INSERT INTO gtest20b (a) VALUES (10); + +INSERT INTO gtest20b (a) VALUES (30); + +ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID; + +ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; + +ALTER TABLE gtest20c ADD CONSTRAINT whole_row_check CHECK (gtest20c IS NOT NULL); + +INSERT INTO gtest20c VALUES (1); + +INSERT INTO gtest20c VALUES (NULL); + +INSERT INTO gtest21a (a) VALUES (1); + +INSERT INTO gtest21a (a) VALUES (0); + +INSERT INTO gtest21ax (a) VALUES (0); + +INSERT INTO gtest21ax (a) VALUES (1); + +ALTER TABLE gtest21ax ALTER COLUMN b SET EXPRESSION AS (nullif(a, 1)); + +DROP TABLE gtest21ax; + +INSERT INTO gtest21ax (a) VALUES (0); + +DROP TABLE gtest21ax; + +ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL; + +INSERT INTO gtest21b (a) VALUES (1); + +INSERT INTO gtest21b (a) VALUES (2), (0); + +INSERT INTO gtest21b (a) VALUES (NULL); + +ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL; + +INSERT INTO gtest21b (a) VALUES (0); + +CREATE TABLE gtestnn_child PARTITION OF gtestnn_parent FOR VALUES FROM (1) TO (5); + +CREATE TABLE gtestnn_childdef PARTITION OF gtestnn_parent default; + +INSERT INTO gtestnn_parent VALUES (2, 2, default), (3, 5, default), (14, 12, default); + +INSERT INTO gtestnn_parent VALUES (1, 2, default); + +INSERT INTO gtestnn_parent VALUES (2, 10, default); + +ALTER TABLE gtestnn_parent ALTER COLUMN f3 SET EXPRESSION AS (nullif(f1, 2) + nullif(f2, 11)); + +INSERT INTO gtestnn_parent VALUES (10, 11, default); + +SELECT * FROM gtestnn_parent ORDER BY f1, f2, f3; + +CREATE TABLE gtest23a (x int PRIMARY KEY, y int); + +CREATE TABLE gtest23q (a int PRIMARY KEY, b int REFERENCES gtest23p (y)); + +CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10); + +CREATE TYPE gtestdomain1range AS range (subtype = gtestdomain1); + +CREATE TABLE gtest24at (a int PRIMARY KEY); + +ALTER TABLE gtest24ata ALTER COLUMN b TYPE gtestdomain1; + +CREATE DOMAIN gtestdomainnn AS int CHECK (VALUE IS NOT NULL); + +CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint); + +DROP TYPE gtest_type CASCADE; + +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint) PARTITION BY RANGE (f1); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); + +DROP TABLE gtest_parent, gtest_child; + +CREATE TABLE gtest_child PARTITION OF gtest_parent + FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); + +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 DEFAULT 42 -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 GENERATED ALWAYS AS (f2 * 2) STORED -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint DEFAULT 42); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS IDENTITY); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 33) STORED); + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +DROP TABLE gtest_child3; + +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); + +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1); + +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 2); + +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-08-15', 3); + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +SELECT tableoid::regclass, * FROM gtest_child ORDER BY 1, 2, 3; + +SELECT tableoid::regclass, * FROM gtest_child2 ORDER BY 1, 2, 3; + +SELECT tableoid::regclass, * FROM gtest_child3 ORDER BY 1, 2, 3; + +UPDATE gtest_parent SET f1 = f1 + 60 WHERE f2 = 1; + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +ALTER TABLE ONLY gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 4); + +ALTER TABLE gtest_child ALTER COLUMN f3 SET EXPRESSION AS (f2 * 10); + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +ALTER TABLE gtest_parent ALTER COLUMN f3 SET EXPRESSION AS (f2 * 2); + +SELECT tableoid::regclass, * FROM gtest_parent ORDER BY 1, 2, 3; + +CREATE TABLE gtest25 (a int PRIMARY KEY); + +INSERT INTO gtest25 VALUES (3), (4); + +SELECT * FROM gtest25 ORDER BY a; + +ALTER TABLE gtest25 ADD COLUMN d int DEFAULT 101; + +SELECT * FROM gtest25 ORDER BY a; + +INSERT INTO gtest27 (a, b) VALUES (3, 7), (4, 11); + +ALTER TABLE gtest27 ALTER COLUMN a TYPE text; + +ALTER TABLE gtest27 ALTER COLUMN x TYPE numeric; + +SELECT * FROM gtest27; + +ALTER TABLE gtest27 ALTER COLUMN x TYPE boolean USING x <> 0; + +ALTER TABLE gtest27 ALTER COLUMN x DROP DEFAULT; + +INSERT INTO gtest27 (a, b) VALUES (NULL, NULL); + +DELETE FROM gtest27 WHERE a IS NULL AND b IS NULL; + +ALTER TABLE gtest27 + ALTER COLUMN a TYPE float8, + ALTER COLUMN b TYPE float8; + +SELECT * FROM gtest27; + +INSERT INTO gtest29 (a) VALUES (3), (4); + +SELECT * FROM gtest29; + +ALTER TABLE gtest29 ALTER COLUMN a SET EXPRESSION AS (a * 3); + +ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION; + +ALTER TABLE gtest29 ALTER COLUMN a DROP EXPRESSION IF EXISTS; + +ALTER TABLE gtest29 ALTER COLUMN b SET EXPRESSION AS (a * 3); + +SELECT * FROM gtest29; + +ALTER TABLE gtest29 ALTER COLUMN b DROP EXPRESSION; + +INSERT INTO gtest29 (a) VALUES (5); + +INSERT INTO gtest29 (a, b) VALUES (6, 66); + +SELECT * FROM gtest29; + +CREATE TABLE gtest30_1 () INHERITS (gtest30); + +ALTER TABLE gtest30 ALTER COLUMN b DROP EXPRESSION; + +DROP TABLE gtest30 CASCADE; + +CREATE TABLE gtest30_1 () INHERITS (gtest30); + +ALTER TABLE ONLY gtest30 ALTER COLUMN b DROP EXPRESSION; + +ALTER TABLE gtest30_1 ALTER COLUMN b DROP EXPRESSION; + +CREATE TABLE gtest31_2 (x int, y gtest31_1); + +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; + +ALTER TABLE gtest31_2 ADD CONSTRAINT cc CHECK ((y).b IS NOT NULL); + +ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello1'); + +ALTER TABLE gtest31_2 DROP CONSTRAINT cc; + +CREATE STATISTICS gtest31_2_stat ON ((y).b is not null) FROM gtest31_2; + +ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello2'); + +DROP STATISTICS gtest31_2_stat; + +CREATE INDEX gtest31_2_y_idx ON gtest31_2(((y).b)); + +ALTER TABLE gtest31_1 ALTER COLUMN b SET EXPRESSION AS ('hello3'); + +DROP TABLE gtest31_1, gtest31_2; + +CREATE TABLE gtest31_2 (x int, y gtest31_1); + +ALTER TABLE gtest31_1 ALTER COLUMN b TYPE varchar; + +DROP TABLE gtest31_1, gtest31_2; + +CREATE FUNCTION gtest_trigger_func() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + IF tg_op IN ('DELETE', 'UPDATE') THEN + RAISE INFO '%: %: old = %', TG_NAME, TG_WHEN, OLD; + END IF; + IF tg_op IN ('INSERT', 'UPDATE') THEN + RAISE INFO '%: %: new = %', TG_NAME, TG_WHEN, NEW; + END IF; + IF tg_op = 'DELETE' THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; +END +$$; + +CREATE TRIGGER gtest1 BEFORE DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- error + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.* IS NOT NULL) -- error + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26 + FOR EACH ROW + WHEN (NEW.a < 0) + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest3 AFTER DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest4 AFTER INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +INSERT INTO gtest26 (a) VALUES (-2), (0), (3); + +SELECT * FROM gtest26 ORDER BY a; + +UPDATE gtest26 SET a = a * -2; + +SELECT * FROM gtest26 ORDER BY a; + +DELETE FROM gtest26 WHERE a = -6; + +SELECT * FROM gtest26 ORDER BY a; + +DROP TRIGGER gtest1 ON gtest26; + +DROP TRIGGER gtest2 ON gtest26; + +DROP TRIGGER gtest3 ON gtest26; + +CREATE FUNCTION gtest_trigger_func3() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'OK'; + RETURN NEW; +END +$$; + +CREATE TRIGGER gtest11 BEFORE UPDATE OF b ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func3(); + +UPDATE gtest26 SET a = 1 WHERE a = 0; + +DROP TRIGGER gtest11 ON gtest26; + +TRUNCATE gtest26; + +CREATE FUNCTION gtest_trigger_func4() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + NEW.a = 10; + NEW.b = 300; + RETURN NEW; +END; +$$; + +CREATE TRIGGER gtest12_01 BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest12_02 BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func4(); + +CREATE TRIGGER gtest12_03 BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); + +INSERT INTO gtest26 (a) VALUES (1); + +SELECT * FROM gtest26 ORDER BY a; + +UPDATE gtest26 SET a = 11 WHERE a = 10; + +SELECT * FROM gtest26 ORDER BY a; + +ALTER TABLE gtest28a DROP COLUMN a; + +CREATE TABLE gtest28b (LIKE gtest28a INCLUDING GENERATED); + +SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's', 'v'); + +insert into gtest32 values (1), (2); + +analyze gtest32; + +select sum(t2.b) over (partition by t2.a), + sum(t2.c) over (partition by t2.a), + sum(t2.d) over (partition by t2.a) +from gtest32 as t1 left join gtest32 as t2 on (t1.a = t2.a) +order by t1.a; + +select sum(t2.b) over (partition by t2.a), + sum(t2.c) over (partition by t2.a), + sum(t2.d) over (partition by t2.a) +from gtest32 as t1 left join gtest32 as t2 on (t1.a = t2.a) +order by t1.a; + +select t1.a from gtest32 t1 left join gtest32 t2 on t1.a = t2.a +where coalesce(t2.b, 1) = 2; + +select t1.a from gtest32 t1 left join gtest32 t2 on t1.a = t2.a +where coalesce(t2.b, 1) = 2; + +select t1.a from gtest32 t1 left join gtest32 t2 on t1.a = t2.a +where coalesce(t2.b, 1) = 2 or t1.a is null; + +select t1.a from gtest32 t1 left join gtest32 t2 on t1.a = t2.a +where coalesce(t2.b, 1) = 2 or t1.a is null; + +select t2.* from gtest32 t1 left join gtest32 t2 on false; + +select t2.* from gtest32 t1 left join gtest32 t2 on false; + +select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20; + +select * from gtest32 t group by grouping sets (a, b, c, d, e) having c = 20; + +alter table gtest32 alter column e type bigint using b; + +select 1 from gtest32 t1 where exists + (select 1 from gtest32 t2 where t1.a > t2.a and t2.b = 2); + +select 1 from gtest32 t1 where exists + (select 1 from gtest32 t2 where t1.a > t2.a and t2.b = 2); + +drop table gtest32; + +set constraint_exclusion to on; + +select * from gtest33 where b < 10; + +select * from gtest33 where b is null; + +reset constraint_exclusion; + +drop table gtest33; diff --git a/crates/pgt_pretty_print/tests/data/multi/geometry_60.sql b/crates/pgt_pretty_print/tests/data/multi/geometry_60.sql new file mode 100644 index 000000000..d90037087 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/geometry_60.sql @@ -0,0 +1,363 @@ +SET extra_float_digits TO -3; + +SELECT center(f1) AS center + FROM BOX_TBL; + +SELECT (@@ f1) AS center + FROM BOX_TBL; + +SELECT point(f1) AS center + FROM CIRCLE_TBL; + +SELECT (@@ f1) AS center + FROM CIRCLE_TBL; + +SELECT (@@ f1) AS center + FROM POLYGON_TBL + WHERE (# f1) > 2; + +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE ishorizontal(p1.f1, point '(0,0)'); + +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE p1.f1 ?- point '(0,0)'; + +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE isvertical(p1.f1, point '(5.1,34.5)'); + +SELECT p1.f1 + FROM POINT_TBL p1 + WHERE p1.f1 ?| point '(5.1,34.5)'; + +SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; + +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; + +SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; + +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] BETWEEN 1 AND 1000; + +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] < 1; + +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] BETWEEN 1 AND 1000; + +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] > 1000; + +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1 ~= '(0,0)'::point; + +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TBL p, LINE_TBL l; + +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TBL p, LSEG_TBL l; + +SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT_TBL p, BOX_TBL b; + +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp FROM POINT_TBL p, PATH_TBL p1; + +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp FROM POINT_TBL p, POLYGON_TBL p1; + +SELECT p1.f1, p2.f1, line(p1.f1, p2.f1) + FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1 <> p2.f1; + +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; + +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l; + +SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b; + +SELECT p.f1, l.s FROM POINT_TBL p, LINE_TBL l WHERE p.f1 <@ l.s; + +SELECT p.f1, l.s FROM POINT_TBL p, LSEG_TBL l WHERE p.f1 <@ l.s; + +SELECT p.f1, p1.f1 FROM POINT_TBL p, PATH_TBL p1 WHERE p.f1 <@ p1.f1; + +SELECT s FROM LINE_TBL WHERE ?| s; + +SELECT s FROM LINE_TBL WHERE ?- s; + +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s = l2.s; + +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?|| l2.s; + +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?-| l2.s; + +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2; + +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s; + +SELECT l.s, b.f1 FROM LINE_TBL l, BOX_TBL b WHERE l.s ?# b.f1; + +SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2; + +SELECT l.s, l1.s, l.s ## l1.s FROM LINE_TBL l, LSEG_TBL l1; + +SELECT p.f1, l.s, l.s # p.f1 AS intersection + FROM LSEG_TBL l, POINT_TBL p; + +SELECT s, @-@ s FROM LSEG_TBL; + +SELECT s FROM LSEG_TBL WHERE ?| s; + +SELECT s FROM LSEG_TBL WHERE ?- s; + +SELECT s, @@ s FROM LSEG_TBL; + +SELECT s, s::point FROM LSEG_TBL; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s < l2.s; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s <= l2.s; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s = l2.s; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s >= l2.s; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s > l2.s; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s != l2.s; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?|| l2.s; + +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?-| l2.s; + +SELECT l.s, l1.s, l.s <-> l1.s AS dist_sl, l1.s <-> l.s AS dist_ls FROM LSEG_TBL l, LINE_TBL l1; + +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + +SELECT l.s, b.f1, l.s <-> b.f1 AS dist_sb, b.f1 <-> l.s AS dist_bs FROM LSEG_TBL l, BOX_TBL b; + +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s ?# l1.s; + +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s ?# b.f1; + +SELECT l1.s, l2.s, l1.s # l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + +SELECT l1.s, l2.s, l1.s ## l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + +SELECT l.s, b.f1, l.s ## b.f1 FROM LSEG_TBL l, BOX_TBL b; + +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s <@ l1.s; + +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s <@ b.f1; + +SELECT box(f1) AS box FROM CIRCLE_TBL; + +SELECT b.f1 + p.f1 AS translation + FROM BOX_TBL b, POINT_TBL p; + +SELECT b.f1 - p.f1 AS translation + FROM BOX_TBL b, POINT_TBL p; + +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] > 1000; + +SELECT b.f1, p.f1, b.f1 / p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + +SELECT f1::box + FROM POINT_TBL; + +SELECT bound_box(a.f1, b.f1) + FROM BOX_TBL a, BOX_TBL b; + +SELECT b1.f1, b2.f1, b1.f1 <^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + +SELECT b1.f1, b2.f1, b1.f1 >^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + +SELECT b1.f1, b2.f1, b1.f1 # b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + +SELECT f1, diagonal(f1) FROM BOX_TBL; + +SELECT b1.f1, b2.f1, b1.f1 <-> b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + +SELECT f1, npoints(f1) FROM PATH_TBL; + +SELECT f1, area(f1) FROM PATH_TBL; + +SELECT f1, @-@ f1 FROM PATH_TBL; + +SELECT f1, f1::polygon FROM PATH_TBL WHERE isclosed(f1); + +SELECT f1, f1::polygon FROM PATH_TBL WHERE isopen(f1); + +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 < p2.f1; + +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 <= p2.f1; + +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 = p2.f1; + +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 >= p2.f1; + +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 > p2.f1; + +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM PATH_TBL p1, PATH_TBL p2; + +SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1; + +SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1; + +SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1; + +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1[0] BETWEEN 1 AND 1000; + +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1 ~= '(0,0)'::point; + +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM PATH_TBL p1, PATH_TBL p2; + +SELECT p.f1, poly.f1, poly.f1 @> p.f1 AS contains + FROM POLYGON_TBL poly, POINT_TBL p; + +SELECT p.f1, poly.f1, p.f1 <@ poly.f1 AS contained + FROM POLYGON_TBL poly, POINT_TBL p; + +SELECT npoints(f1) AS npoints, f1 AS polygon + FROM POLYGON_TBL; + +SELECT polygon(f1) + FROM BOX_TBL; + +SELECT polygon(f1) + FROM PATH_TBL WHERE isclosed(f1); + +SELECT f1 AS open_path, polygon( pclose(f1)) AS polygon + FROM PATH_TBL + WHERE isopen(f1); + +SELECT f1, f1::box FROM POLYGON_TBL; + +SELECT f1, f1::path FROM POLYGON_TBL; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 ~= p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <@ p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 @> p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 && p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 << p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &< p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 >> p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &> p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <<| p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &<| p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |>> p2.f1; + +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |&> p2.f1; + +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2; + +SELECT circle(f1, 50.0) + FROM POINT_TBL; + +SELECT circle(f1) + FROM BOX_TBL; + +SELECT circle(f1) + FROM POLYGON_TBL + WHERE (# f1) >= 3; + +SELECT c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS distance + FROM CIRCLE_TBL c1, POINT_TBL p1 + WHERE (p1.f1 <-> c1.f1) > 0 + ORDER BY distance, area(c1.f1), p1.f1[0]; + +SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + +SELECT f1, polygon(8, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + +SELECT f1, polygon(1, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + +SELECT f1, polygon(10, f1) FROM CIRCLE_TBL WHERE f1 < '<(0,0),1>'; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 ~= c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 && c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &< c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 << c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >> c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &> c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <@ c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 @> c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <<| c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |>> c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &<| c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |&> c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 = c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 != c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 > c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <= c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >= c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + +SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + +SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + +SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] > 1000; + +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1 ~= '(0,0)'::point; + +SELECT c.f1, p.f1, c.f1 <-> p.f1 FROM CIRCLE_TBL c, POLYGON_TBL p; + +CREATE INDEX gcircleind ON circle_tbl USING gist (f1); + +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1); + +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1); + +SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1) + ORDER BY area(f1); + +CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1); + +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0]; + +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0]; + +SELECT * FROM polygon_tbl WHERE f1 @> '((1,1),(2,2),(2,1))'::polygon + ORDER BY (poly_center(f1))[0]; + +SELECT pg_input_is_valid('(1', 'circle'); + +SELECT * FROM pg_input_error_info('1,', 'circle'); + +SELECT pg_input_is_valid('(1,2),-1', 'circle'); + +SELECT * FROM pg_input_error_info('(1,2),-1', 'circle'); diff --git a/crates/pgt_pretty_print/tests/data/multi/gin_60.sql b/crates/pgt_pretty_print/tests/data/multi/gin_60.sql new file mode 100644 index 000000000..d31c19d30 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/gin_60.sql @@ -0,0 +1,183 @@ +create table gin_test_tbl(i int4[]) with (autovacuum_enabled = off); + +create index gin_test_idx on gin_test_tbl using gin (i) + with (fastupdate = on, gin_pending_list_limit = 4096); + +insert into gin_test_tbl select array[1, 2, g] from generate_series(1, 20000) g; + +insert into gin_test_tbl select array[1, 3, g] from generate_series(1, 1000) g; + +select gin_clean_pending_list('gin_test_idx')>10 as many; + +insert into gin_test_tbl select array[3, 1, g] from generate_series(1, 1000) g; + +vacuum gin_test_tbl; + +select gin_clean_pending_list('gin_test_idx'); + +delete from gin_test_tbl where i @> array[2]; + +vacuum gin_test_tbl; + +alter index gin_test_idx set (fastupdate = off); + +insert into gin_test_tbl select array[1, 2, g] from generate_series(1, 1000) g; + +insert into gin_test_tbl select array[1, 3, g] from generate_series(1, 1000) g; + +delete from gin_test_tbl where i @> array[2]; + +vacuum gin_test_tbl; + +select count(*) from gin_test_tbl where i @> array[1, 999]; + +select count(*) from gin_test_tbl where i @> array[1, 999]; + +set gin_fuzzy_search_limit = 1000; + +select count(*) > 0 as ok from gin_test_tbl where i @> array[1]; + +select count(*) > 0 as ok from gin_test_tbl where i @> array[1]; + +reset gin_fuzzy_search_limit; + +create temp table t_gin_test_tbl(i int4[], j int4[]); + +create index on t_gin_test_tbl using gin (i, j); + +insert into t_gin_test_tbl +values + (null, null), + ('{}', null), + ('{1}', null), + ('{1,2}', null), + (null, '{}'), + (null, '{10}'), + ('{1,2}', '{10}'), + ('{2}', '{10}'), + ('{1,3}', '{}'), + ('{1,1}', '{10}'); + +set enable_seqscan = off; + +select * from t_gin_test_tbl where array[0] <@ i; + +select * from t_gin_test_tbl where array[0] <@ i; + +select * from t_gin_test_tbl where array[0] <@ i and '{}'::int4[] <@ j; + +select * from t_gin_test_tbl where i @> '{}'; + +select * from t_gin_test_tbl where i @> '{}'; + +create function explain_query_json(query_sql text) +returns table (explain_line json) +language plpgsql as +$$ +begin + set enable_seqscan = off; + set enable_bitmapscan = on; + return query execute 'EXPLAIN (ANALYZE, FORMAT json) ' || query_sql; +end; +$$; + +create function execute_text_query_index(query_sql text) +returns setof text +language plpgsql +as +$$ +begin + set enable_seqscan = off; + set enable_bitmapscan = on; + return query execute query_sql; +end; +$$; + +create function execute_text_query_heap(query_sql text) +returns setof text +language plpgsql +as +$$ +begin + set enable_seqscan = on; + set enable_bitmapscan = off; + return query execute query_sql; +end; +$$; + +select + query, + js->0->'Plan'->'Plans'->0->'Actual Rows' as "return by index", + js->0->'Plan'->'Rows Removed by Index Recheck' as "removed by recheck", + (res_index = res_heap) as "match" +from + (values + ($$ i @> '{}' $$), + ($$ j @> '{}' $$), + ($$ i @> '{}' and j @> '{}' $$), + ($$ i @> '{1}' $$), + ($$ i @> '{1}' and j @> '{}' $$), + ($$ i @> '{1}' and i @> '{}' and j @> '{}' $$), + ($$ j @> '{10}' $$), + ($$ j @> '{10}' and i @> '{}' $$), + ($$ j @> '{10}' and j @> '{}' and i @> '{}' $$), + ($$ i @> '{1}' and j @> '{10}' $$) + ) q(query), + lateral explain_query_json($$select * from t_gin_test_tbl where $$ || query) js, + lateral execute_text_query_index($$select string_agg((i, j)::text, ' ') from t_gin_test_tbl where $$ || query) res_index, + lateral execute_text_query_heap($$select string_agg((i, j)::text, ' ') from t_gin_test_tbl where $$ || query) res_heap; + +reset enable_seqscan; + +reset enable_bitmapscan; + +insert into t_gin_test_tbl select array[1, g, g/10], array[2, g, g/10] + from generate_series(1, 20000) g; + +select gin_clean_pending_list('t_gin_test_tbl_i_j_idx') is not null; + +analyze t_gin_test_tbl; + +set enable_seqscan = off; + +set enable_bitmapscan = on; + +select count(*) from t_gin_test_tbl where j @> array[50]; + +select count(*) from t_gin_test_tbl where j @> array[50]; + +select count(*) from t_gin_test_tbl where j @> array[2]; + +select count(*) from t_gin_test_tbl where j @> array[2]; + +select count(*) from t_gin_test_tbl where j @> '{}'::int[]; + +select count(*) from t_gin_test_tbl where j @> '{}'::int[]; + +delete from t_gin_test_tbl where j @> array[2]; + +vacuum t_gin_test_tbl; + +select count(*) from t_gin_test_tbl where j @> array[50]; + +select count(*) from t_gin_test_tbl where j @> array[2]; + +select count(*) from t_gin_test_tbl where j @> '{}'::int[]; + +reset enable_seqscan; + +reset enable_bitmapscan; + +drop table t_gin_test_tbl; + +create unlogged table t_gin_test_tbl(i int4[], j int4[]); + +create index on t_gin_test_tbl using gin (i, j); + +insert into t_gin_test_tbl +values + (null, null), + ('{}', null), + ('{1}', '{2,3}'); + +drop table t_gin_test_tbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/gist_60.sql b/crates/pgt_pretty_print/tests/data/multi/gist_60.sql new file mode 100644 index 000000000..3e15bd92a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/gist_60.sql @@ -0,0 +1,154 @@ +create table gist_point_tbl(id int4, p point); + +create index gist_pointidx on gist_point_tbl using gist(p); + +create index gist_pointidx2 on gist_point_tbl using gist(p) with (buffering = on, fillfactor=50); + +create index gist_pointidx3 on gist_point_tbl using gist(p) with (buffering = off); + +create index gist_pointidx4 on gist_point_tbl using gist(p) with (buffering = auto); + +drop index gist_pointidx2, gist_pointidx3, gist_pointidx4; + +create index gist_pointidx5 on gist_point_tbl using gist(p) with (buffering = invalid_value); + +create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=9); + +create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=101); + +insert into gist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10000) g; + +insert into gist_point_tbl (id, p) +select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g; + +delete from gist_point_tbl where id % 2 = 1; + +delete from gist_point_tbl where id > 5000; + +vacuum analyze gist_point_tbl; + +alter index gist_pointidx SET (fillfactor = 40); + +reindex index gist_pointidx; + +create table gist_tbl (b box, p point, c circle); + +insert into gist_tbl +select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), + point(0.05*i, 0.05*i), + circle(point(0.05*i, 0.05*i), 1.0) +from generate_series(0,10000) as i; + +vacuum analyze gist_tbl; + +set enable_seqscan=off; + +set enable_bitmapscan=off; + +set enable_indexonlyscan=on; + +create index gist_tbl_point_index on gist_tbl using gist (p); + +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)); + +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)); + +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by p <-> point(0.201, 0.201); + +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by p <-> point(0.201, 0.201); + +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by point(0.101, 0.101) <-> p; + +select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) +order by point(0.101, 0.101) <-> p; + +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss; + +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss; + +drop index gist_tbl_point_index; + +create index gist_tbl_box_index on gist_tbl using gist (b); + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)); + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)); + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + +drop index gist_tbl_box_index; + +create index gist_tbl_multi_index on gist_tbl using gist (p, c); + +select p, c from gist_tbl +where p <@ box(point(5,5), point(6, 6)); + +select b, p from gist_tbl +where b <@ box(point(4.5, 4.5), point(5.5, 5.5)) +and p <@ box(point(5,5), point(6, 6)); + +drop index gist_tbl_multi_index; + +create index gist_tbl_multi_index on gist_tbl using gist (circle(p,1), p); + +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)); + +select circle(p,1) from gist_tbl +where p <@ box(point(5, 5), point(5.3, 5.3)); + +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95); + +select p from gist_tbl where circle(p,1) @> circle(point(0,0),0.95); + +select count(*) from gist_tbl; + +select count(*) from gist_tbl; + +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; + +select p from gist_tbl order by circle(p,1) <-> point(0,0) limit 1; + +create index gist_tbl_box_index_forcing_buffering on gist_tbl using gist (p) + with (buffering=on, fillfactor=50); + +reset enable_seqscan; + +reset enable_bitmapscan; + +reset enable_indexonlyscan; + +drop table gist_tbl; + +create unlogged table gist_tbl (b box); + +create index gist_tbl_box_index on gist_tbl using gist (b); + +insert into gist_tbl + select box(point(0.05*i, 0.05*i)) from generate_series(0,10) as i; + +drop table gist_tbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/groupingsets_60.sql b/crates/pgt_pretty_print/tests/data/multi/groupingsets_60.sql new file mode 100644 index 000000000..b198ac9d5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/groupingsets_60.sql @@ -0,0 +1,653 @@ +create temp view gstest1(a,b,v) + as values (1,1,10),(1,1,11),(1,2,12),(1,2,13),(1,3,14), + (2,3,15), + (3,3,16),(3,4,17), + (4,1,18),(4,1,19); + +create temp table gstest2 (a integer, b integer, c integer, d integer, + e integer, f integer, g integer, h integer); + +copy gstest2 from stdin; + +create temp table gstest3 (a integer, b integer, c integer, d integer); + +copy gstest3 from stdin; + +alter table gstest3 add primary key (a); + +create temp table gstest4(id integer, v integer, + unhashable_col bit(4), unsortable_col xid); + +insert into gstest4 +values (1,1,b'0000','1'), (2,2,b'0001','1'), + (3,4,b'0010','2'), (4,8,b'0011','2'), + (5,16,b'0000','2'), (6,32,b'0001','2'), + (7,64,b'0010','1'), (8,128,b'0011','1'); + +create temp table gstest_empty (a integer, b integer, v integer); + +create function gstest_data(v integer, out a integer, out b integer) + returns setof record + as $f$ + begin + return query select v, i from generate_series(1,3) i; + end; + $f$ language plpgsql; + +set enable_hashagg = false; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b); + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by a,b; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by b desc, a; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by rollup (a,b) order by coalesce(a,0)+coalesce(b,0); + +select a, b, grouping(a,b), + array_agg(v order by v), + string_agg(v::text, ':' order by v desc), + percentile_disc(0.5) within group (order by v), + rank(1,2,12) within group (order by a,b,v) + from gstest1 group by rollup (a,b) order by a,b; + +select grouping(a), a, array_agg(b), + rank(a) within group (order by b nulls first), + rank(a) within group (order by b nulls last) + from (values (1,1),(1,4),(1,5),(3,1),(3,2)) v(a,b) + group by rollup (a) order by a; + +select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum + from gstest2 group by rollup (a,b) order by rsum, a, b; + +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(()))) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets((), grouping sets((), grouping sets(((a, b))))) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets(grouping sets(rollup(c), grouping sets(cube(c)))) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets(a, grouping sets(a, cube(b))) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, (b)))) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets(grouping sets((a, b))) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a), a)) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets(grouping sets(a, grouping sets(a, grouping sets(a), ((a)), a, grouping sets(a), (a)), a)) + order by 1 desc; + +select sum(c) from gstest2 + group by grouping sets((a,(a,b)), grouping sets((a,(a,b)),a)) + order by 1 desc; + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a); + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()); + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()); + +select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()); + +select t1.a, t2.b, sum(t1.v), count(*) from gstest_empty t1, gstest_empty t2 + group by grouping sets ((t1.a,t2.b),()); + +select t1.a, t2.b, grouping(t1.a, t2.b), sum(t1.v), max(t2.a) + from gstest1 t1, gstest2 t2 + group by grouping sets ((t1.a, t2.b), ()); + +select t1.a, t2.b, grouping(t1.a, t2.b), sum(t1.v), max(t2.a) + from gstest1 t1 join gstest2 t2 on (t1.a=t2.a) + group by grouping sets ((t1.a, t2.b), ()); + +select a, b, grouping(a, b), sum(t1.v), max(t2.c) + from gstest1 t1 join gstest2 t2 using (a,b) + group by grouping sets ((a, b), ()); + +select a, d, grouping(a,b,c) + from gstest3 + group by grouping sets ((a,b), (a,c)); + +select g as alias1, g as alias2 + from generate_series(1,3) g + group by alias1, rollup(alias2); + +select g as alias1, g as alias2 + from generate_series(1,3) g + group by alias1, rollup(alias2); + +select four, x + from (select four, ten, 'foo'::text as x from tenk1) as t + group by grouping sets (four, x) + having x = 'foo'; + +select four, x || 'x' + from (select four, ten, 'foo'::text as x from tenk1) as t + group by grouping sets (four, x) + order by four; + +select (x+y)*1, sum(z) + from (select 1 as x, 2 as y, 3 as z) s + group by grouping sets (x+y, x); + +select x, not x as not_x, q2 from + (select *, q1 = 1 as x from int8_tbl i1) as t + group by grouping sets(x, q2) + order by x, q2; + +select x, y + from (select four as x, four as y from tenk1) as t + group by grouping sets (x, y) + having y is null + order by 1, 2; + +select x, y || 'y' + from (select four as x, four as y from tenk1) as t + group by grouping sets (x, y) + order by 1, 2; + +select * from ( + select 1 as x, q1, sum(q2) + from int8_tbl i1 + group by grouping sets(1, 2) +) ss +where x = 1 and q1 = 123; + +select * from ( + select 1 as x, q1, sum(q2) + from int8_tbl i1 + group by grouping sets(1, 2) +) ss +where x = 1 and q1 = 123; + +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + +select grouping(ss.x) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + +select (select grouping(ss.x)) +from int8_tbl i1 +cross join lateral (select (select i1.q1) as x) ss +group by ss.x; + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by rollup (a,b); + +select * + from (values (1),(2)) v(x), + lateral (select a, b, sum(v.x) from gstest_data(v.x) group by rollup (a,b)) s; + +select min(unique1) from tenk1 GROUP BY (); + +CREATE VIEW gstest_view AS select a, b, grouping(a,b), sum(c), count(*), max(c) + from gstest2 group by rollup ((a,b,c),(c,d)); + +select pg_get_viewdef('gstest_view'::regclass, true); + +select(select (select grouping(a,b) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + +select(select (select grouping(e,f) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + +select(select (select grouping(c) from (values (1)) v2(c) GROUP BY c) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + +select a, b, c, d from gstest2 group by rollup(a,b),grouping sets(c,d); + +select a, b from (values (1,2),(2,3)) v(a,b) group by a,b, grouping sets(a); + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by grouping sets ((a,b),(a+1,b+1),(a+2,b+2)) order by 3,6; + +select(select (select grouping(a,b) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP((e+1),(f+1)); + +select(select (select grouping(a,b) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY CUBE((e+1),(f+1)) ORDER BY (e+1),(f+1); + +select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum + from gstest2 group by cube (a,b) order by rsum, a, b; + +select a, b, sum(c) from (values (1,1,10),(1,1,11),(1,2,12),(1,2,13),(1,3,14),(2,3,15),(3,3,16),(3,4,17),(4,1,18),(4,1,19)) v(a,b,c) group by rollup (a,b); + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by cube (a,b) order by a,b; + +select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a; + +select (select grouping(a,b) from gstest2) from gstest2 group by a,b; + +select a, b, sum(c), count(*) from gstest2 group by grouping sets (rollup(a,b),a); + +select ten, sum(distinct four) from onek a +group by grouping sets((ten,four),(ten)) +having exists (select 1 from onek b where sum(distinct a.four) = b.four); + +select a,count(*) from gstest2 group by rollup(a) order by a; + +select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; + +select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; + +select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c; + +select v.c, (select count(*) from gstest2 group by () having v.c) + from (values (false),(true)) v(c) order by v.c; + +select a, b, count(*) from gstest2 group by grouping sets ((a, b), (a)) having a > 1 and b > 1; + +select a, b, count(*) from gstest2 group by grouping sets ((a, b), (a)) having a > 1 and b > 1; + +select ten, grouping(ten) from onek +group by grouping sets(ten) having grouping(ten) >= 0 +order by 2,1; + +select ten, grouping(ten) from onek +group by grouping sets(ten, four) having grouping(ten) > 0 +order by 2,1; + +select ten, grouping(ten) from onek +group by rollup(ten) having grouping(ten) > 0 +order by 2,1; + +select ten, grouping(ten) from onek +group by cube(ten) having grouping(ten) > 0 +order by 2,1; + +select ten, grouping(ten) from onek +group by (ten) having grouping(ten) >= 0 +order by 2,1; + +select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +group by rollup(ten); + +select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by cube(four,ten)) s on true order by v.a,four,ten; + +select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by cube(two,four) order by two,four) s1) from (values (1),(2)) v(a); + +select sum(ten) from onek group by two, rollup(four::text) order by 1; + +select sum(ten) from onek group by rollup(four::text), two order by 1; + +set enable_hashagg = true; + +select count(*) from gstest4 group by rollup(unhashable_col,unsortable_col); + +select array_agg(v order by v) from gstest4 group by grouping sets ((id,unsortable_col),(id)); + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by grouping sets ((a),(b)) order by 3,1,2; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by grouping sets ((a),(b)) order by 3,1,2; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by cube(a,b) order by 3,1,2; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by cube(a,b) order by 3,1,2; + +select a, b, grouping(a,b), array_agg(v order by v) + from gstest1 group by cube(a,b); + +select unsortable_col, count(*) + from gstest4 group by grouping sets ((unsortable_col),(unsortable_col)) + order by unsortable_col::text; + +select unhashable_col, unsortable_col, + grouping(unhashable_col, unsortable_col), + count(*), sum(v) + from gstest4 group by grouping sets ((unhashable_col),(unsortable_col)) + order by 3, 5; + +select unhashable_col, unsortable_col, + grouping(unhashable_col, unsortable_col), + count(*), sum(v) + from gstest4 group by grouping sets ((unhashable_col),(unsortable_col)) + order by 3,5; + +select unhashable_col, unsortable_col, + grouping(unhashable_col, unsortable_col), + count(*), sum(v) + from gstest4 group by grouping sets ((v,unhashable_col),(v,unsortable_col)) + order by 3,5; + +select unhashable_col, unsortable_col, + grouping(unhashable_col, unsortable_col), + count(*), sum(v) + from gstest4 group by grouping sets ((v,unhashable_col),(v,unsortable_col)) + order by 3,5; + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a); + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a); + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()); + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()); + +select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()); + +select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()); + +select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()); + +select a, d, grouping(a,b,c) + from gstest3 + group by grouping sets ((a,b), (a,c)); + +select a, d, grouping(a,b,c) + from gstest3 + group by grouping sets ((a,b), (a,c)); + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by grouping sets (a,b) + order by 1, 2, 3; + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by grouping sets (a,b) + order by 3, 1, 2; + +select * + from (values (1),(2)) v(x), + lateral (select a, b, sum(v.x) from gstest_data(v.x) group by grouping sets (a,b)) s; + +select * + from (values (1),(2)) v(x), + lateral (select a, b, sum(v.x) from gstest_data(v.x) group by grouping sets (a,b)) s; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by grouping sets ((a,b),(a+1,b+1),(a+2,b+2)) order by 3,6; + +select a, b, grouping(a,b), sum(v), count(*), max(v) + from gstest1 group by grouping sets ((a,b),(a+1,b+1),(a+2,b+2)) order by 3,6; + +select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum + from gstest2 group by cube (a,b) order by rsum, a, b; + +select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum + from gstest2 group by cube (a,b) order by rsum, a, b; + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by cube (a,b) order by a,b; + +select a, b, sum(v.x) + from (values (1),(2)) v(x), gstest_data(v.x) + group by cube (a,b) order by a,b; + +BEGIN; + +SET LOCAL enable_hashagg = false; + +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + +SET LOCAL enable_seqscan = false; + +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + +COMMIT; + +select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by cube(four,ten)) s on true order by v.a,four,ten; + +select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by cube(two,four) order by two,four) s1) from (values (1),(2)) v(a); + +select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by grouping sets(four,ten)) s on true order by v.a,four,ten; + +select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by grouping sets(two,four) order by two,four) s1) from (values (1),(2)) v(a); + +set enable_indexscan = false; + +set hash_mem_multiplier = 1.0; + +set work_mem = '64kB'; + +select unique1, + count(two), count(four), count(ten), + count(hundred), count(thousand), count(twothousand), + count(*) + from tenk1 group by grouping sets (unique1,twothousand,thousand,hundred,ten,four,two); + +select unique1, + count(two), count(four), count(ten), + count(hundred), count(thousand), count(twothousand), + count(*) + from tenk1 group by grouping sets (unique1,hundred,ten,four,two); + +set work_mem = '384kB'; + +select unique1, + count(two), count(four), count(ten), + count(hundred), count(thousand), count(twothousand), + count(*) + from tenk1 group by grouping sets (unique1,twothousand,thousand,hundred,ten,four,two); + +select v||'a', case grouping(v||'a') when 1 then 1 else 0 end, count(*) + from unnest(array[1,1], array['a','b']) u(i,v) + group by rollup(i, v||'a') order by 1,3; + +select v||'a', case when grouping(v||'a') = 1 then 1 else 0 end, count(*) + from unnest(array[1,1], array['a','b']) u(i,v) + group by rollup(i, v||'a') order by 1,3; + +create table bug_16784(i int, j int); + +analyze bug_16784; + +alter table bug_16784 set (autovacuum_enabled = 'false'); + +update pg_class set reltuples = 10 where relname='bug_16784'; + +insert into bug_16784 select g/10, g from generate_series(1,40) g; + +set work_mem='64kB'; + +set enable_sort = false; + +select * from + (values (1),(2)) v(a), + lateral (select a, i, j, count(*) from + bug_16784 group by cube(i,j)) s + order by v.a, i, j; + +create table gs_data_1 as +select g%1000 as g1000, g%100 as g100, g%10 as g10, g + from generate_series(0,1999) g; + +analyze gs_data_1; + +alter table gs_data_1 set (autovacuum_enabled = 'false'); + +update pg_class set reltuples = 10 where relname='gs_data_1'; + +set work_mem='64kB'; + +set enable_sort = true; + +set enable_hashagg = false; + +set jit_above_cost = 0; + +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10); + +create table gs_group_1 as +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10); + +set enable_hashagg = true; + +set enable_sort = false; + +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10); + +create table gs_hash_1 as +select g100, g10, sum(g::numeric), count(*), max(g::text) +from gs_data_1 group by cube (g1000, g100,g10); + +set enable_sort = true; + +set work_mem to default; + +set hash_mem_multiplier to default; + +(select * from gs_hash_1 except select * from gs_group_1) + union all +(select * from gs_group_1 except select * from gs_hash_1); + +drop table gs_group_1; + +drop table gs_hash_1; + +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by all rollup(a, b), rollup(a, c) +order by a, b, c; + +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by rollup(a, b), rollup(a, c) +order by a, b, c; + +select a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by distinct rollup(a, b), rollup(a, c) +order by a, b, c; + +select distinct a, b, c +from (values (1, 2, 3), (4, null, 6), (7, 8, 9)) as t (a, b, c) +group by rollup(a, b), rollup(a, c) +order by a, b, c; + +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1); + +select (select grouping(v1)) from (values ((select 1))) v(v1) group by cube(v1); + +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1; + +select (select grouping(v1)) from (values ((select 1))) v(v1) group by v1; + +create temp table gstest5(id integer primary key, v integer); + +insert into gstest5 select i, i from generate_series(1,5)i; + +select grouping((select t1.v from gstest5 t2 where id = t1.id)), + (select t1.v from gstest5 t2 where id = t1.id) as s +from gstest5 t1 +group by grouping sets(v, s) +order by case when grouping((select t1.v from gstest5 t2 where id = t1.id)) = 0 + then (select t1.v from gstest5 t2 where id = t1.id) + else null end + nulls first; + +select grouping((select t1.v from gstest5 t2 where id = t1.id)), + (select t1.v from gstest5 t2 where id = t1.id) as s +from gstest5 t1 +group by grouping sets(v, s) +order by case when grouping((select t1.v from gstest5 t2 where id = t1.id)) = 0 + then (select t1.v from gstest5 t2 where id = t1.id) + else null end + nulls first; + +select grouping((select t1.v from gstest5 t2 where id = t1.id)), + (select t1.v from gstest5 t2 where id = t1.id) as s, + case when grouping((select t1.v from gstest5 t2 where id = t1.id)) = 0 + then (select t1.v from gstest5 t2 where id = t1.id) + else null end as o +from gstest5 t1 +group by grouping sets(v, s) +order by o nulls first; + +select grouping((select t1.v from gstest5 t2 where id = t1.id)), + (select t1.v from gstest5 t2 where id = t1.id) as s, + case when grouping((select t1.v from gstest5 t2 where id = t1.id)) = 0 + then (select t1.v from gstest5 t2 where id = t1.id) + else null end as o +from gstest5 t1 +group by grouping sets(v, s) +order by o nulls first; + +select a < b and b < 3 from (values (1, 2)) t(a, b) group by rollup(a < b and b < 3) having a < b and b < 3; + +select a < b and b < 3 from (values (1, 2)) t(a, b) group by rollup(a < b and b < 3) having a < b and b < 3; + +select not a from (values(true)) t(a) group by rollup(not a) having not not a; + +select not a from (values(true)) t(a) group by rollup(not a) having not not a; + +select distinct on (a, b) a, b +from (values (1, 1), (2, 2)) as t (a, b) where a = b +group by grouping sets((a, b), (a)) +order by a, b; + +select distinct on (a, b) a, b +from (values (1, 1), (2, 2)) as t (a, b) where a = b +group by grouping sets((a, b), (a)) +order by a, b; + +select distinct on (a, b+1) a, b+1 +from (values (1, 0), (2, 1)) as t (a, b) where a = b+1 +group by grouping sets((a, b+1), (a)) +order by a, b+1; + +select distinct on (a, b+1) a, b+1 +from (values (1, 0), (2, 1)) as t (a, b) where a = b+1 +group by grouping sets((a, b+1), (a)) +order by a, b+1; + +select a, b +from (values (1, 1), (2, 2)) as t (a, b) where a = b +group by grouping sets((a, b), (a)) +order by a, b nulls first; + +select a, b +from (values (1, 1), (2, 2)) as t (a, b) where a = b +group by grouping sets((a, b), (a)) +order by a, b nulls first; + +select 1 as one group by rollup(one) order by one nulls first; + +select 1 as one group by rollup(one) order by one nulls first; + +select a, b, row_number() over (order by a, b nulls first) +from (values (1, 1), (2, 2)) as t (a, b) where a = b +group by grouping sets((a, b), (a)); + +select a, b, row_number() over (order by a, b nulls first) +from (values (1, 1), (2, 2)) as t (a, b) where a = b +group by grouping sets((a, b), (a)); diff --git a/crates/pgt_pretty_print/tests/data/multi/guc_60.sql b/crates/pgt_pretty_print/tests/data/multi/guc_60.sql new file mode 100644 index 000000000..82e7c39a6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/guc_60.sql @@ -0,0 +1,287 @@ +SHOW datestyle; + +SET intervalstyle to 'asd'; + +SET vacuum_cost_delay TO 40; + +SET datestyle = 'ISO, YMD'; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SET LOCAL vacuum_cost_delay TO 50; + +SHOW vacuum_cost_delay; + +SET LOCAL datestyle = 'SQL'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +BEGIN; + +SET LOCAL vacuum_cost_delay TO 50; + +SHOW vacuum_cost_delay; + +SET LOCAL datestyle = 'SQL'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +COMMIT; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +BEGIN; + +SET vacuum_cost_delay TO 60; + +SHOW vacuum_cost_delay; + +SET datestyle = 'German'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +BEGIN; + +SET vacuum_cost_delay TO 70; + +SET datestyle = 'MDY'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SAVEPOINT first_sp; + +SET vacuum_cost_delay TO 80.1; + +SHOW vacuum_cost_delay; + +SET datestyle = 'German, DMY'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK TO first_sp; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SAVEPOINT second_sp; + +SET vacuum_cost_delay TO '900us'; + +SET datestyle = 'SQL, YMD'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SAVEPOINT third_sp; + +SET vacuum_cost_delay TO 100; + +SHOW vacuum_cost_delay; + +SET datestyle = 'Postgres, MDY'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK TO third_sp; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK TO second_sp; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +BEGIN; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SAVEPOINT sp; + +SET LOCAL vacuum_cost_delay TO 30; + +SHOW vacuum_cost_delay; + +SET LOCAL datestyle = 'Postgres, MDY'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK TO sp; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +BEGIN; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SAVEPOINT sp; + +SET LOCAL vacuum_cost_delay TO 30; + +SHOW vacuum_cost_delay; + +SET LOCAL datestyle = 'Postgres, MDY'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +RELEASE SAVEPOINT sp; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +ROLLBACK; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +BEGIN; + +SET vacuum_cost_delay TO 40; + +SET LOCAL vacuum_cost_delay TO 50; + +SHOW vacuum_cost_delay; + +SET datestyle = 'ISO, DMY'; + +SET LOCAL datestyle = 'Postgres, MDY'; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +COMMIT; + +SHOW vacuum_cost_delay; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SET datestyle = iso, ymd; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +RESET datestyle; + +SHOW datestyle; + +SELECT '2006-08-13 12:34:56'::timestamptz; + +SET seq_page_cost TO 'NaN'; + +SET vacuum_cost_delay TO '10s'; + +SET no_such_variable TO 42; + +SHOW custom.my_guc; + +SET custom.my_guc = 42; + +SHOW custom.my_guc; + +RESET custom.my_guc; + +SHOW custom.my_guc; + +SET custom.my.qualified.guc = 'foo'; + +SHOW custom.my.qualified.guc; + +SET custom."bad-guc" = 42; + +SHOW custom."bad-guc"; + +SET special."weird name" = 'foo'; + +SHOW special."weird name"; + +SET plpgsql.extra_foo_warnings = true; + +LOAD 'plpgsql'; + +SET plpgsql.extra_foo_warnings = true; + +SHOW plpgsql.extra_foo_warnings; + +SELECT relname FROM pg_class WHERE relname = 'reset_test'; + +DISCARD TEMP; + +SELECT relname FROM pg_class WHERE relname = 'reset_test'; diff --git a/crates/pgt_pretty_print/tests/data/multi/hash_func_60.sql b/crates/pgt_pretty_print/tests/data/multi/hash_func_60.sql new file mode 100644 index 000000000..4f39025b4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/hash_func_60.sql @@ -0,0 +1,263 @@ +SELECT v as value, hashint2(v)::bit(32) as standard, + hashint2extended(v, 0)::bit(32) as extended0, + hashint2extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0::int2), (1::int2), (17::int2), (42::int2)) x(v) +WHERE hashint2(v)::bit(32) != hashint2extended(v, 0)::bit(32) + OR hashint2(v)::bit(32) = hashint2extended(v, 1)::bit(32); + +SELECT v as value, hashint4(v)::bit(32) as standard, + hashint4extended(v, 0)::bit(32) as extended0, + hashint4extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashint4(v)::bit(32) != hashint4extended(v, 0)::bit(32) + OR hashint4(v)::bit(32) = hashint4extended(v, 1)::bit(32); + +SELECT v as value, hashint8(v)::bit(32) as standard, + hashint8extended(v, 0)::bit(32) as extended0, + hashint8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashint8(v)::bit(32) != hashint8extended(v, 0)::bit(32) + OR hashint8(v)::bit(32) = hashint8extended(v, 1)::bit(32); + +SELECT v as value, hashfloat4(v)::bit(32) as standard, + hashfloat4extended(v, 0)::bit(32) as extended0, + hashfloat4extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashfloat4(v)::bit(32) != hashfloat4extended(v, 0)::bit(32) + OR hashfloat4(v)::bit(32) = hashfloat4extended(v, 1)::bit(32); + +SELECT v as value, hashfloat8(v)::bit(32) as standard, + hashfloat8extended(v, 0)::bit(32) as extended0, + hashfloat8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashfloat8(v)::bit(32) != hashfloat8extended(v, 0)::bit(32) + OR hashfloat8(v)::bit(32) = hashfloat8extended(v, 1)::bit(32); + +SELECT v as value, hashoid(v)::bit(32) as standard, + hashoidextended(v, 0)::bit(32) as extended0, + hashoidextended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v) +WHERE hashoid(v)::bit(32) != hashoidextended(v, 0)::bit(32) + OR hashoid(v)::bit(32) = hashoidextended(v, 1)::bit(32); + +SELECT v as value, hashchar(v)::bit(32) as standard, + hashcharextended(v, 0)::bit(32) as extended0, + hashcharextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::"char"), ('1'), ('x'), ('X'), ('p'), ('N')) x(v) +WHERE hashchar(v)::bit(32) != hashcharextended(v, 0)::bit(32) + OR hashchar(v)::bit(32) = hashcharextended(v, 1)::bit(32); + +SELECT v as value, hashname(v)::bit(32) as standard, + hashnameextended(v, 0)::bit(32) as extended0, + hashnameextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashname(v)::bit(32) != hashnameextended(v, 0)::bit(32) + OR hashname(v)::bit(32) = hashnameextended(v, 1)::bit(32); + +SELECT v as value, hashtext(v)::bit(32) as standard, + hashtextextended(v, 0)::bit(32) as extended0, + hashtextextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashtext(v)::bit(32) != hashtextextended(v, 0)::bit(32) + OR hashtext(v)::bit(32) = hashtextextended(v, 1)::bit(32); + +SELECT v as value, hashoidvector(v)::bit(32) as standard, + hashoidvectorextended(v, 0)::bit(32) as extended0, + hashoidvectorextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::oidvector), ('0 1 2 3 4'), ('17 18 19 20'), + ('42 43 42 45'), ('550273 550273 570274'), + ('207112489 207112499 21512 2155 372325 1363252')) x(v) +WHERE hashoidvector(v)::bit(32) != hashoidvectorextended(v, 0)::bit(32) + OR hashoidvector(v)::bit(32) = hashoidvectorextended(v, 1)::bit(32); + +SELECT v as value, hash_aclitem(v)::bit(32) as standard, + hash_aclitem_extended(v, 0)::bit(32) as extended0, + hash_aclitem_extended(v, 1)::bit(32) as extended1 +FROM (SELECT DISTINCT(relacl[1]) FROM pg_class LIMIT 10) x(v) +WHERE hash_aclitem(v)::bit(32) != hash_aclitem_extended(v, 0)::bit(32) + OR hash_aclitem(v)::bit(32) = hash_aclitem_extended(v, 1)::bit(32); + +SELECT v as value, hashmacaddr(v)::bit(32) as standard, + hashmacaddrextended(v, 0)::bit(32) as extended0, + hashmacaddrextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::macaddr), ('08:00:2b:01:02:04'), ('08:00:2b:01:02:04'), + ('e2:7f:51:3e:70:49'), ('d6:a9:4a:78:1c:d5'), + ('ea:29:b1:5e:1f:a5')) x(v) +WHERE hashmacaddr(v)::bit(32) != hashmacaddrextended(v, 0)::bit(32) + OR hashmacaddr(v)::bit(32) = hashmacaddrextended(v, 1)::bit(32); + +SELECT v as value, hashinet(v)::bit(32) as standard, + hashinetextended(v, 0)::bit(32) as extended0, + hashinetextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::inet), ('192.168.100.128/25'), ('192.168.100.0/8'), + ('172.168.10.126/16'), ('172.18.103.126/24'), ('192.188.13.16/32')) x(v) +WHERE hashinet(v)::bit(32) != hashinetextended(v, 0)::bit(32) + OR hashinet(v)::bit(32) = hashinetextended(v, 1)::bit(32); + +SELECT v as value, hash_numeric(v)::bit(32) as standard, + hash_numeric_extended(v, 0)::bit(32) as extended0, + hash_numeric_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (0), (1.149484958), (17.149484958), (42.149484958), + (149484958.550273), (2071124898672)) x(v) +WHERE hash_numeric(v)::bit(32) != hash_numeric_extended(v, 0)::bit(32) + OR hash_numeric(v)::bit(32) = hash_numeric_extended(v, 1)::bit(32); + +SELECT v as value, hashmacaddr8(v)::bit(32) as standard, + hashmacaddr8extended(v, 0)::bit(32) as extended0, + hashmacaddr8extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::macaddr8), ('08:00:2b:01:02:04:36:49'), + ('08:00:2b:01:02:04:f0:e8'), ('e2:7f:51:3e:70:49:16:29'), + ('d6:a9:4a:78:1c:d5:47:32'), ('ea:29:b1:5e:1f:a5')) x(v) +WHERE hashmacaddr8(v)::bit(32) != hashmacaddr8extended(v, 0)::bit(32) + OR hashmacaddr8(v)::bit(32) = hashmacaddr8extended(v, 1)::bit(32); + +SELECT v as value, hash_array(v)::bit(32) as standard, + hash_array_extended(v, 0)::bit(32) as extended0, + hash_array_extended(v, 1)::bit(32) as extended1 +FROM (VALUES ('{0}'::int4[]), ('{0,1,2,3,4}'), ('{17,18,19,20}'), + ('{42,34,65,98}'), ('{550273,590027, 870273}'), + ('{207112489, 807112489}')) x(v) +WHERE hash_array(v)::bit(32) != hash_array_extended(v, 0)::bit(32) + OR hash_array(v)::bit(32) = hash_array_extended(v, 1)::bit(32); + +SELECT v as value, hash_array(v)::bit(32) as standard +FROM (VALUES ('{101}'::varbit[])) x(v); + +SELECT v as value, hash_array_extended(v, 0)::bit(32) as extended0 +FROM (VALUES ('{101}'::varbit[])) x(v); + +SELECT v as value, hashbpchar(v)::bit(32) as standard, + hashbpcharextended(v, 0)::bit(32) as extended0, + hashbpcharextended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE hashbpchar(v)::bit(32) != hashbpcharextended(v, 0)::bit(32) + OR hashbpchar(v)::bit(32) = hashbpcharextended(v, 1)::bit(32); + +SELECT v as value, time_hash(v)::bit(32) as standard, + time_hash_extended(v, 0)::bit(32) as extended0, + time_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::time), ('11:09:59'), ('1:09:59'), ('11:59:59'), + ('7:9:59'), ('5:15:59')) x(v) +WHERE time_hash(v)::bit(32) != time_hash_extended(v, 0)::bit(32) + OR time_hash(v)::bit(32) = time_hash_extended(v, 1)::bit(32); + +SELECT v as value, timetz_hash(v)::bit(32) as standard, + timetz_hash_extended(v, 0)::bit(32) as extended0, + timetz_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::timetz), ('00:11:52.518762-07'), ('00:11:52.51762-08'), + ('00:11:52.62-01'), ('00:11:52.62+01'), ('11:59:59+04')) x(v) +WHERE timetz_hash(v)::bit(32) != timetz_hash_extended(v, 0)::bit(32) + OR timetz_hash(v)::bit(32) = timetz_hash_extended(v, 1)::bit(32); + +SELECT v as value, interval_hash(v)::bit(32) as standard, + interval_hash_extended(v, 0)::bit(32) as extended0, + interval_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::interval), + ('5 month 7 day 46 minutes'), ('1 year 7 day 46 minutes'), + ('1 year 7 month 20 day 46 minutes'), ('5 month'), + ('17 year 11 month 7 day 9 hours 46 minutes 5 seconds')) x(v) +WHERE interval_hash(v)::bit(32) != interval_hash_extended(v, 0)::bit(32) + OR interval_hash(v)::bit(32) = interval_hash_extended(v, 1)::bit(32); + +SELECT v as value, timestamp_hash(v)::bit(32) as standard, + timestamp_hash_extended(v, 0)::bit(32) as extended0, + timestamp_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::timestamp), ('2017-08-22 00:09:59.518762'), + ('2015-08-20 00:11:52.51762-08'), + ('2017-05-22 00:11:52.62-01'), + ('2013-08-22 00:11:52.62+01'), ('2013-08-22 11:59:59+04')) x(v) +WHERE timestamp_hash(v)::bit(32) != timestamp_hash_extended(v, 0)::bit(32) + OR timestamp_hash(v)::bit(32) = timestamp_hash_extended(v, 1)::bit(32); + +SELECT v as value, uuid_hash(v)::bit(32) as standard, + uuid_hash_extended(v, 0)::bit(32) as extended0, + uuid_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::uuid), ('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'), + ('5a9ba4ac-8d6f-11e7-bb31-be2e44b06b34'), + ('99c6705c-d939-461c-a3c9-1690ad64ed7b'), + ('7deed3ca-8d6f-11e7-bb31-be2e44b06b34'), + ('9ad46d4f-6f2a-4edd-aadb-745993928e1e')) x(v) +WHERE uuid_hash(v)::bit(32) != uuid_hash_extended(v, 0)::bit(32) + OR uuid_hash(v)::bit(32) = uuid_hash_extended(v, 1)::bit(32); + +SELECT v as value, pg_lsn_hash(v)::bit(32) as standard, + pg_lsn_hash_extended(v, 0)::bit(32) as extended0, + pg_lsn_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::pg_lsn), ('16/B374D84'), ('30/B374D84'), + ('255/B374D84'), ('25/B379D90'), ('900/F37FD90')) x(v) +WHERE pg_lsn_hash(v)::bit(32) != pg_lsn_hash_extended(v, 0)::bit(32) + OR pg_lsn_hash(v)::bit(32) = pg_lsn_hash_extended(v, 1)::bit(32); + +CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); + +SELECT v as value, hashenum(v)::bit(32) as standard, + hashenumextended(v, 0)::bit(32) as extended0, + hashenumextended(v, 1)::bit(32) as extended1 +FROM (VALUES ('sad'::mood), ('ok'), ('happy')) x(v) +WHERE hashenum(v)::bit(32) != hashenumextended(v, 0)::bit(32) + OR hashenum(v)::bit(32) = hashenumextended(v, 1)::bit(32); + +DROP TYPE mood; + +SELECT v as value, jsonb_hash(v)::bit(32) as standard, + jsonb_hash_extended(v, 0)::bit(32) as extended0, + jsonb_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::jsonb), + ('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'), + ('{"foo": [true, "bar"], "tags": {"e": 1, "f": null}}'), + ('{"g": {"h": "value"}}')) x(v) +WHERE jsonb_hash(v)::bit(32) != jsonb_hash_extended(v, 0)::bit(32) + OR jsonb_hash(v)::bit(32) = jsonb_hash_extended(v, 1)::bit(32); + +SELECT v as value, hash_range(v)::bit(32) as standard, + hash_range_extended(v, 0)::bit(32) as extended0, + hash_range_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (int4range(10, 20)), (int4range(23, 43)), + (int4range(5675, 550273)), + (int4range(550274, 1550274)), (int4range(1550275, 208112489))) x(v) +WHERE hash_range(v)::bit(32) != hash_range_extended(v, 0)::bit(32) + OR hash_range(v)::bit(32) = hash_range_extended(v, 1)::bit(32); + +SELECT v as value, hash_multirange(v)::bit(32) as standard, + hash_multirange_extended(v, 0)::bit(32) as extended0, + hash_multirange_extended(v, 1)::bit(32) as extended1 +FROM (VALUES ('{[10,20)}'::int4multirange), ('{[23, 43]}'::int4multirange), + ('{[5675, 550273)}'::int4multirange), + ('{[550274, 1550274)}'::int4multirange), + ('{[1550275, 208112489)}'::int4multirange)) x(v) +WHERE hash_multirange(v)::bit(32) != hash_multirange_extended(v, 0)::bit(32) + OR hash_multirange(v)::bit(32) = hash_multirange_extended(v, 1)::bit(32); + +CREATE TYPE hash_test_t1 AS (a int, b text); + +SELECT v as value, hash_record(v)::bit(32) as standard, + hash_record_extended(v, 0)::bit(32) as extended0, + hash_record_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (row(1, 'aaa')::hash_test_t1, row(2, 'bbb'), row(-1, 'ccc'))) x(v) +WHERE hash_record(v)::bit(32) != hash_record_extended(v, 0)::bit(32) + OR hash_record(v)::bit(32) = hash_record_extended(v, 1)::bit(32); + +DROP TYPE hash_test_t1; + +CREATE TYPE hash_test_t2 AS (a varbit, b text); + +SELECT v as value, hash_record(v)::bit(32) as standard +FROM (VALUES (row('10'::varbit, 'aaa')::hash_test_t2)) x(v); + +SELECT v as value, hash_record_extended(v, 0)::bit(32) as extended0 +FROM (VALUES (row('11'::varbit, 'aaa')::hash_test_t2)) x(v); + +DROP TYPE hash_test_t2; + +SELECT hashfloat4('0'::float4) = hashfloat4('-0'::float4) AS t; + +SELECT hashfloat4('NaN'::float4) = hashfloat4(-'NaN'::float4) AS t; + +SELECT hashfloat8('0'::float8) = hashfloat8('-0'::float8) AS t; + +SELECT hashfloat8('NaN'::float8) = hashfloat8(-'NaN'::float8) AS t; + +SELECT hashfloat4('NaN'::float4) = hashfloat8('NaN'::float8) AS t; diff --git a/crates/pgt_pretty_print/tests/data/multi/hash_index_60.sql b/crates/pgt_pretty_print/tests/data/multi/hash_index_60.sql new file mode 100644 index 000000000..a6975f3a6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/hash_index_60.sql @@ -0,0 +1,248 @@ +CREATE TABLE hash_i4_heap ( + seqno int4, + random int4 +); + +CREATE TABLE hash_name_heap ( + seqno int4, + random name +); + +CREATE TABLE hash_txt_heap ( + seqno int4, + random text +); + +CREATE TABLE hash_f8_heap ( + seqno int4, + random float8 +); + +COPY hash_i4_heap FROM 'filename'; + +COPY hash_name_heap FROM 'filename'; + +COPY hash_txt_heap FROM 'filename'; + +COPY hash_f8_heap FROM 'filename'; + +ANALYZE hash_i4_heap; + +ANALYZE hash_name_heap; + +ANALYZE hash_txt_heap; + +ANALYZE hash_f8_heap; + +CREATE INDEX hash_i4_index ON hash_i4_heap USING hash (random int4_ops); + +CREATE INDEX hash_name_index ON hash_name_heap USING hash (random name_ops); + +CREATE INDEX hash_txt_index ON hash_txt_heap USING hash (random text_ops); + +CREATE INDEX hash_f8_index ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=60); + +create unique index hash_f8_index_1 on hash_f8_heap(abs(random)); + +create unique index hash_f8_index_2 on hash_f8_heap((seqno + 1), random); + +create unique index hash_f8_index_3 on hash_f8_heap(random) where seqno > 1000; + +SELECT * FROM hash_i4_heap + WHERE hash_i4_heap.random = 843938989; + +SELECT * FROM hash_i4_heap + WHERE hash_i4_heap.random = 66766766; + +SELECT * FROM hash_name_heap + WHERE hash_name_heap.random = '1505703298'::name; + +SELECT * FROM hash_name_heap + WHERE hash_name_heap.random = '7777777'::name; + +SELECT * FROM hash_txt_heap + WHERE hash_txt_heap.random = '1351610853'::text; + +SELECT * FROM hash_txt_heap + WHERE hash_txt_heap.random = '111111112222222233333333'::text; + +SELECT * FROM hash_f8_heap + WHERE hash_f8_heap.random = '444705537'::float8; + +SELECT * FROM hash_f8_heap + WHERE hash_f8_heap.random = '88888888'::float8; + +UPDATE hash_i4_heap + SET random = 1 + WHERE hash_i4_heap.seqno = 1492; + +SELECT h.seqno AS i1492, h.random AS i1 + FROM hash_i4_heap h + WHERE h.random = 1; + +UPDATE hash_i4_heap + SET seqno = 20000 + WHERE hash_i4_heap.random = 1492795354; + +SELECT h.seqno AS i20000 + FROM hash_i4_heap h + WHERE h.random = 1492795354; + +UPDATE hash_name_heap + SET random = '0123456789abcdef'::name + WHERE hash_name_heap.seqno = 6543; + +SELECT h.seqno AS i6543, h.random AS c0_to_f + FROM hash_name_heap h + WHERE h.random = '0123456789abcdef'::name; + +UPDATE hash_name_heap + SET seqno = 20000 + WHERE hash_name_heap.random = '76652222'::name; + +SELECT h.seqno AS emptyset + FROM hash_name_heap h + WHERE h.random = '76652222'::name; + +UPDATE hash_txt_heap + SET random = '0123456789abcdefghijklmnop'::text + WHERE hash_txt_heap.seqno = 4002; + +SELECT h.seqno AS i4002, h.random AS c0_to_p + FROM hash_txt_heap h + WHERE h.random = '0123456789abcdefghijklmnop'::text; + +UPDATE hash_txt_heap + SET seqno = 20000 + WHERE hash_txt_heap.random = '959363399'::text; + +SELECT h.seqno AS t20000 + FROM hash_txt_heap h + WHERE h.random = '959363399'::text; + +UPDATE hash_f8_heap + SET random = '-1234.1234'::float8 + WHERE hash_f8_heap.seqno = 8906; + +SELECT h.seqno AS i8096, h.random AS f1234_1234 + FROM hash_f8_heap h + WHERE h.random = '-1234.1234'::float8; + +UPDATE hash_f8_heap + SET seqno = 20000 + WHERE hash_f8_heap.random = '488912369'::float8; + +SELECT h.seqno AS f20000 + FROM hash_f8_heap h + WHERE h.random = '488912369'::float8; + +CREATE TABLE hash_split_heap (keycol INT); + +INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 500) a; + +CREATE INDEX hash_split_index on hash_split_heap USING HASH (keycol); + +INSERT INTO hash_split_heap SELECT 1 FROM generate_series(1, 5000) a; + +BEGIN; + +SET enable_seqscan = OFF; + +SET enable_bitmapscan = OFF; + +DECLARE c CURSOR FOR SELECT * from hash_split_heap WHERE keycol = 1; + +MOVE FORWARD ALL FROM c; + +MOVE BACKWARD 10000 FROM c; + +MOVE BACKWARD ALL FROM c; + +CLOSE c; + +END; + +DELETE FROM hash_split_heap WHERE keycol = 1; + +INSERT INTO hash_split_heap SELECT a/2 FROM generate_series(1, 25000) a; + +VACUUM hash_split_heap; + +ALTER INDEX hash_split_index SET (fillfactor = 10); + +REINDEX INDEX hash_split_index; + +DROP TABLE hash_split_heap; + +CREATE TABLE hash_cleanup_heap(keycol INT); + +CREATE INDEX hash_cleanup_index on hash_cleanup_heap USING HASH (keycol); + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i; + +BEGIN; + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1000) as i; + +ROLLBACK; + +CHECKPOINT; + +VACUUM hash_cleanup_heap; + +TRUNCATE hash_cleanup_heap; + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) as i; + +BEGIN; + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) as i; + +ROLLBACK; + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i; + +CHECKPOINT; + +VACUUM hash_cleanup_heap; + +TRUNCATE hash_cleanup_heap; + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 500) as i; + +BEGIN; + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 1500) as i; + +ROLLBACK; + +INSERT INTO hash_cleanup_heap SELECT 1 FROM generate_series(1, 50) as i; + +CHECKPOINT; + +VACUUM hash_cleanup_heap; + +DROP TABLE hash_cleanup_heap; + +CREATE TEMP TABLE hash_temp_heap (x int, y int); + +INSERT INTO hash_temp_heap VALUES (1,1); + +CREATE INDEX hash_idx ON hash_temp_heap USING hash (x); + +DROP TABLE hash_temp_heap CASCADE; + +CREATE TABLE hash_heap_float4 (x float4, y int); + +INSERT INTO hash_heap_float4 VALUES (1.1,1); + +CREATE INDEX hash_idx ON hash_heap_float4 USING hash (x); + +DROP TABLE hash_heap_float4 CASCADE; + +CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=9); + +CREATE INDEX hash_f8_index2 ON hash_f8_heap USING hash (random float8_ops) + WITH (fillfactor=101); diff --git a/crates/pgt_pretty_print/tests/data/multi/hash_part_60.sql b/crates/pgt_pretty_print/tests/data/multi/hash_part_60.sql new file mode 100644 index 000000000..acb242627 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/hash_part_60.sql @@ -0,0 +1,64 @@ +CREATE TABLE mchash (a int, b text, c jsonb) + PARTITION BY HASH (a part_test_int4_ops, b part_test_text_ops); + +CREATE TABLE mchash1 + PARTITION OF mchash FOR VALUES WITH (MODULUS 4, REMAINDER 0); + +SELECT satisfies_hash_partition(0, 4, 0, NULL); + +SELECT satisfies_hash_partition('tenk1'::regclass, 4, 0, NULL); + +SELECT satisfies_hash_partition('mchash1'::regclass, 4, 0, NULL); + +SELECT satisfies_hash_partition('mchash'::regclass, 0, 0, NULL); + +SELECT satisfies_hash_partition('mchash'::regclass, 1, -1, NULL); + +SELECT satisfies_hash_partition('mchash'::regclass, 1, 1, NULL); + +SELECT satisfies_hash_partition('mchash'::regclass, NULL, 0, NULL); + +SELECT satisfies_hash_partition('mchash'::regclass, 4, NULL, NULL); + +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, NULL::int, NULL::text, NULL::json); + +SELECT satisfies_hash_partition('mchash'::regclass, 3, 1, NULL::int); + +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, NULL::int, NULL::int); + +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 0, ''::text); + +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 2, ''::text); + +SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, + variadic array[1,2]::int[]); + +CREATE TABLE mcinthash (a int, b int, c jsonb) + PARTITION BY HASH (a part_test_int4_ops, b part_test_int4_ops); + +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[0, 0]); + +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[0, 1]); + +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[]::int[]); + +SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, + variadic array[now(), now()]); + +create table text_hashp (a text) partition by hash (a); + +create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0); + +create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1); + +select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR + satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies; + +DROP TABLE mchash; + +DROP TABLE mcinthash; + +DROP TABLE text_hashp; diff --git a/crates/pgt_pretty_print/tests/data/multi/horology_60.sql b/crates/pgt_pretty_print/tests/data/multi/horology_60.sql new file mode 100644 index 000000000..7d3e41eae --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/horology_60.sql @@ -0,0 +1,853 @@ +SHOW TimeZone; + +SHOW DateStyle; + +SELECT timestamp with time zone '20011227 040506+08'; + +SELECT timestamp with time zone '20011227 040506-08'; + +SELECT timestamp with time zone '20011227 040506.789+08'; + +SELECT timestamp with time zone '20011227 040506.789-08'; + +SELECT timestamp with time zone '20011227T040506+08'; + +SELECT timestamp with time zone '20011227T040506-08'; + +SELECT timestamp with time zone '20011227T040506.789+08'; + +SELECT timestamp with time zone '20011227T040506.789-08'; + +SELECT timestamp with time zone '2001-12-27 04:05:06.789-08'; + +SELECT timestamp with time zone '2001.12.27 04:05:06.789-08'; + +SELECT timestamp with time zone '2001/12/27 04:05:06.789-08'; + +SELECT timestamp with time zone '12/27/2001 04:05:06.789-08'; + +SELECT timestamp with time zone '2001-12-27 04:05:06.789 MET DST'; + +SELECT timestamp with time zone '2001-12-27 allballs'; + +SELECT timestamp with time zone '27/12/2001 04:05:06.789-08'; + +set datestyle to dmy; + +SELECT timestamp with time zone '27/12/2001 04:05:06.789-08'; + +reset datestyle; + +SELECT timestamp with time zone 'J2452271+08'; + +SELECT timestamp with time zone 'J2452271-08'; + +SELECT timestamp with time zone 'J2452271.5+08'; + +SELECT timestamp with time zone 'J2452271.5-08'; + +SELECT timestamp with time zone 'J2452271 04:05:06+08'; + +SELECT timestamp with time zone 'J2452271 04:05:06-08'; + +SELECT timestamp with time zone 'J2452271T040506+08'; + +SELECT timestamp with time zone 'J2452271T040506-08'; + +SELECT timestamp with time zone 'J2452271T040506.789+08'; + +SELECT timestamp with time zone 'J2452271T040506.789-08'; + +SELECT timestamp with time zone '12.27.2001 04:05:06.789+08'; + +SELECT timestamp with time zone '12.27.2001 04:05:06.789-08'; + +SET DateStyle = 'German'; + +SELECT timestamp with time zone '27.12.2001 04:05:06.789+08'; + +SELECT timestamp with time zone '27.12.2001 04:05:06.789-08'; + +SET DateStyle = 'ISO'; + +SELECT time without time zone '040506.789+08'; + +SELECT time without time zone '040506.789-08'; + +SELECT time without time zone 'T040506.789+08'; + +SELECT time without time zone 'T040506.789-08'; + +SELECT time with time zone '040506.789+08'; + +SELECT time with time zone '040506.789-08'; + +SELECT time with time zone 'T040506.789+08'; + +SELECT time with time zone 'T040506.789-08'; + +SELECT time with time zone 'T040506.789 +08'; + +SELECT time with time zone 'T040506.789 -08'; + +SELECT time with time zone 'T040506.789 America/Los_Angeles'; + +SELECT time with time zone '2001-12-27 T040506.789 America/Los_Angeles'; + +SELECT time with time zone 'J2452271 T040506.789 America/Los_Angeles'; + +SELECT time without time zone '040506.07'; + +SELECT time without time zone '04:05:06.07'; + +SELECT time without time zone '040506'; + +SELECT time without time zone '04:05:06'; + +SELECT time without time zone '0405'; + +SELECT time without time zone '04:05'; + +SELECT time without time zone 'T040506.07'; + +SELECT time without time zone 'T04:05:06.07'; + +SELECT time without time zone 'T040506'; + +SELECT time without time zone 'T04:05:06'; + +SELECT time without time zone 'T0405'; + +SELECT time without time zone 'T04:05'; + +SELECT time without time zone 'T04'; + +SELECT time with time zone '040506.07+08'; + +SELECT time with time zone '04:05:06.07+08'; + +SELECT time with time zone '040506+08'; + +SELECT time with time zone '04:05:06+08'; + +SELECT time with time zone '0405+08'; + +SELECT time with time zone '04:05+08'; + +SELECT time with time zone 'T040506.07+08'; + +SELECT time with time zone 'T04:05:06.07+08'; + +SELECT time with time zone 'T040506+08'; + +SELECT time with time zone 'T04:05:06+08'; + +SELECT time with time zone 'T0405+08'; + +SELECT time with time zone 'T04:05+08'; + +SELECT time with time zone 'T04+08'; + +SET DateStyle = 'Postgres, MDY'; + +SELECT date 'J1520447' AS "Confucius' Birthday"; + +SELECT date 'J0' AS "Julian Epoch"; + +SELECT date '1995-08-06 J J J'; + +SELECT date 'J J 1520447'; + +SELECT timestamp with time zone 'Y2001M12D27H04M05S06.789+08'; + +SELECT timestamp with time zone 'Y2001M12D27H04MM05S06.789-08'; + +SELECT timestamp with time zone 'J2452271 T X03456-08'; + +SELECT timestamp with time zone 'J2452271 T X03456.001e6-08'; + +SELECT date '1995-08-06 epoch'; + +SELECT date '1995-08-06 infinity'; + +SELECT date '1995-08-06 -infinity'; + +SELECT date 'today infinity'; + +SELECT date '-infinity infinity'; + +SELECT timestamp '1995-08-06 epoch'; + +SELECT timestamp '1995-08-06 infinity'; + +SELECT timestamp '1995-08-06 -infinity'; + +SELECT timestamp 'epoch 01:01:01'; + +SELECT timestamp 'infinity 01:01:01'; + +SELECT timestamp '-infinity 01:01:01'; + +SELECT timestamp 'now epoch'; + +SELECT timestamp '-infinity infinity'; + +SELECT timestamptz '1995-08-06 epoch'; + +SELECT timestamptz '1995-08-06 infinity'; + +SELECT timestamptz '1995-08-06 -infinity'; + +SELECT timestamptz 'epoch 01:01:01'; + +SELECT timestamptz 'infinity 01:01:01'; + +SELECT timestamptz '-infinity 01:01:01'; + +SELECT timestamptz 'now epoch'; + +SELECT timestamptz '-infinity infinity'; + +SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time"; + +SELECT date '1991-02-03' + time with time zone '04:05:06 PST' AS "Date + Time PST"; + +SELECT date '2001-02-03' + time with time zone '04:05:06 UTC' AS "Date + Time UTC"; + +SELECT date '1991-02-03' + interval '2 years' AS "Add Two Years"; + +SELECT date '2001-12-13' - interval '2 years' AS "Subtract Two Years"; + +SELECT date '1991-02-03' - time '04:05:06' AS "Subtract Time"; + +SELECT date '1991-02-03' - time with time zone '04:05:06 UTC' AS "Subtract Time UTC"; + +SELECT timestamp without time zone '1996-03-01' - interval '1 second' AS "Feb 29"; + +SELECT timestamp without time zone '1999-03-01' - interval '1 second' AS "Feb 28"; + +SELECT timestamp without time zone '2000-03-01' - interval '1 second' AS "Feb 29"; + +SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31"; + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506"; + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244"; + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276"; + +SELECT timestamp without time zone '2000-01-01' - interval '2483590 days' AS "out of range"; + +SELECT timestamp without time zone '294276-12-31 23:59:59' + interval '9223372036854775807 microseconds' AS "out of range"; + +SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days"; + +SELECT (timestamp without time zone 'today' = (timestamp without time zone 'yesterday' + interval '1 day')) as "True"; + +SELECT (timestamp without time zone 'today' = (timestamp without time zone 'tomorrow' - interval '1 day')) as "True"; + +SELECT (timestamp without time zone 'today 10:30' = (timestamp without time zone 'yesterday' + interval '1 day 10 hr 30 min')) as "True"; + +SELECT (timestamp without time zone '10:30 today' = (timestamp without time zone 'yesterday' + interval '1 day 10 hr 30 min')) as "True"; + +SELECT (timestamp without time zone 'tomorrow' = (timestamp without time zone 'yesterday' + interval '2 days')) as "True"; + +SELECT (timestamp without time zone 'tomorrow 16:00:00' = (timestamp without time zone 'today' + interval '1 day 16 hours')) as "True"; + +SELECT (timestamp without time zone '16:00:00 tomorrow' = (timestamp without time zone 'today' + interval '1 day 16 hours')) as "True"; + +SELECT (timestamp without time zone 'yesterday 12:34:56' = (timestamp without time zone 'tomorrow' - interval '2 days - 12:34:56')) as "True"; + +SELECT (timestamp without time zone '12:34:56 yesterday' = (timestamp without time zone 'tomorrow' - interval '2 days - 12:34:56')) as "True"; + +SELECT (timestamp without time zone 'tomorrow' > 'now') as "True"; + +SELECT date '1994-01-01' + time '11:00' AS "Jan_01_1994_11am"; + +SELECT date '1994-01-01' + time '10:00' AS "Jan_01_1994_10am"; + +SELECT date '1994-01-01' + timetz '11:00-5' AS "Jan_01_1994_8am"; + +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am"; + +SELECT d1 + interval '1 year' AS one_year FROM TIMESTAMP_TBL; + +SELECT d1 - interval '1 year' AS one_year FROM TIMESTAMP_TBL; + +SELECT timestamp with time zone '1996-03-01' - interval '1 second' AS "Feb 29"; + +SELECT timestamp with time zone '1999-03-01' - interval '1 second' AS "Feb 28"; + +SELECT timestamp with time zone '2000-03-01' - interval '1 second' AS "Feb 29"; + +SELECT timestamp with time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31"; + +SELECT timestamp with time zone '2000-01-01' - interval '2483590 days' AS "out of range"; + +SELECT timestamp with time zone '294276-12-31 23:59:59 UTC' + interval '9223372036854775807 microseconds' AS "out of range"; + +SELECT (timestamp with time zone 'today' = (timestamp with time zone 'yesterday' + interval '1 day')) as "True"; + +SELECT (timestamp with time zone 'today' = (timestamp with time zone 'tomorrow' - interval '1 day')) as "True"; + +SELECT (timestamp with time zone 'tomorrow' = (timestamp with time zone 'yesterday' + interval '2 days')) as "True"; + +SELECT (timestamp with time zone 'tomorrow' > 'now') as "True"; + +SET TIME ZONE 'CST7CDT,M4.1.0,M10.5.0'; + +SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '1 day' as "Apr 3, 12:00"; + +SELECT timestamp with time zone '2005-04-02 12:00-07' + interval '24 hours' as "Apr 3, 13:00"; + +SELECT timestamp with time zone '2005-04-03 12:00-06' - interval '1 day' as "Apr 2, 12:00"; + +SELECT timestamp with time zone '2005-04-03 12:00-06' - interval '24 hours' as "Apr 2, 11:00"; + +RESET TIME ZONE; + +SELECT timestamptz(date '1994-01-01', time '11:00') AS "Jan_01_1994_10am"; + +SELECT timestamptz(date '1994-01-01', time '10:00') AS "Jan_01_1994_9am"; + +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-8') AS "Jan_01_1994_11am"; + +SELECT timestamptz(date '1994-01-01', time with time zone '10:00-8') AS "Jan_01_1994_10am"; + +SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am"; + +SELECT d1 + interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL; + +SELECT d1 - interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL; + +SELECT CAST(time '01:02' AS interval) AS "+01:02"; + +SELECT CAST(interval '02:03' AS time) AS "02:03:00"; + +SELECT CAST(interval '-02:03' AS time) AS "21:57:00"; + +SELECT CAST(interval '-9223372022400000000 us' AS time) AS "00:00:00"; + +SELECT time '01:30' + interval '02:01' AS "03:31:00"; + +SELECT time '01:30' - interval '02:01' AS "23:29:00"; + +SELECT time '02:30' + interval '36:01' AS "14:31:00"; + +SELECT time '03:30' + interval '1 month 04:01' AS "07:31:00"; + +SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01"; + +SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08"; + +SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08"; + +SELECT time with time zone '02:30-08' + interval '36:01' AS "14:31:00-08"; + +SELECT CAST(CAST(date 'today' + time with time zone '05:30' + + interval '02:01' AS time with time zone) AS time) AS "07:31:00"; + +SELECT CAST(cast(date 'today' + time with time zone '03:30' + + interval '1 month 04:01' as timestamp without time zone) AS time) AS "07:31:00"; + +SELECT t.d1 AS t, i.f1 AS i, t.d1 + i.f1 AS "add", t.d1 - i.f1 AS "subtract" + FROM TIMESTAMP_TBL t, INTERVAL_TBL i + WHERE t.d1 BETWEEN '1990-01-01' AND '2001-01-01' + AND i.f1 BETWEEN '00:00' AND '23:00' + ORDER BY 1,2; + +SELECT t.f1 AS t, i.f1 AS i, t.f1 + i.f1 AS "add", t.f1 - i.f1 AS "subtract" + FROM TIME_TBL t, INTERVAL_TBL i + WHERE isfinite(i.f1) + ORDER BY 1,2; + +SELECT t.f1 AS t, i.f1 AS i, t.f1 + i.f1 AS "add", t.f1 - i.f1 AS "subtract" + FROM TIMETZ_TBL t, INTERVAL_TBL i + WHERE isfinite(i.f1) + ORDER BY 1,2; + +SELECT (timestamp with time zone '2000-11-27', timestamp with time zone '2000-11-28') + OVERLAPS (timestamp with time zone '2000-11-27 12:00', timestamp with time zone '2000-11-30') AS "True"; + +SELECT (timestamp with time zone '2000-11-26', timestamp with time zone '2000-11-27') + OVERLAPS (timestamp with time zone '2000-11-27 12:00', timestamp with time zone '2000-11-30') AS "False"; + +SELECT (timestamp with time zone '2000-11-27', timestamp with time zone '2000-11-28') + OVERLAPS (timestamp with time zone '2000-11-27 12:00', interval '1 day') AS "True"; + +SELECT (timestamp with time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp with time zone '2000-11-27 12:00', timestamp with time zone '2000-11-30') AS "False"; + +SELECT (timestamp with time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp with time zone '2000-11-27', interval '12 hours') AS "True"; + +SELECT (timestamp with time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp with time zone '2000-11-27 12:00', interval '12 hours') AS "False"; + +SELECT (timestamp without time zone '2000-11-27', timestamp without time zone '2000-11-28') + OVERLAPS (timestamp without time zone '2000-11-27 12:00', timestamp without time zone '2000-11-30') AS "True"; + +SELECT (timestamp without time zone '2000-11-26', timestamp without time zone '2000-11-27') + OVERLAPS (timestamp without time zone '2000-11-27 12:00', timestamp without time zone '2000-11-30') AS "False"; + +SELECT (timestamp without time zone '2000-11-27', timestamp without time zone '2000-11-28') + OVERLAPS (timestamp without time zone '2000-11-27 12:00', interval '1 day') AS "True"; + +SELECT (timestamp without time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp without time zone '2000-11-27 12:00', timestamp without time zone '2000-11-30') AS "False"; + +SELECT (timestamp without time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp without time zone '2000-11-27', interval '12 hours') AS "True"; + +SELECT (timestamp without time zone '2000-11-27', interval '12 hours') + OVERLAPS (timestamp without time zone '2000-11-27 12:00', interval '12 hours') AS "False"; + +SELECT (time '00:00', time '01:00') + OVERLAPS (time '00:30', time '01:30') AS "True"; + +SELECT (time '00:00', interval '1 hour') + OVERLAPS (time '00:30', interval '1 hour') AS "True"; + +SELECT (time '00:00', interval '1 hour') + OVERLAPS (time '01:30', interval '1 hour') AS "False"; + +SELECT (time '00:00', interval '1 hour') + OVERLAPS (time '01:30', interval '1 day') AS "False"; + +CREATE TABLE TEMP_TIMESTAMP (f1 timestamp with time zone); + +INSERT INTO TEMP_TIMESTAMP (f1) + SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 BETWEEN '13-jun-1957' AND '1-jan-1997' + OR d1 BETWEEN '1-jan-1999' AND '1-jan-2010'; + +SELECT f1 AS "timestamp" + FROM TEMP_TIMESTAMP + ORDER BY "timestamp"; + +SELECT d.f1 AS "timestamp", t.f1 AS "interval", d.f1 + t.f1 AS plus + FROM TEMP_TIMESTAMP d, INTERVAL_TBL t + ORDER BY plus, "timestamp", "interval"; + +SELECT d.f1 AS "timestamp", t.f1 AS "interval", d.f1 - t.f1 AS minus + FROM TEMP_TIMESTAMP d, INTERVAL_TBL t + ORDER BY minus, "timestamp", "interval"; + +SELECT d.f1 AS "timestamp", + timestamp with time zone '1980-01-06 00:00 GMT' AS gpstime_zero, + d.f1 - timestamp with time zone '1980-01-06 00:00 GMT' AS difference + FROM TEMP_TIMESTAMP d + ORDER BY difference; + +SELECT d1.f1 AS timestamp1, d2.f1 AS timestamp2, d1.f1 - d2.f1 AS difference + FROM TEMP_TIMESTAMP d1, TEMP_TIMESTAMP d2 + ORDER BY timestamp1, timestamp2, difference; + +SELECT f1 AS "timestamp", date(f1) AS date + FROM TEMP_TIMESTAMP + WHERE f1 <> timestamp 'now' + ORDER BY date, "timestamp"; + +DROP TABLE TEMP_TIMESTAMP; + +SELECT '2202020-10-05'::date::timestamp; + +SELECT '2202020-10-05'::date > '2020-10-05'::timestamp as t; + +SELECT '2020-10-05'::timestamp > '2202020-10-05'::date as f; + +SELECT '2202020-10-05'::date::timestamptz; + +SELECT '2202020-10-05'::date > '2020-10-05'::timestamptz as t; + +SELECT '2020-10-05'::timestamptz > '2202020-10-05'::date as f; + +SELECT '4714-11-24 BC'::date::timestamptz; + +SET TimeZone = 'UTC-2'; + +SELECT '4714-11-24 BC'::date::timestamptz; + +SELECT '4714-11-24 BC'::date < '2020-10-05'::timestamptz as t; + +SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::date as t; + +SELECT '4714-11-24 BC'::timestamp < '2020-10-05'::timestamptz as t; + +SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::timestamp as t; + +RESET TimeZone; + +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01'; + +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01'; + +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01'; + +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01'; + +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01'; + +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01'; + +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01'; + +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01'; + +SET DateStyle TO 'US,Postgres'; + +SHOW DateStyle; + +SELECT d1 AS us_postgres FROM TIMESTAMP_TBL; + +SET DateStyle TO 'US,ISO'; + +SELECT d1 AS us_iso FROM TIMESTAMP_TBL; + +SET DateStyle TO 'US,SQL'; + +SHOW DateStyle; + +SELECT d1 AS us_sql FROM TIMESTAMP_TBL; + +SET DateStyle TO 'European,Postgres'; + +SHOW DateStyle; + +INSERT INTO TIMESTAMP_TBL VALUES('13/06/1957'); + +SELECT count(*) as one FROM TIMESTAMP_TBL WHERE d1 = 'Jun 13 1957'; + +SELECT d1 AS european_postgres FROM TIMESTAMP_TBL; + +SET DateStyle TO 'European,ISO'; + +SHOW DateStyle; + +SELECT d1 AS european_iso FROM TIMESTAMP_TBL; + +SET DateStyle TO 'European,SQL'; + +SHOW DateStyle; + +SELECT d1 AS european_sql FROM TIMESTAMP_TBL; + +RESET DateStyle; + +SELECT to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS'); + +SELECT to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS'); + +SELECT to_timestamp('2011$03!18 23_38_15', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('1985 January 12', 'YYYY FMMonth DD'); + +SELECT to_timestamp('1985 FMMonth 12', 'YYYY "FMMonth" DD'); + +SELECT to_timestamp('1985 \ 12', 'YYYY \\ DD'); + +SELECT to_timestamp('My birthday-> Year: 1976, Month: May, Day: 16', + '"My birthday-> Year:" YYYY, "Month:" FMMonth, "Day:" DD'); + +SELECT to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); + +SELECT to_timestamp('15 "text between quote marks" 98 54 45', + E'HH24 "\\"text between quote marks\\"" YY MI SS'); + +SELECT to_timestamp('05121445482000', 'MMDDHH24MISSYYYY'); + +SELECT to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay'); + +SELECT to_timestamp('97/Feb/16', 'YYMonDD'); + +SELECT to_timestamp('97/Feb/16', 'YY:Mon:DD'); + +SELECT to_timestamp('97/Feb/16', 'FXYY:Mon:DD'); + +SELECT to_timestamp('97/Feb/16', 'FXYY/Mon/DD'); + +SELECT to_timestamp('19971116', 'YYYYMMDD'); + +SELECT to_timestamp('20000-1116', 'YYYY-MMDD'); + +SELECT to_timestamp('1997 AD 11 16', 'YYYY BC MM DD'); + +SELECT to_timestamp('1997 BC 11 16', 'YYYY BC MM DD'); + +SELECT to_timestamp('1997 A.D. 11 16', 'YYYY B.C. MM DD'); + +SELECT to_timestamp('1997 B.C. 11 16', 'YYYY B.C. MM DD'); + +SELECT to_timestamp('9-1116', 'Y-MMDD'); + +SELECT to_timestamp('95-1116', 'YY-MMDD'); + +SELECT to_timestamp('995-1116', 'YYY-MMDD'); + +SELECT to_timestamp('2005426', 'YYYYWWD'); + +SELECT to_timestamp('2005300', 'YYYYDDD'); + +SELECT to_timestamp('2005527', 'IYYYIWID'); + +SELECT to_timestamp('005527', 'IYYIWID'); + +SELECT to_timestamp('05527', 'IYIWID'); + +SELECT to_timestamp('5527', 'IIWID'); + +SELECT to_timestamp('2005364', 'IYYYIDDD'); + +SELECT to_timestamp('20050302', 'YYYYMMDD'); + +SELECT to_timestamp('2005 03 02', 'YYYYMMDD'); + +SELECT to_timestamp(' 2005 03 02', 'YYYYMMDD'); + +SELECT to_timestamp(' 20050302', 'YYYYMMDD'); + +SELECT to_timestamp('2011-12-18 11:38 AM', 'YYYY-MM-DD HH12:MI PM'); + +SELECT to_timestamp('2011-12-18 11:38 PM', 'YYYY-MM-DD HH12:MI PM'); + +SELECT to_timestamp('2011-12-18 11:38 A.M.', 'YYYY-MM-DD HH12:MI P.M.'); + +SELECT to_timestamp('2011-12-18 11:38 P.M.', 'YYYY-MM-DD HH12:MI P.M.'); + +SELECT to_timestamp('2011-12-18 11:38 +05', 'YYYY-MM-DD HH12:MI TZH'); + +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZH'); + +SELECT to_timestamp('2011-12-18 11:38 +05:20', 'YYYY-MM-DD HH12:MI TZH:TZM'); + +SELECT to_timestamp('2011-12-18 11:38 -05:20', 'YYYY-MM-DD HH12:MI TZH:TZM'); + +SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM'); + +SELECT to_timestamp('2011-12-18 11:38 EST', 'YYYY-MM-DD HH12:MI TZ'); + +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZ'); + +SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI TZ'); + +SELECT to_timestamp('2011-12-18 11:38 MSK', 'YYYY-MM-DD HH12:MI TZ'); + +SELECT to_timestamp('2011-12-18 00:00 LMT', 'YYYY-MM-DD HH24:MI TZ'); + +SELECT to_timestamp('2011-12-18 11:38ESTFOO24', 'YYYY-MM-DD HH12:MITZFOOSS'); + +SELECT to_timestamp('2011-12-18 11:38-05FOO24', 'YYYY-MM-DD HH12:MITZFOOSS'); + +SELECT to_timestamp('2011-12-18 11:38 JUNK', 'YYYY-MM-DD HH12:MI TZ'); + +SELECT to_timestamp('2011-12-18 11:38 ...', 'YYYY-MM-DD HH12:MI TZ'); + +SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI OF'); + +SELECT to_timestamp('2011-12-18 11:38 +01:30', 'YYYY-MM-DD HH12:MI OF'); + +SELECT to_timestamp('2011-12-18 11:38 +xyz', 'YYYY-MM-DD HH12:MI OF'); + +SELECT to_timestamp('2011-12-18 11:38 +01:xyz', 'YYYY-MM-DD HH12:MI OF'); + +SELECT to_timestamp('2018-11-02 12:34:56.025', 'YYYY-MM-DD HH24:MI:SS.MS'); + +SELECT i, to_timestamp('2018-11-02 12:34:56', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('2018-11-02 12:34:56.1', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('2018-11-02 12:34:56.12', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('2018-11-02 12:34:56.123', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('2018-11-02 12:34:56.1234', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('2018-11-02 12:34:56.12345', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('2018-11-02 12:34:56.123456', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('2018-11-02 12:34:56.123456789', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + +SELECT i, to_timestamp('20181102123456123456', 'YYYYMMDDHH24MISSFF' || i) FROM generate_series(1, 6) i; + +SELECT to_date('1 4 1902', 'Q MM YYYY'); + +SELECT to_date('3 4 21 01', 'W MM CC YY'); + +SELECT to_date('2458872', 'J'); + +SELECT to_date('44-02-01 BC','YYYY-MM-DD BC'); + +SELECT to_date('-44-02-01','YYYY-MM-DD'); + +SELECT to_date('-44-02-01 BC','YYYY-MM-DD BC'); + +SELECT to_timestamp('44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC'); + +SELECT to_timestamp('-44-02-01 11:12:13','YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('-44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC'); + +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2000+ JUN', 'YYYY/MON'); + +SELECT to_timestamp(' 2000 +JUN', 'YYYY/MON'); + +SELECT to_timestamp(' 2000 +JUN', 'YYYY//MON'); + +SELECT to_timestamp('2000 +JUN', 'YYYY//MON'); + +SELECT to_timestamp('2000 + JUN', 'YYYY MON'); + +SELECT to_timestamp('2000 ++ JUN', 'YYYY MON'); + +SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); + +SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); + +SELECT to_timestamp('2000 -10', 'YYYY TZH'); + +SELECT to_timestamp('2000 -10', 'YYYY TZH'); + +SELECT to_date('2011 12 18', 'YYYY MM DD'); + +SELECT to_date('2011 12 18', 'YYYY MM DD'); + +SELECT to_date('2011 12 18', 'YYYY MM DD'); + +SELECT to_date('2011 12 18', 'YYYY MM DD'); + +SELECT to_date('2011 12 18', 'YYYY MM DD'); + +SELECT to_date('2011 12 18', 'YYYY MM DD'); + +SELECT to_date('2011 12 18', 'YYYYxMMxDD'); + +SELECT to_date('2011x 12x 18', 'YYYYxMMxDD'); + +SELECT to_date('2011 x12 x18', 'YYYYxMMxDD'); + +SELECT to_timestamp('2005527', 'YYYYIWID'); + +SELECT to_timestamp('19971', 'YYYYMMDD'); + +SELECT to_timestamp('19971)24', 'YYYYMMDD'); + +SELECT to_timestamp('Friday 1-January-1999', 'DY DD MON YYYY'); + +SELECT to_timestamp('Fri 1-January-1999', 'DY DD MON YYYY'); + +SELECT to_timestamp('Fri 1-Jan-1999', 'DY DD MON YYYY'); + +SELECT to_timestamp('1997-11-Jan-16', 'YYYY-MM-Mon-DD'); + +SELECT to_timestamp('199711xy', 'YYYYMMDD'); + +SELECT to_timestamp('10000000000', 'FMYYYY'); + +SELECT to_timestamp('2016-06-13 25:00:00', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2016-06-13 15:60:00', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2016-06-13 15:50:60', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH:MI:SS'); + +SELECT to_timestamp('2016-13-01 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2016-02-30 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2016-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2015-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); + +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSS'); + +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSS'); + +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSSS'); + +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSSS'); + +SELECT to_timestamp('1000000000,999', 'Y,YYY'); + +SELECT to_timestamp('0.-2147483648', 'SS.MS'); + +SELECT to_timestamp('613566758', 'W'); + +SELECT to_timestamp('2024 613566758 1', 'YYYY WW D'); + +SELECT to_date('2016-13-10', 'YYYY-MM-DD'); + +SELECT to_date('2016-02-30', 'YYYY-MM-DD'); + +SELECT to_date('2016-02-29', 'YYYY-MM-DD'); + +SELECT to_date('2015-02-29', 'YYYY-MM-DD'); + +SELECT to_date('2015 365', 'YYYY DDD'); + +SELECT to_date('2015 366', 'YYYY DDD'); + +SELECT to_date('2016 365', 'YYYY DDD'); + +SELECT to_date('2016 366', 'YYYY DDD'); + +SELECT to_date('2016 367', 'YYYY DDD'); + +SELECT to_date('0000-02-01','YYYY-MM-DD'); + +SELECT to_date('100000000', 'CC'); + +SELECT to_date('-100000000', 'CC'); + +SELECT to_date('-2147483648 01', 'CC YY'); + +SELECT to_date('2147483647 01', 'CC YY'); + +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ'); + +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS tz'); + +SET TIME ZONE 'America/New_York'; + +SET TIME ZONE '-1.5'; + +SHOW TIME ZONE; + +SELECT '2012-12-12 12:00'::timestamptz; + +SELECT '2012-12-12 12:00 America/New_York'::timestamptz; + +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ'); + +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSS'); + +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSSS'); + +SET TIME ZONE '+2'; + +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ'); + +RESET TIME ZONE; diff --git a/crates/pgt_pretty_print/tests/data/multi/identity_60.sql b/crates/pgt_pretty_print/tests/data/multi/identity_60.sql new file mode 100644 index 000000000..b46025734 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/identity_60.sql @@ -0,0 +1,235 @@ +SELECT attrelid, attname, attidentity FROM pg_attribute WHERE attidentity NOT IN ('', 'a', 'd'); + +CREATE TABLE itest1 (a int generated by default as identity, b text); + +CREATE TABLE itest2 (a bigint generated always as identity, b text); + +CREATE TABLE itest3 (a smallint generated by default as identity (start with 7 increment by 5), b text); + +ALTER TABLE itest3 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +SELECT table_name, column_name, column_default, is_nullable, is_identity, identity_generation, identity_start, identity_increment, identity_maximum, identity_minimum, identity_cycle FROM information_schema.columns WHERE table_name LIKE 'itest_' ORDER BY 1, 2; + +SELECT sequence_name FROM information_schema.sequences WHERE sequence_name LIKE 'itest%'; + +SELECT pg_get_serial_sequence('itest1', 'a'); + +CREATE TABLE itest4 (a int, b text); + +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest4 ALTER COLUMN a SET NOT NULL; + +ALTER TABLE itest4 ALTER COLUMN c ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL; + +ALTER TABLE itest4 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest4 ALTER COLUMN b ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest4 ALTER COLUMN b SET DEFAULT ''; + +CREATE TABLE itest_err_1 (a text generated by default as identity); + +CREATE TABLE itest_err_2 (a int generated always as identity generated by default as identity); + +CREATE TABLE itest_err_3 (a int default 5 generated by default as identity); + +CREATE TABLE itest_err_4 (a serial generated by default as identity); + +INSERT INTO itest1 DEFAULT VALUES; + +INSERT INTO itest1 DEFAULT VALUES; + +INSERT INTO itest2 DEFAULT VALUES; + +INSERT INTO itest2 DEFAULT VALUES; + +INSERT INTO itest3 DEFAULT VALUES; + +INSERT INTO itest3 DEFAULT VALUES; + +INSERT INTO itest4 DEFAULT VALUES; + +INSERT INTO itest4 DEFAULT VALUES; + +SELECT * FROM itest1; + +SELECT * FROM itest2; + +SELECT * FROM itest3; + +SELECT * FROM itest4; + +CREATE TABLE itest5 (a int generated always as identity, b text); + +INSERT INTO itest5 VALUES (1, 'a'); + +INSERT INTO itest5 VALUES (DEFAULT, 'a'); + +INSERT INTO itest5 VALUES (2, 'b'), (3, 'c'); + +INSERT INTO itest5 VALUES (DEFAULT, 'b'), (3, 'c'); + +INSERT INTO itest5 VALUES (2, 'b'), (DEFAULT, 'c'); + +INSERT INTO itest5 VALUES (DEFAULT, 'b'), (DEFAULT, 'c'); + +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-1, 'aa'); + +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-2, 'bb'), (-3, 'cc'); + +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'dd'), (-4, 'ee'); + +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (-5, 'ff'), (DEFAULT, 'gg'); + +INSERT INTO itest5 OVERRIDING SYSTEM VALUE VALUES (DEFAULT, 'hh'), (DEFAULT, 'ii'); + +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-1, 'aaa'); + +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-2, 'bbb'), (-3, 'ccc'); + +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'ddd'), (-4, 'eee'); + +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (-5, 'fff'), (DEFAULT, 'ggg'); + +INSERT INTO itest5 OVERRIDING USER VALUE VALUES (DEFAULT, 'hhh'), (DEFAULT, 'iii'); + +SELECT * FROM itest5; + +DROP TABLE itest5; + +INSERT INTO itest3 VALUES (DEFAULT, 'a'); + +INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c'); + +SELECT * FROM itest3; + +INSERT INTO itest1 VALUES (10, 'xyz'); + +INSERT INTO itest1 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz'); + +INSERT INTO itest1 OVERRIDING USER VALUE VALUES (30, 'xyz'); + +SELECT * FROM itest1; + +INSERT INTO itest2 VALUES (10, 'xyz'); + +INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz'); + +INSERT INTO itest2 OVERRIDING USER VALUE VALUES (30, 'xyz'); + +SELECT * FROM itest2; + +UPDATE itest1 SET a = 101 WHERE a = 1; + +UPDATE itest1 SET a = DEFAULT WHERE a = 2; + +SELECT * FROM itest1; + +UPDATE itest2 SET a = 101 WHERE a = 1; + +UPDATE itest2 SET a = DEFAULT WHERE a = 2; + +SELECT * FROM itest2; + +CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint); + +SELECT * FROM itest9 ORDER BY c; + +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY; + +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY; + +ALTER TABLE itest4 ALTER COLUMN a DROP IDENTITY IF EXISTS; + +INSERT INTO itest4 DEFAULT VALUES; + +ALTER TABLE itest4 ALTER COLUMN a DROP NOT NULL; + +INSERT INTO itest4 DEFAULT VALUES; + +SELECT * FROM itest4; + +SELECT sequence_name FROM itest4_a_seq; + +CREATE TABLE itest10 (a int generated by default as identity, b text); + +CREATE TABLE itest11 (a int generated always as identity, b text); + +CREATE VIEW itestv10 AS SELECT * FROM itest10; + +CREATE VIEW itestv11 AS SELECT * FROM itest11; + +INSERT INTO itestv10 DEFAULT VALUES; + +INSERT INTO itestv10 DEFAULT VALUES; + +INSERT INTO itestv11 DEFAULT VALUES; + +INSERT INTO itestv11 DEFAULT VALUES; + +SELECT * FROM itestv10; + +SELECT * FROM itestv11; + +INSERT INTO itestv10 VALUES (10, 'xyz'); + +INSERT INTO itestv10 OVERRIDING USER VALUE VALUES (11, 'xyz'); + +SELECT * FROM itestv10; + +INSERT INTO itestv11 VALUES (10, 'xyz'); + +INSERT INTO itestv11 OVERRIDING SYSTEM VALUE VALUES (11, 'xyz'); + +SELECT * FROM itestv11; + +DROP VIEW itestv10, itestv11; + +CREATE TABLE itest13 (a int); + +ALTER TABLE itest13 ADD COLUMN b int GENERATED BY DEFAULT AS IDENTITY; + +INSERT INTO itest13 VALUES (1), (2), (3); + +ALTER TABLE itest13 ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY; + +SELECT * FROM itest13; + +ALTER TABLE itest1 ALTER COLUMN a SET DEFAULT 1; + +CREATE TABLE itest5 (a serial, b text); + +ALTER TABLE itest5 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest3 ALTER COLUMN a TYPE int; + +SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regclass; + +ALTER TABLE itest3 ALTER COLUMN a TYPE text; + +CREATE UNLOGGED TABLE itest17 (a int NOT NULL, b text); + +ALTER TABLE itest17 ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest17 ADD COLUMN c int GENERATED ALWAYS AS IDENTITY; + +CREATE TABLE itest18 (a int NOT NULL, b text); + +ALTER TABLE itest18 SET UNLOGGED, ALTER COLUMN a ADD GENERATED ALWAYS AS IDENTITY; + +ALTER TABLE itest18 SET LOGGED; + +ALTER TABLE itest18 SET UNLOGGED; + +ALTER TABLE itest3 + ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY, + ALTER COLUMN c SET GENERATED ALWAYS; + +CREATE TABLE itest6 (a int GENERATED ALWAYS AS IDENTITY, b text); + +INSERT INTO itest6 DEFAULT VALUES; diff --git a/crates/pgt_pretty_print/tests/data/multi/incremental_sort_60.sql b/crates/pgt_pretty_print/tests/data/multi/incremental_sort_60.sql new file mode 100644 index 000000000..f411bb86a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/incremental_sort_60.sql @@ -0,0 +1,382 @@ +select * from (select * from tenk1 order by four) t order by four, ten +limit 1; + +set work_mem to '2MB'; + +select * from (select * from tenk1 order by four) t order by four, ten; + +reset work_mem; + +create table t(a integer, b integer); + +create or replace function explain_analyze_without_memory(query text) +returns table (out_line text) language plpgsql +as +$$ +declare + line text; +begin + for line in + execute 'explain (analyze, costs off, summary off, timing off, buffers off) ' || query + loop + out_line := regexp_replace(line, '\d+kB', 'NNkB', 'g'); + return next; + end loop; +end; +$$; + +create or replace function explain_analyze_inc_sort_nodes(query text) +returns jsonb language plpgsql +as +$$ +declare + elements jsonb; + element jsonb; + matching_nodes jsonb := '[]'::jsonb; +begin + execute 'explain (analyze, costs off, summary off, timing off, buffers off, format ''json'') ' || query into strict elements; + while jsonb_array_length(elements) > 0 loop + element := elements->0; + elements := elements - 0; + case jsonb_typeof(element) + when 'array' then + if jsonb_array_length(element) > 0 then + elements := elements || element; + end if; + when 'object' then + if element ? 'Plan' then + elements := elements || jsonb_build_array(element->'Plan'); + element := element - 'Plan'; + else + if element ? 'Plans' then + elements := elements || jsonb_build_array(element->'Plans'); + element := element - 'Plans'; + end if; + if (element->>'Node Type')::text = 'Incremental Sort' then + matching_nodes := matching_nodes || element; + end if; + end if; + end case; + end loop; + return matching_nodes; +end; +$$; + +create or replace function explain_analyze_inc_sort_nodes_without_memory(query text) +returns jsonb language plpgsql +as +$$ +declare + nodes jsonb := '[]'::jsonb; + node jsonb; + group_key text; + space_key text; +begin + for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop + for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop + for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop + node := jsonb_set(node, array[group_key, space_key, 'Average Sort Space Used'], '"NN"', false); + node := jsonb_set(node, array[group_key, space_key, 'Peak Sort Space Used'], '"NN"', false); + end loop; + end loop; + nodes := nodes || node; + end loop; + return nodes; +end; +$$; + +create or replace function explain_analyze_inc_sort_nodes_verify_invariants(query text) +returns bool language plpgsql +as +$$ +declare + node jsonb; + group_stats jsonb; + group_key text; + space_key text; +begin + for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop + for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop + group_stats := node->group_key; + for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop + if (group_stats->space_key->'Peak Sort Space Used')::bigint < (group_stats->space_key->'Peak Sort Space Used')::bigint then + raise exception '% has invalid max space < average space', group_key; + end if; + end loop; + end loop; + end loop; + return true; +end; +$$; + +insert into t(a, b) select i/100 + 1, i + 1 from generate_series(0, 999) n(i); + +analyze t; + +select * from (select * from t order by a) s order by a, b limit 31; + +select * from (select * from t order by a) s order by a, b limit 31; + +select * from (select * from t order by a) s order by a, b limit 32; + +select * from (select * from t order by a) s order by a, b limit 32; + +select * from (select * from t order by a) s order by a, b limit 33; + +select * from (select * from t order by a) s order by a, b limit 33; + +select * from (select * from t order by a) s order by a, b limit 65; + +select * from (select * from t order by a) s order by a, b limit 65; + +select * from (select * from t order by a) s order by a, b limit 66; + +select * from (select * from t order by a) s order by a, b limit 66; + +delete from t; + +insert into t(a, b) select i/50 + 1, i + 1 from generate_series(0, 999) n(i); + +analyze t; + +select * from (select * from t order by a) s order by a, b limit 55; + +select * from (select * from t order by a) s order by a, b limit 55; + +select explain_analyze_without_memory('select * from (select * from t order by a) s order by a, b limit 55'); + +select jsonb_pretty(explain_analyze_inc_sort_nodes_without_memory('select * from (select * from t order by a) s order by a, b limit 55')); + +select explain_analyze_inc_sort_nodes_verify_invariants('select * from (select * from t order by a) s order by a, b limit 55'); + +delete from t; + +insert into t(a, b) select (case when i < 5 then i else 9 end), i from generate_series(1, 1000) n(i); + +analyze t; + +select * from (select * from t order by a) s order by a, b limit 70; + +select * from (select * from t order by a) s order by a, b limit 70; + +select * from (select * from t order by a) s order by a, b limit 5; + +select * from (select * from t order by a) s order by a, b limit 5; + +begin; + +set local enable_hashjoin = off; + +set local enable_mergejoin = off; + +set local enable_material = off; + +set local enable_sort = off; + +select * from t left join (select * from (select * from t order by a) v order by a, b) s on s.a = t.a where t.a in (1, 2); + +select * from t left join (select * from (select * from t order by a) v order by a, b) s on s.a = t.a where t.a in (1, 2); + +rollback; + +select explain_analyze_without_memory('select * from (select * from t order by a) s order by a, b limit 70'); + +select jsonb_pretty(explain_analyze_inc_sort_nodes_without_memory('select * from (select * from t order by a) s order by a, b limit 70')); + +select explain_analyze_inc_sort_nodes_verify_invariants('select * from (select * from t order by a) s order by a, b limit 70'); + +delete from t; + +insert into t(a, b) select i / 10, i from generate_series(1, 1000) n(i); + +analyze t; + +select * from (select * from t order by a) s order by a, b limit 31; + +select * from (select * from t order by a) s order by a, b limit 31; + +select * from (select * from t order by a) s order by a, b limit 32; + +select * from (select * from t order by a) s order by a, b limit 32; + +select * from (select * from t order by a) s order by a, b limit 33; + +select * from (select * from t order by a) s order by a, b limit 33; + +select * from (select * from t order by a) s order by a, b limit 65; + +select * from (select * from t order by a) s order by a, b limit 65; + +select * from (select * from t order by a) s order by a, b limit 66; + +select * from (select * from t order by a) s order by a, b limit 66; + +delete from t; + +insert into t(a, b) select i, i from generate_series(1, 1000) n(i); + +analyze t; + +select * from (select * from t order by a) s order by a, b limit 31; + +select * from (select * from t order by a) s order by a, b limit 31; + +select * from (select * from t order by a) s order by a, b limit 32; + +select * from (select * from t order by a) s order by a, b limit 32; + +select * from (select * from t order by a) s order by a, b limit 33; + +select * from (select * from t order by a) s order by a, b limit 33; + +select * from (select * from t order by a) s order by a, b limit 65; + +select * from (select * from t order by a) s order by a, b limit 65; + +select * from (select * from t order by a) s order by a, b limit 66; + +select * from (select * from t order by a) s order by a, b limit 66; + +delete from t; + +drop table t; + +set min_parallel_table_scan_size = '1kB'; + +set min_parallel_index_scan_size = '1kB'; + +set parallel_setup_cost = 0; + +set parallel_tuple_cost = 0; + +set max_parallel_workers_per_gather = 2; + +create table t (a int, b int, c int); + +insert into t select mod(i,10),mod(i,10),i from generate_series(1,10000) s(i); + +create index on t (a); + +analyze t; + +set enable_incremental_sort = off; + +select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1; + +set enable_incremental_sort = on; + +select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1; + +set enable_hashagg to off; + +select * from t union select * from t order by 1,3; + +select distinct a,b from t; + +drop table t; + +set enable_hashagg=off; + +set enable_seqscan=off; + +set enable_incremental_sort = off; + +set parallel_tuple_cost=0; + +set parallel_setup_cost=0; + +set min_parallel_table_scan_size = 0; + +set min_parallel_index_scan_size = 0; + +select distinct sub.unique1, stringu1 +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub; + +select sub.unique1, stringu1 +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub +order by 1, 2; + +select distinct sub.unique1, md5(stringu1) +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub; + +select sub.unique1, md5(stringu1) +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub +order by 1, 2; + +select count(*) +from tenk1 t1 +join tenk1 t2 on t1.unique1 = t2.unique2 +join tenk1 t3 on t2.unique1 = t3.unique1 +order by count(*); + +select distinct + unique1, + (select t.unique1 from tenk1 where tenk1.unique1 = t.unique1) +from tenk1 t, generate_series(1, 1000); + +select + unique1, + (select t.unique1 from tenk1 where tenk1.unique1 = t.unique1) +from tenk1 t, generate_series(1, 1000) +order by 1, 2; + +select distinct sub.unique1, stringu1 || random()::text +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub; + +select sub.unique1, stringu1 || random()::text +from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub +order by 1, 2; + +reset enable_hashagg; + +reset enable_seqscan; + +reset enable_incremental_sort; + +reset parallel_tuple_cost; + +reset parallel_setup_cost; + +reset min_parallel_table_scan_size; + +reset min_parallel_index_scan_size; + +create table point_table (a point, b int); + +create index point_table_a_idx on point_table using gist(a); + +select a, b, a <-> point(5, 5) dist from point_table order by dist, b limit 1; + +select a, b, a <-> point(5, 5) dist from point_table order by dist, b desc limit 1; + +select * from + (select * from tenk1 order by four) t1 join tenk1 t2 on t1.four = t2.four and t1.two = t2.two +order by t1.four, t1.two limit 1; + +create table prt_tbl (a int, b int) partition by range (a); + +create table prt_tbl_1 partition of prt_tbl for values from (0) to (100); + +create table prt_tbl_2 partition of prt_tbl for values from (100) to (200); + +insert into prt_tbl select i%200, i from generate_series(1,1000)i; + +create index on prt_tbl_1(a); + +create index on prt_tbl_2(a, b); + +analyze prt_tbl; + +set enable_seqscan to off; + +set enable_bitmapscan to off; + +select * from prt_tbl order by a, b; + +select * from prt_tbl_1 union all select * from prt_tbl_2 order by a, b; + +reset enable_bitmapscan; + +reset enable_seqscan; + +drop table prt_tbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/index_including_60.sql b/crates/pgt_pretty_print/tests/data/multi/index_including_60.sql new file mode 100644 index 000000000..3ab11d88a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/index_including_60.sql @@ -0,0 +1,282 @@ +CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_include_reg SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +CREATE INDEX tbl_include_reg_idx ON tbl_include_reg (c1, c2) INCLUDE (c3, c4); + +CREATE INDEX ON tbl_include_reg (c1, c2) INCLUDE (c1, c3); + +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname; + +CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 using btree (c1, c2) INCLUDE (c3, c4); + +ALTER TABLE tbl_include_unique1 add UNIQUE USING INDEX tbl_include_unique1_idx_unique; + +ALTER TABLE tbl_include_unique1 add UNIQUE (c1, c2) INCLUDE (c3, c4); + +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_unique1'::regclass ORDER BY c.relname; + +CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_include_unique2 SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 using btree (c1, c2) INCLUDE (c3, c4); + +ALTER TABLE tbl_include_unique2 add UNIQUE (c1, c2) INCLUDE (c3, c4); + +CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_include_pk SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +ALTER TABLE tbl_include_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); + +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_pk'::regclass ORDER BY c.relname; + +CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_include_box SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box using btree (c1, c2) INCLUDE (c3, c4); + +ALTER TABLE tbl_include_box add PRIMARY KEY USING INDEX tbl_include_box_idx_unique; + +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_include_box'::regclass ORDER BY c.relname; + +CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_include_box_pk SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + CONSTRAINT covering UNIQUE(c1,c2) INCLUDE(c3,c4)); + +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; + +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + CONSTRAINT covering PRIMARY KEY(c1,c2) INCLUDE(c3,c4)); + +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; + +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid AND contype = 'p'; + +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,300) AS x; + +select * from tbl where (c1,c2,c3) < (2,5,1); + +select * from tbl where (c1,c2,c3) < (2,5,1); + +SET enable_seqscan = off; + +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1; + +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1; + +DROP TABLE tbl; + +RESET enable_seqscan; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + UNIQUE(c1,c2) INCLUDE(c3,c4)); + +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; + +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + PRIMARY KEY(c1,c2) INCLUDE(c3,c4)); + +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; + +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid AND contype = 'p'; + +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, + EXCLUDE USING btree (c1 WITH =) INCLUDE(c3,c4)); + +SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; + +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + +INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 int); + +CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2, c3, c4); + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +ALTER TABLE tbl DROP COLUMN c3; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box); + +CREATE UNIQUE INDEX tbl_idx ON tbl using btree(c1, c2) INCLUDE(c3,c4); + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +ALTER TABLE tbl DROP COLUMN c3; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)); + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +ALTER TABLE tbl DROP COLUMN c3; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +ALTER TABLE tbl DROP COLUMN c1; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int, c2 int); + +CREATE INDEX tbl_idx ON tbl (c1, (c1+0)) INCLUDE (c2); + +ALTER INDEX tbl_idx ALTER COLUMN 1 SET STATISTICS 1000; + +ALTER INDEX tbl_idx ALTER COLUMN 2 SET STATISTICS 1000; + +ALTER INDEX tbl_idx ALTER COLUMN 3 SET STATISTICS 1000; + +ALTER INDEX tbl_idx ALTER COLUMN 4 SET STATISTICS 1000; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)); + +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,1000) AS x; + +CREATE UNIQUE INDEX CONCURRENTLY on tbl (c1, c2) INCLUDE (c3, c4); + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)); + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +ALTER TABLE tbl DROP COLUMN c3; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +REINDEX INDEX tbl_c1_c2_c3_c4_key; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +ALTER TABLE tbl DROP COLUMN c1; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 box, c4 box); + +CREATE INDEX on tbl USING brin(c1, c2) INCLUDE (c3, c4); + +CREATE INDEX on tbl USING gist(c3) INCLUDE (c1, c4); + +CREATE INDEX on tbl USING spgist(c3) INCLUDE (c4); + +CREATE INDEX on tbl USING gin(c1, c2) INCLUDE (c3, c4); + +CREATE INDEX on tbl USING hash(c1, c2) INCLUDE (c3, c4); + +CREATE INDEX on tbl USING rtree(c3) INCLUDE (c1, c4); + +CREATE INDEX on tbl USING btree(c1, c2) INCLUDE (c3, c4); + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree(c1, c2) INCLUDE (c3,c4); + +UPDATE tbl SET c1 = 100 WHERE c1 = 2; + +UPDATE tbl SET c1 = 1 WHERE c1 = 3; + +UPDATE tbl SET c2 = 2 WHERE c1 = 1; + +UPDATE tbl SET c3 = 1; + +DELETE FROM tbl WHERE c1 = 5 OR c3 = 12; + +DROP TABLE tbl; + +CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1, c2) INCLUDE(c3,c4)); + +INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; + +ALTER TABLE tbl ALTER c1 TYPE bigint; + +ALTER TABLE tbl ALTER c3 TYPE bigint; + +DROP TABLE tbl; + +CREATE TABLE nametbl (c1 int, c2 name, c3 float); + +CREATE INDEX nametbl_c1_c2_idx ON nametbl (c2, c1) INCLUDE (c3); + +INSERT INTO nametbl VALUES(1, 'two', 3.0); + +VACUUM nametbl; + +SET enable_seqscan = 0; + +SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1; + +SELECT c2, c1, c3 FROM nametbl WHERE c2 = 'two' AND c1 = 1; + +RESET enable_seqscan; + +DROP TABLE nametbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/index_including_gist_60.sql b/crates/pgt_pretty_print/tests/data/multi/index_including_gist_60.sql new file mode 100644 index 000000000..b0bbd12e0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/index_including_gist_60.sql @@ -0,0 +1,103 @@ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x; + +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); + +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname; + +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + +SET enable_bitmapscan TO off; + +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + +SET enable_bitmapscan TO default; + +DROP TABLE tbl_gist; + +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); + +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x; + +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname; + +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + +SET enable_bitmapscan TO off; + +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + +SET enable_bitmapscan TO default; + +DROP TABLE tbl_gist; + +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; + +CREATE INDEX CONCURRENTLY tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + +DROP TABLE tbl_gist; + +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; + +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + +REINDEX INDEX tbl_gist_idx; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + +ALTER TABLE tbl_gist DROP COLUMN c1; + +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + +DROP TABLE tbl_gist; + +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; + +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); + +UPDATE tbl_gist SET c1 = 100 WHERE c1 = 2; + +UPDATE tbl_gist SET c1 = 1 WHERE c1 = 3; + +DELETE FROM tbl_gist WHERE c1 = 5 OR c3 = 12; + +DROP TABLE tbl_gist; + +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; + +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); + +ALTER TABLE tbl_gist ALTER c1 TYPE bigint; + +ALTER TABLE tbl_gist ALTER c3 TYPE bigint; + +DROP TABLE tbl_gist; + +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box, EXCLUDE USING gist (c4 WITH &&) INCLUDE (c1, c2, c3)); + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; + +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(3*x,2*x),point(3*x+1,2*x+1)) FROM generate_series(1,10) AS x; + +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + +DROP TABLE tbl_gist; diff --git a/crates/pgt_pretty_print/tests/data/multi/indexing_60.sql b/crates/pgt_pretty_print/tests/data/multi/indexing_60.sql new file mode 100644 index 000000000..5a884f23e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/indexing_60.sql @@ -0,0 +1,1278 @@ +create table idxpart (a int, b int, c text) partition by range (a); + +create index idxpart_idx on idxpart (a); + +select relhassubclass from pg_class where relname = 'idxpart_idx'; + +select indexdef from pg_indexes where indexname like 'idxpart_idx%'; + +drop index idxpart_idx; + +create table idxpart1 partition of idxpart for values from (0) to (10); + +create table idxpart2 partition of idxpart for values from (10) to (100) + partition by range (b); + +create table idxpart21 partition of idxpart2 for values from (0) to (100); + +create index idxpart_idx on only idxpart(a); + +select relhassubclass from pg_class where relname = 'idxpart_idx'; + +drop index idxpart_idx; + +create index on idxpart (a); + +select relname, relkind, relhassubclass, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname; + +drop table idxpart; + +create table idxpart (a int, b int, c text) partition by range (a); + +create table idxpart1 partition of idxpart for values from (0) to (10); + +create index concurrently on idxpart (a); + +drop table idxpart; + +CREATE TABLE idxpart (col1 INT) PARTITION BY RANGE (col1); + +CREATE INDEX ON idxpart (col1); + +CREATE TABLE idxpart_two (col2 INT); + +SELECT col2 FROM idxpart_two fk LEFT OUTER JOIN idxpart pk ON (col1 = col2); + +DROP table idxpart, idxpart_two; + +CREATE TABLE idxpart (a INT, b TEXT, c INT) PARTITION BY RANGE(a); + +CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (MINVALUE) TO (MAXVALUE); + +CREATE INDEX partidx_abc_idx ON idxpart (a, b, c); + +INSERT INTO idxpart (a, b, c) SELECT i, i, i FROM generate_series(1, 50) i; + +ALTER TABLE idxpart ALTER COLUMN c TYPE numeric; + +DROP TABLE idxpart; + +create table idxpart (a int, b int, c text) partition by range (a); + +create index idxparti on idxpart (a); + +create index idxparti2 on idxpart (b, c); + +create table idxpart1 (like idxpart); + +alter table idxpart attach partition idxpart1 for values from (0) to (10); + +create index idxpart_c on only idxpart (c); + +create index idxpart1_c on idxpart1 (c); + +alter table idxpart_c attach partition idxpart1_c for values from (10) to (20); + +alter index idxpart_c attach partition idxpart1_c; + +select relname, relpartbound from pg_class + where relname in ('idxpart_c', 'idxpart1_c') + order by relname; + +alter table idxpart_c detach partition idxpart1_c; + +drop table idxpart; + +create table idxpart (a int, b int) partition by range (a, b); + +create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10); + +create index on idxpart1 (a, b); + +create index on idxpart (a, b); + +select relname, relkind, relhassubclass, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname; + +drop table idxpart; + +create table idxpart (a int) partition by range (a); + +create index on idxpart (a); + +create table idxpart1 partition of idxpart for values from (0) to (10); + +drop index idxpart1_a_idx; + +drop index concurrently idxpart_a_idx; + +drop index idxpart_a_idx; + +select relname, relkind from pg_class + where relname like 'idxpart%' order by relname; + +create index on idxpart (a); + +drop table idxpart1; + +select relname, relkind from pg_class + where relname like 'idxpart%' order by relname; + +drop table idxpart; + +create temp table idxpart_temp (a int) partition by range (a); + +create index on idxpart_temp(a); + +create temp table idxpart1_temp partition of idxpart_temp + for values from (0) to (10); + +drop index idxpart1_temp_a_idx; + +drop index concurrently idxpart_temp_a_idx; + +select relname, relkind from pg_class + where relname like 'idxpart_temp%' order by relname; + +drop table idxpart_temp; + +create table idxpart (a int, b int) partition by range (a, b); + +create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10); + +create index idxpart_a_b_idx on only idxpart (a, b); + +create index idxpart1_a_b_idx on idxpart1 (a, b); + +create index idxpart1_tst1 on idxpart1 (b, a); + +create index idxpart1_tst2 on idxpart1 using hash (a); + +create index idxpart1_tst3 on idxpart1 (a, b) where a > 10; + +alter index idxpart attach partition idxpart1; + +alter index idxpart_a_b_idx attach partition idxpart1; + +alter index idxpart_a_b_idx attach partition idxpart_a_b_idx; + +alter index idxpart_a_b_idx attach partition idxpart1_b_idx; + +alter index idxpart_a_b_idx attach partition idxpart1_tst1; + +alter index idxpart_a_b_idx attach partition idxpart1_tst2; + +alter index idxpart_a_b_idx attach partition idxpart1_tst3; + +alter index idxpart_a_b_idx attach partition idxpart1_a_b_idx; + +alter index idxpart_a_b_idx attach partition idxpart1_a_b_idx; + +create index idxpart1_2_a_b on idxpart1 (a, b); + +alter index idxpart_a_b_idx attach partition idxpart1_2_a_b; + +drop table idxpart; + +select indexrelid::regclass, indrelid::regclass + from pg_index where indexrelid::regclass::text like 'idxpart%'; + +create table idxpart (a int, b int) partition by range (a); + +create table idxpart1 (a int, b int); + +create index on idxpart1 using hash (a); + +create index on idxpart1 (a) where b > 1; + +create index on idxpart1 ((a + 0)); + +create index on idxpart1 (a, a); + +create index on idxpart (a); + +alter table idxpart attach partition idxpart1 for values from (0) to (1000); + +drop table idxpart; + +create table idxpart (a int) partition by range (a); + +create table idxpart1 partition of idxpart for values from (0) to (100); + +create table idxpart2 partition of idxpart for values from (100) to (1000) + partition by range (a); + +create table idxpart21 partition of idxpart2 for values from (100) to (200); + +create table idxpart22 partition of idxpart2 for values from (200) to (300); + +create index on idxpart22 (a); + +create index on only idxpart2 (a); + +create index on idxpart (a); + +select indexrelid::regclass, indrelid::regclass, inhparent::regclass + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) +where indexrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +alter index idxpart2_a_idx attach partition idxpart22_a_idx; + +select indexrelid::regclass, indrelid::regclass, inhparent::regclass + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) +where indexrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +alter index idxpart2_a_idx attach partition idxpart22_a_idx; + +create index on idxpart21 (a); + +alter index idxpart2_a_idx attach partition idxpart21_a_idx; + +drop table idxpart; + +create table idxpart (a int, b int, c text, d bool) partition by range (a); + +create index idxparti on idxpart (a); + +create index idxparti2 on idxpart (b, c); + +create table idxpart1 (like idxpart including indexes); + +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname; + +alter table idxpart attach partition idxpart1 for values from (0) to (10); + +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname; + +create index on idxpart1 ((a+b)) where d = true; + +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname; + +create index idxparti3 on idxpart ((a+b)) where d = true; + +select relname, relkind, inhparent::regclass + from pg_class left join pg_index ix on (indexrelid = oid) + left join pg_inherits on (ix.indexrelid = inhrelid) + where relname like 'idxpart%' order by relname; + +drop table idxpart; + +create table idxpart (a int, b int) partition by range (a); + +create table idxpart1 partition of idxpart for values from (1) to (1000) partition by range (a); + +create table idxpart11 partition of idxpart1 for values from (1) to (100); + +create index on only idxpart1 (a); + +create index on only idxpart (a); + +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname; + +alter index idxpart_a_idx attach partition idxpart1_a_idx; + +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname; + +create index on idxpart11 (a); + +alter index idxpart1_a_idx attach partition idxpart11_a_idx; + +select relname, indisvalid from pg_class join pg_index on indexrelid = oid + where relname like 'idxpart%' order by relname; + +drop table idxpart; + +create table idxpart (a int) partition by range (a); + +create table idxpart1 (like idxpart); + +create index on idxpart1 (a); + +create index on idxpart (a); + +create table idxpart2 (like idxpart); + +alter table idxpart attach partition idxpart1 for values from (0000) to (1000); + +alter table idxpart attach partition idxpart2 for values from (1000) to (2000); + +create table idxpart3 partition of idxpart for values from (2000) to (3000); + +select relname, relkind from pg_class where relname like 'idxpart%' order by relname; + +alter table idxpart detach partition idxpart1; + +alter table idxpart detach partition idxpart2; + +alter table idxpart detach partition idxpart3; + +drop index idxpart1_a_idx; + +drop index idxpart2_a_idx; + +drop index idxpart3_a_idx; + +select relname, relkind from pg_class where relname like 'idxpart%' order by relname; + +drop table idxpart, idxpart1, idxpart2, idxpart3; + +select relname, relkind from pg_class where relname like 'idxpart%' order by relname; + +create table idxpart (a int) partition by range (a); + +create table idxpart1 (like idxpart); + +create index on idxpart1 (a); + +create index on idxpart (a); + +create table idxpart2 (like idxpart); + +alter table idxpart attach partition idxpart1 for values from (0000) to (1000); + +alter table idxpart attach partition idxpart2 for values from (1000) to (2000); + +create table idxpart3 partition of idxpart for values from (2000) to (3000); + +select relname, relkind from pg_class where relname like 'idxpart%' order by relname; + +alter table idxpart detach partition idxpart1; + +alter table idxpart detach partition idxpart2; + +alter table idxpart detach partition idxpart3; + +drop index idxpart_a_idx; + +select relname, relkind from pg_class where relname like 'idxpart%' order by relname; + +drop table idxpart, idxpart1, idxpart2, idxpart3; + +select relname, relkind from pg_class where relname like 'idxpart%' order by relname; + +create table idxpart (a int, b int, c int) partition by range(a); + +create index on idxpart(c); + +create table idxpart1 partition of idxpart for values from (0) to (250); + +create table idxpart2 partition of idxpart for values from (250) to (500); + +alter table idxpart detach partition idxpart2; + +alter table idxpart2 drop column c; + +drop table idxpart, idxpart2; + +create table idxpart (a int, b int) partition by range (a); + +create table idxpart1 (like idxpart); + +create index on idxpart1 ((a + b)); + +create index on idxpart ((a + b)); + +create table idxpart2 (like idxpart); + +alter table idxpart attach partition idxpart1 for values from (0000) to (1000); + +alter table idxpart attach partition idxpart2 for values from (1000) to (2000); + +create table idxpart3 partition of idxpart for values from (2000) to (3000); + +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname; + +drop table idxpart; + +create table idxpart (a text) partition by range (a); + +create table idxpart1 (like idxpart); + +create table idxpart2 (like idxpart); + +create index on idxpart2 (a collate "POSIX"); + +create index on idxpart2 (a); + +create index on idxpart2 (a collate "C"); + +alter table idxpart attach partition idxpart1 for values from ('aaa') to ('bbb'); + +alter table idxpart attach partition idxpart2 for values from ('bbb') to ('ccc'); + +create table idxpart3 partition of idxpart for values from ('ccc') to ('ddd'); + +create index on idxpart (a collate "C"); + +create table idxpart4 partition of idxpart for values from ('ddd') to ('eee'); + +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname; + +drop table idxpart; + +create table idxpart (a text) partition by range (a); + +create table idxpart1 (like idxpart); + +create table idxpart2 (like idxpart); + +create index on idxpart2 (a); + +alter table idxpart attach partition idxpart1 for values from ('aaa') to ('bbb'); + +alter table idxpart attach partition idxpart2 for values from ('bbb') to ('ccc'); + +create table idxpart3 partition of idxpart for values from ('ccc') to ('ddd'); + +create index on idxpart (a text_pattern_ops); + +create table idxpart4 partition of idxpart for values from ('ddd') to ('eee'); + +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname; + +drop index idxpart_a_idx; + +create index on only idxpart (a text_pattern_ops); + +alter index idxpart_a_idx attach partition idxpart2_a_idx; + +drop table idxpart; + +create table idxpart (col1 int, a int, col2 int, b int) partition by range (a); + +create table idxpart1 (b int, col1 int, col2 int, col3 int, a int); + +alter table idxpart drop column col1, drop column col2; + +alter table idxpart1 drop column col1, drop column col2, drop column col3; + +alter table idxpart attach partition idxpart1 for values from (0) to (1000); + +create index idxpart_1_idx on only idxpart (b, a); + +create index idxpart1_1_idx on idxpart1 (b, a); + +create index idxpart1_1b_idx on idxpart1 (b); + +create index idxpart_2_idx on only idxpart ((b + a)) where a > 1; + +create index idxpart1_2_idx on idxpart1 ((b + a)) where a > 1; + +create index idxpart1_2b_idx on idxpart1 ((a + b)) where a > 1; + +create index idxpart1_2c_idx on idxpart1 ((b + a)) where b > 1; + +alter index idxpart_1_idx attach partition idxpart1_1b_idx; + +alter index idxpart_1_idx attach partition idxpart1_1_idx; + +alter index idxpart_2_idx attach partition idxpart1_2b_idx; + +alter index idxpart_2_idx attach partition idxpart1_2c_idx; + +alter index idxpart_2_idx attach partition idxpart1_2_idx; + +select relname as child, inhparent::regclass as parent, pg_get_indexdef as childdef + from pg_class left join pg_inherits on inhrelid = oid, + lateral pg_get_indexdef(pg_class.oid) + where relkind in ('i', 'I') and relname like 'idxpart%' order by relname; + +drop table idxpart; + +create table idxpart (a int, b int, c text) partition by range (a); + +create index idxparti on idxpart (a); + +create index idxparti2 on idxpart (c, b); + +create table idxpart1 (c text, a int, b int); + +alter table idxpart attach partition idxpart1 for values from (0) to (10); + +create table idxpart2 (c text, a int, b int); + +create index on idxpart2 (a); + +create index on idxpart2 (c, b); + +alter table idxpart attach partition idxpart2 for values from (10) to (20); + +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +drop table idxpart; + +create table idxpart (col1 int, col2 int, a int, b int) partition by range (a); + +create table idxpart1 (col2 int, b int, col1 int, a int); + +create table idxpart2 (col1 int, col2 int, b int, a int); + +alter table idxpart drop column col1, drop column col2; + +alter table idxpart1 drop column col1, drop column col2; + +alter table idxpart2 drop column col1, drop column col2; + +create index on idxpart2 (abs(b)); + +alter table idxpart attach partition idxpart2 for values from (0) to (1); + +create index on idxpart (abs(b)); + +create index on idxpart ((b + 1)); + +alter table idxpart attach partition idxpart1 for values from (1) to (2); + +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +drop table idxpart; + +create table idxpart (col1 int, a int, col3 int, b int) partition by range (a); + +alter table idxpart drop column col1, drop column col3; + +create table idxpart1 (col1 int, col2 int, col3 int, col4 int, b int, a int); + +alter table idxpart1 drop column col1, drop column col2, drop column col3, drop column col4; + +alter table idxpart attach partition idxpart1 for values from (0) to (1000); + +create table idxpart2 (col1 int, col2 int, b int, a int); + +create index on idxpart2 (a) where b > 1000; + +alter table idxpart2 drop column col1, drop column col2; + +alter table idxpart attach partition idxpart2 for values from (1000) to (2000); + +create index on idxpart (a) where b > 1000; + +select c.relname, pg_get_indexdef(indexrelid) + from pg_class c join pg_index i on c.oid = i.indexrelid + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +drop table idxpart; + +create table idxpart1 (drop_1 int, drop_2 int, col_keep int, drop_3 int); + +alter table idxpart1 drop column drop_1; + +alter table idxpart1 drop column drop_2; + +alter table idxpart1 drop column drop_3; + +create index on idxpart1 (col_keep); + +create table idxpart (col_keep int) partition by range (col_keep); + +create index on idxpart (col_keep); + +alter table idxpart attach partition idxpart1 for values from (0) to (1000); + +select attrelid::regclass, attname, attnum from pg_attribute + where attrelid::regclass::text like 'idxpart%' and attnum > 0 + order by attrelid::regclass, attnum; + +drop table idxpart; + +create table idxpart(drop_1 int, drop_2 int, col_keep int, drop_3 int) partition by range (col_keep); + +alter table idxpart drop column drop_1; + +alter table idxpart drop column drop_2; + +alter table idxpart drop column drop_3; + +create table idxpart1 (col_keep int); + +create index on idxpart1 (col_keep); + +create index on idxpart (col_keep); + +alter table idxpart attach partition idxpart1 for values from (0) to (1000); + +select attrelid::regclass, attname, attnum from pg_attribute + where attrelid::regclass::text like 'idxpart%' and attnum > 0 + order by attrelid::regclass, attnum; + +drop table idxpart; + +create table idxpart (a int primary key, b int) partition by range (a); + +create table failpart partition of idxpart (b primary key) for values from (0) to (100); + +drop table idxpart; + +create table idxpart (a int) partition by range (a); + +create table idxpart1pk partition of idxpart (a primary key) for values from (0) to (100); + +drop table idxpart; + +create table idxpart (a int unique, b int) partition by range (a, b); + +create table idxpart (a int, b int unique) partition by range (a, b); + +create table idxpart (a int primary key, b int) partition by range (b, a); + +create table idxpart (a int, b int primary key) partition by range (b, a); + +create table idxpart (a int, b int, c text, primary key (a, b, c)) partition by range (b, c, a); + +drop table idxpart; + +create table idxpart (a int4range, exclude USING GIST (a with = )) partition by range (a); + +drop table idxpart; + +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with =)) partition by range (a, b); + +drop table idxpart; + +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with =)) partition by range (a); + +drop table idxpart; + +create table idxpart (a int4range, b int4range, exclude USING GIST (a with = )) partition by range (a, b); + +create table idxpart (a int4range, exclude USING GIST (a with -|- )) partition by range (a); + +create table idxpart (a int4range, b int4range, exclude USING GIST (a with =, b with &&)) partition by range (a); + +drop table idxpart; + +create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (b with =, c with &&)) partition by range (a); + +create table idxpart (a int4range, b int4range, c int4range, exclude USING GIST (a with =, b with =, c with &&)) partition by range (a, b); + +drop table idxpart; + +create table idxpart (a int primary key, b int) partition by range ((b + a)); + +create table idxpart (a int unique, b int) partition by range ((b + a)); + +create table idxpart (a int, b int, c text) partition by range (a, b); + +alter table idxpart add primary key (a); + +alter table idxpart add primary key (a, b); + +create table idxpart1 partition of idxpart for values from (0, 0) to (1000, 1000); + +drop table idxpart; + +create table idxpart (a int, b int) partition by range (a, b); + +alter table idxpart add unique (a); + +alter table idxpart add unique (b, a); + +drop table idxpart; + +create table idxpart (a int4range, b int4range) partition by range (a); + +alter table idxpart add exclude USING GIST (a with =); + +drop table idxpart; + +create table idxpart (a int4range, b int4range) partition by range (a, b); + +alter table idxpart add exclude USING GIST (a with =, b with =); + +drop table idxpart; + +create table idxpart (a int4range, b int4range) partition by range (a); + +alter table idxpart add exclude USING GIST (a with =, b with =); + +drop table idxpart; + +create table idxpart (a int4range, b int4range) partition by range (a, b); + +alter table idxpart add exclude USING GIST (a with =); + +drop table idxpart; + +create table idxpart (a int4range, b int4range) partition by range (a, b); + +alter table idxpart add exclude USING GIST (a with -|-); + +drop table idxpart; + +create table idxpart (a int4range, b int4range) partition by range (a); + +alter table idxpart add exclude USING GIST (a with =, b with &&); + +drop table idxpart; + +create table idxpart (a int4range, b int4range, c int4range) partition by range (a); + +alter table idxpart add exclude USING GIST (b with =, c with &&); + +drop table idxpart; + +create table idxpart (a int4range, b int4range, c int4range) partition by range (a, b); + +alter table idxpart add exclude USING GIST (a with =, b with =, c with &&); + +drop table idxpart; + +create table idxpart (a int, b int, primary key (a, b)) partition by range (a, b); + +create table idxpart1 partition of idxpart for values from (1, 1) to (10, 10); + +create table idxpart2 partition of idxpart for values from (10, 10) to (20, 20) + partition by range (b); + +create table idxpart21 partition of idxpart2 for values from (10) to (15); + +create table idxpart22 partition of idxpart2 for values from (15) to (20); + +create table idxpart3 (b int not null, a int not null); + +alter table idxpart attach partition idxpart3 for values from (20, 20) to (30, 30); + +select conname, contype, conrelid::regclass, conindid::regclass, conkey + from pg_constraint where conrelid::regclass::text like 'idxpart%' + order by conrelid::regclass::text, conname; + +drop table idxpart; + +create table idxpart (a int, b int, primary key (a)) partition by range (a); + +create table idxpart2 partition of idxpart +for values from (0) to (1000) partition by range (b); + +drop table idxpart; + +create table idxpart (a int unique, b int) partition by range (a); + +create table idxpart1 (a int not null, b int, unique (a, b)) + partition by range (a, b); + +alter table idxpart attach partition idxpart1 for values from (1) to (1000); + +DROP TABLE idxpart, idxpart1; + +create table idxpart (a int, b int, primary key (a, b)) partition by range (a); + +create table idxpart2 partition of idxpart for values from (0) to (1000) partition by range (b); + +create table idxpart21 partition of idxpart2 for values from (0) to (1000); + +select conname, contype, conrelid::regclass, conindid::regclass, conkey + from pg_constraint where conrelid::regclass::text like 'idxpart%' + order by conrelid::regclass::text, conname; + +drop table idxpart; + +create table idxpart (i int) partition by hash (i); + +create table idxpart0 partition of idxpart (i) for values with (modulus 2, remainder 0); + +create table idxpart1 partition of idxpart (i) for values with (modulus 2, remainder 1); + +alter table idxpart0 add primary key(i); + +alter table idxpart add primary key(i); + +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +drop index idxpart0_pkey; + +drop index idxpart1_pkey; + +alter table idxpart0 drop constraint idxpart0_pkey; + +alter table idxpart1 drop constraint idxpart1_pkey; + +alter table idxpart drop constraint idxpart_pkey; + +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +drop table idxpart; + +CREATE TABLE idxpart (c1 INT PRIMARY KEY, c2 INT, c3 VARCHAR(10)) PARTITION BY RANGE(c1); + +CREATE TABLE idxpart1 (LIKE idxpart); + +ALTER TABLE idxpart1 ADD PRIMARY KEY (c1, c2); + +ALTER TABLE idxpart ATTACH PARTITION idxpart1 FOR VALUES FROM (100) TO (200); + +DROP TABLE idxpart, idxpart1; + +create table idxpart (a int, b int, primary key (a)) partition by range (a); + +create table idxpart1 (a int not null, b int) partition by range (a); + +create table idxpart11 (a int not null, b int primary key); + +alter table idxpart1 attach partition idxpart11 for values from (0) to (1000); + +alter table idxpart attach partition idxpart1 for values from (0) to (10000); + +drop table idxpart, idxpart1, idxpart11; + +create table idxpart (a int) partition by range (a); + +create table idxpart0 (like idxpart); + +alter table idxpart0 add primary key (a); + +alter table idxpart attach partition idxpart0 for values from (0) to (1000); + +alter table only idxpart add primary key (a); + +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +alter index idxpart_pkey attach partition idxpart0_pkey; + +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +drop table idxpart; + +create table idxpart (a int) partition by range (a); + +create table idxpart0 (like idxpart); + +alter table idxpart0 add unique (a); + +alter table idxpart attach partition idxpart0 default; + +alter table only idxpart add primary key (a); + +alter table idxpart0 alter column a set not null; + +alter table only idxpart add primary key (a); + +alter index idxpart_pkey attach partition idxpart0_a_key; + +drop table idxpart; + +create table idxpart (a int, b int) partition by range (a); + +create table idxpart1 (a int not null, b int); + +create unique index on idxpart1 (a); + +alter table idxpart add primary key (a); + +alter table idxpart attach partition idxpart1 for values from (1) to (1000); + +select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid, + conname, conislocal, coninhcount, connoinherit, convalidated + from pg_index idx left join pg_inherits inh on (idx.indexrelid = inh.inhrelid) + left join pg_constraint con on (idx.indexrelid = con.conindid) + where indrelid::regclass::text like 'idxpart%' + order by indexrelid::regclass::text collate "C"; + +drop table idxpart; + +create table idxpart (a int, b int) partition by range (a); + +create table idxpart1 (a int not null, b int); + +create unique index on idxpart1 (a); + +alter table idxpart attach partition idxpart1 for values from (1) to (1000); + +alter table only idxpart add primary key (a); + +alter index idxpart_pkey attach partition idxpart1_a_idx; + +drop table idxpart; + +create table idxpart (a int, b text, primary key (a, b)) partition by range (a); + +create table idxpart1 partition of idxpart for values from (0) to (100000); + +create table idxpart2 (c int, like idxpart); + +insert into idxpart2 (c, a, b) values (42, 572814, 'inserted first'); + +alter table idxpart2 drop column c; + +create unique index on idxpart (a); + +alter table idxpart attach partition idxpart2 for values from (100000) to (1000000); + +insert into idxpart values (0, 'zero'), (42, 'life'), (2^16, 'sixteen'); + +insert into idxpart select 2^g, format('two to power of %s', g) from generate_series(15, 17) g; + +insert into idxpart values (16, 'sixteen'); + +insert into idxpart (b, a) values ('one', 142857), ('two', 285714); + +insert into idxpart select a * 2, b || b from idxpart where a between 2^16 and 2^19; + +insert into idxpart values (572814, 'five'); + +insert into idxpart values (857142, 'six'); + +select tableoid::regclass, * from idxpart order by a; + +drop table idxpart; + +create table idxpart (a int, b text, c int[]) partition by range (a); + +create table idxpart1 partition of idxpart for values from (0) to (100000); + +set enable_seqscan to off; + +create index idxpart_brin on idxpart using brin(b); + +select * from idxpart where b = 'abcd'; + +drop index idxpart_brin; + +create index idxpart_spgist on idxpart using spgist(b); + +select * from idxpart where b = 'abcd'; + +drop index idxpart_spgist; + +create index idxpart_gin on idxpart using gin(c); + +select * from idxpart where c @> array[42]; + +drop index idxpart_gin; + +reset enable_seqscan; + +drop table idxpart; + +create table idxpart (a int) partition by range (a); + +create table idxpart1 partition of idxpart for values from (0) to (100); + +create table idxpart2 partition of idxpart for values from (100) to (1000) + partition by range (a); + +create table idxpart21 partition of idxpart2 for values from (100) to (200); + +create table idxpart22 partition of idxpart2 for values from (200) to (300); + +create index on idxpart22 (a); + +create index on only idxpart2 (a); + +alter index idxpart2_a_idx attach partition idxpart22_a_idx; + +create index on idxpart (a); + +create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a); + +create table idxpart_another_1 partition of idxpart_another for values from (0) to (100); + +create table idxpart3 (c int, b int, a int) partition by range (a); + +alter table idxpart3 drop column b, drop column c; + +create table idxpart31 partition of idxpart3 for values from (1000) to (1200); + +create table idxpart32 partition of idxpart3 for values from (1200) to (1400); + +alter table idxpart attach partition idxpart3 for values from (1000) to (2000); + +create schema regress_indexing; + +set search_path to regress_indexing; + +create table pk (a int primary key) partition by range (a); + +create table pk1 partition of pk for values from (0) to (1000); + +create table pk2 (b int, a int); + +alter table pk2 drop column b; + +alter table pk2 alter a set not null; + +alter table pk attach partition pk2 for values from (1000) to (2000); + +create table pk3 partition of pk for values from (2000) to (3000); + +create table pk4 (like pk); + +alter table pk attach partition pk4 for values from (3000) to (4000); + +create table pk5 (like pk) partition by range (a); + +create table pk51 partition of pk5 for values from (4000) to (4500); + +create table pk52 partition of pk5 for values from (4500) to (5000); + +alter table pk attach partition pk5 for values from (4000) to (5000); + +reset search_path; + +create table covidxpart (a int, b int) partition by list (a); + +create unique index on covidxpart (a) include (b); + +create table covidxpart1 partition of covidxpart for values in (1); + +create table covidxpart2 partition of covidxpart for values in (2); + +insert into covidxpart values (1, 1); + +insert into covidxpart values (1, 1); + +create table covidxpart3 (b int, c int, a int); + +alter table covidxpart3 drop c; + +alter table covidxpart attach partition covidxpart3 for values in (3); + +insert into covidxpart values (3, 1); + +insert into covidxpart values (3, 1); + +create table covidxpart4 (b int, a int); + +create unique index on covidxpart4 (a) include (b); + +create unique index on covidxpart4 (a); + +alter table covidxpart attach partition covidxpart4 for values in (4); + +insert into covidxpart values (4, 1); + +insert into covidxpart values (4, 1); + +create unique index on covidxpart (b) include (a); + +create table parted_pk_detach_test (a int primary key) partition by list (a); + +create table parted_pk_detach_test1 partition of parted_pk_detach_test for values in (1); + +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey; + +alter table parted_pk_detach_test detach partition parted_pk_detach_test1; + +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey; + +drop table parted_pk_detach_test, parted_pk_detach_test1; + +create table parted_uniq_detach_test (a int unique) partition by list (a); + +create table parted_uniq_detach_test1 partition of parted_uniq_detach_test for values in (1); + +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key; + +alter table parted_uniq_detach_test detach partition parted_uniq_detach_test1; + +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key; + +drop table parted_uniq_detach_test, parted_uniq_detach_test1; + +create table parted_index_col_drop(a int, b int, c int) + partition by list (a); + +create table parted_index_col_drop1 partition of parted_index_col_drop + for values in (1) partition by list (a); + +create table parted_index_col_drop2 partition of parted_index_col_drop + for values in (2) partition by list (a); + +create table parted_index_col_drop11 partition of parted_index_col_drop1 + for values in (1); + +create index on parted_index_col_drop (b); + +create index on parted_index_col_drop (c); + +create index on parted_index_col_drop (b, c); + +alter table parted_index_col_drop drop column c; + +drop table parted_index_col_drop; + +create table parted_inval_tab (a int) partition by range (a); + +create index parted_inval_idx on parted_inval_tab (a); + +create table parted_inval_tab_1 (a int) partition by range (a); + +create table parted_inval_tab_1_1 partition of parted_inval_tab_1 + for values from (0) to (10); + +create table parted_inval_tab_1_2 partition of parted_inval_tab_1 + for values from (10) to (20); + +create index parted_inval_ixd_1 on only parted_inval_tab_1 (a); + +alter table parted_inval_tab attach partition parted_inval_tab_1 + for values from (1) to (100); + +select indexrelid::regclass, indisvalid, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_inval%' + order by indexrelid::regclass::text collate "C"; + +drop table parted_inval_tab; + +create table parted_isvalid_tab (a int, b int) partition by range (a); + +create table parted_isvalid_tab_1 partition of parted_isvalid_tab + for values from (1) to (10) partition by range (a); + +create table parted_isvalid_tab_2 partition of parted_isvalid_tab + for values from (10) to (20) partition by range (a); + +create table parted_isvalid_tab_11 partition of parted_isvalid_tab_1 + for values from (1) to (5); + +create table parted_isvalid_tab_12 partition of parted_isvalid_tab_1 + for values from (5) to (10); + +insert into parted_isvalid_tab_11 values (1, 0); + +create index concurrently parted_isvalid_idx_11 on parted_isvalid_tab_11 ((a/b)); + +create index parted_isvalid_idx on parted_isvalid_tab ((a/b)); + +select indexrelid::regclass, indisvalid, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_isvalid%' + order by indexrelid::regclass::text collate "C"; + +drop table parted_isvalid_tab; + +begin; + +create table parted_replica_tab (id int not null) partition by range (id); + +create table parted_replica_tab_1 partition of parted_replica_tab + for values from (1) to (10) partition by range (id); + +create table parted_replica_tab_11 partition of parted_replica_tab_1 + for values from (1) to (5); + +create unique index parted_replica_idx + on only parted_replica_tab using btree (id); + +create unique index parted_replica_idx_1 + on only parted_replica_tab_1 using btree (id); + +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1; + +create unique index parted_replica_idx_11 on parted_replica_tab_11 USING btree (id); + +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; + +alter index parted_replica_idx ATTACH PARTITION parted_replica_idx_1; + +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; + +alter index parted_replica_idx_1 ATTACH PARTITION parted_replica_idx_11; + +alter table only parted_replica_tab_1 replica identity + using index parted_replica_idx_1; + +commit; + +select indexrelid::regclass, indisvalid, indisreplident, + indrelid::regclass, inhparent::regclass + from pg_index idx left join + pg_inherits inh on (idx.indexrelid = inh.inhrelid) + where indexrelid::regclass::text like 'parted_replica%' + order by indexrelid::regclass::text collate "C"; + +drop table parted_replica_tab; + +create table test_pg_index_toast_table (a int); + +create or replace function test_pg_index_toast_func (a int, b int[]) + returns bool as $$ select true $$ language sql immutable; + +select array_agg(n) b from generate_series(1, 10000) n ; + +create index concurrently test_pg_index_toast_index + on test_pg_index_toast_table (test_pg_index_toast_func(a, 'b')); + +reindex index concurrently test_pg_index_toast_index; + +drop index concurrently test_pg_index_toast_index; + +create index test_pg_index_toast_index + on test_pg_index_toast_table (test_pg_index_toast_func(a, 'b')); + +reindex index test_pg_index_toast_index; + +drop index test_pg_index_toast_index; + +drop function test_pg_index_toast_func; + +drop table test_pg_index_toast_table; diff --git a/crates/pgt_pretty_print/tests/data/multi/indirect_toast_60.sql b/crates/pgt_pretty_print/tests/data/multi/indirect_toast_60.sql new file mode 100644 index 000000000..6f67c6456 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/indirect_toast_60.sql @@ -0,0 +1,68 @@ +CREATE FUNCTION make_tuple_indirect (record) + RETURNS record + AS 'regresslib' + LANGUAGE C STRICT; + +SET default_toast_compression = 'pglz'; + +CREATE TABLE indtoasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text); + +INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000)); + +INSERT INTO indtoasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000)); + +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000)); + +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000)); + +SELECT descr, substring(make_tuple_indirect(indtoasttest)::text, 1, 200) FROM indtoasttest; + +UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200); + +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200); + +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200); + +UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200); + +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest; + +VACUUM FREEZE indtoasttest; + +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest; + +CREATE FUNCTION update_using_indirect() + RETURNS trigger + LANGUAGE plpgsql AS $$ +BEGIN + NEW := make_tuple_indirect(NEW); + RETURN NEW; +END$$; + +CREATE TRIGGER indtoasttest_update_indirect + BEFORE INSERT OR UPDATE + ON indtoasttest + FOR EACH ROW + EXECUTE PROCEDURE update_using_indirect(); + +UPDATE indtoasttest SET cnt = cnt +1 RETURNING substring(indtoasttest::text, 1, 200); + +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(indtoasttest::text, 1, 200); + +UPDATE indtoasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(indtoasttest::text, 1, 200); + +UPDATE indtoasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(indtoasttest::text, 1, 200); + +INSERT INTO indtoasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL); + +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest; + +VACUUM FREEZE indtoasttest; + +SELECT substring(indtoasttest::text, 1, 200) FROM indtoasttest; + +DROP TABLE indtoasttest; + +DROP FUNCTION update_using_indirect(); + +RESET default_toast_compression; diff --git a/crates/pgt_pretty_print/tests/data/multi/inet_60.sql b/crates/pgt_pretty_print/tests/data/multi/inet_60.sql new file mode 100644 index 000000000..7ebb894c3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/inet_60.sql @@ -0,0 +1,338 @@ +DROP TABLE INET_TBL; + +CREATE TABLE INET_TBL (c cidr, i inet); + +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.226/24'); + +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.0/26', '192.168.1.226'); + +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.0/24'); + +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.0/25'); + +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.255/24'); + +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.255/25'); + +INSERT INTO INET_TBL (c, i) VALUES ('10', '10.1.2.3/8'); + +INSERT INTO INET_TBL (c, i) VALUES ('10.0.0.0', '10.1.2.3/8'); + +INSERT INTO INET_TBL (c, i) VALUES ('10.1.2.3', '10.1.2.3/32'); + +INSERT INTO INET_TBL (c, i) VALUES ('10.1.2', '10.1.2.3/24'); + +INSERT INTO INET_TBL (c, i) VALUES ('10.1', '10.1.2.3/16'); + +INSERT INTO INET_TBL (c, i) VALUES ('10', '10.1.2.3/8'); + +INSERT INTO INET_TBL (c, i) VALUES ('10', '11.1.2.3/8'); + +INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8'); + +INSERT INTO INET_TBL (c, i) VALUES ('10:23::f1', '10:23::f1/64'); + +INSERT INTO INET_TBL (c, i) VALUES ('10:23::8000/113', '10:23::ffff'); + +INSERT INTO INET_TBL (c, i) VALUES ('::ffff:1.2.3.4', '::4.3.2.1/24'); + +INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/30', '192.168.1.226'); + +INSERT INTO INET_TBL (c, i) VALUES ('1234::1234::1234', '::1.2.3.4'); + +INSERT INTO INET_TBL (c, i) VALUES (cidr('192.168.1.2/30'), '192.168.1.226'); + +INSERT INTO INET_TBL (c, i) VALUES (cidr('ffff:ffff:ffff:ffff::/24'), '::192.168.1.226'); + +SELECT c AS cidr, i AS inet FROM INET_TBL; + +SELECT i AS inet, host(i), text(i), family(i) FROM INET_TBL; + +SELECT c AS cidr, abbrev(c) AS "abbrev(cidr)", + i AS inet, abbrev(i) AS "abbrev(inet)" FROM INET_TBL; + +SELECT c AS cidr, broadcast(c) AS "broadcast(cidr)", + i AS inet, broadcast(i) AS "broadcast(inet)" FROM INET_TBL; + +SELECT c AS cidr, network(c) AS "network(cidr)", + i AS inet, network(i) AS "network(inet)" FROM INET_TBL; + +SELECT c AS cidr, masklen(c) AS "masklen(cidr)", + i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL; + +SELECT c AS cidr, masklen(c) AS "masklen(cidr)", + i AS inet, masklen(i) AS "masklen(inet)" FROM INET_TBL + WHERE masklen(c) <= 8; + +SELECT i AS inet, netmask(i) AS "netmask(inet)" FROM INET_TBL; + +SELECT i AS inet, hostmask(i) AS "hostmask(inet)" FROM INET_TBL; + +SELECT c AS cidr, i AS inet FROM INET_TBL + WHERE c = i; + +SELECT i, c, + i < c AS lt, i <= c AS le, i = c AS eq, + i >= c AS ge, i > c AS gt, i <> c AS ne, + i << c AS sb, i <<= c AS sbe, + i >> c AS sup, i >>= c AS spe, + i && c AS ovr + FROM INET_TBL; + +SELECT max(i) AS max, min(i) AS min FROM INET_TBL; + +SELECT max(c) AS max, min(c) AS min FROM INET_TBL; + +SELECT c AS cidr, set_masklen(cidr(text(c)), 24) AS "set_masklen(cidr)", + i AS inet, set_masklen(inet(text(i)), 24) AS "set_masklen(inet)" FROM INET_TBL; + +SELECT c AS cidr, set_masklen(cidr(text(c)), -1) AS "set_masklen(cidr)", + i AS inet, set_masklen(inet(text(i)), -1) AS "set_masklen(inet)" FROM INET_TBL; + +SELECT set_masklen(inet(text(i)), 33) FROM INET_TBL; + +SELECT set_masklen(cidr(text(c)), 33) FROM INET_TBL; + +CREATE INDEX inet_idx1 ON inet_tbl(i); + +SET enable_seqscan TO off; + +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr; + +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr; + +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr; + +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr; + +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i; + +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i; + +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i; + +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i; + +SET enable_seqscan TO on; + +DROP INDEX inet_idx1; + +CREATE INDEX inet_idx2 ON inet_tbl using gist (i inet_ops); + +SET enable_seqscan TO off; + +SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i; + +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + +SET enable_seqscan TO on; + +DROP INDEX inet_idx2; + +CREATE INDEX inet_idx3 ON inet_tbl using spgist (i); + +SET enable_seqscan TO off; + +SELECT * FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i <<= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i && '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i >>= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i >> '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i < '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i <= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i; + +SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i; + +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + +SET enable_seqscan TO on; + +DROP INDEX inet_idx3; + +SELECT i, ~i AS "~i" FROM inet_tbl; + +SELECT i, c, i & c AS "and" FROM inet_tbl; + +SELECT i, c, i | c AS "or" FROM inet_tbl; + +SELECT i, i + 500 AS "i+500" FROM inet_tbl; + +SELECT i, i - 500 AS "i-500" FROM inet_tbl; + +SELECT i, c, i - c AS "minus" FROM inet_tbl; + +SELECT '127.0.0.1'::inet + 257; + +SELECT ('127.0.0.1'::inet + 257) - 257; + +SELECT '127::1'::inet + 257; + +SELECT ('127::1'::inet + 257) - 257; + +SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet + 500); + +SELECT '127.0.0.2'::inet - ('127.0.0.2'::inet - 500); + +SELECT '127::2'::inet - ('127::2'::inet + 500); + +SELECT '127::2'::inet - ('127::2'::inet - 500); + +SELECT '127.0.0.1'::inet + 10000000000; + +SELECT '127.0.0.1'::inet - 10000000000; + +SELECT '126::1'::inet - '127::2'::inet; + +SELECT '127::1'::inet - '126::2'::inet; + +SELECT '127::1'::inet + 10000000000; + +SELECT '127::1'::inet - '127::2'::inet; + +INSERT INTO INET_TBL (c, i) VALUES ('10', '10::/8'); + +SELECT inet_merge(c, i) FROM INET_TBL; + +SELECT inet_merge(c, i) FROM INET_TBL WHERE inet_same_family(c, i); + +SELECT a FROM (VALUES + ('0.0.0.0/0'::inet), + ('0.0.0.0/1'::inet), + ('0.0.0.0/32'::inet), + ('0.0.0.1/0'::inet), + ('0.0.0.1/1'::inet), + ('127.126.127.127/0'::inet), + ('127.127.127.127/0'::inet), + ('127.128.127.127/0'::inet), + ('192.168.1.0/24'::inet), + ('192.168.1.0/25'::inet), + ('192.168.1.1/23'::inet), + ('192.168.1.1/5'::inet), + ('192.168.1.1/6'::inet), + ('192.168.1.1/25'::inet), + ('192.168.1.2/25'::inet), + ('192.168.1.1/26'::inet), + ('192.168.1.2/26'::inet), + ('192.168.1.2/23'::inet), + ('192.168.1.255/5'::inet), + ('192.168.1.255/6'::inet), + ('192.168.1.3/1'::inet), + ('192.168.1.3/23'::inet), + ('192.168.1.4/0'::inet), + ('192.168.1.5/0'::inet), + ('255.0.0.0/0'::inet), + ('255.1.0.0/0'::inet), + ('255.2.0.0/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/15'::inet), + ('255.255.000.000/16'::inet), + ('255.255.255.254/32'::inet), + ('255.255.255.000/32'::inet), + ('255.255.255.001/31'::inet), + ('255.255.255.002/31'::inet), + ('255.255.255.003/31'::inet), + ('255.255.255.003/32'::inet), + ('255.255.255.001/32'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/1'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/31'::inet), + ('255.255.255.255/32'::inet), + ('255.255.255.253/32'::inet), + ('255.255.255.252/32'::inet), + ('255.3.0.0/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/128'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0001/128'::inet), + ('10:23::f1/64'::inet), + ('10:23::f1/65'::inet), + ('10:23::ffff'::inet), + ('127::1'::inet), + ('127::2'::inet), + ('8000:0000:0000:0000:0000:0000:0000:0000/1'::inet), + ('::1:ffff:ffff:ffff:ffff/128'::inet), + ('::2:ffff:ffff:ffff:ffff/128'::inet), + ('::4:3:2:0/24'::inet), + ('::4:3:2:1/24'::inet), + ('::4:3:2:2/24'::inet), + ('ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70'::inet), + ('ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44'::inet), + ('ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69'::inet), + ('ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73'::inet), + ('ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89'::inet), + ('ffff:8dd0:646:694c:7c16:7e35:6a26:171/104'::inet), + ('ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121'::inet), + ('ffff:90e7:e744:664:a93:8efe:1f25:7663/122'::inet), + ('ffff:9597:c69c:8b24:57a:8639:ec78:6026/111'::inet), + ('ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88'::inet), + ('ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23'::inet), + ('ffff:fffa:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffb:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffc:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffd:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffe:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffa:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffb:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffc:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffd::/128'::inet), + ('ffff:ffff:ffff:fffd:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffe::/128'::inet), + ('ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:0/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:1/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:2/24'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet) +) AS i(a) ORDER BY a; + +SELECT pg_input_is_valid('1234', 'cidr'); + +SELECT * FROM pg_input_error_info('1234', 'cidr'); + +SELECT pg_input_is_valid('192.168.198.200/24', 'cidr'); + +SELECT * FROM pg_input_error_info('192.168.198.200/24', 'cidr'); + +SELECT pg_input_is_valid('1234', 'inet'); + +SELECT * FROM pg_input_error_info('1234', 'inet'); diff --git a/crates/pgt_pretty_print/tests/data/multi/infinite_recurse_60.sql b/crates/pgt_pretty_print/tests/data/multi/infinite_recurse_60.sql new file mode 100644 index 000000000..7a141deae --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/infinite_recurse_60.sql @@ -0,0 +1,7 @@ +create function infinite_recurse() returns int as +'select infinite_recurse()' language sql; + +SELECT version() ~ 'powerpc64[^,]*-linux-gnu' + AS skip_test ; + +select infinite_recurse(); diff --git a/crates/pgt_pretty_print/tests/data/multi/inherit_60.sql b/crates/pgt_pretty_print/tests/data/multi/inherit_60.sql new file mode 100644 index 000000000..4e611a0f6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/inherit_60.sql @@ -0,0 +1,1825 @@ +CREATE TABLE a (aa TEXT); + +CREATE TABLE b (bb TEXT) INHERITS (a); + +CREATE TABLE c (cc TEXT) INHERITS (a); + +CREATE TABLE d (dd TEXT) INHERITS (b,c,a); + +INSERT INTO a(aa) VALUES('aaa'); + +INSERT INTO a(aa) VALUES('aaaa'); + +INSERT INTO a(aa) VALUES('aaaaa'); + +INSERT INTO a(aa) VALUES('aaaaaa'); + +INSERT INTO a(aa) VALUES('aaaaaaa'); + +INSERT INTO a(aa) VALUES('aaaaaaaa'); + +INSERT INTO b(aa) VALUES('bbb'); + +INSERT INTO b(aa) VALUES('bbbb'); + +INSERT INTO b(aa) VALUES('bbbbb'); + +INSERT INTO b(aa) VALUES('bbbbbb'); + +INSERT INTO b(aa) VALUES('bbbbbbb'); + +INSERT INTO b(aa) VALUES('bbbbbbbb'); + +INSERT INTO c(aa) VALUES('ccc'); + +INSERT INTO c(aa) VALUES('cccc'); + +INSERT INTO c(aa) VALUES('ccccc'); + +INSERT INTO c(aa) VALUES('cccccc'); + +INSERT INTO c(aa) VALUES('ccccccc'); + +INSERT INTO c(aa) VALUES('cccccccc'); + +INSERT INTO d(aa) VALUES('ddd'); + +INSERT INTO d(aa) VALUES('dddd'); + +INSERT INTO d(aa) VALUES('ddddd'); + +INSERT INTO d(aa) VALUES('dddddd'); + +INSERT INTO d(aa) VALUES('ddddddd'); + +INSERT INTO d(aa) VALUES('dddddddd'); + +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid; + +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid; + +UPDATE a SET aa='zzzz' WHERE aa='aaaa'; + +UPDATE ONLY a SET aa='zzzzz' WHERE aa='aaaaa'; + +UPDATE b SET aa='zzz' WHERE aa='aaa'; + +UPDATE ONLY b SET aa='zzz' WHERE aa='aaa'; + +UPDATE a SET aa='zzzzzz' WHERE aa LIKE 'aaa%'; + +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid; + +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid; + +UPDATE b SET aa='new'; + +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid; + +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid; + +UPDATE a SET aa='new'; + +DELETE FROM ONLY c WHERE aa='new'; + +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid; + +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid; + +DELETE FROM a; + +SELECT relname, a.* FROM a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM d, pg_class where d.tableoid = pg_class.oid; + +SELECT relname, a.* FROM ONLY a, pg_class where a.tableoid = pg_class.oid; + +SELECT relname, b.* FROM ONLY b, pg_class where b.tableoid = pg_class.oid; + +SELECT relname, c.* FROM ONLY c, pg_class where c.tableoid = pg_class.oid; + +SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid; + +CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a); + +INSERT INTO z VALUES (NULL, 'text'); + +CREATE TEMP TABLE z2 (b TEXT, UNIQUE(aa, b)) inherits (a); + +INSERT INTO z2 VALUES (NULL, 'text'); + +create table some_tab (f1 int, f2 int, f3 int, check (f1 < 10) no inherit); + +create table some_tab_child () inherits(some_tab); + +insert into some_tab_child select i, i+1, 0 from generate_series(1,1000) i; + +create index on some_tab_child(f1, f2); + +create function some_tab_stmt_trig_func() returns trigger as +$$begin raise notice 'updating some_tab'; return NULL; end;$$ +language plpgsql; + +create trigger some_tab_stmt_trig + before update on some_tab execute function some_tab_stmt_trig_func(); + +update some_tab set f3 = 11 where f1 = 12 and f2 = 13; + +update some_tab set f3 = 11 where f1 = 12 and f2 = 13; + +drop table some_tab cascade; + +drop function some_tab_stmt_trig_func(); + +create table some_tab (a int, b int); + +create table some_tab_child () inherits (some_tab); + +insert into some_tab_child values(1,2); + +update some_tab set a = a + 1 where false; + +update some_tab set a = a + 1 where false; + +update some_tab set a = a + 1 where false returning b, a; + +update some_tab set a = a + 1 where false returning b, a; + +table some_tab; + +drop table some_tab cascade; + +create temp table foo(f1 int, f2 int); + +create temp table foo2(f3 int) inherits (foo); + +create temp table bar(f1 int, f2 int); + +create temp table bar2(f3 int) inherits (bar); + +insert into foo values(1,1); + +insert into foo values(3,3); + +insert into foo2 values(2,2,2); + +insert into foo2 values(3,3,3); + +insert into bar values(1,1); + +insert into bar values(2,2); + +insert into bar values(3,3); + +insert into bar values(4,4); + +insert into bar2 values(1,1,1); + +insert into bar2 values(2,2,2); + +insert into bar2 values(3,3,3); + +insert into bar2 values(4,4,4); + +update bar set f2 = f2 + 100 where f1 in (select f1 from foo); + +select tableoid::regclass::text as relname, bar.* from bar order by 1,2; + +update bar set f2 = f2 + 100 +from + ( select f1 from foo union all select f1+3 from foo ) ss +where bar.f1 = ss.f1; + +select tableoid::regclass::text as relname, bar.* from bar order by 1,2; + +create table some_tab (a int); + +insert into some_tab values (0); + +create table some_tab_child () inherits (some_tab); + +insert into some_tab_child values (1); + +create table parted_tab (a int, b char) partition by list (a); + +create table parted_tab_part1 partition of parted_tab for values in (1); + +create table parted_tab_part2 partition of parted_tab for values in (2); + +create table parted_tab_part3 partition of parted_tab for values in (3); + +insert into parted_tab values (1, 'a'), (2, 'a'), (3, 'a'); + +update parted_tab set b = 'b' +from + (select a from some_tab union all select a+1 from some_tab) ss (a) +where parted_tab.a = ss.a; + +select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2; + +truncate parted_tab; + +insert into parted_tab values (1, 'a'), (2, 'a'), (3, 'a'); + +update parted_tab set b = 'b' +from + (select 0 from parted_tab union all select 1 from parted_tab) ss (a) +where parted_tab.a = ss.a; + +select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2; + +update parted_tab set a = 2 where false; + +drop table parted_tab; + +create table mlparted_tab (a int, b char, c text) partition by list (a); + +create table mlparted_tab_part1 partition of mlparted_tab for values in (1); + +create table mlparted_tab_part2 partition of mlparted_tab for values in (2) partition by list (b); + +create table mlparted_tab_part3 partition of mlparted_tab for values in (3); + +create table mlparted_tab_part2a partition of mlparted_tab_part2 for values in ('a'); + +create table mlparted_tab_part2b partition of mlparted_tab_part2 for values in ('b'); + +insert into mlparted_tab values (1, 'a'), (2, 'a'), (2, 'b'), (3, 'a'); + +update mlparted_tab mlp set c = 'xxx' +from + (select a from some_tab union all select a+1 from some_tab) ss (a) +where (mlp.a = ss.a and mlp.b = 'b') or mlp.a = 3; + +select tableoid::regclass::text as relname, mlparted_tab.* from mlparted_tab order by 1,2; + +drop table mlparted_tab; + +drop table some_tab cascade; + +CREATE TABLE firstparent (tomorrow date default now()::date + 1); + +CREATE TABLE secondparent (tomorrow date default now() :: date + 1); + +CREATE TABLE jointchild () INHERITS (firstparent, secondparent); + +CREATE TABLE thirdparent (tomorrow date default now()::date - 1); + +CREATE TABLE otherchild () INHERITS (firstparent, thirdparent); + +CREATE TABLE otherchild (tomorrow date default now()) + INHERITS (firstparent, thirdparent); + +DROP TABLE firstparent, secondparent, jointchild, thirdparent, otherchild; + +insert into d values('test','one','two','three'); + +alter table a alter column aa type integer using bit_length(aa); + +select * from d; + +create temp table parent1(f1 int, f2 int); + +create temp table parent2(f1 int, f3 bigint); + +create temp table childtab(f4 int) inherits(parent1, parent2); + +alter table parent1 alter column f1 type bigint; + +alter table parent1 alter column f2 type bigint; + +create table p1(ff1 int); + +alter table p1 add constraint p1chk check (ff1 > 0) no inherit; + +alter table p1 add constraint p2chk check (ff1 > 10); + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.connoinherit from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname = 'p1' order by 1,2; + +create table c1 () inherits (p1); + +create table c2 (constraint p2chk check (ff1 > 10) no inherit) inherits (p1); + +drop table p1 cascade; + +create table base (i integer); + +create table derived () inherits (base); + +create table more_derived (like derived, b int) inherits (derived); + +insert into derived (i) values (0); + +select derived::base from derived; + +select NULL::derived::base; + +select row(i, b)::more_derived::derived::base from more_derived; + +select (1, 2)::more_derived::derived::base; + +drop table more_derived; + +drop table derived; + +drop table base; + +create table p1(ff1 int); + +create table p2(f1 text); + +create function p2text(p2) returns text as 'select $1.f1' language sql; + +create table c1(f3 int) inherits(p1,p2); + +insert into c1 values(123456789, 'hi', 42); + +select p2text(c1.*) from c1; + +drop function p2text(p2); + +drop table c1; + +drop table p2; + +drop table p1; + +CREATE TABLE ac (aa TEXT); + +alter table ac add constraint ac_check check (aa is not null); + +CREATE TABLE bc (bb TEXT) INHERITS (ac); + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +insert into ac (aa) values (NULL); + +insert into bc (aa) values (NULL); + +alter table bc drop constraint ac_check; + +alter table ac drop constraint ac_check; + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +alter table ac add check (aa is not null); + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +insert into ac (aa) values (NULL); + +insert into bc (aa) values (NULL); + +alter table bc drop constraint ac_aa_check; + +alter table ac drop constraint ac_aa_check; + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +alter table ac add constraint ac_check check (aa is not null); + +alter table bc no inherit ac; + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +alter table bc drop constraint ac_check; + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +alter table ac drop constraint ac_check; + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +drop table bc; + +drop table ac; + +create table ac (a int constraint check_a check (a <> 0)); + +create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac); + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; + +drop table bc; + +drop table ac; + +create table ac (a int constraint check_a check (a <> 0)); + +create table bc (b int constraint check_b check (b <> 0)); + +create table cc (c int constraint check_c check (c <> 0)) inherits (ac, bc); + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; + +alter table cc no inherit bc; + +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; + +drop table cc; + +drop table bc; + +drop table ac; + +create table p1(f1 int); + +create table p2(f2 int); + +create table c1(f3 int) inherits(p1,p2); + +insert into c1 values(1,-1,2); + +alter table p2 add constraint cc check (f2>0); + +alter table p2 add check (f2>0); + +delete from c1; + +insert into c1 values(1,1,2); + +alter table p2 add check (f2>0); + +insert into c1 values(1,-1,2); + +create table c2(f3 int) inherits(p1,p2); + +create table c3 (f4 int) inherits(c1,c2); + +drop table p1 cascade; + +drop table p2 cascade; + +create table pp1 (f1 int); + +create table cc1 (f2 text, f3 int) inherits (pp1); + +alter table pp1 add column a1 int check (a1 > 0); + +create table cc2(f4 float) inherits(pp1,cc1); + +alter table pp1 add column a2 int check (a2 > 0); + +drop table pp1 cascade; + +CREATE TABLE inht1 (a int, b int); + +CREATE TABLE inhs1 (b int, c int); + +CREATE TABLE inhts (d int) INHERITS (inht1, inhs1); + +ALTER TABLE inht1 RENAME a TO aa; + +ALTER TABLE inht1 RENAME b TO bb; + +ALTER TABLE inhts RENAME aa TO aaa; + +ALTER TABLE inhts RENAME d TO dd; + +DROP TABLE inhts; + +CREATE TABLE inhta (); + +CREATE TABLE inhtb () INHERITS (inhta); + +CREATE TABLE inhtc () INHERITS (inhtb); + +CREATE TABLE inhtd () INHERITS (inhta, inhtb, inhtc); + +ALTER TABLE inhta ADD COLUMN i int, ADD COLUMN j bigint DEFAULT 1; + +DROP TABLE inhta, inhtb, inhtc, inhtd; + +CREATE TABLE inht2 (x int) INHERITS (inht1); + +CREATE TABLE inht3 (y int) INHERITS (inht1); + +CREATE TABLE inht4 (z int) INHERITS (inht2, inht3); + +ALTER TABLE inht1 RENAME aa TO aaa; + +CREATE TABLE inhts (d int) INHERITS (inht2, inhs1); + +ALTER TABLE inht1 RENAME aaa TO aaaa; + +ALTER TABLE inht1 RENAME b TO bb; + +WITH RECURSIVE r AS ( + SELECT 'inht1'::regclass AS inhrelid +UNION ALL + SELECT c.inhrelid FROM pg_inherits c, r WHERE r.inhrelid = c.inhparent +) +SELECT a.attrelid::regclass, a.attname, a.attinhcount, e.expected + FROM (SELECT inhrelid, count(*) AS expected FROM pg_inherits + WHERE inhparent IN (SELECT inhrelid FROM r) GROUP BY inhrelid) e + JOIN pg_attribute a ON e.inhrelid = a.attrelid WHERE NOT attislocal + ORDER BY a.attrelid::regclass::name, a.attnum; + +DROP TABLE inht1, inhs1 CASCADE; + +CREATE TABLE test_constraints (id int, val1 varchar, val2 int, UNIQUE(val1, val2)); + +CREATE TABLE test_constraints_inh () INHERITS (test_constraints); + +ALTER TABLE ONLY test_constraints DROP CONSTRAINT test_constraints_val1_val2_key; + +DROP TABLE test_constraints_inh; + +DROP TABLE test_constraints; + +CREATE TABLE test_ex_constraints ( + c circle, + EXCLUDE USING gist (c WITH &&) +); + +CREATE TABLE test_ex_constraints_inh () INHERITS (test_ex_constraints); + +ALTER TABLE test_ex_constraints DROP CONSTRAINT test_ex_constraints_c_excl; + +DROP TABLE test_ex_constraints_inh; + +DROP TABLE test_ex_constraints; + +CREATE TABLE test_primary_constraints(id int PRIMARY KEY); + +CREATE TABLE test_foreign_constraints(id1 int REFERENCES test_primary_constraints(id)); + +CREATE TABLE test_foreign_constraints_inh () INHERITS (test_foreign_constraints); + +ALTER TABLE test_foreign_constraints DROP CONSTRAINT test_foreign_constraints_id1_fkey; + +DROP TABLE test_foreign_constraints_inh; + +DROP TABLE test_foreign_constraints; + +DROP TABLE test_primary_constraints; + +create table inh_fk_1 (a int primary key); + +insert into inh_fk_1 values (1), (2), (3); + +create table inh_fk_2 (x int primary key, y int references inh_fk_1 on delete cascade); + +insert into inh_fk_2 values (11, 1), (22, 2), (33, 3); + +create table inh_fk_2_child () inherits (inh_fk_2); + +insert into inh_fk_2_child values (111, 1), (222, 2); + +delete from inh_fk_1 where a = 1; + +select * from inh_fk_1 order by 1; + +select * from inh_fk_2 order by 1, 2; + +drop table inh_fk_1, inh_fk_2, inh_fk_2_child; + +create table p1(f1 int); + +create table p1_c1() inherits(p1); + +alter table p1 add constraint inh_check_constraint1 check (f1 > 0); + +alter table p1_c1 add constraint inh_check_constraint1 check (f1 > 0); + +alter table p1_c1 add constraint inh_check_constraint2 check (f1 < 10); + +alter table p1 add constraint inh_check_constraint2 check (f1 < 10); + +create table p1_c2(f1 int constraint inh_check_constraint4 check (f1 < 10)) inherits(p1); + +create table p1_c3() inherits(p1, p1_c1); + +select conrelid::regclass::text as relname, conname, conislocal, coninhcount, conenforced, convalidated +from pg_constraint where conname like 'inh\_check\_constraint%' +order by 1, 2; + +drop table p1 cascade; + +alter table p1_c1 inherit p1; + +drop table p1 cascade; + +alter table p1_c1 inherit p1; + +drop table p1, p1_c1; + +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)); + +create table p1_c1 (f1 int constraint f1_pos CHECK (f1 > 0)) inherits (p1); + +alter table p1_c1 drop constraint f1_pos; + +alter table p1 drop constraint f1_pos; + +drop table p1 cascade; + +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)); + +create table p2(f1 int constraint f1_pos CHECK (f1 > 0)); + +create table p1p2_c1 (f1 int) inherits (p1, p2); + +create table p1p2_c2 (f1 int constraint f1_pos CHECK (f1 > 0)) inherits (p1, p2); + +alter table p2 drop constraint f1_pos; + +alter table p1 drop constraint f1_pos; + +drop table p1, p2 cascade; + +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)); + +create table p1_c1() inherits (p1); + +create table p1_c2() inherits (p1); + +create table p1_c1c2() inherits (p1_c1, p1_c2); + +alter table p1 drop constraint f1_pos; + +drop table p1 cascade; + +create table p1(f1 int constraint f1_pos CHECK (f1 > 0)); + +create table p1_c1() inherits (p1); + +create table p1_c2(constraint f1_pos CHECK (f1 > 0)) inherits (p1); + +create table p1_c1c2() inherits (p1_c1, p1_c2, p1); + +alter table p1_c2 drop constraint f1_pos; + +alter table p1 drop constraint f1_pos; + +alter table p1_c1c2 drop constraint f1_pos; + +alter table p1_c2 drop constraint f1_pos; + +drop table p1 cascade; + +create table invalid_check_con(f1 int); + +create table invalid_check_con_child() inherits(invalid_check_con); + +alter table invalid_check_con_child add constraint inh_check_constraint check(f1 > 0) not valid; + +alter table invalid_check_con add constraint inh_check_constraint check(f1 > 0); + +alter table invalid_check_con_child drop constraint inh_check_constraint; + +insert into invalid_check_con values(0); + +alter table invalid_check_con_child add constraint inh_check_constraint check(f1 > 0); + +alter table invalid_check_con add constraint inh_check_constraint check(f1 > 0) not valid; + +insert into invalid_check_con values(0); + +insert into invalid_check_con_child values(0); + +select conrelid::regclass::text as relname, conname, + convalidated, conislocal, coninhcount, connoinherit +from pg_constraint where conname like 'inh\_check\_constraint%' +order by 1, 2; + +create temp table patest0 (id, x) as + select x, x from generate_series(0,1000) x; + +create temp table patest1() inherits (patest0); + +insert into patest1 + select x, x from generate_series(0,1000) x; + +create temp table patest2() inherits (patest0); + +insert into patest2 + select x, x from generate_series(0,1000) x; + +create index patest0i on patest0(id); + +create index patest1i on patest1(id); + +create index patest2i on patest2(id); + +analyze patest0; + +analyze patest1; + +analyze patest2; + +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1; + +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1; + +drop index patest2i; + +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1; + +select * from patest0 join (select f1 from int4_tbl limit 1) ss on id = f1; + +drop table patest0 cascade; + +create table matest0 (id serial primary key, name text); + +create table matest1 (id integer primary key) inherits (matest0); + +create table matest2 (id integer primary key) inherits (matest0); + +create table matest3 (id integer primary key) inherits (matest0); + +create index matest0i on matest0 ((1-id)); + +create index matest1i on matest1 ((1-id)); + +create index matest3i on matest3 ((1-id)); + +insert into matest1 (name) values ('Test 1'); + +insert into matest1 (name) values ('Test 2'); + +insert into matest2 (name) values ('Test 3'); + +insert into matest2 (name) values ('Test 4'); + +insert into matest3 (name) values ('Test 5'); + +insert into matest3 (name) values ('Test 6'); + +set enable_indexscan = off; + +select * from matest0 order by 1-id; + +select * from matest0 order by 1-id; + +select min(1-id) from matest0; + +select min(1-id) from matest0; + +reset enable_indexscan; + +set enable_seqscan = off; + +set enable_parallel_append = off; + +select * from matest0 order by 1-id; + +select * from matest0 order by 1-id; + +select min(1-id) from matest0; + +select min(1-id) from matest0; + +reset enable_seqscan; + +reset enable_parallel_append; + +select 1 - id as c from +(select id from matest3 t1 union all select id * 2 from matest3 t2) ss +order by c; + +select 1 - id as c from +(select id from matest3 t1 union all select id * 2 from matest3 t2) ss +order by c; + +drop table matest0 cascade; + +create table matest0 (a int, b int, c int, d int); + +create table matest1 () inherits(matest0); + +create index matest0i on matest0 (b, c); + +create index matest1i on matest1 (b, c); + +set enable_nestloop = off; + +select t1.* from matest0 t1, matest0 t2 +where t1.b = t2.b and t2.c = t2.d +order by t1.b limit 10; + +reset enable_nestloop; + +drop table matest0 cascade; + +create table matest0(a int primary key); + +create table matest1() inherits (matest0); + +insert into matest0 select generate_series(1, 400); + +insert into matest1 select generate_series(1, 200); + +analyze matest0; + +analyze matest1; + +select * from matest0 where a < 100 order by a; + +drop table matest0 cascade; + +set enable_seqscan = off; + +set enable_indexscan = on; + +set enable_bitmapscan = off; + +SELECT thousand, tenthous FROM tenk1 +UNION ALL +SELECT thousand, thousand FROM tenk1 +ORDER BY thousand, tenthous; + +SELECT thousand, tenthous, thousand+tenthous AS x FROM tenk1 +UNION ALL +SELECT 42, 42, hundred FROM tenk1 +ORDER BY thousand, tenthous; + +SELECT thousand, tenthous FROM tenk1 +UNION ALL +SELECT thousand, random()::integer FROM tenk1 +ORDER BY thousand, tenthous; + +SELECT min(x) FROM + (SELECT unique1 AS x FROM tenk1 a + UNION ALL + SELECT unique2 AS x FROM tenk1 b) s; + +SELECT min(y) FROM + (SELECT unique1 AS x, unique1 AS y FROM tenk1 a + UNION ALL + SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s; + +SELECT x, y FROM + (SELECT thousand AS x, tenthous AS y FROM tenk1 a + UNION ALL + SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s +ORDER BY x, y; + +SELECT + ARRAY(SELECT f.i FROM ( + (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1) + UNION ALL + (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1) + ) f(i) + ORDER BY f.i LIMIT 10) +FROM generate_series(1, 3) g(i); + +SELECT + ARRAY(SELECT f.i FROM ( + (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1) + UNION ALL + (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1) + ) f(i) + ORDER BY f.i LIMIT 10) +FROM generate_series(1, 3) g(i); + +reset enable_seqscan; + +reset enable_indexscan; + +reset enable_bitmapscan; + +create table inhpar(f1 int, f2 name); + +create table inhcld(f2 name, f1 int); + +alter table inhcld inherit inhpar; + +insert into inhpar select x, x::text from generate_series(1,5) x; + +insert into inhcld select x::text, x from generate_series(6,10) x; + +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1); + +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1); + +select * from inhpar; + +drop table inhpar cascade; + +create table inhpar(f1 int primary key, f2 name) partition by range (f1); + +create table inhcld1(f2 name, f1 int primary key); + +create table inhcld2(f1 int primary key, f2 name); + +alter table inhpar attach partition inhcld1 for values from (1) to (5); + +alter table inhpar attach partition inhcld2 for values from (5) to (100); + +insert into inhpar select x, x::text from generate_series(1,10) x; + +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1); + +update inhpar i set (f1, f2) = (select i.f1, i.f2 || '-' from int4_tbl limit 1); + +select * from inhpar; + +insert into inhpar as i values (3), (7) on conflict (f1) + do update set (f1, f2) = (select i.f1, i.f2 || '+'); + +select * from inhpar order by f1; + +drop table inhpar cascade; + +create table cnullparent (f1 int); + +create table cnullchild (check (f1 = 1 or f1 = null)) inherits(cnullparent); + +insert into cnullchild values(1); + +insert into cnullchild values(2); + +insert into cnullchild values(null); + +select * from cnullparent; + +select * from cnullparent where f1 = 2; + +drop table cnullparent cascade; + +create table pp1 (f1 int); + +create table cc1 (f2 text, f3 int) inherits (pp1); + +create table cc2 (f4 float) inherits (pp1,cc1); + +create table cc3 () inherits (pp1,cc1,cc2); + +alter table pp1 alter f1 set not null; + +alter table cc3 no inherit pp1; + +alter table cc3 no inherit cc1; + +alter table cc3 no inherit cc2; + +drop table cc3; + +alter table cc1 add column a2 int constraint nn not null; + +alter table pp1 alter column f1 set not null; + +alter table cc2 alter column a2 drop not null; + +alter table cc1 alter column a2 drop not null; + +alter table cc2 alter column f1 drop not null; + +alter table cc1 alter column f1 drop not null; + +alter table pp1 alter column f1 drop not null; + +alter table pp1 add primary key (f1); + +alter table inh_child inherit inh_parent; + +alter table inh_child no inherit inh_parent; + +drop table inh_parent, inh_child; + +create table inh_pp1 (f1 int); + +create table inh_cc1 (f2 text, f3 int) inherits (inh_pp1); + +create table inh_cc2(f4 float) inherits(inh_pp1,inh_cc1); + +alter table inh_pp1 alter column f1 set not null; + +alter table inh_cc2 no inherit inh_pp1; + +alter table inh_cc2 no inherit inh_cc1; + +drop table inh_pp1, inh_cc1, inh_cc2; + +create table inh_pp1 (f1 int not null); + +create table inh_cc1 (f2 text, f3 int) inherits (inh_pp1); + +create table inh_cc2(f4 float) inherits(inh_pp1,inh_cc1); + +alter table inh_pp1 alter column f1 drop not null; + +drop table inh_pp1, inh_cc1, inh_cc2; + +CREATE TABLE inh_parent (); + +CREATE TABLE inh_child (i int) INHERITS (inh_parent); + +CREATE TABLE inh_grandchild () INHERITS (inh_parent, inh_child); + +ALTER TABLE inh_parent ADD COLUMN i int NOT NULL; + +drop table inh_parent, inh_child, inh_grandchild; + +create table inh_parent1(a int constraint nn not null); + +create table inh_parent2(b int constraint nn not null); + +create table inh_child1 () inherits (inh_parent1, inh_parent2); + +alter table inh_child2 no inherit inh_parent2; + +drop table inh_parent1, inh_parent2, inh_child1, inh_child2; + +create table inh_parent1(a int, b int, c int, primary key (a, b)); + +create table inh_parent2(d int, e int, b int, primary key (d, b)); + +create table inh_child() inherits (inh_parent1, inh_parent2); + +select conrelid::regclass, conname, contype, conkey, + coninhcount, conislocal, connoinherit + from pg_constraint where contype in ('n','p') and + conrelid::regclass::text in ('inh_child', 'inh_parent1', 'inh_parent2') + order by 1, 2; + +drop table inh_parent1, inh_parent2, inh_child; + +create table inh_nn_parent(a int); + +create table inh_nn_child() inherits (inh_nn_parent); + +create table inh_nn_child2() inherits (inh_nn_parent); + +select conrelid::regclass, conname, contype, conkey, + (select attname from pg_attribute where attrelid = conrelid and attnum = conkey[1]), + coninhcount, conislocal, connoinherit + from pg_constraint where contype = 'n' and + conrelid::regclass::text like 'inh\_nn\_%' + order by 2, 1; + +drop table inh_nn_parent, inh_nn_child, inh_nn_child2; + +CREATE TABLE inh_nn_child() INHERITS (inh_nn_parent); + +ALTER TABLE inh_nn_parent ALTER a SET NOT NULL; + +DROP TABLE inh_nn_parent cascade; + +CREATE TABLE inh_nn_lvl1 (a int); + +CREATE TABLE inh_nn_lvl2 () INHERITS (inh_nn_lvl1); + +ALTER TABLE inh_nn_lvl1 ADD PRIMARY KEY (a); + +DROP TABLE inh_nn_lvl1, inh_nn_lvl2, inh_nn_lvl3; + +CREATE TABLE inh_nn1 (a int not null); + +DROP TABLE IF EXISTS inh_nn1, inh_nn2, inh_nn3, inh_nn4; + +create table inh_parent(f1 int); + +create table inh_child1(f1 int not null); + +create table inh_child2(f1 int); + +alter table inh_child1 inherit inh_parent; + +alter table inh_child2 inherit inh_child1; + +alter table inh_child2 alter column f1 set not null; + +alter table inh_child2 inherit inh_child1; + +alter table inh_parent alter column f1 set not null; + +select conrelid::regclass, conname, contype, coninhcount, conislocal + from pg_constraint where contype = 'n' and + conrelid in ('inh_parent'::regclass, 'inh_child1'::regclass, 'inh_child2'::regclass) + order by 2, 1; + +create table inh_child3 () inherits (inh_child1); + +alter table inh_child1 no inherit inh_parent; + +select conrelid::regclass, conname, contype, coninhcount, conislocal + from pg_constraint where contype = 'n' and + conrelid::regclass::text in ('inh_parent', 'inh_child1', 'inh_child2', 'inh_child3') + order by 2, 1; + +drop table inh_parent, inh_child1, inh_child2, inh_child3; + +create table inh_parent (a int not null); + +create table inh_child (a int); + +alter table inh_child inherit inh_parent; + +drop table inh_parent, inh_child; + +create table inh_parent (a int not null); + +alter table inh_child inherit inh_parent; + +drop table inh_parent, inh_child; + +create table inh_parent (a int primary key); + +create table inh_child (a int primary key) inherits (inh_parent); + +alter table inh_parent add constraint inh_parent_excl exclude ((1) with =); + +alter table inh_parent add constraint inh_parent_uq unique (a); + +alter table inh_parent add constraint inh_parent_fk foreign key (a) references inh_parent (a); + +create table inh_child2 () inherits (inh_parent); + +create table inh_child3 (like inh_parent); + +alter table inh_child3 inherit inh_parent; + +select conrelid::regclass, conname, contype, coninhcount, conislocal + from pg_constraint + where conrelid::regclass::text in ('inh_parent', 'inh_child', 'inh_child2', 'inh_child3') + order by 2, 1; + +drop table inh_parent, inh_child, inh_child2, inh_child3; + +create table inh_parent(f1 int not null); + +create table inh_child1() inherits(inh_parent); + +create table inh_child2() inherits(inh_parent); + +create table inh_child3() inherits(inh_child1, inh_child2); + +select conrelid::regclass, conname, contype, coninhcount, conislocal + from pg_constraint where contype = 'n' and + conrelid in ('inh_parent'::regclass, 'inh_child1'::regclass, 'inh_child2'::regclass, 'inh_child3'::regclass) + order by 2, conrelid::regclass::text; + +drop table inh_parent cascade; + +create table inh_parent_1(f1 int); + +create table inh_parent_2(f2 text); + +create table inh_child(f1 int not null, f2 text not null) inherits(inh_parent_1, inh_parent_2); + +select conrelid::regclass, conname, contype, coninhcount, conislocal + from pg_constraint where contype = 'n' and + conrelid in ('inh_parent_1'::regclass, 'inh_parent_2'::regclass, 'inh_child'::regclass) + order by 2, conrelid::regclass::text; + +drop table inh_parent_1 cascade; + +drop table inh_parent_2; + +create table inh_p1(f1 int not null); + +create table inh_p2(f1 int not null); + +create table inh_p3(f2 int); + +create table inh_p4(f1 int not null, f3 text not null); + +create table inh_multiparent() inherits(inh_p1, inh_p2, inh_p3, inh_p4); + +select conrelid::regclass, contype, conname, + (select attname from pg_attribute where attrelid = conrelid and attnum = conkey[1]), + coninhcount, conislocal + from pg_constraint where contype = 'n' and + conrelid::regclass in ('inh_p1', 'inh_p2', 'inh_p3', 'inh_p4', + 'inh_multiparent') + order by conrelid::regclass::text, conname; + +create table inh_multiparent2 (a int not null, f1 int) inherits(inh_p3, inh_multiparent); + +select conrelid::regclass, contype, conname, + (select attname from pg_attribute where attrelid = conrelid and attnum = conkey[1]), + coninhcount, conislocal + from pg_constraint where contype = 'n' and + conrelid::regclass in ('inh_p3', 'inh_multiparent', 'inh_multiparent2') + order by conrelid::regclass::text, conname; + +drop table inh_p1, inh_p2, inh_p3, inh_p4 cascade; + +create table inh_nn2 (f2 text, f3 int, f1 int); + +alter table inh_nn2 inherit inh_nn1; + +create table inh_nn3 (f4 float) inherits (inh_nn2); + +create table inh_nn4 (f5 int, f4 float, f2 text, f3 int, f1 int); + +alter table inh_nn4 inherit inh_nn2, inherit inh_nn1, inherit inh_nn3; + +select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit + from pg_constraint where contype = 'n' and + conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') + order by 2, 1; + +select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit + from pg_constraint where contype = 'n' and + conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') + order by 2, 1; + +alter table inh_nn1 drop constraint inh_nn1_f1_not_null; + +select conrelid::regclass, conname, coninhcount, conislocal, connoinherit + from pg_constraint where contype = 'n' and + conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') + order by 2, 1; + +drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4; + +create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1); + +insert into inh_nn2 values(NULL, 'sample', 1); + +delete from inh_nn2; + +create table inh_nn3 () inherits (inh_nn2); + +create table inh_nn4 () inherits (inh_nn1, inh_nn2); + +select conrelid::regclass, conname, coninhcount, conislocal, connoinherit + from pg_constraint where contype = 'n' and + conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') + order by 2, 1; + +drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4; + +create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1); + +select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit + from pg_constraint where contype = 'n' and + conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3') + order by 2, 1; + +select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit + from pg_constraint where contype = 'n' and + conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3') + order by 2, 1; + +drop table inh_nn1, inh_nn2, inh_nn3; + +create table inh_nn1 (f1 int check(f1 > 5) primary key references inh_nn1, f2 int not null); + +create table inh_nn2 () inherits (inh_nn1); + +drop table inh_nn1, inh_nn2; + +create role regress_alice; + +create role regress_bob; + +grant all on schema public to regress_alice, regress_bob; + +grant regress_alice to regress_bob; + +set session authorization regress_alice; + +create table inh_parent (a int not null); + +set session authorization regress_bob; + +create table inh_child () inherits (inh_parent); + +set session authorization regress_alice; + +alter table inh_parent alter a drop not null; + +set session authorization regress_bob; + +alter table inh_parent alter a drop not null; + +reset session authorization; + +drop table inh_parent, inh_child; + +revoke all on schema public from regress_alice, regress_bob; + +drop role regress_alice, regress_bob; + +create table inh_perm_parent (a1 int); + +create temp table inh_temp_parent (a1 int); + +create temp table inh_temp_child () inherits (inh_perm_parent); + +create table inh_perm_child () inherits (inh_temp_parent); + +create temp table inh_temp_child_2 () inherits (inh_temp_parent); + +insert into inh_perm_parent values (1); + +insert into inh_temp_parent values (2); + +insert into inh_temp_child values (3); + +insert into inh_temp_child_2 values (4); + +select tableoid::regclass, a1 from inh_perm_parent; + +select tableoid::regclass, a1 from inh_temp_parent; + +drop table inh_perm_parent cascade; + +drop table inh_temp_parent cascade; + +create table list_parted ( + a varchar +) partition by list (a); + +create table part_ab_cd partition of list_parted for values in ('ab', 'cd'); + +create table part_ef_gh partition of list_parted for values in ('ef', 'gh'); + +create table part_null_xy partition of list_parted for values in (null, 'xy'); + +select * from list_parted; + +select * from list_parted where a is null; + +select * from list_parted where a is not null; + +select * from list_parted where a in ('ab', 'cd', 'ef'); + +select * from list_parted where a = 'ab' or a in (null, 'cd'); + +select * from list_parted where a = 'ab'; + +create table range_list_parted ( + a int, + b char(2) +) partition by range (a); + +create table part_1_10 partition of range_list_parted for values from (1) to (10) partition by list (b); + +create table part_1_10_ab partition of part_1_10 for values in ('ab'); + +create table part_1_10_cd partition of part_1_10 for values in ('cd'); + +create table part_10_20 partition of range_list_parted for values from (10) to (20) partition by list (b); + +create table part_10_20_ab partition of part_10_20 for values in ('ab'); + +create table part_10_20_cd partition of part_10_20 for values in ('cd'); + +create table part_21_30 partition of range_list_parted for values from (21) to (30) partition by list (b); + +create table part_21_30_ab partition of part_21_30 for values in ('ab'); + +create table part_21_30_cd partition of part_21_30 for values in ('cd'); + +create table part_40_inf partition of range_list_parted for values from (40) to (maxvalue) partition by list (b); + +create table part_40_inf_ab partition of part_40_inf for values in ('ab'); + +create table part_40_inf_cd partition of part_40_inf for values in ('cd'); + +create table part_40_inf_null partition of part_40_inf for values in (null); + +select * from range_list_parted; + +select * from range_list_parted where a = 5; + +select * from range_list_parted where b = 'ab'; + +select * from range_list_parted where a between 3 and 23 and b in ('ab'); + +select * from range_list_parted where a is null; + +select * from range_list_parted where b is null; + +select * from range_list_parted where a is not null and a < 67; + +select * from range_list_parted where a >= 30; + +drop table list_parted; + +drop table range_list_parted; + +create table mcrparted (a int, b int, c int) partition by range (a, abs(b), c); + +create table mcrparted_def partition of mcrparted default; + +create table mcrparted0 partition of mcrparted for values from (minvalue, minvalue, minvalue) to (1, 1, 1); + +create table mcrparted1 partition of mcrparted for values from (1, 1, 1) to (10, 5, 10); + +create table mcrparted2 partition of mcrparted for values from (10, 5, 10) to (10, 10, 10); + +create table mcrparted3 partition of mcrparted for values from (11, 1, 1) to (20, 10, 10); + +create table mcrparted4 partition of mcrparted for values from (20, 10, 10) to (20, 20, 20); + +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue); + +select * from mcrparted where a = 0; + +select * from mcrparted where a = 10 and abs(b) < 5; + +select * from mcrparted where a = 10 and abs(b) = 5; + +select * from mcrparted where abs(b) = 5; + +select * from mcrparted where a > -1; + +select * from mcrparted where a = 20 and abs(b) = 10 and c > 10; + +select * from mcrparted where a = 20 and c > 20; + +create table parted_minmax (a int, b varchar(16)) partition by range (a); + +create table parted_minmax1 partition of parted_minmax for values from (1) to (10); + +create index parted_minmax1i on parted_minmax1 (a, b); + +insert into parted_minmax values (1,'12345'); + +select min(a), max(a) from parted_minmax where b = '12345'; + +select min(a), max(a) from parted_minmax where b = '12345'; + +drop table parted_minmax; + +create index mcrparted_a_abs_c_idx on mcrparted (a, abs(b), c); + +select * from mcrparted order by a, abs(b), c; + +drop table mcrparted_def; + +select * from mcrparted order by a, abs(b), c; + +select * from mcrparted order by a desc, abs(b) desc, c desc; + +drop table mcrparted5; + +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) partition by list (a); + +create table mcrparted5a partition of mcrparted5 for values in(20); + +create table mcrparted5_def partition of mcrparted5 default; + +select * from mcrparted order by a, abs(b), c; + +drop table mcrparted5_def; + +select a, abs(b) from mcrparted order by a, abs(b), c; + +select * from mcrparted where a < 20 order by a, abs(b), c; + +set enable_bitmapscan to off; + +set enable_sort to off; + +create table mclparted (a int) partition by list(a); + +create table mclparted1 partition of mclparted for values in(1); + +create table mclparted2 partition of mclparted for values in(2); + +create index on mclparted (a); + +select * from mclparted order by a; + +create table mclparted3_5 partition of mclparted for values in(3,5); + +create table mclparted4 partition of mclparted for values in(4); + +select * from mclparted order by a; + +select * from mclparted where a in(3,4,5) order by a; + +create table mclparted_null partition of mclparted for values in(null); + +create table mclparted_def partition of mclparted default; + +select * from mclparted where a in(1,2,4) order by a; + +select * from mclparted where a in(1,2,4) or a is null order by a; + +drop table mclparted_null; + +create table mclparted_0_null partition of mclparted for values in(0,null); + +select * from mclparted where a in(1,2,4) or a is null order by a; + +select * from mclparted where a in(0,1,2,4) order by a; + +select * from mclparted where a in(1,2,4) order by a; + +select * from mclparted where a in(1,2,4,100) order by a; + +drop table mclparted; + +reset enable_sort; + +reset enable_bitmapscan; + +drop index mcrparted_a_abs_c_idx; + +create index on mcrparted1 (a, abs(b), c); + +create index on mcrparted2 (a, abs(b), c); + +create index on mcrparted3 (a, abs(b), c); + +create index on mcrparted4 (a, abs(b), c); + +select * from mcrparted where a < 20 order by a, abs(b), c limit 1; + +set enable_bitmapscan = 0; + +select * from mcrparted where a = 10 order by a, abs(b), c; + +reset enable_bitmapscan; + +drop table mcrparted; + +create table bool_lp (b bool) partition by list(b); + +create table bool_lp_true partition of bool_lp for values in(true); + +create table bool_lp_false partition of bool_lp for values in(false); + +create index on bool_lp (b); + +select * from bool_lp order by b; + +drop table bool_lp; + +create table bool_rp (b bool, a int) partition by range(b,a); + +create table bool_rp_false_1k partition of bool_rp for values from (false,0) to (false,1000); + +create table bool_rp_true_1k partition of bool_rp for values from (true,0) to (true,1000); + +create table bool_rp_false_2k partition of bool_rp for values from (false,1000) to (false,2000); + +create table bool_rp_true_2k partition of bool_rp for values from (true,1000) to (true,2000); + +create index on bool_rp (b,a); + +select * from bool_rp where b = true order by b,a; + +select * from bool_rp where b = false order by b,a; + +select * from bool_rp where b = true order by a; + +select * from bool_rp where b = false order by a; + +drop table bool_rp; + +create table range_parted (a int, b int, c int) partition by range(a, b); + +create table range_parted1 partition of range_parted for values from (0,0) to (10,10); + +create table range_parted2 partition of range_parted for values from (10,10) to (20,20); + +create index on range_parted (a,b,c); + +select * from range_parted order by a,b,c; + +select * from range_parted order by a desc,b desc,c desc; + +drop table range_parted; + +create table permtest_parent (a int, b text, c text) partition by list (a); + +create table permtest_child (b text, c text, a int) partition by list (b); + +create table permtest_grandchild (c text, b text, a int); + +alter table permtest_child attach partition permtest_grandchild for values in ('a'); + +alter table permtest_parent attach partition permtest_child for values in (1); + +create index on permtest_parent (left(c, 3)); + +insert into permtest_parent + select 1, 'a', left(fipshash(i::text), 5) from generate_series(0, 100) i; + +analyze permtest_parent; + +create role regress_no_child_access; + +revoke all on permtest_grandchild from regress_no_child_access; + +grant select on permtest_parent to regress_no_child_access; + +set session authorization regress_no_child_access; + +select * from permtest_parent p1 inner join permtest_parent p2 + on p1.a = p2.a and p1.c ~ 'a1$'; + +select * from permtest_parent p1 inner join permtest_parent p2 + on p1.a = p2.a and left(p1.c, 3) ~ 'a1$'; + +reset session authorization; + +revoke all on permtest_parent from regress_no_child_access; + +grant select(a,c) on permtest_parent to regress_no_child_access; + +set session authorization regress_no_child_access; + +select p2.a, p1.c from permtest_parent p1 inner join permtest_parent p2 + on p1.a = p2.a and p1.c ~ 'a1$'; + +select p2.a, p1.c from permtest_parent p1 inner join permtest_parent p2 + on p1.a = p2.a and left(p1.c, 3) ~ 'a1$'; + +reset session authorization; + +revoke all on permtest_parent from regress_no_child_access; + +drop role regress_no_child_access; + +drop table permtest_parent; + +CREATE TABLE errtst_parent ( + partid int not null, + shdata int not null, + data int NOT NULL DEFAULT 0, + CONSTRAINT shdata_small CHECK(shdata < 3) +) PARTITION BY RANGE (partid); + +CREATE TABLE errtst_child_fastdef ( + partid int not null, + shdata int not null, + CONSTRAINT shdata_small CHECK(shdata < 3) +); + +CREATE TABLE errtst_child_plaindef ( + partid int not null, + shdata int not null, + data int NOT NULL DEFAULT 0, + CONSTRAINT shdata_small CHECK(shdata < 3), + CHECK(data < 10) +); + +CREATE TABLE errtst_child_reorder ( + data int NOT NULL DEFAULT 0, + shdata int not null, + partid int not null, + CONSTRAINT shdata_small CHECK(shdata < 3), + CHECK(data < 10) +); + +ALTER TABLE errtst_child_fastdef ADD COLUMN data int NOT NULL DEFAULT 0; + +ALTER TABLE errtst_child_fastdef ADD CONSTRAINT errtest_child_fastdef_data_check CHECK (data < 10); + +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_fastdef FOR VALUES FROM (0) TO (10); + +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_plaindef FOR VALUES FROM (10) TO (20); + +ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_reorder FOR VALUES FROM (20) TO (30); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '5'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '5'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '5'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '10'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '10'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '10'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', NULL); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', NULL); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', NULL); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '5', '5'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '5', '5'); + +INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '5', '5'); + +BEGIN; + +UPDATE errtst_parent SET data = data + 1 WHERE partid = 0; + +UPDATE errtst_parent SET data = data + 1 WHERE partid = 10; + +UPDATE errtst_parent SET data = data + 1 WHERE partid = 20; + +ROLLBACK; + +UPDATE errtst_parent SET data = data + 10 WHERE partid = 0; + +UPDATE errtst_parent SET data = data + 10 WHERE partid = 10; + +UPDATE errtst_parent SET data = data + 10 WHERE partid = 20; + +BEGIN; + +UPDATE errtst_child_fastdef SET partid = 1 WHERE partid = 0; + +UPDATE errtst_child_plaindef SET partid = 11 WHERE partid = 10; + +UPDATE errtst_child_reorder SET partid = 21 WHERE partid = 20; + +ROLLBACK; + +UPDATE errtst_child_fastdef SET partid = partid + 10 WHERE partid = 0; + +UPDATE errtst_child_plaindef SET partid = partid + 10 WHERE partid = 10; + +UPDATE errtst_child_reorder SET partid = partid + 10 WHERE partid = 20; + +BEGIN; + +UPDATE errtst_parent SET partid = 10, data = data + 1 WHERE partid = 0; + +UPDATE errtst_parent SET partid = 20, data = data + 1 WHERE partid = 10; + +UPDATE errtst_parent SET partid = 0, data = data + 1 WHERE partid = 20; + +ROLLBACK; + +UPDATE errtst_parent SET partid = 10, data = data + 10 WHERE partid = 0; + +UPDATE errtst_parent SET partid = 20, data = data + 10 WHERE partid = 10; + +UPDATE errtst_parent SET partid = 0, data = data + 10 WHERE partid = 20; + +UPDATE errtst_parent SET partid = 30, data = data + 10 WHERE partid = 20; + +DROP TABLE errtst_parent; + +create table tuplesest_parted (a int, b int, c float) partition by range(a); + +create table tuplesest_parted1 partition of tuplesest_parted for values from (0) to (100); + +create table tuplesest_parted2 partition of tuplesest_parted for values from (100) to (200); + +create table tuplesest_tab (a int, b int); + +insert into tuplesest_parted select i%200, i%300, i%400 from generate_series(1, 1000)i; + +insert into tuplesest_tab select i, i from generate_series(1, 100)i; + +analyze tuplesest_parted; + +analyze tuplesest_tab; + +select * from tuplesest_tab join + (select b from tuplesest_parted where c < 100 group by b) sub + on tuplesest_tab.a = sub.b; + +drop table tuplesest_parted; + +drop table tuplesest_tab; diff --git a/crates/pgt_pretty_print/tests/data/multi/init_privs_60.sql b/crates/pgt_pretty_print/tests/data/multi/init_privs_60.sql new file mode 100644 index 000000000..132981372 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/init_privs_60.sql @@ -0,0 +1,7 @@ +SELECT count(*) > 0 FROM pg_init_privs; + +GRANT SELECT ON pg_proc TO CURRENT_USER; + +GRANT SELECT (prosrc) ON pg_proc TO CURRENT_USER; + +GRANT SELECT (rolname, rolsuper) ON pg_authid TO CURRENT_USER; diff --git a/crates/pgt_pretty_print/tests/data/multi/insert_60.sql b/crates/pgt_pretty_print/tests/data/multi/insert_60.sql new file mode 100644 index 000000000..2d9e1e8b1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/insert_60.sql @@ -0,0 +1,818 @@ +create table inserttest (col1 int4, col2 int4 NOT NULL, col3 text default 'testing'); + +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT); + +insert into inserttest (col2, col3) values (3, DEFAULT); + +insert into inserttest (col1, col2, col3) values (DEFAULT, 5, DEFAULT); + +insert into inserttest values (DEFAULT, 5, 'test'); + +insert into inserttest values (DEFAULT, 7); + +select * from inserttest; + +insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT); + +insert into inserttest (col1, col2, col3) values (1, 2); + +insert into inserttest (col1) values (1, 2); + +insert into inserttest (col1) values (DEFAULT, DEFAULT); + +select * from inserttest; + +insert into inserttest values(10, 20, '40'), (-1, 2, DEFAULT), + ((select 2), (select i from (values(3)) as foo (i)), 'values are fun!'); + +select * from inserttest; + +insert into inserttest values(30, 50, repeat('x', 10000)); + +select col1, col2, char_length(col3) from inserttest; + +drop table inserttest; + +CREATE TABLE large_tuple_test (a int, b text) WITH (fillfactor = 10); + +ALTER TABLE large_tuple_test ALTER COLUMN b SET STORAGE plain; + +INSERT INTO large_tuple_test (select 1, NULL); + +INSERT INTO large_tuple_test (select 2, repeat('a', 1000)); + +SELECT pg_size_pretty(pg_relation_size('large_tuple_test'::regclass, 'main')); + +INSERT INTO large_tuple_test (select 3, NULL); + +INSERT INTO large_tuple_test (select 4, repeat('a', 8126)); + +DROP TABLE large_tuple_test; + +create type insert_test_type as (if1 int, if2 text[]); + +create table inserttest (f1 int, f2 int[], + f3 insert_test_type, f4 insert_test_type[]); + +insert into inserttest (f2[1], f2[2]) values (1,2); + +insert into inserttest (f2[1], f2[2]) values (3,4), (5,6); + +insert into inserttest (f2[1], f2[2]) select 7,8; + +insert into inserttest (f2[1], f2[2]) values (1,default); + +insert into inserttest (f3.if1, f3.if2) values (1,array['foo']); + +insert into inserttest (f3.if1, f3.if2) values (1,'{foo}'), (2,'{bar}'); + +insert into inserttest (f3.if1, f3.if2) select 3, '{baz,quux}'; + +insert into inserttest (f3.if1, f3.if2) values (1,default); + +insert into inserttest (f3.if2[1], f3.if2[2]) values ('foo', 'bar'); + +insert into inserttest (f3.if2[1], f3.if2[2]) values ('foo', 'bar'), ('baz', 'quux'); + +insert into inserttest (f3.if2[1], f3.if2[2]) select 'bear', 'beer'; + +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) values ('foo', 'bar'); + +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) values ('foo', 'bar'), ('baz', 'quux'); + +insert into inserttest (f4[1].if2[1], f4[1].if2[2]) select 'bear', 'beer'; + +select * from inserttest; + +create table inserttest2 (f1 bigint, f2 text); + +create rule irule1 as on insert to inserttest2 do also + insert into inserttest (f3.if2[1], f3.if2[2]) + values (new.f1,new.f2); + +create rule irule2 as on insert to inserttest2 do also + insert into inserttest (f4[1].if1, f4[1].if2[2]) + values (1,'fool'),(new.f1,new.f2); + +select new.f1, new.f2; + +drop table inserttest2; + +drop table inserttest; + +create domain insert_pos_ints as int[] check (value[1] > 0); + +create domain insert_test_domain as insert_test_type + check ((value).if2[1] is not null); + +create table inserttesta (f1 int, f2 insert_pos_ints); + +create table inserttestb (f3 insert_test_domain, f4 insert_test_domain[]); + +insert into inserttesta (f2[1], f2[2]) values (1,2); + +insert into inserttesta (f2[1], f2[2]) values (3,4), (5,6); + +insert into inserttesta (f2[1], f2[2]) select 7,8; + +insert into inserttesta (f2[1], f2[2]) values (1,default); + +insert into inserttesta (f2[1], f2[2]) values (0,2); + +insert into inserttesta (f2[1], f2[2]) values (3,4), (0,6); + +insert into inserttesta (f2[1], f2[2]) select 0,8; + +insert into inserttestb (f3.if1, f3.if2) values (1,array['foo']); + +insert into inserttestb (f3.if1, f3.if2) values (1,'{foo}'), (2,'{bar}'); + +insert into inserttestb (f3.if1, f3.if2) select 3, '{baz,quux}'; + +insert into inserttestb (f3.if1, f3.if2) values (1,default); + +insert into inserttestb (f3.if1, f3.if2) values (1,array[null]); + +insert into inserttestb (f3.if1, f3.if2) values (1,'{null}'), (2,'{bar}'); + +insert into inserttestb (f3.if1, f3.if2) select 3, '{null,quux}'; + +insert into inserttestb (f3.if2[1], f3.if2[2]) values ('foo', 'bar'); + +insert into inserttestb (f3.if2[1], f3.if2[2]) values ('foo', 'bar'), ('baz', 'quux'); + +insert into inserttestb (f3.if2[1], f3.if2[2]) select 'bear', 'beer'; + +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) values (row(1,'{x}'), 'foo', 'bar'); + +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) values (row(1,'{x}'), 'foo', 'bar'), (row(2,'{y}'), 'baz', 'quux'); + +insert into inserttestb (f3, f4[1].if2[1], f4[1].if2[2]) select row(1,'{x}')::insert_test_domain, 'bear', 'beer'; + +select * from inserttesta; + +select * from inserttestb; + +create table inserttest2 (f1 bigint, f2 text); + +create rule irule1 as on insert to inserttest2 do also + insert into inserttestb (f3.if2[1], f3.if2[2]) + values (new.f1,new.f2); + +create rule irule2 as on insert to inserttest2 do also + insert into inserttestb (f4[1].if1, f4[1].if2[2]) + values (1,'fool'),(new.f1,new.f2); + +select new.f1, new.f2; + +drop table inserttest2; + +drop table inserttesta; + +drop table inserttestb; + +drop domain insert_pos_ints; + +drop domain insert_test_domain; + +create domain insert_nnarray as int[] + check (value[1] is not null and value[2] is not null); + +create domain insert_test_domain as insert_test_type + check ((value).if1 is not null and (value).if2 is not null); + +create table inserttesta (f1 insert_nnarray); + +insert into inserttesta (f1[1]) values (1); + +insert into inserttesta (f1[1], f1[2]) values (1, 2); + +create table inserttestb (f1 insert_test_domain); + +insert into inserttestb (f1.if1) values (1); + +insert into inserttestb (f1.if1, f1.if2) values (1, '{foo}'); + +drop table inserttesta; + +drop table inserttestb; + +drop domain insert_nnarray; + +drop type insert_test_type cascade; + +create table range_parted ( + a text, + b int +) partition by range (a, (b+0)); + +insert into range_parted values ('a', 11); + +create table part1 partition of range_parted for values from ('a', 1) to ('a', 10); + +create table part2 partition of range_parted for values from ('a', 10) to ('a', 20); + +create table part3 partition of range_parted for values from ('b', 1) to ('b', 10); + +create table part4 partition of range_parted for values from ('b', 10) to ('b', 20); + +insert into part1 values ('a', 11); + +insert into part1 values ('b', 1); + +insert into part1 values ('a', 1); + +insert into part4 values ('b', 21); + +insert into part4 values ('a', 10); + +insert into part4 values ('b', 10); + +insert into part1 values (null); + +insert into part1 values (1); + +create table list_parted ( + a text, + b int +) partition by list (lower(a)); + +create table part_aa_bb partition of list_parted FOR VALUES IN ('aa', 'bb'); + +create table part_cc_dd partition of list_parted FOR VALUES IN ('cc', 'dd'); + +create table part_null partition of list_parted FOR VALUES IN (null); + +insert into part_aa_bb values ('cc', 1); + +insert into part_aa_bb values ('AAa', 1); + +insert into part_aa_bb values (null); + +insert into part_cc_dd values ('cC', 1); + +insert into part_null values (null, 0); + +create table part_ee_ff partition of list_parted for values in ('ee', 'ff') partition by range (b); + +create table part_ee_ff1 partition of part_ee_ff for values from (1) to (10); + +create table part_ee_ff2 partition of part_ee_ff for values from (10) to (20); + +create table part_default partition of list_parted default; + +insert into part_default values ('aa', 2); + +insert into part_default values (null, 2); + +insert into part_default values ('Zz', 2); + +drop table part_default; + +create table part_xx_yy partition of list_parted for values in ('xx', 'yy') partition by list (a); + +create table part_xx_yy_p1 partition of part_xx_yy for values in ('xx'); + +create table part_xx_yy_defpart partition of part_xx_yy default; + +create table part_default partition of list_parted default partition by range(b); + +create table part_default_p1 partition of part_default for values from (20) to (30); + +create table part_default_p2 partition of part_default for values from (30) to (40); + +insert into part_ee_ff1 values ('EE', 11); + +insert into part_default_p2 values ('gg', 43); + +insert into part_ee_ff1 values ('cc', 1); + +insert into part_default values ('gg', 43); + +insert into part_ee_ff1 values ('ff', 1); + +insert into part_ee_ff2 values ('ff', 11); + +insert into part_default_p1 values ('cd', 25); + +insert into part_default_p2 values ('de', 35); + +insert into list_parted values ('ab', 21); + +insert into list_parted values ('xx', 1); + +insert into list_parted values ('yy', 2); + +select tableoid::regclass, * from list_parted; + +insert into range_parted values ('a', 0); + +insert into range_parted values ('a', 1); + +insert into range_parted values ('a', 10); + +insert into range_parted values ('a', 20); + +insert into range_parted values ('b', 1); + +insert into range_parted values ('b', 10); + +insert into range_parted values ('a'); + +create table part_def partition of range_parted default; + +insert into part_def values ('b', 10); + +insert into part_def values ('c', 10); + +insert into range_parted values (null, null); + +insert into range_parted values ('a', null); + +insert into range_parted values (null, 19); + +insert into range_parted values ('b', 20); + +select tableoid::regclass, * from range_parted; + +insert into list_parted values (null, 1); + +insert into list_parted (a) values ('aA'); + +insert into list_parted values ('EE', 0); + +insert into part_ee_ff values ('EE', 0); + +insert into list_parted values ('EE', 1); + +insert into part_ee_ff values ('EE', 10); + +select tableoid::regclass, * from list_parted; + +create table part_gg partition of list_parted for values in ('gg') partition by range (b); + +create table part_gg1 partition of part_gg for values from (minvalue) to (1); + +create table part_gg2 partition of part_gg for values from (1) to (10) partition by range (b); + +create table part_gg2_1 partition of part_gg2 for values from (1) to (5); + +create table part_gg2_2 partition of part_gg2 for values from (5) to (10); + +create table part_ee_ff3 partition of part_ee_ff for values from (20) to (30) partition by range (b); + +create table part_ee_ff3_1 partition of part_ee_ff3 for values from (20) to (25); + +create table part_ee_ff3_2 partition of part_ee_ff3 for values from (25) to (30); + +truncate list_parted; + +insert into list_parted values ('aa'), ('cc'); + +insert into list_parted select 'Ff', s.a from generate_series(1, 29) s(a); + +insert into list_parted select 'gg', s.a from generate_series(1, 9) s(a); + +insert into list_parted (b) values (1); + +select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_parted group by 1, 2 order by 1; + +create table hash_parted ( + a int +) partition by hash (a part_test_int4_ops); + +create table hpart0 partition of hash_parted for values with (modulus 4, remainder 0); + +create table hpart1 partition of hash_parted for values with (modulus 4, remainder 1); + +create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2); + +create table hpart3 partition of hash_parted for values with (modulus 4, remainder 3); + +insert into hash_parted values(generate_series(1,10)); + +insert into hpart0 values(12),(16); + +insert into hpart0 values(11); + +insert into hpart3 values(11); + +select tableoid::regclass as part, a, a%4 as "remainder = a % 4" +from hash_parted order by part; + +drop table range_parted, list_parted; + +drop table hash_parted; + +create table list_parted (a int) partition by list (a); + +create table part_default partition of list_parted default; + +insert into part_default values (null); + +insert into part_default values (1); + +insert into part_default values (-1); + +select tableoid::regclass, a from list_parted; + +drop table list_parted; + +create table mlparted (a int, b int) partition by range (a, b); + +create table mlparted1 (b int not null, a int not null) partition by range ((b+0)); + +create table mlparted11 (like mlparted1); + +alter table mlparted11 drop a; + +alter table mlparted11 add a int; + +alter table mlparted11 drop a; + +alter table mlparted11 add a int not null; + +select attrelid::regclass, attname, attnum +from pg_attribute +where attname = 'a' + and (attrelid = 'mlparted'::regclass + or attrelid = 'mlparted1'::regclass + or attrelid = 'mlparted11'::regclass) +order by attrelid::regclass::text; + +alter table mlparted1 attach partition mlparted11 for values from (2) to (5); + +alter table mlparted attach partition mlparted1 for values from (1, 2) to (1, 10); + +insert into mlparted values (1, 2); + +select tableoid::regclass, * from mlparted; + +insert into mlparted (a, b) values (1, 5); + +truncate mlparted; + +alter table mlparted add constraint check_b check (b = 3); + +create function mlparted11_trig_fn() +returns trigger AS +$$ +begin + NEW.b := 4; + return NEW; +end; +$$ +language plpgsql; + +create trigger mlparted11_trig before insert ON mlparted11 + for each row execute procedure mlparted11_trig_fn(); + +insert into mlparted values (1, 2); + +drop trigger mlparted11_trig on mlparted11; + +drop function mlparted11_trig_fn(); + +insert into mlparted1 (a, b) values (2, 3); + +create table lparted_nonullpart (a int, b char) partition by list (b); + +create table lparted_nonullpart_a partition of lparted_nonullpart for values in ('a'); + +insert into lparted_nonullpart values (1); + +drop table lparted_nonullpart; + +alter table mlparted drop constraint check_b; + +create table mlparted12 partition of mlparted1 for values from (5) to (10); + +create table mlparted2 (b int not null, a int not null); + +alter table mlparted attach partition mlparted2 for values from (1, 10) to (1, 20); + +create table mlparted3 partition of mlparted for values from (1, 20) to (1, 30); + +create table mlparted4 (like mlparted); + +alter table mlparted4 drop a; + +alter table mlparted4 add a int not null; + +alter table mlparted attach partition mlparted4 for values from (1, 30) to (1, 40); + +with ins (a, b, c) as + (insert into mlparted (b, a) select s.a, 1 from generate_series(2, 39) s(a) returning tableoid::regclass, *) + select a, b, min(c), max(c) from ins group by a, b order by 1; + +alter table mlparted add c text; + +create table mlparted5 (c text, a int not null, b int not null) partition by list (c); + +create table mlparted5a (a int not null, c text, b int not null); + +alter table mlparted5 attach partition mlparted5a for values in ('a'); + +alter table mlparted attach partition mlparted5 for values from (1, 40) to (1, 50); + +alter table mlparted add constraint check_b check (a = 1 and b < 45); + +insert into mlparted values (1, 45, 'a'); + +create function mlparted5abrtrig_func() returns trigger as $$ begin new.c = 'b'; return new; end; $$ language plpgsql; + +create trigger mlparted5abrtrig before insert on mlparted5a for each row execute procedure mlparted5abrtrig_func(); + +insert into mlparted5 (a, b, c) values (1, 40, 'a'); + +drop table mlparted5; + +alter table mlparted drop constraint check_b; + +create table mlparted_def partition of mlparted default partition by range(a); + +create table mlparted_def1 partition of mlparted_def for values from (40) to (50); + +create table mlparted_def2 partition of mlparted_def for values from (50) to (60); + +insert into mlparted values (40, 100); + +insert into mlparted_def1 values (42, 100); + +insert into mlparted_def2 values (54, 50); + +insert into mlparted values (70, 100); + +insert into mlparted_def1 values (52, 50); + +insert into mlparted_def2 values (34, 50); + +create table mlparted_defd partition of mlparted_def default; + +insert into mlparted values (70, 100); + +select tableoid::regclass, * from mlparted_def; + +alter table mlparted add d int, add e int; + +alter table mlparted drop e; + +create table mlparted5 partition of mlparted + for values from (1, 40) to (1, 50) partition by range (c); + +create table mlparted5_ab partition of mlparted5 + for values from ('a') to ('c') partition by list (c); + +create table mlparted5_cd partition of mlparted5 + for values from ('c') to ('e') partition by list (c); + +create table mlparted5_a partition of mlparted5_ab for values in ('a'); + +create table mlparted5_b (d int, b int, c text, a int); + +alter table mlparted5_ab attach partition mlparted5_b for values in ('b'); + +truncate mlparted; + +insert into mlparted values (1, 2, 'a', 1); + +insert into mlparted values (1, 40, 'a', 1); + +insert into mlparted values (1, 45, 'b', 1); + +insert into mlparted values (1, 45, 'c', 1); + +insert into mlparted values (1, 45, 'f', 1); + +select tableoid::regclass, * from mlparted order by a, b, c, d; + +alter table mlparted drop d; + +truncate mlparted; + +alter table mlparted add e int, add d int; + +alter table mlparted drop e; + +insert into mlparted values (1, 2, 'a', 1); + +insert into mlparted values (1, 40, 'a', 1); + +insert into mlparted values (1, 45, 'b', 1); + +insert into mlparted values (1, 45, 'c', 1); + +insert into mlparted values (1, 45, 'f', 1); + +select tableoid::regclass, * from mlparted order by a, b, c, d; + +alter table mlparted drop d; + +drop table mlparted5; + +create table key_desc (a int, b int) partition by list ((a+0)); + +create table key_desc_1 partition of key_desc for values in (1) partition by range (b); + +create user regress_insert_other_user; + +grant select (a) on key_desc_1 to regress_insert_other_user; + +grant insert on key_desc to regress_insert_other_user; + +set role regress_insert_other_user; + +insert into key_desc values (1, 1); + +reset role; + +grant select (b) on key_desc_1 to regress_insert_other_user; + +set role regress_insert_other_user; + +insert into key_desc values (1, 1); + +insert into key_desc values (2, 1); + +reset role; + +revoke all on key_desc from regress_insert_other_user; + +revoke all on key_desc_1 from regress_insert_other_user; + +drop role regress_insert_other_user; + +drop table key_desc, key_desc_1; + +create table mcrparted (a int, b int, c int) partition by range (a, abs(b), c); + +create table mcrparted0 partition of mcrparted for values from (minvalue, 0, 0) to (1, maxvalue, maxvalue); + +create table mcrparted2 partition of mcrparted for values from (10, 6, minvalue) to (10, maxvalue, minvalue); + +create table mcrparted4 partition of mcrparted for values from (21, minvalue, 0) to (30, 20, minvalue); + +create table mcrparted0 partition of mcrparted for values from (minvalue, minvalue, minvalue) to (1, maxvalue, maxvalue); + +create table mcrparted1 partition of mcrparted for values from (2, 1, minvalue) to (10, 5, 10); + +create table mcrparted2 partition of mcrparted for values from (10, 6, minvalue) to (10, maxvalue, maxvalue); + +create table mcrparted3 partition of mcrparted for values from (11, 1, 1) to (20, 10, 10); + +create table mcrparted4 partition of mcrparted for values from (21, minvalue, minvalue) to (30, 20, maxvalue); + +create table mcrparted5 partition of mcrparted for values from (30, 21, 20) to (maxvalue, maxvalue, maxvalue); + +insert into mcrparted values (null, null, null); + +insert into mcrparted values (0, 1, 1); + +insert into mcrparted0 values (0, 1, 1); + +insert into mcrparted values (9, 1000, 1); + +insert into mcrparted1 values (9, 1000, 1); + +insert into mcrparted values (10, 5, -1); + +insert into mcrparted1 values (10, 5, -1); + +insert into mcrparted values (2, 1, 0); + +insert into mcrparted1 values (2, 1, 0); + +insert into mcrparted values (10, 6, 1000); + +insert into mcrparted2 values (10, 6, 1000); + +insert into mcrparted values (10, 1000, 1000); + +insert into mcrparted2 values (10, 1000, 1000); + +insert into mcrparted values (11, 1, -1); + +insert into mcrparted3 values (11, 1, -1); + +insert into mcrparted values (30, 21, 20); + +insert into mcrparted5 values (30, 21, 20); + +insert into mcrparted4 values (30, 21, 20); + +select tableoid::regclass::text, * from mcrparted order by 1; + +drop table mcrparted; + +create table brtrigpartcon (a int, b text) partition by list (a); + +create table brtrigpartcon1 partition of brtrigpartcon for values in (1); + +create or replace function brtrigpartcon1trigf() returns trigger as $$begin new.a := 2; return new; end$$ language plpgsql; + +create trigger brtrigpartcon1trig before insert on brtrigpartcon1 for each row execute procedure brtrigpartcon1trigf(); + +insert into brtrigpartcon values (1, 'hi there'); + +insert into brtrigpartcon1 values (1, 'hi there'); + +create table inserttest3 (f1 text default 'foo', f2 text default 'bar', f3 int); + +create role regress_coldesc_role; + +grant insert on inserttest3 to regress_coldesc_role; + +grant insert on brtrigpartcon to regress_coldesc_role; + +revoke select on brtrigpartcon from regress_coldesc_role; + +set role regress_coldesc_role; + +with result as (insert into brtrigpartcon values (1, 'hi there') returning 1) + insert into inserttest3 (f3) select * from result; + +reset role; + +revoke all on inserttest3 from regress_coldesc_role; + +revoke all on brtrigpartcon from regress_coldesc_role; + +drop role regress_coldesc_role; + +drop table inserttest3; + +drop table brtrigpartcon; + +drop function brtrigpartcon1trigf(); + +create table donothingbrtrig_test (a int, b text) partition by list (a); + +create table donothingbrtrig_test1 (b text, a int); + +create table donothingbrtrig_test2 (c text, b text, a int); + +alter table donothingbrtrig_test2 drop column c; + +create or replace function donothingbrtrig_func() returns trigger as $$begin raise notice 'b: %', new.b; return NULL; end$$ language plpgsql; + +create trigger donothingbrtrig1 before insert on donothingbrtrig_test1 for each row execute procedure donothingbrtrig_func(); + +create trigger donothingbrtrig2 before insert on donothingbrtrig_test2 for each row execute procedure donothingbrtrig_func(); + +alter table donothingbrtrig_test attach partition donothingbrtrig_test1 for values in (1); + +alter table donothingbrtrig_test attach partition donothingbrtrig_test2 for values in (2); + +insert into donothingbrtrig_test values (1, 'foo'), (2, 'bar'); + +copy donothingbrtrig_test from stdout; + +select tableoid::regclass, * from donothingbrtrig_test; + +drop table donothingbrtrig_test; + +drop function donothingbrtrig_func(); + +create table mcrparted (a text, b int) partition by range(a, b); + +create table mcrparted1_lt_b partition of mcrparted for values from (minvalue, minvalue) to ('b', minvalue); + +create table mcrparted2_b partition of mcrparted for values from ('b', minvalue) to ('c', minvalue); + +create table mcrparted3_c_to_common partition of mcrparted for values from ('c', minvalue) to ('common', minvalue); + +create table mcrparted4_common_lt_0 partition of mcrparted for values from ('common', minvalue) to ('common', 0); + +create table mcrparted5_common_0_to_10 partition of mcrparted for values from ('common', 0) to ('common', 10); + +create table mcrparted6_common_ge_10 partition of mcrparted for values from ('common', 10) to ('common', maxvalue); + +create table mcrparted7_gt_common_lt_d partition of mcrparted for values from ('common', maxvalue) to ('d', minvalue); + +create table mcrparted8_ge_d partition of mcrparted for values from ('d', minvalue) to (maxvalue, maxvalue); + +insert into mcrparted values ('aaa', 0), ('b', 0), ('bz', 10), ('c', -10), + ('comm', -10), ('common', -10), ('common', 0), ('common', 10), + ('commons', 0), ('d', -10), ('e', 0); + +select tableoid::regclass, * from mcrparted order by a, b; + +drop table mcrparted; + +create table returningwrtest (a int) partition by list (a); + +create table returningwrtest1 partition of returningwrtest for values in (1); + +insert into returningwrtest values (1) returning returningwrtest; + +alter table returningwrtest add b text; + +create table returningwrtest2 (b text, c int, a int); + +alter table returningwrtest2 drop c; + +alter table returningwrtest attach partition returningwrtest2 for values in (2); + +insert into returningwrtest values (2, 'foo') returning returningwrtest; + +drop table returningwrtest; diff --git a/crates/pgt_pretty_print/tests/data/multi/insert_conflict_60.sql b/crates/pgt_pretty_print/tests/data/multi/insert_conflict_60.sql new file mode 100644 index 000000000..fab0239e4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/insert_conflict_60.sql @@ -0,0 +1,567 @@ +create table insertconflicttest(key int4, fruit text); + +create view insertconflictview as select * from insertconflicttest; + +create unique index op_index_key on insertconflicttest(key, fruit text_pattern_ops); + +create unique index collation_index_key on insertconflicttest(key, fruit collate "C"); + +create unique index both_index_key on insertconflicttest(key, fruit collate "C" text_pattern_ops); + +create unique index both_index_expr_key on insertconflicttest(key, lower(fruit) collate "C" text_pattern_ops); + +insert into insertconflicttest values(0, 'Crowberry') on conflict (key) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit, key) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing; + +insert into insertconflictview values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do update set fruit = excluded.fruit + where exists (select 1 from insertconflicttest ii where ii.key = excluded.key); + +insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit text_pattern_ops) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit collate "C") do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit collate "C" text_pattern_ops, key) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C", key, key) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit text_pattern_ops, key) do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C" text_pattern_ops, key, key) do nothing; + +drop index op_index_key; + +drop index collation_index_key; + +drop index both_index_key; + +drop index both_index_expr_key; + +create unique index cross_match on insertconflicttest(lower(fruit) collate "C", upper(fruit) text_pattern_ops); + +insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) text_pattern_ops, upper(fruit) collate "C") do nothing; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate "C", upper(fruit) text_pattern_ops) do nothing; + +drop index cross_match; + +create unique index key_index on insertconflicttest(key); + +insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Cawesh'; + +insert into insertconflicttest values(0, 'Crowberry') on conflict (key) do update set fruit = excluded.fruit where excluded.fruit != 'Elderberry'; + +insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Lime' returning *; + +insert into insertconflicttest values (1, 'Apple') on conflict do update set fruit = excluded.fruit; + +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (2, 'Orange') on conflict (key, key, key) do update set fruit = excluded.fruit; + +insert into insertconflicttest +values (1, 'Apple'), (2, 'Orange') +on conflict (key) do update set (fruit, key) = (excluded.fruit, excluded.key); + +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit RETURNING excluded.fruit; + +insert into insertconflicttest values (1, 'Apple') on conflict (keyy) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruitt; + +insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (4, 'Mango') on conflict (fruit, key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (5, 'Lemon') on conflict (fruit) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (6, 'Passionfruit') on conflict (lower(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = ict.fruit; + +insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = insertconflicttest.fruit; + +insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set insertconflicttest.fruit = 'Mango'; + +drop index key_index; + +create unique index comp_key_index on insertconflicttest(key, fruit); + +insert into insertconflicttest values (7, 'Raspberry') on conflict (key, fruit) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (8, 'Lime') on conflict (fruit, key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (9, 'Banana') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (10, 'Blueberry') on conflict (key, key, key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (11, 'Cherry') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (12, 'Date') on conflict (lower(fruit), key) do update set fruit = excluded.fruit; + +drop index comp_key_index; + +create unique index part_comp_key_index on insertconflicttest(key, fruit) where key < 5; + +create unique index expr_part_comp_key_index on insertconflicttest(key, lower(fruit)) where key < 5; + +insert into insertconflicttest values (13, 'Grape') on conflict (key, fruit) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (14, 'Raisin') on conflict (fruit, key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (15, 'Cranberry') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (16, 'Melon') on conflict (key, key, key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (17, 'Mulberry') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (18, 'Pineapple') on conflict (lower(fruit), key) do update set fruit = excluded.fruit; + +drop index part_comp_key_index; + +drop index expr_part_comp_key_index; + +create unique index expr_key_index on insertconflicttest(lower(fruit)); + +insert into insertconflicttest values (20, 'Quince') on conflict (lower(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (21, 'Pomegranate') on conflict (lower(fruit), lower(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (22, 'Apricot') on conflict (upper(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (23, 'Blackberry') on conflict (fruit) do update set fruit = excluded.fruit; + +drop index expr_key_index; + +create unique index expr_comp_key_index on insertconflicttest(key, lower(fruit)); + +create unique index tricky_expr_comp_key_index on insertconflicttest(key, lower(fruit), upper(fruit)); + +insert into insertconflicttest values (24, 'Plum') on conflict (key, lower(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (25, 'Peach') on conflict (lower(fruit), key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (26, 'Fig') on conflict (lower(fruit), key, lower(fruit), key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (27, 'Prune') on conflict (key, upper(fruit)) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (28, 'Redcurrant') on conflict (fruit, key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (29, 'Nectarine') on conflict (key) do update set fruit = excluded.fruit; + +drop index expr_comp_key_index; + +drop index tricky_expr_comp_key_index; + +create unique index key_index on insertconflicttest(key); + +create unique index fruit_index on insertconflicttest(fruit); + +insert into insertconflicttest values (26, 'Fig') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (26, 'Peach') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (25, 'Fig') on conflict (fruit) do update set fruit = excluded.fruit; + +drop index key_index; + +drop index fruit_index; + +create unique index partial_key_index on insertconflicttest(key) where fruit like '%berry'; + +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like '%berry' do update set fruit = excluded.fruit; + +insert into insertconflicttest as t values (23, 'Blackberry') on conflict (key) where fruit like '%berry' and t.fruit = 'inconsequential' do nothing; + +insert into insertconflictview as t values (23, 'Blackberry') on conflict (key) where fruit like '%berry' and t.fruit = 'inconsequential' do nothing; + +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) do update set fruit = excluded.fruit; + +insert into insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like '%berry' or fruit = 'consequential' do nothing; + +insert into insertconflicttest values (23, 'Blackberry') on conflict (fruit) where fruit like '%berry' do update set fruit = excluded.fruit; + +drop index partial_key_index; + +create unique index plain on insertconflicttest(key); + +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* != excluded.* returning *; + +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* != excluded.* returning *; + +insert into insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do update set fruit = excluded.fruit + where i.* = excluded.* returning *; + +insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text + returning *; + +insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.fruit where excluded.* is null; + +insert into insertconflicttest as i values (23, 'Avocado') on conflict (key) do update set fruit = excluded.*::text; + +drop index plain; + +drop view insertconflictview; + +drop table insertconflicttest; + +create table syscolconflicttest(key int4, data text); + +insert into syscolconflicttest values (1); + +insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.ctid::text; + +drop table syscolconflicttest; + +create table insertconflict (a bigint, b bigint); + +create unique index insertconflicti1 on insertconflict(coalesce(a, 0)); + +create unique index insertconflicti2 on insertconflict(b) + where coalesce(a, 1) > 0; + +insert into insertconflict values (1, 2) +on conflict (coalesce(a, 0)) do nothing; + +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 0 do nothing; + +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 1 do nothing; + +drop table insertconflict; + +create table insertconflict (f1 int primary key, f2 text); + +create view insertconflictv as + select * from insertconflict with cascaded check option; + +insert into insertconflictv values (1,'foo') + on conflict (f1) do update set f2 = excluded.f2; + +select * from insertconflict; + +insert into insertconflictv values (1,'bar') + on conflict (f1) do update set f2 = excluded.f2; + +select * from insertconflict; + +drop view insertconflictv; + +drop table insertconflict; + +create table cities ( + name text, + population float8, + altitude int -- (in ft) +); + +create table capitals ( + state char(2) +) inherits (cities); + +create unique index cities_names_unique on cities (name); + +create unique index capitals_names_unique on capitals (name); + +insert into cities values ('San Francisco', 7.24E+5, 63); + +insert into cities values ('Las Vegas', 2.583E+5, 2174); + +insert into cities values ('Mariposa', 1200, 1953); + +insert into capitals values ('Sacramento', 3.694E+5, 30, 'CA'); + +insert into capitals values ('Madison', 1.913E+5, 845, 'WI'); + +select * from capitals; + +insert into cities values ('Las Vegas', 2.583E+5, 2174) on conflict do nothing; + +insert into capitals values ('Sacramento', 4664.E+5, 30, 'CA') on conflict (name) do update set population = excluded.population; + +insert into capitals values ('Sacramento', 50, 2267, 'NE') on conflict (name) do nothing; + +select * from capitals; + +insert into cities values ('Las Vegas', 5.83E+5, 2001) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude; + +select tableoid::regclass, * from cities; + +insert into capitals values ('Las Vegas', 5.83E+5, 2222, 'NV') on conflict (name) do update set population = excluded.population; + +select * from capitals; + +select tableoid::regclass, * from cities; + +insert into cities values ('Las Vegas', 5.86E+5, 2223) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude; + +select tableoid::regclass, * from cities; + +drop table capitals; + +drop table cities; + +create table excluded(key int primary key, data text); + +insert into excluded values(1, '1'); + +insert into excluded values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *; + +insert into excluded AS target values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *; + +insert into excluded AS target values(1, '2') on conflict (key) do update set data = target.data RETURNING *; + +insert into excluded values(1, '2') on conflict (key) do update set data = 3 RETURNING excluded.*; + +drop table excluded; + +create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float); + +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1); + +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 2, '2', '2', 2) on conflict(key) + do update set drop1 = excluded.drop1, keep1 = excluded.keep1, drop2 = excluded.drop2, keep2 = excluded.keep2 + where excluded.drop1 is not null and excluded.keep1 is not null and excluded.drop2 is not null and excluded.keep2 is not null + and dropcol.drop1 is not null and dropcol.keep1 is not null and dropcol.drop2 is not null and dropcol.keep2 is not null + returning *; + +insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 3, '3', '3', 3) on conflict(key) + do update set drop1 = dropcol.drop1, keep1 = dropcol.keep1, drop2 = dropcol.drop2, keep2 = dropcol.keep2 + returning *; + +alter table dropcol drop column drop1, drop column drop2; + +insert into dropcol(key, keep1, keep2) values(1, '4', 4) on conflict(key) + do update set keep1 = excluded.keep1, keep2 = excluded.keep2 + where excluded.keep1 is not null and excluded.keep2 is not null + and dropcol.keep1 is not null and dropcol.keep2 is not null + returning *; + +insert into dropcol(key, keep1, keep2) values(1, '5', 5) on conflict(key) + do update set keep1 = dropcol.keep1, keep2 = dropcol.keep2 + returning *; + +DROP TABLE dropcol; + +create table twoconstraints (f1 int unique, f2 box, + exclude using gist(f2 with &&)); + +insert into twoconstraints values(1, '((0,0),(1,1))'); + +insert into twoconstraints values(1, '((2,2),(3,3))'); + +insert into twoconstraints values(2, '((0,0),(1,2))'); + +insert into twoconstraints values(2, '((0,0),(1,2))') + on conflict on constraint twoconstraints_f1_key do nothing; + +insert into twoconstraints values(2, '((0,0),(1,2))') + on conflict on constraint twoconstraints_f2_excl do nothing; + +select * from twoconstraints; + +drop table twoconstraints; + +create table selfconflict (f1 int primary key, f2 int); + +begin transaction isolation level read committed; + +insert into selfconflict values (1,1), (1,2) on conflict do nothing; + +commit; + +begin transaction isolation level repeatable read; + +insert into selfconflict values (2,1), (2,2) on conflict do nothing; + +commit; + +begin transaction isolation level serializable; + +insert into selfconflict values (3,1), (3,2) on conflict do nothing; + +commit; + +begin transaction isolation level read committed; + +insert into selfconflict values (4,1), (4,2) on conflict(f1) do update set f2 = 0; + +commit; + +begin transaction isolation level repeatable read; + +insert into selfconflict values (5,1), (5,2) on conflict(f1) do update set f2 = 0; + +commit; + +begin transaction isolation level serializable; + +insert into selfconflict values (6,1), (6,2) on conflict(f1) do update set f2 = 0; + +commit; + +select * from selfconflict; + +drop table selfconflict; + +create table parted_conflict_test (a int unique, b char) partition by list (a); + +create table parted_conflict_test_1 partition of parted_conflict_test (b unique) for values in (1, 2); + +insert into parted_conflict_test values (1, 'a') on conflict do nothing; + +insert into parted_conflict_test values (1, 'a') on conflict (a) do nothing; + +insert into parted_conflict_test values (1, 'a') on conflict (a) do update set b = excluded.b; + +insert into parted_conflict_test_1 values (1, 'a') on conflict (a) do nothing; + +insert into parted_conflict_test_1 values (1, 'b') on conflict (a) do update set b = excluded.b; + +insert into parted_conflict_test values (2, 'b') on conflict (b) do update set a = excluded.a; + +insert into parted_conflict_test_1 values (2, 'b') on conflict (b) do update set a = excluded.a; + +select * from parted_conflict_test order by a; + +create table parted_conflict_test_2 (b char, a int unique); + +alter table parted_conflict_test attach partition parted_conflict_test_2 for values in (3); + +truncate parted_conflict_test; + +insert into parted_conflict_test values (3, 'a') on conflict (a) do update set b = excluded.b; + +insert into parted_conflict_test values (3, 'b') on conflict (a) do update set b = excluded.b; + +select * from parted_conflict_test order by a; + +alter table parted_conflict_test drop b, add b char; + +create table parted_conflict_test_3 partition of parted_conflict_test for values in (4); + +truncate parted_conflict_test; + +insert into parted_conflict_test (a, b) values (4, 'a') on conflict (a) do update set b = excluded.b; + +insert into parted_conflict_test (a, b) values (4, 'b') on conflict (a) do update set b = excluded.b where parted_conflict_test.b = 'a'; + +select * from parted_conflict_test order by a; + +create table parted_conflict_test_4 partition of parted_conflict_test for values in (5) partition by list (a); + +create table parted_conflict_test_4_1 partition of parted_conflict_test_4 for values in (5); + +truncate parted_conflict_test; + +insert into parted_conflict_test (a, b) values (5, 'a') on conflict (a) do update set b = excluded.b; + +insert into parted_conflict_test (a, b) values (5, 'b') on conflict (a) do update set b = excluded.b where parted_conflict_test.b = 'a'; + +select * from parted_conflict_test order by a; + +truncate parted_conflict_test; + +insert into parted_conflict_test (a, b) values (1, 'a'), (2, 'a'), (4, 'a') on conflict (a) do update set b = excluded.b where excluded.b = 'b'; + +insert into parted_conflict_test (a, b) values (1, 'b'), (2, 'c'), (4, 'b') on conflict (a) do update set b = excluded.b where excluded.b = 'b'; + +select * from parted_conflict_test order by a; + +drop table parted_conflict_test; + +create table parted_conflict (a int primary key, b text) partition by range (a); + +create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a); + +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500); + +insert into parted_conflict values (40, 'forty'); + +insert into parted_conflict_1 values (40, 'cuarenta') + on conflict (a) do update set b = excluded.b; + +drop table parted_conflict; + +create table parted_conflict (a int, b text) partition by range (a); + +create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a); + +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500); + +create unique index on only parted_conflict_1 (a); + +create unique index on only parted_conflict (a); + +alter index parted_conflict_a_idx attach partition parted_conflict_1_a_idx; + +insert into parted_conflict values (40, 'forty'); + +insert into parted_conflict_1 values (40, 'cuarenta') + on conflict (a) do update set b = excluded.b; + +drop table parted_conflict; + +create table parted_conflict (a int, b text, c int) partition by range (a); + +create table parted_conflict_1 (drp text, c int, a int, b text); + +alter table parted_conflict_1 drop column drp; + +create unique index on parted_conflict (a, b); + +alter table parted_conflict attach partition parted_conflict_1 for values from (0) to (1000); + +truncate parted_conflict; + +insert into parted_conflict values (50, 'cincuenta', 1); + +insert into parted_conflict values (50, 'cincuenta', 2) + on conflict (a, b) do update set (a, b, c) = row(excluded.*) + where parted_conflict = (50, text 'cincuenta', 1) and + excluded = (50, text 'cincuenta', 2); + +select * from parted_conflict order by a; + +create or replace function parted_conflict_update_func() returns trigger as $$ +declare + r record; +begin + for r in select * from inserted loop + raise notice 'a = %, b = %, c = %', r.a, r.b, r.c; + end loop; + return new; +end; +$$ language plpgsql; + +create trigger parted_conflict_update + after update on parted_conflict + referencing new table as inserted + for each statement + execute procedure parted_conflict_update_func(); + +truncate parted_conflict; + +insert into parted_conflict values (0, 'cero', 1); + +insert into parted_conflict values(0, 'cero', 1) + on conflict (a,b) do update set c = parted_conflict.c + 1; + +drop table parted_conflict; + +drop function parted_conflict_update_func(); diff --git a/crates/pgt_pretty_print/tests/data/multi/int2_60.sql b/crates/pgt_pretty_print/tests/data/multi/int2_60.sql new file mode 100644 index 000000000..b93e64a3a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/int2_60.sql @@ -0,0 +1,168 @@ +INSERT INTO INT2_TBL(f1) VALUES ('34.5'); + +INSERT INTO INT2_TBL(f1) VALUES ('100000'); + +INSERT INTO INT2_TBL(f1) VALUES ('asdf'); + +INSERT INTO INT2_TBL(f1) VALUES (' '); + +INSERT INTO INT2_TBL(f1) VALUES ('- 1234'); + +INSERT INTO INT2_TBL(f1) VALUES ('4 444'); + +INSERT INTO INT2_TBL(f1) VALUES ('123 dt'); + +INSERT INTO INT2_TBL(f1) VALUES (''); + +SELECT * FROM INT2_TBL; + +SELECT pg_input_is_valid('34', 'int2'); + +SELECT pg_input_is_valid('asdf', 'int2'); + +SELECT pg_input_is_valid('50000', 'int2'); + +SELECT * FROM pg_input_error_info('50000', 'int2'); + +SELECT pg_input_is_valid(' 1 3 5 ', 'int2vector'); + +SELECT * FROM pg_input_error_info('1 asdf', 'int2vector'); + +SELECT * FROM pg_input_error_info('50000', 'int2vector'); + +SELECT * FROM INT2_TBL AS f(a, b); + +SELECT * FROM (TABLE int2_tbl) AS s (a, b); + +SELECT i.* FROM INT2_TBL i WHERE i.f1 <> int2 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 <> int4 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 = int2 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 = int4 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 < int2 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 < int4 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 <= int2 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 <= int4 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 > int2 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 > int4 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 >= int2 '0'; + +SELECT i.* FROM INT2_TBL i WHERE i.f1 >= int4 '0'; + +SELECT i.* FROM INT2_TBL i WHERE (i.f1 % int2 '2') = int2 '1'; + +SELECT i.* FROM INT2_TBL i WHERE (i.f1 % int4 '2') = int2 '0'; + +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i; + +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i +WHERE abs(f1) < 16384; + +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT2_TBL i; + +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i; + +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i +WHERE f1 < 32766; + +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT2_TBL i; + +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i; + +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i +WHERE f1 > -32767; + +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT2_TBL i; + +SELECT i.f1, i.f1 / int2 '2' AS x FROM INT2_TBL i; + +SELECT i.f1, i.f1 / int4 '2' AS x FROM INT2_TBL i; + +SELECT (-1::int2<<15)::text; + +SELECT ((-1::int2<<15)+1::int2)::text; + +SELECT (-32768)::int2 * (-1)::int2; + +SELECT (-32768)::int2 / (-1)::int2; + +SELECT (-32768)::int2 % (-1)::int2; + +SELECT x, x::int2 AS int2_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x); + +SELECT x, x::int2 AS int2_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x); + +SELECT int2 '0b100101'; + +SELECT int2 '0o273'; + +SELECT int2 '0x42F'; + +SELECT int2 '0b'; + +SELECT int2 '0o'; + +SELECT int2 '0x'; + +SELECT int2 '0b111111111111111'; + +SELECT int2 '0b1000000000000000'; + +SELECT int2 '0o77777'; + +SELECT int2 '0o100000'; + +SELECT int2 '0x7FFF'; + +SELECT int2 '0x8000'; + +SELECT int2 '-0b1000000000000000'; + +SELECT int2 '-0b1000000000000001'; + +SELECT int2 '-0o100000'; + +SELECT int2 '-0o100001'; + +SELECT int2 '-0x8000'; + +SELECT int2 '-0x8001'; + +SELECT int2 '1_000'; + +SELECT int2 '1_2_3'; + +SELECT int2 '0xE_FF'; + +SELECT int2 '0o2_73'; + +SELECT int2 '0b_10_0101'; + +SELECT int2 '_100'; + +SELECT int2 '100_'; + +SELECT int2 '10__000'; diff --git a/crates/pgt_pretty_print/tests/data/multi/int4_60.sql b/crates/pgt_pretty_print/tests/data/multi/int4_60.sql new file mode 100644 index 000000000..80c5b2e6a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/int4_60.sql @@ -0,0 +1,220 @@ +INSERT INTO INT4_TBL(f1) VALUES ('34.5'); + +INSERT INTO INT4_TBL(f1) VALUES ('1000000000000'); + +INSERT INTO INT4_TBL(f1) VALUES ('asdf'); + +INSERT INTO INT4_TBL(f1) VALUES (' '); + +INSERT INTO INT4_TBL(f1) VALUES (' asdf '); + +INSERT INTO INT4_TBL(f1) VALUES ('- 1234'); + +INSERT INTO INT4_TBL(f1) VALUES ('123 5'); + +INSERT INTO INT4_TBL(f1) VALUES (''); + +SELECT * FROM INT4_TBL; + +SELECT pg_input_is_valid('34', 'int4'); + +SELECT pg_input_is_valid('asdf', 'int4'); + +SELECT pg_input_is_valid('1000000000000', 'int4'); + +SELECT * FROM pg_input_error_info('1000000000000', 'int4'); + +SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int2 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 <> int4 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 = int2 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 = int4 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 < int2 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 < int4 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 <= int2 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 <= int4 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 > int2 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 > int4 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 >= int2 '0'; + +SELECT i.* FROM INT4_TBL i WHERE i.f1 >= int4 '0'; + +SELECT i.* FROM INT4_TBL i WHERE (i.f1 % int2 '2') = int2 '1'; + +SELECT i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0'; + +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i; + +SELECT i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i +WHERE abs(f1) < 1073741824; + +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i; + +SELECT i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i +WHERE abs(f1) < 1073741824; + +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i; + +SELECT i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i +WHERE f1 < 2147483646; + +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i; + +SELECT i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i +WHERE f1 < 2147483646; + +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i; + +SELECT i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i +WHERE f1 > -2147483647; + +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i; + +SELECT i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i +WHERE f1 > -2147483647; + +SELECT i.f1, i.f1 / int2 '2' AS x FROM INT4_TBL i; + +SELECT i.f1, i.f1 / int4 '2' AS x FROM INT4_TBL i; + +SELECT -2+3 AS one; + +SELECT 4-2 AS two; + +SELECT 2- -1 AS three; + +SELECT 2 - -2 AS four; + +SELECT int2 '2' * int2 '2' = int2 '16' / int2 '4' AS true; + +SELECT int4 '2' * int2 '2' = int2 '16' / int4 '4' AS true; + +SELECT int2 '2' * int4 '2' = int4 '16' / int2 '4' AS true; + +SELECT int4 '1000' < int4 '999' AS false; + +SELECT 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 AS ten; + +SELECT 2 + 2 / 2 AS three; + +SELECT (2 + 2) / 2 AS two; + +SELECT (-1::int4<<31)::text; + +SELECT ((-1::int4<<31)+1)::text; + +SELECT (-2147483648)::int4 * (-1)::int4; + +SELECT (-2147483648)::int4 / (-1)::int4; + +SELECT (-2147483648)::int4 % (-1)::int4; + +SELECT (-2147483648)::int4 * (-1)::int2; + +SELECT (-2147483648)::int4 / (-1)::int2; + +SELECT (-2147483648)::int4 % (-1)::int2; + +SELECT x, x::int4 AS int4_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x); + +SELECT x, x::int4 AS int4_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x); + +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(b, a), gcd(-b, a) +FROM (VALUES (0::int4, 0::int4), + (0::int4, 6410818::int4), + (61866666::int4, 6410818::int4), + (-61866666::int4, 6410818::int4), + ((-2147483648)::int4, 1::int4), + ((-2147483648)::int4, 2147483647::int4), + ((-2147483648)::int4, 1073741824::int4)) AS v(a, b); + +SELECT gcd((-2147483648)::int4, 0::int4); + +SELECT gcd((-2147483648)::int4, (-2147483648)::int4); + +SELECT a, b, lcm(a, b), lcm(a, -b), lcm(b, a), lcm(-b, a) +FROM (VALUES (0::int4, 0::int4), + (0::int4, 42::int4), + (42::int4, 42::int4), + (330::int4, 462::int4), + (-330::int4, 462::int4), + ((-2147483648)::int4, 0::int4)) AS v(a, b); + +SELECT lcm((-2147483648)::int4, 1::int4); + +SELECT lcm(2147483647::int4, 2147483646::int4); + +SELECT int4 '0b100101'; + +SELECT int4 '0o273'; + +SELECT int4 '0x42F'; + +SELECT int4 '0b'; + +SELECT int4 '0o'; + +SELECT int4 '0x'; + +SELECT int4 '0b1111111111111111111111111111111'; + +SELECT int4 '0b10000000000000000000000000000000'; + +SELECT int4 '0o17777777777'; + +SELECT int4 '0o20000000000'; + +SELECT int4 '0x7FFFFFFF'; + +SELECT int4 '0x80000000'; + +SELECT int4 '-0b10000000000000000000000000000000'; + +SELECT int4 '-0b10000000000000000000000000000001'; + +SELECT int4 '-0o20000000000'; + +SELECT int4 '-0o20000000001'; + +SELECT int4 '-0x80000000'; + +SELECT int4 '-0x80000001'; + +SELECT int4 '1_000_000'; + +SELECT int4 '1_2_3'; + +SELECT int4 '0x1EEE_FFFF'; + +SELECT int4 '0o2_73'; + +SELECT int4 '0b_10_0101'; + +SELECT int4 '_100'; + +SELECT int4 '100_'; + +SELECT int4 '100__000'; diff --git a/crates/pgt_pretty_print/tests/data/multi/int8_60.sql b/crates/pgt_pretty_print/tests/data/multi/int8_60.sql new file mode 100644 index 000000000..cf4268c15 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/int8_60.sql @@ -0,0 +1,379 @@ +INSERT INTO INT8_TBL(q1) VALUES (' '); + +INSERT INTO INT8_TBL(q1) VALUES ('xxx'); + +INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485'); + +INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934'); + +INSERT INTO INT8_TBL(q1) VALUES ('- 123'); + +INSERT INTO INT8_TBL(q1) VALUES (' 345 5'); + +INSERT INTO INT8_TBL(q1) VALUES (''); + +SELECT * FROM INT8_TBL; + +SELECT pg_input_is_valid('34', 'int8'); + +SELECT pg_input_is_valid('asdf', 'int8'); + +SELECT pg_input_is_valid('10000000000000000000', 'int8'); + +SELECT * FROM pg_input_error_info('10000000000000000000', 'int8'); + +SELECT * FROM INT8_TBL WHERE q2 = 4567890123456789; + +SELECT * FROM INT8_TBL WHERE q2 <> 4567890123456789; + +SELECT * FROM INT8_TBL WHERE q2 < 4567890123456789; + +SELECT * FROM INT8_TBL WHERE q2 > 4567890123456789; + +SELECT * FROM INT8_TBL WHERE q2 <= 4567890123456789; + +SELECT * FROM INT8_TBL WHERE q2 >= 4567890123456789; + +SELECT * FROM INT8_TBL WHERE q2 = 456; + +SELECT * FROM INT8_TBL WHERE q2 <> 456; + +SELECT * FROM INT8_TBL WHERE q2 < 456; + +SELECT * FROM INT8_TBL WHERE q2 > 456; + +SELECT * FROM INT8_TBL WHERE q2 <= 456; + +SELECT * FROM INT8_TBL WHERE q2 >= 456; + +SELECT * FROM INT8_TBL WHERE 123 = q1; + +SELECT * FROM INT8_TBL WHERE 123 <> q1; + +SELECT * FROM INT8_TBL WHERE 123 < q1; + +SELECT * FROM INT8_TBL WHERE 123 > q1; + +SELECT * FROM INT8_TBL WHERE 123 <= q1; + +SELECT * FROM INT8_TBL WHERE 123 >= q1; + +SELECT * FROM INT8_TBL WHERE q2 = '456'::int2; + +SELECT * FROM INT8_TBL WHERE q2 <> '456'::int2; + +SELECT * FROM INT8_TBL WHERE q2 < '456'::int2; + +SELECT * FROM INT8_TBL WHERE q2 > '456'::int2; + +SELECT * FROM INT8_TBL WHERE q2 <= '456'::int2; + +SELECT * FROM INT8_TBL WHERE q2 >= '456'::int2; + +SELECT * FROM INT8_TBL WHERE '123'::int2 = q1; + +SELECT * FROM INT8_TBL WHERE '123'::int2 <> q1; + +SELECT * FROM INT8_TBL WHERE '123'::int2 < q1; + +SELECT * FROM INT8_TBL WHERE '123'::int2 > q1; + +SELECT * FROM INT8_TBL WHERE '123'::int2 <= q1; + +SELECT * FROM INT8_TBL WHERE '123'::int2 >= q1; + +SELECT q1 AS plus, -q1 AS minus FROM INT8_TBL; + +SELECT q1, q2, q1 + q2 AS plus FROM INT8_TBL; + +SELECT q1, q2, q1 - q2 AS minus FROM INT8_TBL; + +SELECT q1, q2, q1 * q2 AS multiply FROM INT8_TBL; + +SELECT q1, q2, q1 * q2 AS multiply FROM INT8_TBL + WHERE q1 < 1000 or (q2 > 0 and q2 < 1000); + +SELECT q1, q2, q1 / q2 AS divide, q1 % q2 AS mod FROM INT8_TBL; + +SELECT q1, float8(q1) FROM INT8_TBL; + +SELECT q2, float8(q2) FROM INT8_TBL; + +SELECT 37 + q1 AS plus4 FROM INT8_TBL; + +SELECT 37 - q1 AS minus4 FROM INT8_TBL; + +SELECT 2 * q1 AS "twice int4" FROM INT8_TBL; + +SELECT q1 * 2 AS "twice int4" FROM INT8_TBL; + +SELECT q1 + 42::int4 AS "8plus4", q1 - 42::int4 AS "8minus4", q1 * 42::int4 AS "8mul4", q1 / 42::int4 AS "8div4" FROM INT8_TBL; + +SELECT 246::int4 + q1 AS "4plus8", 246::int4 - q1 AS "4minus8", 246::int4 * q1 AS "4mul8", 246::int4 / q1 AS "4div8" FROM INT8_TBL; + +SELECT q1 + 42::int2 AS "8plus2", q1 - 42::int2 AS "8minus2", q1 * 42::int2 AS "8mul2", q1 / 42::int2 AS "8div2" FROM INT8_TBL; + +SELECT 246::int2 + q1 AS "2plus8", 246::int2 - q1 AS "2minus8", 246::int2 * q1 AS "2mul8", 246::int2 / q1 AS "2div8" FROM INT8_TBL; + +SELECT q2, abs(q2) FROM INT8_TBL; + +SELECT min(q1), min(q2) FROM INT8_TBL; + +SELECT max(q1), max(q2) FROM INT8_TBL; + +SELECT to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999') + FROM INT8_TBL; + +SELECT to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999') + FROM INT8_TBL; + +SELECT to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR') + FROM INT8_TBL; + +SELECT to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999') + FROM INT8_TBL; + +SELECT to_char(q2, 'MI9999999999999999') FROM INT8_TBL; + +SELECT to_char(q2, '9999999999999999PL') FROM INT8_TBL; + +SELECT to_char(q2, 'FMS9999999999999999') FROM INT8_TBL; + +SELECT to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL; + +SELECT to_char(q2, 'SG9999999999999999th') FROM INT8_TBL; + +SELECT to_char(q2, '0999999999999999') FROM INT8_TBL; + +SELECT to_char(q2, 'S0999999999999999') FROM INT8_TBL; + +SELECT to_char(q2, 'FM0999999999999999') FROM INT8_TBL; + +SELECT to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL; + +SELECT to_char(q2, 'L9999999999999999.000') FROM INT8_TBL; + +SELECT to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL; + +SELECT to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL; + +SELECT to_char(q2, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL; + +SELECT to_char(q2, '999999SG9999999999') FROM INT8_TBL; + +SELECT to_char(q2, 'FMRN') FROM INT8_TBL; + +SELECT to_char(1234, '9.99EEEE'); + +SELECT to_char(1234::int8, '9.99eeee'); + +SELECT to_char(-1234::int8, '9.99eeee'); + +SELECT to_char(1234, '99999V99'); + +SELECT to_char(1234::int8, '99999V99'); + +select '-9223372036854775808'::int8; + +select '-9223372036854775809'::int8; + +select '9223372036854775807'::int8; + +select '9223372036854775808'::int8; + +select -('-9223372036854775807'::int8); + +select -('-9223372036854775808'::int8); + +select 0::int8 - '-9223372036854775808'::int8; + +select '9223372036854775800'::int8 + '9223372036854775800'::int8; + +select '-9223372036854775800'::int8 + '-9223372036854775800'::int8; + +select '9223372036854775800'::int8 - '-9223372036854775800'::int8; + +select '-9223372036854775800'::int8 - '9223372036854775800'::int8; + +select '9223372036854775800'::int8 * '9223372036854775800'::int8; + +select '9223372036854775800'::int8 / '0'::int8; + +select '9223372036854775800'::int8 % '0'::int8; + +select abs('-9223372036854775808'::int8); + +select '9223372036854775800'::int8 + '100'::int4; + +select '-9223372036854775800'::int8 - '100'::int4; + +select '9223372036854775800'::int8 * '100'::int4; + +select '100'::int4 + '9223372036854775800'::int8; + +select '-100'::int4 - '9223372036854775800'::int8; + +select '100'::int4 * '9223372036854775800'::int8; + +select '9223372036854775800'::int8 + '100'::int2; + +select '-9223372036854775800'::int8 - '100'::int2; + +select '9223372036854775800'::int8 * '100'::int2; + +select '-9223372036854775808'::int8 / '0'::int2; + +select '100'::int2 + '9223372036854775800'::int8; + +select '-100'::int2 - '9223372036854775800'::int8; + +select '100'::int2 * '9223372036854775800'::int8; + +select '100'::int2 / '0'::int8; + +SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 = 456; + +SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 <> 456; + +SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 = 456; + +SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 <> 456; + +SELECT CAST('42'::int2 AS int8), CAST('-37'::int2 AS int8); + +SELECT CAST(q1 AS float4), CAST(q2 AS float8) FROM INT8_TBL; + +SELECT CAST('36854775807.0'::float4 AS int8); + +SELECT CAST('922337203685477580700.0'::float8 AS int8); + +SELECT CAST(q1 AS oid) FROM INT8_TBL; + +SELECT oid::int8 FROM pg_class WHERE relname = 'pg_class'; + +SELECT q1, q2, q1 & q2 AS "and", q1 | q2 AS "or", q1 # q2 AS "xor", ~q1 AS "not" FROM INT8_TBL; + +SELECT q1, q1 << 2 AS "shl", q1 >> 3 AS "shr" FROM INT8_TBL; + +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8); + +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 0); + +SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 2); + +SELECT (-1::int8<<63)::text; + +SELECT ((-1::int8<<63)+1)::text; + +SELECT (-9223372036854775808)::int8 * (-1)::int8; + +SELECT (-9223372036854775808)::int8 / (-1)::int8; + +SELECT (-9223372036854775808)::int8 % (-1)::int8; + +SELECT (-9223372036854775808)::int8 * (-1)::int4; + +SELECT (-9223372036854775808)::int8 / (-1)::int4; + +SELECT (-9223372036854775808)::int8 % (-1)::int4; + +SELECT (-9223372036854775808)::int8 * (-1)::int2; + +SELECT (-9223372036854775808)::int8 / (-1)::int2; + +SELECT (-9223372036854775808)::int8 % (-1)::int2; + +SELECT x, x::int8 AS int8_value +FROM (VALUES (-2.5::float8), + (-1.5::float8), + (-0.5::float8), + (0.0::float8), + (0.5::float8), + (1.5::float8), + (2.5::float8)) t(x); + +SELECT x, x::int8 AS int8_value +FROM (VALUES (-2.5::numeric), + (-1.5::numeric), + (-0.5::numeric), + (0.0::numeric), + (0.5::numeric), + (1.5::numeric), + (2.5::numeric)) t(x); + +SELECT a, b, gcd(a, b), gcd(a, -b), gcd(b, a), gcd(-b, a) +FROM (VALUES (0::int8, 0::int8), + (0::int8, 29893644334::int8), + (288484263558::int8, 29893644334::int8), + (-288484263558::int8, 29893644334::int8), + ((-9223372036854775808)::int8, 1::int8), + ((-9223372036854775808)::int8, 9223372036854775807::int8), + ((-9223372036854775808)::int8, 4611686018427387904::int8)) AS v(a, b); + +SELECT gcd((-9223372036854775808)::int8, 0::int8); + +SELECT gcd((-9223372036854775808)::int8, (-9223372036854775808)::int8); + +SELECT a, b, lcm(a, b), lcm(a, -b), lcm(b, a), lcm(-b, a) +FROM (VALUES (0::int8, 0::int8), + (0::int8, 29893644334::int8), + (29893644334::int8, 29893644334::int8), + (288484263558::int8, 29893644334::int8), + (-288484263558::int8, 29893644334::int8), + ((-9223372036854775808)::int8, 0::int8)) AS v(a, b); + +SELECT lcm((-9223372036854775808)::int8, 1::int8); + +SELECT lcm(9223372036854775807::int8, 9223372036854775806::int8); + +SELECT int8 '0b100101'; + +SELECT int8 '0o273'; + +SELECT int8 '0x42F'; + +SELECT int8 '0b'; + +SELECT int8 '0o'; + +SELECT int8 '0x'; + +SELECT int8 '0b111111111111111111111111111111111111111111111111111111111111111'; + +SELECT int8 '0b1000000000000000000000000000000000000000000000000000000000000000'; + +SELECT int8 '0o777777777777777777777'; + +SELECT int8 '0o1000000000000000000000'; + +SELECT int8 '0x7FFFFFFFFFFFFFFF'; + +SELECT int8 '0x8000000000000000'; + +SELECT int8 '-0b1000000000000000000000000000000000000000000000000000000000000000'; + +SELECT int8 '-0b1000000000000000000000000000000000000000000000000000000000000001'; + +SELECT int8 '-0o1000000000000000000000'; + +SELECT int8 '-0o1000000000000000000001'; + +SELECT int8 '-0x8000000000000000'; + +SELECT int8 '-0x8000000000000001'; + +SELECT int8 '1_000_000'; + +SELECT int8 '1_2_3'; + +SELECT int8 '0x1EEE_FFFF'; + +SELECT int8 '0o2_73'; + +SELECT int8 '0b_10_0101'; + +SELECT int8 '_100'; + +SELECT int8 '100_'; + +SELECT int8 '100__000'; diff --git a/crates/pgt_pretty_print/tests/data/multi/interval_60.sql b/crates/pgt_pretty_print/tests/data/multi/interval_60.sql new file mode 100644 index 000000000..7e2c2e776 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/interval_60.sql @@ -0,0 +1,1051 @@ +SET DATESTYLE = 'ISO'; + +SET IntervalStyle to postgres; + +SELECT INTERVAL '01:00' AS "One hour"; + +SELECT INTERVAL '+02:00' AS "Two hours"; + +SELECT INTERVAL '-08:00' AS "Eight hours"; + +SELECT INTERVAL '-1 +02:03' AS "22 hours ago..."; + +SELECT INTERVAL '-1 days +02:03' AS "22 hours ago..."; + +SELECT INTERVAL '1.5 weeks' AS "Ten days twelve hours"; + +SELECT INTERVAL '1.5 months' AS "One month 15 days"; + +SELECT INTERVAL '10 years -11 month -12 days +13:14' AS "9 years..."; + +SELECT INTERVAL 'infinity' AS "eternity"; + +SELECT INTERVAL '-infinity' AS "beginning of time"; + +CREATE TABLE INTERVAL_TBL (f1 interval); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 1 minute'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 5 hour'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 10 day'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 34 year'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 3 months'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 14 seconds ago'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('1 day 2 hours 3 minutes 4 seconds'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('6 years'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('5 months'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('5 months 12 hours'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('infinity'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('-infinity'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('badly formatted interval'); + +INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 30 eons ago'); + +SELECT pg_input_is_valid('1.5 weeks', 'interval'); + +SELECT pg_input_is_valid('garbage', 'interval'); + +SELECT pg_input_is_valid('@ 30 eons ago', 'interval'); + +SELECT * FROM pg_input_error_info('garbage', 'interval'); + +SELECT * FROM pg_input_error_info('@ 30 eons ago', 'interval'); + +SELECT * FROM INTERVAL_TBL; + +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 <> interval '@ 10 days'; + +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 <= interval '@ 5 hours'; + +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 < interval '@ 1 day'; + +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 = interval '@ 34 years'; + +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 >= interval '@ 1 month'; + +SELECT * FROM INTERVAL_TBL + WHERE INTERVAL_TBL.f1 > interval '@ 3 seconds ago'; + +SELECT r1.*, r2.* + FROM INTERVAL_TBL r1, INTERVAL_TBL r2 + WHERE r1.f1 > r2.f1 + ORDER BY r1.f1, r2.f1; + +SELECT f1, -f1 FROM INTERVAL_TBL; + +SELECT -('-2147483648 months'::interval); + +SELECT -('-2147483647 months'::interval); + +SELECT -('-2147483648 days'::interval); + +SELECT -('-2147483647 days'::interval); + +SELECT -('-9223372036854775808 us'::interval); + +SELECT -('-9223372036854775807 us'::interval); + +SELECT -('-2147483647 months -2147483647 days -9223372036854775807 us'::interval); + +CREATE TEMP TABLE INTERVAL_TBL_OF (f1 interval); + +INSERT INTO INTERVAL_TBL_OF (f1) VALUES + ('2147483647 days 2147483647 months'), + ('2147483647 days -2147483648 months'), + ('1 year'), + ('-2147483648 days 2147483647 months'), + ('-2147483648 days -2147483648 months'); + +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483648 days'); + +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483649 days'); + +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483647 years'); + +INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483648 years'); + +select extract(epoch from '256 microseconds'::interval * (2^55)::float8); + +SELECT r1.*, r2.* + FROM INTERVAL_TBL_OF r1, INTERVAL_TBL_OF r2 + WHERE r1.f1 > r2.f1 + ORDER BY r1.f1, r2.f1; + +CREATE INDEX ON INTERVAL_TBL_OF USING btree (f1); + +SET enable_seqscan TO false; + +SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1; + +SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1; + +RESET enable_seqscan; + +SELECT f1 - f1 FROM INTERVAL_TBL_OF; + +DROP TABLE INTERVAL_TBL_OF; + +CREATE TABLE INTERVAL_MULDIV_TBL (span interval); + +SELECT span * 0.3 AS product +FROM INTERVAL_MULDIV_TBL; + +SELECT span * 8.2 AS product +FROM INTERVAL_MULDIV_TBL; + +SELECT span / 10 AS quotient +FROM INTERVAL_MULDIV_TBL; + +SELECT span / 100 AS quotient +FROM INTERVAL_MULDIV_TBL; + +DROP TABLE INTERVAL_MULDIV_TBL; + +SET DATESTYLE = 'postgres'; + +SET IntervalStyle to postgres_verbose; + +SELECT * FROM INTERVAL_TBL; + +SELECT '3000000 months'::interval * 1000; + +SELECT '3000000 months'::interval / 0.001; + +SELECT '3000000 days'::interval * 1000; + +SELECT '3000000 days'::interval / 0.001; + +SELECT '1 month 2146410 days'::interval * 1000.5002; + +SELECT '4611686018427387904 usec'::interval / 0.1; + +select avg(f1) from interval_tbl where isfinite(f1); + +select '4 millenniums 5 centuries 4 decades 1 year 4 months 4 days 17 minutes 31 seconds'::interval; + +select '100000000y 10mon -1000000000d -100000h -10min -10.000001s ago'::interval; + +SELECT justify_hours(interval '6 months 3 days 52 hours 3 minutes 2 seconds') as "6 mons 5 days 4 hours 3 mins 2 seconds"; + +SELECT justify_days(interval '6 months 36 days 5 hours 4 minutes 3 seconds') as "7 mons 6 days 5 hours 4 mins 3 seconds"; + +SELECT justify_hours(interval '2147483647 days 24 hrs'); + +SELECT justify_days(interval '2147483647 months 30 days'); + +SELECT justify_interval(interval '1 month -1 hour') as "1 month -1 hour"; + +SELECT justify_interval(interval '2147483647 days 24 hrs'); + +SELECT justify_interval(interval '-2147483648 days -24 hrs'); + +SELECT justify_interval(interval '2147483647 months 30 days'); + +SELECT justify_interval(interval '-2147483648 months -30 days'); + +SELECT justify_interval(interval '2147483647 months 30 days -24 hrs'); + +SELECT justify_interval(interval '-2147483648 months -30 days 24 hrs'); + +SELECT justify_interval(interval '2147483647 months -30 days 1440 hrs'); + +SELECT justify_interval(interval '-2147483648 months 30 days -1440 hrs'); + +SET DATESTYLE = 'ISO'; + +SET IntervalStyle TO postgres; + +SELECT '1 millisecond'::interval, '1 microsecond'::interval, + '500 seconds 99 milliseconds 51 microseconds'::interval; + +SELECT '3 days 5 milliseconds'::interval; + +SELECT '1 second 2 seconds'::interval; + +SELECT '10 milliseconds 20 milliseconds'::interval; + +SELECT '5.5 seconds 3 milliseconds'::interval; + +SELECT '1:20:05 5 microseconds'::interval; + +SELECT '1 day 1 day'::interval; + +SELECT interval '1-2'; + +SELECT interval '999' second; + +SELECT interval '999' minute; + +SELECT interval '999' hour; + +SELECT interval '999' day; + +SELECT interval '999' month; + +SELECT interval '1' year; + +SELECT interval '2' month; + +SELECT interval '3' day; + +SELECT interval '4' hour; + +SELECT interval '5' minute; + +SELECT interval '6' second; + +SELECT interval '1' year to month; + +SELECT interval '1-2' year to month; + +SELECT interval '1 2' day to hour; + +SELECT interval '1 2:03' day to hour; + +SELECT interval '1 2:03:04' day to hour; + +SELECT interval '1 2' day to minute; + +SELECT interval '1 2:03' day to minute; + +SELECT interval '1 2:03:04' day to minute; + +SELECT interval '1 2' day to second; + +SELECT interval '1 2:03' day to second; + +SELECT interval '1 2:03:04' day to second; + +SELECT interval '1 2' hour to minute; + +SELECT interval '1 2:03' hour to minute; + +SELECT interval '1 2:03:04' hour to minute; + +SELECT interval '1 2' hour to second; + +SELECT interval '1 2:03' hour to second; + +SELECT interval '1 2:03:04' hour to second; + +SELECT interval '1 2' minute to second; + +SELECT interval '1 2:03' minute to second; + +SELECT interval '1 2:03:04' minute to second; + +SELECT interval '1 +2:03' minute to second; + +SELECT interval '1 +2:03:04' minute to second; + +SELECT interval '1 -2:03' minute to second; + +SELECT interval '1 -2:03:04' minute to second; + +SELECT interval '123 11' day to hour; + +SELECT interval '123 11' day; + +SELECT interval '123 11'; + +SELECT interval '123 2:03 -2:04'; + +SELECT interval(0) '1 day 01:23:45.6789'; + +SELECT interval(2) '1 day 01:23:45.6789'; + +SELECT interval '12:34.5678' minute to second(2); + +SELECT interval '1.234' second; + +SELECT interval '1.234' second(2); + +SELECT interval '1 2.345' day to second(2); + +SELECT interval '1 2:03' day to second(2); + +SELECT interval '1 2:03.4567' day to second(2); + +SELECT interval '1 2:03:04.5678' day to second(2); + +SELECT interval '1 2.345' hour to second(2); + +SELECT interval '1 2:03.45678' hour to second(2); + +SELECT interval '1 2:03:04.5678' hour to second(2); + +SELECT interval '1 2.3456' minute to second(2); + +SELECT interval '1 2:03.5678' minute to second(2); + +SELECT interval '1 2:03:04.5678' minute to second(2); + +SELECT interval '2562047788:00:54.775807' second(2); + +SELECT interval '-2562047788:00:54.775807' second(2); + +SELECT f1, f1::INTERVAL DAY TO MINUTE AS "minutes", + (f1 + INTERVAL '1 month')::INTERVAL MONTH::INTERVAL YEAR AS "years" + FROM interval_tbl; + +SET IntervalStyle TO sql_standard; + +SELECT interval '0' AS "zero", + interval '1-2' year to month AS "year-month", + interval '1 2:03:04' day to second AS "day-time", + - interval '1-2' AS "negative year-month", + - interval '1 2:03:04' AS "negative day-time"; + +SET IntervalStyle TO postgres; + +SELECT interval '+1 -1:00:00', + interval '-1 +1:00:00', + interval '+1-2 -3 +4:05:06.789', + interval '-1-2 +3 -4:05:06.789'; + +SELECT interval '-23 hours 45 min 12.34 sec', + interval '-1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min +12.34 sec'; + +SET IntervalStyle TO sql_standard; + +SELECT interval '1 day -1 hours', + interval '-1 days +1 hours', + interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds', + - interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds'; + +SELECT interval '-23 hours 45 min 12.34 sec', + interval '-1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min 12.34 sec', + interval '-1 year 2 months 1 day 23 hours 45 min +12.34 sec'; + +SELECT interval ''; + +SET IntervalStyle to iso_8601; + +select interval '0' AS "zero", + interval '1-2' AS "a year 2 months", + interval '1 2:03:04' AS "a bit over a day", + interval '2:03:04.45679' AS "a bit over 2 hours", + (interval '1-2' + interval '3 4:05:06.7') AS "all fields", + (interval '1-2' - interval '3 4:05:06.7') AS "mixed sign", + (- interval '1-2' + interval '3 4:05:06.7') AS "negative"; + +SET IntervalStyle to sql_standard; + +select interval 'P0Y' AS "zero", + interval 'P1Y2M' AS "a year 2 months", + interval 'P1W' AS "a week", + interval 'P1DT2H3M4S' AS "a bit over a day", + interval 'P1Y2M3DT4H5M6.7S' AS "all fields", + interval 'P-1Y-2M-3DT-4H-5M-6.7S' AS "negative", + interval 'PT-0.1S' AS "fractional second"; + +SET IntervalStyle to postgres; + +select interval 'P00021015T103020' AS "ISO8601 Basic Format", + interval 'P0002-10-15T10:30:20' AS "ISO8601 Extended Format"; + +select interval 'P0002' AS "year only", + interval 'P0002-10' AS "year month", + interval 'P0002-10-15' AS "year month day", + interval 'P0002T1S' AS "year only plus time", + interval 'P0002-10T1S' AS "year month plus time", + interval 'P0002-10-15T1S' AS "year month day plus time", + interval 'PT10' AS "hour only", + interval 'PT10:30' AS "hour minute"; + +select interval 'P1Y0M3DT4H5M6S'; + +select interval 'P1.0Y0M3DT4H5M6S'; + +select interval 'P1.1Y0M3DT4H5M6S'; + +select interval 'P1.Y0M3DT4H5M6S'; + +select interval 'P.1Y0M3DT4H5M6S'; + +select interval 'P10.5e4Y'; + +select interval 'P.Y0M3DT4H5M6S'; + +SET IntervalStyle to postgres_verbose; + +select interval '-10 mons -3 days +03:55:06.70'; + +select interval '1 year 2 mons 3 days 04:05:06.699999'; + +select interval '0:0:0.7', interval '@ 0.70 secs', interval '0.7 seconds'; + +select interval '2562047788.01521550194 hours'; + +select interval '-2562047788.01521550222 hours'; + +select interval '153722867280.912930117 minutes'; + +select interval '-153722867280.912930133 minutes'; + +select interval '9223372036854.775807 seconds'; + +select interval '-9223372036854.775808 seconds'; + +select interval '9223372036854775.807 milliseconds'; + +select interval '-9223372036854775.808 milliseconds'; + +select interval '9223372036854775807 microseconds'; + +select interval '-9223372036854775808 microseconds'; + +select interval 'PT2562047788H54.775807S'; + +select interval 'PT-2562047788H-54.775808S'; + +select interval 'PT2562047788:00:54.775807'; + +select interval 'PT2562047788.0152155019444'; + +select interval 'PT-2562047788.0152155022222'; + +select interval '2147483648 years'; + +select interval '-2147483649 years'; + +select interval '2147483648 months'; + +select interval '-2147483649 months'; + +select interval '2147483648 days'; + +select interval '-2147483649 days'; + +select interval '2562047789 hours'; + +select interval '-2562047789 hours'; + +select interval '153722867281 minutes'; + +select interval '-153722867281 minutes'; + +select interval '9223372036855 seconds'; + +select interval '-9223372036855 seconds'; + +select interval '9223372036854777 millisecond'; + +select interval '-9223372036854777 millisecond'; + +select interval '9223372036854775808 microsecond'; + +select interval '-9223372036854775809 microsecond'; + +select interval 'P2147483648'; + +select interval 'P-2147483649'; + +select interval 'P1-2147483647-2147483647'; + +select interval 'PT2562047789'; + +select interval 'PT-2562047789'; + +select interval '2147483647 weeks'; + +select interval '-2147483648 weeks'; + +select interval '2147483647 decades'; + +select interval '-2147483648 decades'; + +select interval '2147483647 centuries'; + +select interval '-2147483648 centuries'; + +select interval '2147483647 millennium'; + +select interval '-2147483648 millennium'; + +select interval '1 week 2147483647 days'; + +select interval '-1 week -2147483648 days'; + +select interval '2147483647 days 1 week'; + +select interval '-2147483648 days -1 week'; + +select interval 'P1W2147483647D'; + +select interval 'P-1W-2147483648D'; + +select interval 'P2147483647D1W'; + +select interval 'P-2147483648D-1W'; + +select interval '1 decade 2147483647 years'; + +select interval '1 century 2147483647 years'; + +select interval '1 millennium 2147483647 years'; + +select interval '-1 decade -2147483648 years'; + +select interval '-1 century -2147483648 years'; + +select interval '-1 millennium -2147483648 years'; + +select interval '2147483647 years 1 decade'; + +select interval '2147483647 years 1 century'; + +select interval '2147483647 years 1 millennium'; + +select interval '-2147483648 years -1 decade'; + +select interval '-2147483648 years -1 century'; + +select interval '-2147483648 years -1 millennium'; + +select interval '0.1 millennium 2147483647 months'; + +select interval '0.1 centuries 2147483647 months'; + +select interval '0.1 decades 2147483647 months'; + +select interval '0.1 yrs 2147483647 months'; + +select interval '-0.1 millennium -2147483648 months'; + +select interval '-0.1 centuries -2147483648 months'; + +select interval '-0.1 decades -2147483648 months'; + +select interval '-0.1 yrs -2147483648 months'; + +select interval '2147483647 months 0.1 millennium'; + +select interval '2147483647 months 0.1 centuries'; + +select interval '2147483647 months 0.1 decades'; + +select interval '2147483647 months 0.1 yrs'; + +select interval '-2147483648 months -0.1 millennium'; + +select interval '-2147483648 months -0.1 centuries'; + +select interval '-2147483648 months -0.1 decades'; + +select interval '-2147483648 months -0.1 yrs'; + +select interval '0.1 months 2147483647 days'; + +select interval '-0.1 months -2147483648 days'; + +select interval '2147483647 days 0.1 months'; + +select interval '-2147483648 days -0.1 months'; + +select interval '0.5 weeks 2147483647 days'; + +select interval '-0.5 weeks -2147483648 days'; + +select interval '2147483647 days 0.5 weeks'; + +select interval '-2147483648 days -0.5 weeks'; + +select interval '0.01 months 9223372036854775807 microseconds'; + +select interval '-0.01 months -9223372036854775808 microseconds'; + +select interval '9223372036854775807 microseconds 0.01 months'; + +select interval '-9223372036854775808 microseconds -0.01 months'; + +select interval '0.1 weeks 9223372036854775807 microseconds'; + +select interval '-0.1 weeks -9223372036854775808 microseconds'; + +select interval '9223372036854775807 microseconds 0.1 weeks'; + +select interval '-9223372036854775808 microseconds -0.1 weeks'; + +select interval '0.1 days 9223372036854775807 microseconds'; + +select interval '-0.1 days -9223372036854775808 microseconds'; + +select interval '9223372036854775807 microseconds 0.1 days'; + +select interval '-9223372036854775808 microseconds -0.1 days'; + +select interval 'P0.1Y2147483647M'; + +select interval 'P-0.1Y-2147483648M'; + +select interval 'P2147483647M0.1Y'; + +select interval 'P-2147483648M-0.1Y'; + +select interval 'P0.1M2147483647D'; + +select interval 'P-0.1M-2147483648D'; + +select interval 'P2147483647D0.1M'; + +select interval 'P-2147483648D-0.1M'; + +select interval 'P0.5W2147483647D'; + +select interval 'P-0.5W-2147483648D'; + +select interval 'P2147483647D0.5W'; + +select interval 'P-2147483648D-0.5W'; + +select interval 'P0.01MT2562047788H54.775807S'; + +select interval 'P-0.01MT-2562047788H-54.775808S'; + +select interval 'P0.1DT2562047788H54.775807S'; + +select interval 'P-0.1DT-2562047788H-54.775808S'; + +select interval 'PT2562047788.1H54.775807S'; + +select interval 'PT-2562047788.1H-54.775808S'; + +select interval 'PT2562047788H0.1M54.775807S'; + +select interval 'PT-2562047788H-0.1M-54.775808S'; + +select interval 'P0.1-2147483647-00'; + +select interval 'P00-0.1-2147483647'; + +select interval 'P00-0.01-00T2562047788:00:54.775807'; + +select interval 'P00-00-0.1T2562047788:00:54.775807'; + +select interval 'PT2562047788.1:00:54.775807'; + +select interval 'PT2562047788:01.:54.775807'; + +select interval '0.1 2562047788:0:54.775807'; + +select interval '0.1 2562047788:0:54.775808 ago'; + +select interval '2562047788.1:0:54.775807'; + +select interval '2562047788.1:0:54.775808 ago'; + +select interval '2562047788:0.1:54.775807'; + +select interval '2562047788:0.1:54.775808 ago'; + +select interval '-2147483648 months ago'; + +select interval '-2147483648 days ago'; + +select interval '-9223372036854775808 microseconds ago'; + +select interval '-2147483648 months -2147483648 days -9223372036854775808 microseconds ago'; + +select make_interval(years := 178956971); + +select make_interval(years := -178956971); + +select make_interval(years := 1, months := 2147483647); + +select make_interval(years := -1, months := -2147483648); + +select make_interval(weeks := 306783379); + +select make_interval(weeks := -306783379); + +select make_interval(weeks := 1, days := 2147483647); + +select make_interval(weeks := -1, days := -2147483648); + +select make_interval(secs := 1e308); + +select make_interval(secs := 1e18); + +select make_interval(secs := -1e18); + +select make_interval(mins := 1, secs := 9223372036800.0); + +select make_interval(mins := -1, secs := -9223372036800.0); + +SET IntervalStyle to postgres; + +select interval '-2147483647 months -2147483648 days -9223372036854775808 us'; + +SET IntervalStyle to sql_standard; + +select interval '-2147483647 months -2147483648 days -9223372036854775808 us'; + +SET IntervalStyle to iso_8601; + +select interval '-2147483647 months -2147483648 days -9223372036854775808 us'; + +SET IntervalStyle to postgres_verbose; + +select interval '-2147483647 months -2147483648 days -9223372036854775808 us'; + +select '30 days'::interval = '1 month'::interval as t; + +select interval_hash('30 days'::interval) = interval_hash('1 month'::interval) as t; + +select make_interval(years := 2); + +select make_interval(years := 1, months := 6); + +select make_interval(years := 1, months := -1, weeks := 5, days := -7, hours := 25, mins := -180); + +select make_interval() = make_interval(years := 0, months := 0, weeks := 0, days := 0, mins := 0, secs := 0.0); + +select make_interval(hours := -2, mins := -10, secs := -25.3); + +select make_interval(years := 'inf'::float::int); + +select make_interval(months := 'NaN'::float::int); + +select make_interval(secs := 'inf'); + +select make_interval(secs := 'NaN'); + +select make_interval(secs := 7e12); + +SELECT f1, + EXTRACT(MICROSECOND FROM f1) AS MICROSECOND, + EXTRACT(MILLISECOND FROM f1) AS MILLISECOND, + EXTRACT(SECOND FROM f1) AS SECOND, + EXTRACT(MINUTE FROM f1) AS MINUTE, + EXTRACT(HOUR FROM f1) AS HOUR, + EXTRACT(DAY FROM f1) AS DAY, + EXTRACT(WEEK FROM f1) AS WEEK, + EXTRACT(MONTH FROM f1) AS MONTH, + EXTRACT(QUARTER FROM f1) AS QUARTER, + EXTRACT(YEAR FROM f1) AS YEAR, + EXTRACT(DECADE FROM f1) AS DECADE, + EXTRACT(CENTURY FROM f1) AS CENTURY, + EXTRACT(MILLENNIUM FROM f1) AS MILLENNIUM, + EXTRACT(EPOCH FROM f1) AS EPOCH + FROM INTERVAL_TBL; + +SELECT -f1, + EXTRACT(MICROSECOND FROM -f1) AS MICROSECOND, + EXTRACT(MILLISECOND FROM -f1) AS MILLISECOND, + EXTRACT(SECOND FROM -f1) AS SECOND, + EXTRACT(MINUTE FROM -f1) AS MINUTE, + EXTRACT(HOUR FROM -f1) AS HOUR, + EXTRACT(DAY FROM -f1) AS DAY, + EXTRACT(WEEK FROM -f1) AS WEEK, + EXTRACT(MONTH FROM -f1) AS MONTH, + EXTRACT(QUARTER FROM -f1) AS QUARTER, + EXTRACT(YEAR FROM -f1) AS YEAR, + EXTRACT(DECADE FROM -f1) AS DECADE, + EXTRACT(CENTURY FROM -f1) AS CENTURY, + EXTRACT(MILLENNIUM FROM -f1) AS MILLENNIUM, + EXTRACT(EPOCH FROM -f1) AS EPOCH + FROM INTERVAL_TBL; + +SELECT EXTRACT(FORTNIGHT FROM INTERVAL '2 days'); + +SELECT EXTRACT(TIMEZONE FROM INTERVAL '2 days'); + +SELECT EXTRACT(DECADE FROM INTERVAL '100 y'); + +SELECT EXTRACT(DECADE FROM INTERVAL '99 y'); + +SELECT EXTRACT(DECADE FROM INTERVAL '-99 y'); + +SELECT EXTRACT(DECADE FROM INTERVAL '-100 y'); + +SELECT EXTRACT(CENTURY FROM INTERVAL '100 y'); + +SELECT EXTRACT(CENTURY FROM INTERVAL '99 y'); + +SELECT EXTRACT(CENTURY FROM INTERVAL '-99 y'); + +SELECT EXTRACT(CENTURY FROM INTERVAL '-100 y'); + +SELECT f1, + date_part('microsecond', f1) AS microsecond, + date_part('millisecond', f1) AS millisecond, + date_part('second', f1) AS second, + date_part('epoch', f1) AS epoch + FROM INTERVAL_TBL; + +SELECT extract(epoch from interval '1000000000 days'); + +SELECT interval '-2147483648 months -2147483648 days -9223372036854775807 us'; + +SELECT interval '2147483647 months 2147483647 days 9223372036854775806 us'; + +SELECT interval '-2147483648 months -2147483648 days -9223372036854775808 us'; + +SELECT interval '2147483647 months 2147483647 days 9223372036854775807 us'; + +CREATE TABLE INFINITE_INTERVAL_TBL (i interval); + +INSERT INTO INFINITE_INTERVAL_TBL VALUES ('infinity'), ('-infinity'), ('1 year 2 days 3 hours'); + +SELECT i, isfinite(i) FROM INFINITE_INTERVAL_TBL; + +CREATE FUNCTION eval(expr text) +RETURNS text AS +$$ +DECLARE + result text; +BEGIN + EXECUTE 'select '||expr INTO result; + RETURN result; +EXCEPTION WHEN OTHERS THEN + RETURN SQLERRM; +END +$$ +LANGUAGE plpgsql; + +SELECT d AS date, i AS interval, + eval(format('date %L + interval %L', d, i)) AS plus, + eval(format('date %L - interval %L', d, i)) AS minus +FROM (VALUES (date '-infinity'), + (date '1995-08-06'), + (date 'infinity')) AS t1(d), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i); + +SELECT i1 AS interval1, i2 AS interval2, + eval(format('interval %L + interval %L', i1, i2)) AS plus, + eval(format('interval %L - interval %L', i1, i2)) AS minus +FROM (VALUES (interval '-infinity'), + (interval '2 months'), + (interval 'infinity')) AS t1(i1), + (VALUES (interval '-infinity'), + (interval '10 days'), + (interval 'infinity')) AS t2(i2); + +SELECT interval '2147483646 months 2147483646 days 9223372036854775806 us' + interval '1 month 1 day 1 us'; + +SELECT interval '-2147483647 months -2147483647 days -9223372036854775807 us' + interval '-1 month -1 day -1 us'; + +SELECT interval '2147483646 months 2147483646 days 9223372036854775806 us' - interval '-1 month -1 day -1 us'; + +SELECT interval '-2147483647 months -2147483647 days -9223372036854775807 us' - interval '1 month 1 day 1 us'; + +SELECT t AS timestamp, i AS interval, + eval(format('timestamp %L + interval %L', t, i)) AS plus, + eval(format('timestamp %L - interval %L', t, i)) AS minus +FROM (VALUES (timestamp '-infinity'), + (timestamp '1995-08-06 12:30:15'), + (timestamp 'infinity')) AS t1(t), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i); + +SELECT t AT TIME ZONE 'GMT' AS timestamptz, i AS interval, + eval(format('timestamptz %L + interval %L', t, i)) AS plus, + eval(format('timestamptz %L - interval %L', t, i)) AS minus +FROM (VALUES (timestamptz '-infinity'), + (timestamptz '1995-08-06 12:30:15 GMT'), + (timestamptz 'infinity')) AS t1(t), + (VALUES (interval '-infinity'), + (interval 'infinity')) AS t2(i); + +SELECT time '11:27:42' + interval 'infinity'; + +SELECT time '11:27:42' + interval '-infinity'; + +SELECT time '11:27:42' - interval 'infinity'; + +SELECT time '11:27:42' - interval '-infinity'; + +SELECT timetz '11:27:42' + interval 'infinity'; + +SELECT timetz '11:27:42' + interval '-infinity'; + +SELECT timetz '11:27:42' - interval 'infinity'; + +SELECT timetz '11:27:42' - interval '-infinity'; + +SELECT lhst.i lhs, + rhst.i rhs, + lhst.i < rhst.i AS lt, + lhst.i <= rhst.i AS le, + lhst.i = rhst.i AS eq, + lhst.i > rhst.i AS gt, + lhst.i >= rhst.i AS ge, + lhst.i <> rhst.i AS ne + FROM INFINITE_INTERVAL_TBL lhst CROSS JOIN INFINITE_INTERVAL_TBL rhst + WHERE NOT isfinite(lhst.i); + +SELECT i AS interval, + -i AS um, + i * 2.0 AS mul, + i * -2.0 AS mul_neg, + i * 'infinity' AS mul_inf, + i * '-infinity' AS mul_inf_neg, + i / 3.0 AS div, + i / -3.0 AS div_neg + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i); + +SELECT -interval '-2147483647 months -2147483647 days -9223372036854775807 us'; + +SELECT interval 'infinity' * 'nan'; + +SELECT interval '-infinity' * 'nan'; + +SELECT interval '-1073741824 months -1073741824 days -4611686018427387904 us' * 2; + +SELECT interval 'infinity' * 0; + +SELECT interval '-infinity' * 0; + +SELECT interval '0 days' * 'infinity'::float; + +SELECT interval '0 days' * '-infinity'::float; + +SELECT interval '5 days' * 'infinity'::float; + +SELECT interval '5 days' * '-infinity'::float; + +SELECT interval 'infinity' / 'infinity'; + +SELECT interval 'infinity' / '-infinity'; + +SELECT interval 'infinity' / 'nan'; + +SELECT interval '-infinity' / 'infinity'; + +SELECT interval '-infinity' / '-infinity'; + +SELECT interval '-infinity' / 'nan'; + +SELECT interval '-1073741824 months -1073741824 days -4611686018427387904 us' / 0.5; + +SELECT date_bin('infinity', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00'); + +SELECT date_bin('-infinity', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00'); + +SELECT i AS interval, date_trunc('hour', i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i); + +SELECT i AS interval, date_trunc('week', i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i); + +SELECT i AS interval, date_trunc('ago', i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i); + +SELECT i AS interval, justify_days(i), justify_hours(i), justify_interval(i) + FROM INFINITE_INTERVAL_TBL + WHERE NOT isfinite(i); + +SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamp); + +SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamp); + +SELECT timezone('infinity'::interval, '1995-08-06 12:12:12'::timestamptz); + +SELECT timezone('-infinity'::interval, '1995-08-06 12:12:12'::timestamptz); + +SELECT timezone('infinity'::interval, '12:12:12'::time); + +SELECT timezone('-infinity'::interval, '12:12:12'::time); + +SELECT timezone('infinity'::interval, '12:12:12'::timetz); + +SELECT timezone('-infinity'::interval, '12:12:12'::timetz); + +SELECT 'infinity'::interval::time; + +SELECT '-infinity'::interval::time; + +SELECT to_char('infinity'::interval, 'YYYY'); + +SELECT to_char('-infinity'::interval, 'YYYY'); + +SELECT INTERVAL '42 days 2 seconds ago ago'; + +SELECT INTERVAL '2 minutes ago 5 days'; + +SELECT INTERVAL 'hour 5 months'; + +SELECT INTERVAL '1 year months days 5 hours'; + +SELECT INTERVAL 'now'; + +SELECT INTERVAL 'today'; + +SELECT INTERVAL 'tomorrow'; + +SELECT INTERVAL 'allballs'; + +SELECT INTERVAL 'epoch'; + +SELECT INTERVAL 'yesterday'; + +SELECT INTERVAL 'infinity years'; + +SELECT INTERVAL 'infinity ago'; + +SELECT INTERVAL '+infinity -infinity'; diff --git a/crates/pgt_pretty_print/tests/data/multi/join_60.sql b/crates/pgt_pretty_print/tests/data/multi/join_60.sql new file mode 100644 index 000000000..53c661fe0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/join_60.sql @@ -0,0 +1,1271 @@ +CREATE TABLE J1_TBL ( + i integer, + j integer, + t text +); + +CREATE TABLE J2_TBL ( + i integer, + k integer +); + +INSERT INTO J1_TBL VALUES (1, 4, 'one'); + +INSERT INTO J1_TBL VALUES (2, 3, 'two'); + +INSERT INTO J1_TBL VALUES (3, 2, 'three'); + +INSERT INTO J1_TBL VALUES (4, 1, 'four'); + +INSERT INTO J1_TBL VALUES (5, 0, 'five'); + +INSERT INTO J1_TBL VALUES (6, 6, 'six'); + +INSERT INTO J1_TBL VALUES (7, 7, 'seven'); + +INSERT INTO J1_TBL VALUES (8, 8, 'eight'); + +INSERT INTO J1_TBL VALUES (0, NULL, 'zero'); + +INSERT INTO J1_TBL VALUES (NULL, NULL, 'null'); + +INSERT INTO J1_TBL VALUES (NULL, 0, 'zero'); + +INSERT INTO J2_TBL VALUES (1, -1); + +INSERT INTO J2_TBL VALUES (2, 2); + +INSERT INTO J2_TBL VALUES (3, -3); + +INSERT INTO J2_TBL VALUES (2, 4); + +INSERT INTO J2_TBL VALUES (5, -5); + +INSERT INTO J2_TBL VALUES (5, -5); + +INSERT INTO J2_TBL VALUES (0, NULL); + +INSERT INTO J2_TBL VALUES (NULL, NULL); + +INSERT INTO J2_TBL VALUES (NULL, 0); + +create temp table onerow(); + +insert into onerow default values; + +analyze onerow; + +SELECT * + FROM J1_TBL AS tx; + +SELECT * + FROM J1_TBL tx; + +SELECT * + FROM J1_TBL AS t1 (a, b, c); + +SELECT * + FROM J1_TBL t1 (a, b, c); + +SELECT * + FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e); + +SELECT t1.a, t2.e + FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e) + WHERE t1.a = t2.d; + +SELECT * + FROM J1_TBL CROSS JOIN J2_TBL; + +SELECT i, k, t + FROM J1_TBL CROSS JOIN J2_TBL; + +SELECT t1.i, k, t + FROM J1_TBL t1 CROSS JOIN J2_TBL t2; + +SELECT ii, tt, kk + FROM (J1_TBL CROSS JOIN J2_TBL) + AS tx (ii, jj, tt, ii2, kk); + +SELECT tx.ii, tx.jj, tx.kk + FROM (J1_TBL t1 (a, b, c) CROSS JOIN J2_TBL t2 (d, e)) + AS tx (ii, jj, tt, ii2, kk); + +SELECT * + FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; + +SELECT * + FROM J1_TBL INNER JOIN J2_TBL USING (i); + +SELECT * + FROM J1_TBL JOIN J2_TBL USING (i); + +SELECT * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a) + ORDER BY a, d; + +SELECT * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) + ORDER BY b, t1.a; + +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) WHERE J1_TBL.t = 'one'; + +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one'; + +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.i = 1; + +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one'; + +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1; + +SELECT * FROM J1_TBL a1 JOIN J2_TBL a2 USING (i) AS a1; + +SELECT x.* FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + +SELECT ROW(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + +SELECT row_to_json(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + +SELECT * + FROM J1_TBL NATURAL JOIN J2_TBL; + +SELECT * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); + +SELECT * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); + +SELECT * + FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); + +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); + +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); + +SELECT * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); + +SELECT * + FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t; + +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) + ORDER BY i, k, t; + +SELECT * + FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); + +SELECT * + FROM J1_TBL RIGHT JOIN J2_TBL USING (i); + +SELECT * + FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t; + +SELECT * + FROM J1_TBL FULL JOIN J2_TBL USING (i) + ORDER BY i, k, t; + +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1); + +SELECT * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1); + +select * from tenk1 a, tenk1 b +where exists(select * from tenk1 c + where b.twothousand = c.twothousand and b.fivethous <> c.fivethous) + and a.tenthous = b.tenthous and a.tenthous < 5000; + +CREATE TABLE t1 (name TEXT, n INTEGER); + +CREATE TABLE t2 (name TEXT, n INTEGER); + +CREATE TABLE t3 (name TEXT, n INTEGER); + +INSERT INTO t1 VALUES ( 'bb', 11 ); + +INSERT INTO t2 VALUES ( 'bb', 12 ); + +INSERT INTO t2 VALUES ( 'cc', 22 ); + +INSERT INTO t2 VALUES ( 'ee', 42 ); + +INSERT INTO t3 VALUES ( 'bb', 13 ); + +INSERT INTO t3 VALUES ( 'cc', 23 ); + +INSERT INTO t3 VALUES ( 'dd', 33 ); + +SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); + +SELECT * FROM +(SELECT * FROM t2) as s2 +INNER JOIN +(SELECT * FROM t3) s3 +USING (name); + +SELECT * FROM +(SELECT * FROM t2) as s2 +LEFT JOIN +(SELECT * FROM t3) s3 +USING (name); + +SELECT * FROM +(SELECT * FROM t2) as s2 +FULL JOIN +(SELECT * FROM t3) s3 +USING (name); + +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL LEFT JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL FULL JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL INNER JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL FULL JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL FULL JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + +SELECT * FROM +(SELECT name, n as s1_n FROM t1) as s1 +NATURAL FULL JOIN + (SELECT * FROM + (SELECT name, n as s2_n FROM t2) as s2 + NATURAL FULL JOIN + (SELECT name, n as s3_n FROM t3) as s3 + ) ss2; + +SELECT * FROM +(SELECT name, n as s1_n FROM t1) as s1 +NATURAL FULL JOIN + (SELECT * FROM + (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 + NATURAL FULL JOIN + (SELECT name, n as s3_n FROM t3) as s3 + ) ss2; + +SELECT * FROM + (SELECT name, n as s1_n FROM t1) as s1 +FULL JOIN + (SELECT name, 2 as s2_n FROM t2) as s2 +ON (s1_n = s2_n); + +create temp table x (x1 int, x2 int); + +insert into x values (1,11); + +insert into x values (2,22); + +insert into x values (3,null); + +insert into x values (4,44); + +insert into x values (5,null); + +create temp table y (y1 int, y2 int); + +insert into y values (1,111); + +insert into y values (2,222); + +insert into y values (3,333); + +insert into y values (4,null); + +select * from x; + +select * from y; + +select * from x left join y on (x1 = y1 and x2 is not null); + +select * from x left join y on (x1 = y1 and y2 is not null); + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1); + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and x2 is not null); + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and y2 is not null); + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and xx2 is not null); + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (x2 is not null); + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (y2 is not null); + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (xx2 is not null); + +select count(*) from tenk1 a where unique1 in + (select unique1 from tenk1 b join tenk1 c using (unique1) + where b.unique2 = 42); + +select count(*) from tenk1 x where + x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and + x.unique1 = 0 and + x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); + +begin; + +set geqo = on; + +set geqo_threshold = 2; + +select count(*) from tenk1 x where + x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and + x.unique1 = 0 and + x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); + +rollback; + +select aa, bb, unique1, unique1 + from tenk1 right join b_star on aa = unique1 + where bb < bb and bb is null; + +select aa, bb, unique1, unique1 + from tenk1 right join b_star on aa = unique1 + where bb < bb and bb is null; + +select * from int8_tbl i1 left join (int8_tbl i2 join + (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 +order by 1, 2; + +select * from int8_tbl i1 left join (int8_tbl i2 join + (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 +order by 1, 2; + +select count(*) +from + (select t3.tenthous as x1, coalesce(t1.stringu1, t2.stringu1) as x2 + from tenk1 t1 + left join tenk1 t2 on t1.unique1 = t2.unique1 + join tenk1 t3 on t1.unique2 = t3.unique2) ss, + tenk1 t4, + tenk1 t5 +where t4.thousand = t5.unique1 and ss.x1 = t4.tenthous and ss.x2 = t5.stringu1; + +select a.f1, b.f1, t.thousand, t.tenthous from + tenk1 t, + (select sum(f1)+1 as f1 from int4_tbl i4a) a, + (select sum(f1) as f1 from int4_tbl i4b) b +where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; + +select a.f1, b.f1, t.thousand, t.tenthous from + tenk1 t, + (select sum(f1)+1 as f1 from int4_tbl i4a) a, + (select sum(f1) as f1 from int4_tbl i4b) b +where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; + +select t1.unique1,t2.unique1 from tenk1 t1 +inner join tenk1 t2 on t1.two = t2.two + and t1.unique1 = (select min(unique1) from tenk1 + where t2.unique1=unique1) +where t1.unique1 < 10 and t2.unique1 < 10 +order by t1.unique1; + +select t1.unique1,t2.unique1 from tenk1 t1 +inner join tenk1 t2 on t1.two = t2.two + and t1.unique1 = (select min(unique1) from tenk1 + where t2.unique1=unique1) +where t1.unique1 < 10 and t2.unique1 < 10 +order by t1.unique1; + +select t1.f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on t3.f1 > 0 + left join int4_tbl t4 on t3.f1 > 1 +where t4.f1 is null; + +select t1.f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on t3.f1 > 0 + left join int4_tbl t4 on t3.f1 > 1 +where t4.f1 is null; + +select * +from int4_tbl t1 left join int4_tbl t2 on true + left join int4_tbl t3 on t2.f1 > 0 + left join int4_tbl t4 on t3.f1 > 0; + +select * from onek t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join onek t3 on t2.unique1 != t3.unique1 + left join onek t4 on t3.unique1 = t4.unique1; + +select * from int4_tbl t1 + left join (select now() from int4_tbl t2 + left join int4_tbl t3 on t2.f1 = t3.f1 + left join int4_tbl t4 on t3.f1 = t4.f1) s on true + inner join int4_tbl t5 on true; + +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on true + left join int4_tbl t4 on t2.f1 = t3.f1; + +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on t2.f1 = t3.f1 + left join int4_tbl t4 on t3.f1 != t4.f1; + +select * from int4_tbl t1 + left join (int4_tbl t2 left join int4_tbl t3 on t2.f1 > 0) on t2.f1 > 1 + left join int4_tbl t4 on t2.f1 > 2 and t3.f1 > 3 +where t1.f1 = coalesce(t2.f1, 1); + +select * from int4_tbl t1 + left join ((select t2.f1 from int4_tbl t2 + left join int4_tbl t3 on t2.f1 > 0 + where t3.f1 is null) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = t1.f1; + +select * from int4_tbl t1 + left join ((select t2.f1 from int4_tbl t2 + left join int4_tbl t3 on t2.f1 > 0 + where t2.f1 <> coalesce(t3.f1, -1)) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = t1.f1; + +select * from onek t1 + left join onek t2 on t1.unique1 = t2.unique1 + left join onek t3 on t2.unique1 = t3.unique1 + left join onek t4 on t3.unique1 = t4.unique1 and t2.unique2 = t4.unique2; + +select * from int8_tbl t1 left join + (int8_tbl t2 left join int8_tbl t3 full join int8_tbl t4 on false on false) + left join int8_tbl t5 on t2.q1 = t5.q1 +on t2.q2 = 123; + +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from int8_tbl t3 where t3.q1 = t2.q1 offset 0) s + on t2.q1 = 1; + +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from generate_series(t2.q1, 100)) s + on t2.q1 = 1; + +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select t2.q1 from int8_tbl t3) s + on t2.q1 = 1; + +select * from onek t1 + left join onek t2 on true + left join lateral + (select * from onek t3 where t3.two = t2.two offset 0) s + on t2.unique1 = 1; + +select * from + j1_tbl full join + (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl + on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; + +select * from + j1_tbl full join + (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl + on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; + +select count(*) from + (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x + left join + (select * from tenk1 y order by y.unique2) y + on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; + +select count(*) from + (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x + left join + (select * from tenk1 y order by y.unique2) y + on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; + +set enable_hashjoin = 0; + +set enable_nestloop = 0; + +set enable_hashagg = 0; + +select x.thousand, x.twothousand, count(*) +from tenk1 x inner join tenk1 y on x.thousand = y.thousand +group by x.thousand, x.twothousand +order by x.thousand desc, x.twothousand; + +reset enable_hashagg; + +reset enable_nestloop; + +reset enable_hashjoin; + +DROP TABLE t1; + +DROP TABLE t2; + +DROP TABLE t3; + +DROP TABLE J1_TBL; + +DROP TABLE J2_TBL; + +CREATE TEMP TABLE t1 (a int, b int); + +CREATE TEMP TABLE t2 (a int, b int); + +CREATE TEMP TABLE t3 (x int, y int); + +INSERT INTO t1 VALUES (5, 10); + +INSERT INTO t1 VALUES (15, 20); + +INSERT INTO t1 VALUES (100, 100); + +INSERT INTO t1 VALUES (200, 1000); + +INSERT INTO t2 VALUES (200, 2000); + +INSERT INTO t3 VALUES (5, 20); + +INSERT INTO t3 VALUES (6, 7); + +INSERT INTO t3 VALUES (7, 8); + +INSERT INTO t3 VALUES (500, 100); + +DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; + +SELECT * FROM t3; + +DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a; + +SELECT * FROM t3; + +DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; + +SELECT * FROM t3; + +create temp table t2a () inherits (t2); + +insert into t2a values (200, 2001); + +select * from t1 left join t2 on (t1.a = t2.a); + +select t1.x from t1 join t3 on (t1.a = t3.x); + +select t1.*, t2.*, unnamed_join.* from + t1 join t2 on (t1.a = t2.a), t3 as unnamed_join + for update of unnamed_join; + +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of unnamed_join; + +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of foo; + +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of foo; + +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of bar; + +CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ); + +INSERT INTO tt1 VALUES (1, 11); + +INSERT INTO tt1 VALUES (2, NULL); + +CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ); + +INSERT INTO tt2 VALUES (21, 11); + +INSERT INTO tt2 VALUES (22, 11); + +set enable_hashjoin to off; + +set enable_nestloop to off; + +select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; + +select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; + +reset enable_hashjoin; + +reset enable_nestloop; + +create temp table tbl_ra(a int unique, b int); + +insert into tbl_ra select i, i%100 from generate_series(1,1000)i; + +create index on tbl_ra (b); + +analyze tbl_ra; + +set enable_hashjoin to off; + +set enable_nestloop to off; + +select * from tbl_ra t1 +where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; + +select * from tbl_ra t1 +where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; + +reset enable_hashjoin; + +reset enable_nestloop; + +create temp table tbl_rs(a int, b int); + +insert into tbl_rs select i, i from generate_series(1,10)i; + +analyze tbl_rs; + +select * from tbl_rs t1 join + lateral (select * from tbl_rs t2 where t2.a in + (select t1.a+t3.a from tbl_rs t3) and t2.a < 5) + on true; + +select * from tbl_rs t1 join + lateral (select * from tbl_rs t2 where t2.a in + (select t1.a+t3.a from tbl_rs t3) and t2.a < 5) + on true; + +set work_mem to '64kB'; + +set enable_mergejoin to off; + +set enable_memoize to off; + +select count(*) from tenk1 a, tenk1 b + where a.hundred = b.thousand and (b.fivethous % 10) < 10; + +select count(*) from tenk1 a, tenk1 b + where a.hundred = b.thousand and (b.fivethous % 10) < 10; + +reset work_mem; + +reset enable_mergejoin; + +reset enable_memoize; + +create temp table tt3(f1 int, f2 text); + +insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; + +analyze tt3; + +create temp table tt4(f1 int); + +insert into tt4 values (0),(1),(9999); + +analyze tt4; + +set enable_nestloop to off; + +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE COALESCE(c.f1, 0) = 0 +) AS d ON (a.f1 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; + +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE COALESCE(c.f1, 0) = 0 +) AS d ON (a.f1 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; + +reset enable_nestloop; + +select a.* from tenk1 a +where unique1 in (select unique2 from tenk1 b); + +select a.* from tenk1 a +where unique1 not in (select unique2 from tenk1 b); + +select a.* from tenk1 a +where exists (select 1 from tenk1 b where a.unique1 = b.unique2); + +select a.* from tenk1 a +where not exists (select 1 from tenk1 b where a.unique1 = b.unique2); + +select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2 +where b.unique2 is null; + +set enable_memoize to off; + +select 1 from tenk1 +where (hundred, thousand) in (select twothousand, twothousand from onek); + +reset enable_memoize; + +select a.* from tenk1 a +where exists (select 1 from tenk1 b where a.unique1 = b.unique2 group by b.unique1); + +create temp table tt4x(c1 int, c2 int, c3 int); + +select * from tt4x t1 +where not exists ( + select 1 from tt4x t2 + left join tt4x t3 on t2.c3 = t3.c1 + left join ( select t5.c1 as c1 + from tt4x t4 left join tt4x t5 on t4.c2 = t5.c1 + ) a1 on t3.c2 = a1.c1 + where t1.c1 = t2.c2 +); + +create temp table tt5(f1 int, f2 int); + +create temp table tt6(f1 int, f2 int); + +insert into tt5 values(1, 10); + +insert into tt5 values(1, 11); + +insert into tt6 values(1, 9); + +insert into tt6 values(1, 2); + +insert into tt6 values(2, 9); + +select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; + +create temp table xx (pkxx int); + +create temp table yy (pkyy int, pkxx int); + +insert into xx values (1); + +insert into xx values (2); + +insert into xx values (3); + +insert into yy values (101, 1); + +insert into yy values (201, 2); + +insert into yy values (301, NULL); + +select yy.pkyy as yy_pkyy, yy.pkxx as yy_pkxx, yya.pkyy as yya_pkyy, + xxa.pkxx as xxa_pkxx, xxb.pkxx as xxb_pkxx +from yy + left join (SELECT * FROM yy where pkyy = 101) as yya ON yy.pkyy = yya.pkyy + left join xx xxa on yya.pkxx = xxa.pkxx + left join xx xxb on coalesce (xxa.pkxx, 1) = xxb.pkxx; + +create temp table zt1 (f1 int primary key); + +create temp table zt2 (f2 int primary key); + +create temp table zt3 (f3 int primary key); + +insert into zt1 values(53); + +insert into zt2 values(53); + +select * from + zt2 left join zt3 on (f2 = f3) + left join zt1 on (f3 = f1) +where f2 = 53; + +create temp view zv1 as select *,'dummy'::text AS junk from zt1; + +select * from + zt2 left join zt3 on (f2 = f3) + left join zv1 on (f3 = f1) +where f2 = 53; + +select a.unique2, a.ten, b.tenthous, b.unique2, b.hundred +from tenk1 a left join tenk1 b on a.unique2 = b.tenthous +where a.unique1 = 42 and + ((b.unique2 is null and a.ten = 2) or b.hundred = 3); + +prepare foo(bool) as + select count(*) from tenk1 a left join tenk1 b + on (a.unique2 = b.unique1 and exists + (select 1 from tenk1 c where c.thousand = b.unique2 and $1)); + +execute foo(true); + +execute foo(false); + +begin; + +set enable_mergejoin = 1; + +set enable_hashjoin = 0; + +set enable_nestloop = 0; + +create temp table a (i integer); + +create temp table b (x integer, y integer); + +select * from a left join b on i = x and i = y and x = i; + +rollback; + +begin; + +create type mycomptype as (id int, v bigint); + +create temp table tidv (idv mycomptype); + +create index on tidv (idv); + +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; + +set enable_mergejoin = 0; + +set enable_hashjoin = 0; + +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; + +rollback; + +select t1.q2, count(t2.*) +from int8_tbl t1 left join int8_tbl t2 on (t1.q2 = t2.q1) +group by t1.q2 order by 1; + +select t1.q2, count(t2.*) +from int8_tbl t1 left join (select * from int8_tbl) t2 on (t1.q2 = t2.q1) +group by t1.q2 order by 1; + +select t1.q2, count(t2.*) +from int8_tbl t1 left join (select * from int8_tbl offset 0) t2 on (t1.q2 = t2.q1) +group by t1.q2 order by 1; + +select t1.q2, count(t2.*) +from int8_tbl t1 left join + (select q1, case when q2=1 then 1 else q2 end as q2 from int8_tbl) t2 + on (t1.q2 = t2.q1) +group by t1.q2 order by 1; + +begin; + +create temp table a ( + code char not null, + constraint a_pk primary key (code) +); + +create temp table b ( + a char not null, + num integer not null, + constraint b_pk primary key (a, num) +); + +create temp table c ( + name char not null, + a char, + constraint c_pk primary key (name) +); + +insert into a (code) values ('p'); + +insert into a (code) values ('q'); + +insert into b (a, num) values ('p', 1); + +insert into b (a, num) values ('p', 2); + +insert into c (name, a) values ('A', 'p'); + +insert into c (name, a) values ('B', 'q'); + +insert into c (name, a) values ('C', null); + +select c.name, ss.code, ss.b_cnt, ss.const +from c left join + (select a.code, coalesce(b_grp.cnt, 0) as b_cnt, -1 as const + from a left join + (select count(1) as cnt, b.a from b group by b.a) as b_grp + on a.code = b_grp.a + ) as ss + on (c.a = ss.code) +order by c.name; + +rollback; + +SELECT * FROM +( SELECT 1 as key1 ) sub1 +LEFT JOIN +( SELECT sub3.key3, sub4.value2, COALESCE(sub4.value2, 66) as value3 FROM + ( SELECT 1 as key3 ) sub3 + LEFT JOIN + ( SELECT sub5.key5, COALESCE(sub6.value1, 1) as value2 FROM + ( SELECT 1 as key5 ) sub5 + LEFT JOIN + ( SELECT 2 as key6, 42 as value1 ) sub6 + ON sub5.key5 = sub6.key6 + ) sub4 + ON sub4.key5 = sub3.key3 +) sub2 +ON sub1.key1 = sub2.key3; + +SELECT * FROM +( SELECT 1 as key1 ) sub1 +LEFT JOIN +( SELECT sub3.key3, value2, COALESCE(value2, 66) as value3 FROM + ( SELECT 1 as key3 ) sub3 + LEFT JOIN + ( SELECT sub5.key5, COALESCE(sub6.value1, 1) as value2 FROM + ( SELECT 1 as key5 ) sub5 + LEFT JOIN + ( SELECT 2 as key6, 42 as value1 ) sub6 + ON sub5.key5 = sub6.key6 + ) sub4 + ON sub4.key5 = sub3.key3 +) sub2 +ON sub1.key1 = sub2.key3; + +SELECT qq, unique1 + FROM + ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 + FULL OUTER JOIN + ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 + USING (qq) + INNER JOIN tenk1 c ON qq = unique2; + +SELECT qq, unique1 + FROM + ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 + FULL OUTER JOIN + ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 + USING (qq) + INNER JOIN tenk1 c ON qq = unique2; + +create temp table nt1 ( + id int primary key, + a1 boolean, + a2 boolean +); + +create temp table nt2 ( + id int primary key, + nt1_id int, + b1 boolean, + b2 boolean, + foreign key (nt1_id) references nt1(id) +); + +create temp table nt3 ( + id int primary key, + nt2_id int, + c1 boolean, + foreign key (nt2_id) references nt2(id) +); + +insert into nt1 values (1,true,true); + +insert into nt1 values (2,true,false); + +insert into nt1 values (3,false,false); + +insert into nt2 values (1,1,true,true); + +insert into nt2 values (2,2,true,false); + +insert into nt2 values (3,3,false,false); + +insert into nt3 values (1,1,true); + +insert into nt3 values (2,2,false); + +insert into nt3 values (3,3,true); + +select nt3.id +from nt3 as nt3 + left join + (select nt2.*, (nt2.b1 and ss1.a3) AS b3 + from nt2 as nt2 + left join + (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 + on ss1.id = nt2.nt1_id + ) as ss2 + on ss2.id = nt3.nt2_id +where nt3.id = 1 and ss2.b3; + +select nt3.id +from nt3 as nt3 + left join + (select nt2.*, (nt2.b1 and ss1.a3) AS b3 + from nt2 as nt2 + left join + (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 + on ss1.id = nt2.nt1_id + ) as ss2 + on ss2.id = nt3.nt2_id +where nt3.id = 1 and ss2.b3; + +select * from + int8_tbl t1 left join + (select q1 as x, 42 as y from int8_tbl t2) ss + on t1.q2 = ss.x +where + 1 = (select 1 from int8_tbl t3 where ss.y is not null limit 1) +order by 1,2; + +select * from + int8_tbl t1 left join + (select q1 as x, 42 as y from int8_tbl t2) ss + on t1.q2 = ss.x +where + 1 = (select 1 from int8_tbl t3 where ss.y is not null limit 1) +order by 1,2; + +select * from + int4_tbl as i41, + lateral + (select 1 as x from + (select i41.f1 as lat, + i42.f1 as loc from + int8_tbl as i81, int4_tbl as i42) as ss1 + right join int4_tbl as i43 on (i43.f1 > 1) + where ss1.loc = ss1.lat) as ss2 +where i41.f1 > 0; + +select * from + int4_tbl as i41, + lateral + (select 1 as x from + (select i41.f1 as lat, + i42.f1 as loc from + int8_tbl as i81, int4_tbl as i42) as ss1 + right join int4_tbl as i43 on (i43.f1 > 1) + where ss1.loc = ss1.lat) as ss2 +where i41.f1 > 0; + +select * from int4_tbl a full join int4_tbl b on true; + +select * from int4_tbl a full join int4_tbl b on false; + +create temp table q1 as select 1 as q1; + +create temp table q2 as select 0 as q2; + +analyze q1; + +analyze q2; + +select * from + tenk1 join int4_tbl on f1 = twothousand, + q1, q2 +where q1 = thousand or q2 = thousand; + +select * from + tenk1 join int4_tbl on f1 = twothousand, + q1, q2 +where thousand = (q1 + q2); + +select * from + tenk1, int8_tbl a, int8_tbl b +where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2; + +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (select 1,0 from onerow) v1(x1,x2) + left join (select 3,1 from onerow) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (select 1,0 from onerow) v1(x1,x2) + left join (select 3,1 from onerow) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + +select ss1.d1 from + tenk1 as t1 + inner join tenk1 as t2 + on t1.tenthous = t2.ten + inner join + int8_tbl as i8 + left join int4_tbl as i4 + inner join (select 64::information_schema.cardinal_number as d1 + from tenk1 t3, + lateral (select abs(t3.unique1) + random()) ss0(x) + where t3.fivethous < 0) as ss1 + on i4.f1 = ss1.d1 + on i8.q1 = i4.f1 + on t1.tenthous = ss1.d1 +where t1.unique1 < i4.f1; + +select ss1.d1 from + tenk1 as t1 + inner join tenk1 as t2 + on t1.tenthous = t2.ten + inner join + int8_tbl as i8 + left join int4_tbl as i4 + inner join (select 64::information_schema.cardinal_number as d1 + from tenk1 t3, + lateral (select abs(t3.unique1) + random()) ss0(x) + where t3.fivethous < 0) as ss1 + on i4.f1 = ss1.d1 + on i8.q1 = i4.f1 + on t1.tenthous = ss1.d1 +where t1.unique1 < i4.f1; + +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (values(1,0)) v1(x1,x2) + left join (values(3,1)) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (values(1,0)) v1(x1,x2) + left join (values(3,1)) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + +select * from + (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), + lateral (select ss2.y as z limit 1) ss3; + +select * from + (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), + lateral (select ss2.y as z limit 1) ss3; + +begin; + +set local from_collapse_limit to 2; + +select * from int8_tbl t1 + left join + (select coalesce(t2.q1 + x, 0) from int8_tbl t2, + lateral (select t3.q1 as x from int8_tbl t3, + lateral (select t2.q1, t3.q1 offset 0) s)) + on true; + +rollback; + +begin; + +create temp table t(i int primary key); + +select * from t t1 + left join (select 1 as x, * from t t2(i2)) t2ss on t1.i = t2ss.i2 + left join t t3(i3) on false + left join t t4(i4) on t4.i4 > t2ss.x; + +select * from + (select k from + (select i, coalesce(i, j) as k from + (select i from t union all select 0) + join (select 1 as j limit 1) on i = j) + right join (select 2 as x) on true + join (select 3 as y) on i is not null + ), + lateral (select k as kl limit 1); + +rollback; + +select * +from int8_tbl i8 + inner join + (select (select true) as x + from int4_tbl i4, lateral (select i4.f1 as y limit 1) ss1 + where i4.f1 = 0) ss2 on true + right join (select false as z) ss3 on true, + lateral (select i8.q2 as q2l where x limit 1) ss4 +where i8.q2 = 123; + +select * +from int8_tbl i8 + inner join + (select (select true) as x + from int4_tbl i4, lateral (select 1 as y limit 1) ss1 + where i4.f1 = 0) ss2 on true + right join (select false as z) ss3 on true, + lateral (select i8.q2 as q2l where x limit 1) ss4 +where i8.q2 = 123; + +select * from + (select 0 as z) as t1 + left join + (select true as a) as t2 + on true, + lateral (select true as b + union all + select a as b) as t3 +where b; + +select * from + (select 0 as z) as t1 + left join + (select true as a) as t2 + on true, + lateral (select true as b + union all + select a as b) as t3 +where b; diff --git a/crates/pgt_pretty_print/tests/data/multi/join_hash_60.sql b/crates/pgt_pretty_print/tests/data/multi/join_hash_60.sql new file mode 100644 index 000000000..2123ea74f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/join_hash_60.sql @@ -0,0 +1,731 @@ +begin; + +set local min_parallel_table_scan_size = 0; + +set local parallel_setup_cost = 0; + +set local enable_hashjoin = on; + +create or replace function find_hash(node json) +returns json language plpgsql +as +$$ +declare + x json; + child json; +begin + if node->>'Node Type' = 'Hash' then + return node; + else + for child in select json_array_elements(node->'Plans') + loop + x := find_hash(child); + if x is not null then + return x; + end if; + end loop; + return null; + end if; +end; +$$; + +create or replace function hash_join_batches(query text) +returns table (original int, final int) language plpgsql +as +$$ +declare + whole_plan json; + hash_node json; +begin + for whole_plan in + execute 'explain (analyze, format ''json'') ' || query + loop + hash_node := find_hash(json_extract_path(whole_plan, '0', 'Plan')); + original := hash_node->>'Original Hash Batches'; + final := hash_node->>'Hash Batches'; + return next; + end loop; +end; +$$; + +create table simple as + select generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; + +alter table simple set (parallel_workers = 2); + +analyze simple; + +create table bigger_than_it_looks as + select generate_series(1, 20000) as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; + +alter table bigger_than_it_looks set (autovacuum_enabled = 'false'); + +alter table bigger_than_it_looks set (parallel_workers = 2); + +analyze bigger_than_it_looks; + +update pg_class set reltuples = 1000 where relname = 'bigger_than_it_looks'; + +create table extremely_skewed (id int, t text); + +alter table extremely_skewed set (autovacuum_enabled = 'false'); + +alter table extremely_skewed set (parallel_workers = 2); + +analyze extremely_skewed; + +insert into extremely_skewed + select 42 as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + from generate_series(1, 20000); + +update pg_class + set reltuples = 2, relpages = pg_relation_size('extremely_skewed') / 8192 + where relname = 'extremely_skewed'; + +create table wide as select generate_series(1, 2) as id, rpad('', 320000, 'x') as t; + +alter table wide set (parallel_workers = 2); + +savepoint settings; + +set local max_parallel_workers_per_gather = 0; + +set local work_mem = '4MB'; + +set local hash_mem_multiplier = 1.0; + +select count(*) from simple r join simple s using (id); + +select count(*) from simple r join simple s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +set local work_mem = '4MB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = off; + +select count(*) from simple r join simple s using (id); + +select count(*) from simple r join simple s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +set local work_mem = '4MB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = on; + +select count(*) from simple r join simple s using (id); + +select count(*) from simple r join simple s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 0; + +set local work_mem = '128kB'; + +set local hash_mem_multiplier = 1.0; + +select count(*) from simple r join simple s using (id); + +select count(*) from simple r join simple s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +set local work_mem = '128kB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = off; + +select count(*) from simple r join simple s using (id); + +select count(*) from simple r join simple s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +set local work_mem = '192kB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = on; + +select count(*) from simple r join simple s using (id); + +select count(*) from simple r join simple s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + +select count(*) from simple r full outer join simple s using (id); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 0; + +set local work_mem = '128kB'; + +set local hash_mem_multiplier = 1.0; + +select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); + +select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +set local work_mem = '128kB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = off; + +select count(*) from simple r join bigger_than_it_looks s using (id); + +select count(*) from simple r join bigger_than_it_looks s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 1; + +set local work_mem = '192kB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = on; + +select count(*) from simple r join bigger_than_it_looks s using (id); + +select count(*) from simple r join bigger_than_it_looks s using (id); + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 0; + +set local work_mem = '128kB'; + +set local hash_mem_multiplier = 1.0; + +select count(*) from simple r join extremely_skewed s using (id); + +select count(*) from simple r join extremely_skewed s using (id); + +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +set local work_mem = '128kB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = off; + +select count(*) from simple r join extremely_skewed s using (id); + +select count(*) from simple r join extremely_skewed s using (id); + +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 1; + +set local work_mem = '128kB'; + +set local hash_mem_multiplier = 1.0; + +set local enable_parallel_hash = on; + +select count(*) from simple r join extremely_skewed s using (id); + +select count(*) from simple r join extremely_skewed s using (id); + +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +set local work_mem = '4MB'; + +set local hash_mem_multiplier = 1.0; + +set local parallel_leader_participation = off; + +select * from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + +rollback to settings; + +create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t; + +alter table join_foo set (parallel_workers = 0); + +create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t; + +alter table join_bar set (parallel_workers = 2); + +savepoint settings; + +set enable_parallel_hash = off; + +set parallel_leader_participation = off; + +set min_parallel_table_scan_size = 0; + +set parallel_setup_cost = 0; + +set parallel_tuple_cost = 0; + +set max_parallel_workers_per_gather = 2; + +set enable_material = off; + +set enable_mergejoin = off; + +set work_mem = '64kB'; + +set hash_mem_multiplier = 1.0; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + +rollback to settings; + +savepoint settings; + +set enable_parallel_hash = off; + +set parallel_leader_participation = off; + +set min_parallel_table_scan_size = 0; + +set parallel_setup_cost = 0; + +set parallel_tuple_cost = 0; + +set max_parallel_workers_per_gather = 2; + +set enable_material = off; + +set enable_mergejoin = off; + +set work_mem = '4MB'; + +set hash_mem_multiplier = 1.0; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + +rollback to settings; + +savepoint settings; + +set enable_parallel_hash = on; + +set parallel_leader_participation = off; + +set min_parallel_table_scan_size = 0; + +set parallel_setup_cost = 0; + +set parallel_tuple_cost = 0; + +set max_parallel_workers_per_gather = 2; + +set enable_material = off; + +set enable_mergejoin = off; + +set work_mem = '64kB'; + +set hash_mem_multiplier = 1.0; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + +rollback to settings; + +savepoint settings; + +set enable_parallel_hash = on; + +set parallel_leader_participation = off; + +set min_parallel_table_scan_size = 0; + +set parallel_setup_cost = 0; + +set parallel_tuple_cost = 0; + +set max_parallel_workers_per_gather = 2; + +set enable_material = off; + +set enable_mergejoin = off; + +set work_mem = '4MB'; + +set hash_mem_multiplier = 1.0; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 0; + +select count(*) from simple r full outer join simple s using (id); + +select count(*) from simple r full outer join simple s using (id); + +rollback to settings; + +savepoint settings; + +set enable_parallel_hash = off; + +set local max_parallel_workers_per_gather = 2; + +select count(*) from simple r full outer join simple s using (id); + +select count(*) from simple r full outer join simple s using (id); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +select count(*) from simple r full outer join simple s using (id); + +select count(*) from simple r full outer join simple s using (id); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 0; + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + +rollback to settings; + +savepoint settings; + +set enable_parallel_hash = off; + +set local max_parallel_workers_per_gather = 2; + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + +rollback to settings; + +savepoint settings; + +set local max_parallel_workers_per_gather = 2; + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + +rollback to settings; + +savepoint settings; + +set max_parallel_workers_per_gather = 2; + +set enable_parallel_hash = on; + +set work_mem = '128kB'; + +set hash_mem_multiplier = 1.0; + +select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); + +select length(max(s.t)) +from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); + +select final > 1 as multibatch + from hash_join_batches( +$$ + select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); +$$); + +rollback to settings; + +SAVEPOINT settings; + +SET enable_parallel_hash = on; + +SET min_parallel_table_scan_size = 0; + +SET parallel_setup_cost = 0; + +SET parallel_tuple_cost = 0; + +CREATE TABLE hjtest_matchbits_t1(id int); + +CREATE TABLE hjtest_matchbits_t2(id int); + +INSERT INTO hjtest_matchbits_t1 VALUES (1); + +INSERT INTO hjtest_matchbits_t2 VALUES (2); + +UPDATE hjtest_matchbits_t2 set id = 2; + +SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id + ORDER BY t1.id; + +RESET parallel_setup_cost; + +SET enable_parallel_hash = off; + +SELECT * FROM hjtest_matchbits_t1 t1 FULL JOIN hjtest_matchbits_t2 t2 ON t1.id = t2.id; + +ROLLBACK TO settings; + +rollback; + +BEGIN; + +SET LOCAL enable_sort = OFF; + +SET LOCAL from_collapse_limit = 1; + +CREATE TABLE hjtest_1 (a text, b int, id int, c bool); + +CREATE TABLE hjtest_2 (a bool, id int, b text, c int); + +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 2, 1, false); + +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 2, false); + +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 20, 1, false); + +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 1, false); + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 2); + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 3, 'another', 7); + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 90); + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 3); + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'text', 1); + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_1, hjtest_2 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_1, hjtest_2 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_2, hjtest_1 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_2, hjtest_1 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +ROLLBACK; + +begin; + +set local enable_hashjoin = on; + +select i8.q2, ss.* from +int8_tbl i8, +lateral (select t1.fivethous, i4.f1 from tenk1 t1 join int4_tbl i4 + on t1.fivethous = i4.f1+i8.q2 order by 1,2) ss; + +select i8.q2, ss.* from +int8_tbl i8, +lateral (select t1.fivethous, i4.f1 from tenk1 t1 join int4_tbl i4 + on t1.fivethous = i4.f1+i8.q2 order by 1,2) ss; + +rollback; diff --git a/crates/pgt_pretty_print/tests/data/multi/json_60.sql b/crates/pgt_pretty_print/tests/data/multi/json_60.sql new file mode 100644 index 000000000..b7164b367 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/json_60.sql @@ -0,0 +1,1087 @@ +SELECT '""'::json; + +SELECT $$''$$::json; + +SELECT '"abc"'::json; + +SELECT '"abc'::json; + +SELECT '"abc +def"'::json; + +SELECT '"\n\"\\"'::json; + +SELECT '"\v"'::json; + +SELECT ('"'||repeat('.', 12)||'abc"')::json; + +SELECT ('"'||repeat('.', 12)||'abc\n"')::json; + +SELECT row_to_json(j)::jsonb FROM ( + SELECT left(E'abcdefghijklmnopqrstuv"\twxyz012345678', a) AS a + FROM generate_series(0,37) a +) j; + +SELECT '1'::json; + +SELECT '0'::json; + +SELECT '01'::json; + +SELECT '0.1'::json; + +SELECT '9223372036854775808'::json; + +SELECT '1e100'::json; + +SELECT '1.3e100'::json; + +SELECT '1f2'::json; + +SELECT '0.x1'::json; + +SELECT '1.3ex100'::json; + +SELECT '[]'::json; + +SELECT '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'::json; + +SELECT '[1,2]'::json; + +SELECT '[1,2,]'::json; + +SELECT '[1,2'::json; + +SELECT '[1,[2]'::json; + +SELECT '{}'::json; + +SELECT '{"abc"}'::json; + +SELECT '{"abc":1}'::json; + +SELECT '{1:"abc"}'::json; + +SELECT '{"abc",1}'::json; + +SELECT '{"abc"=1}'::json; + +SELECT '{"abc"::1}'::json; + +SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::json; + +SELECT '{"abc":1:2}'::json; + +SELECT '{"abc":1,3}'::json; + +SET max_stack_depth = '100kB'; + +SELECT repeat('[', 10000)::json; + +SELECT repeat('{"a":', 10000)::json; + +RESET max_stack_depth; + +SELECT 'true'::json; + +SELECT 'false'::json; + +SELECT 'null'::json; + +SELECT ' true '::json; + +SELECT 'true false'::json; + +SELECT 'true, false'::json; + +SELECT 'truf'::json; + +SELECT 'trues'::json; + +SELECT ''::json; + +SELECT ' '::json; + +SELECT '{ + "one": 1, + "two":"two", + "three": + true}'::json; + +SELECT '{ + "one": 1, + "two":,"two", -- ERROR extraneous comma before field "two" + "three": + true}'::json; + +SELECT '{ + "one": 1, + "two":"two", + "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::json; + +select pg_input_is_valid('{"a":true}', 'json'); + +select pg_input_is_valid('{"a":true', 'json'); + +select * from pg_input_error_info('{"a":true', 'json'); + +SELECT array_to_json(array(select 1 as a)); + +SELECT array_to_json(array_agg(q),false) from (select x as b, x * 2 as c from generate_series(1,3) x) q; + +SELECT array_to_json(array_agg(q),true) from (select x as b, x * 2 as c from generate_series(1,3) x) q; + +SELECT array_to_json(array_agg(q),false) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q; + +SELECT array_to_json(array_agg(x),false) from generate_series(5,10) x; + +SELECT array_to_json('{{1,5},{99,100}}'::int[]); + +SELECT row_to_json(row(1,'foo')); + +SELECT row_to_json(q) +FROM (SELECT $$a$$ || x AS b, + y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q; + +SELECT row_to_json(q,true) +FROM (SELECT $$a$$ || x AS b, + y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q; + +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x; + +SELECT row_to_json(q,true) +FROM rows q; + +SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),false); + +analyze rows; + +select attname, to_json(histogram_bounds) histogram_bounds +from pg_stats +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1; + +select to_json(timestamp '2014-05-28 12:22:35.614298'); + +BEGIN; + +SET LOCAL TIME ZONE 10.5; + +select to_json(timestamptz '2014-05-28 12:22:35.614298-04'); + +SET LOCAL TIME ZONE -8; + +select to_json(timestamptz '2014-05-28 12:22:35.614298-04'); + +COMMIT; + +select to_json(date '2014-05-28'); + +select to_json(date 'Infinity'); + +select to_json(date '-Infinity'); + +select to_json(timestamp 'Infinity'); + +select to_json(timestamp '-Infinity'); + +select to_json(timestamptz 'Infinity'); + +select to_json(timestamptz '-Infinity'); + +SELECT json_agg(q) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q; + +SELECT json_agg(q ORDER BY x, y) + FROM rows q; + +UPDATE rows SET x = NULL WHERE x = 1; + +SELECT json_agg(q ORDER BY x NULLS FIRST, y) + FROM rows q; + +SELECT row_to_json(q) +FROM (SELECT 'NaN'::float8 AS "float8field") q; + +SELECT row_to_json(q) +FROM (SELECT 'Infinity'::float8 AS "float8field") q; + +SELECT row_to_json(q) +FROM (SELECT '-Infinity'::float8 AS "float8field") q; + +SELECT row_to_json(q) +FROM (SELECT '{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::json AS "jsonfield") q; + +CREATE TEMP TABLE test_json ( + json_type text, + test_json json +); + +INSERT INTO test_json VALUES +('scalar','"a scalar"'), +('array','["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}]'), +('object','{"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}}'); + +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'scalar'; + +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'array'; + +SELECT test_json -> 'x' +FROM test_json +WHERE json_type = 'object'; + +SELECT test_json->'field2' +FROM test_json +WHERE json_type = 'object'; + +SELECT test_json->>'field2' +FROM test_json +WHERE json_type = 'object'; + +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'scalar'; + +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'array'; + +SELECT test_json -> -1 +FROM test_json +WHERE json_type = 'array'; + +SELECT test_json -> 2 +FROM test_json +WHERE json_type = 'object'; + +SELECT test_json->>2 +FROM test_json +WHERE json_type = 'array'; + +SELECT test_json ->> 6 FROM test_json WHERE json_type = 'array'; + +SELECT test_json ->> 7 FROM test_json WHERE json_type = 'array'; + +SELECT test_json ->> 'field4' FROM test_json WHERE json_type = 'object'; + +SELECT test_json ->> 'field5' FROM test_json WHERE json_type = 'object'; + +SELECT test_json ->> 'field6' FROM test_json WHERE json_type = 'object'; + +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'scalar'; + +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'array'; + +SELECT json_object_keys(test_json) +FROM test_json +WHERE json_type = 'object'; + +select count(*) from + (select json_object_keys(json_object(array_agg(g))) + from (select unnest(array['f'||n,n::text])as g + from generate_series(1,300) as n) x ) y; + +select (test_json->'field3') is null as expect_false +from test_json +where json_type = 'object'; + +select (test_json->>'field3') is null as expect_true +from test_json +where json_type = 'object'; + +select (test_json->3) is null as expect_false +from test_json +where json_type = 'array'; + +select (test_json->>3) is null as expect_true +from test_json +where json_type = 'array'; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::text; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::int; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 1; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> -1; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 'z'; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> ''; + +select '[{"b": "c"}, {"b": "cc"}]'::json -> 1; + +select '[{"b": "c"}, {"b": "cc"}]'::json -> 3; + +select '[{"b": "c"}, {"b": "cc"}]'::json -> 'z'; + +select '{"a": "c", "b": null}'::json -> 'b'; + +select '"foo"'::json -> 1; + +select '"foo"'::json -> 'z'; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::text; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::int; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 1; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 'z'; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> ''; + +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 1; + +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 3; + +select '[{"b": "c"}, {"b": "cc"}]'::json ->> 'z'; + +select '{"a": "c", "b": null}'::json ->> 'b'; + +select '"foo"'::json ->> 1; + +select '"foo"'::json ->> 'z'; + +SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]'); + +SELECT json_array_length('[]'); + +SELECT json_array_length('{"f1":1,"f2":[5,6]}'); + +SELECT json_array_length('4'); + +select json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null}'); + +select * from json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q; + +select json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}'); + +select * from json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q; + +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6'); + +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2'); + +select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text); + +select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text); + +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6'); + +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2'); + +select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text); + +select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text); + +select json_extract_path('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_false; + +select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_true; + +select json_extract_path('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_false; + +select json_extract_path_text('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_true; + +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f4','f6']; + +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2']; + +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','0']; + +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','1']; + +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f4','f6']; + +select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2']; + +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','0']; + +select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','1']; + +select '{"a": {"b":{"c": "foo"}}}'::json #> '{}'; + +select '[1,2,3]'::json #> '{}'; + +select '"foo"'::json #> '{}'; + +select '42'::json #> '{}'; + +select 'null'::json #> '{}'; + +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a']; + +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', null]; + +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', '']; + +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b']; + +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c']; + +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c','d']; + +select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','z','c']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','1','b']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','z','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::json #> array['1','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::json #> array['z','b']; + +select '[{"b": "c"}, {"b": null}]'::json #> array['1','b']; + +select '"foo"'::json #> array['z']; + +select '42'::json #> array['f2']; + +select '42'::json #> array['0']; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> '{}'; + +select '[1,2,3]'::json #>> '{}'; + +select '"foo"'::json #>> '{}'; + +select '42'::json #>> '{}'; + +select 'null'::json #>> '{}'; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a']; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', null]; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', '']; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b']; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c']; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c','d']; + +select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','z','c']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','1','b']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','z','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['1','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['z','b']; + +select '[{"b": "c"}, {"b": null}]'::json #>> array['1','b']; + +select '"foo"'::json #>> array['z']; + +select '42'::json #>> array['f2']; + +select '42'::json #>> array['0']; + +select json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]'); + +select * from json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q; + +select json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]'); + +select * from json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q; + +create type jpop as (a text, b int, c timestamp); + +CREATE DOMAIN js_int_not_null AS int NOT NULL; + +CREATE DOMAIN js_int_array_1d AS int[] CHECK(array_length(VALUE, 1) = 3); + +CREATE DOMAIN js_int_array_2d AS int[][] CHECK(array_length(VALUE, 2) = 3); + +create type j_unordered_pair as (x int, y int); + +create domain j_ordered_pair as j_unordered_pair check((value).x <= (value).y); + +CREATE TYPE jsrec AS ( + i int, + ia _int4, + ia1 int[], + ia2 int[][], + ia3 int[][][], + ia1d js_int_array_1d, + ia2d js_int_array_2d, + t text, + ta text[], + c char(10), + ca char(10)[], + ts timestamp, + js json, + jsb jsonb, + jsa json[], + rec jpop, + reca jpop[] +); + +CREATE TYPE jsrec_i_not_null AS ( + i js_int_not_null +); + +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q; + +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q; + +select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q; + +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q; + +select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}') q; + +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}') q; + +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}') q; + +select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{}') q; + +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"x": 43.2}') q; + +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"i": null}') q; + +SELECT i FROM json_populate_record(NULL::jsrec_i_not_null, '{"i": 12345}') q; + +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": null}') q; + +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": 123}') q; + +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [1, "2", null, 4]}') q; + +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1, 2], [3, 4]]}') q; + +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], 2]}') q; + +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], [2, 3]]}') q; + +SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": "{1,2,3}"}') q; + +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": null}') q; + +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": 123}') q; + +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": [1, "2", null, 4]}') q; + +SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": [[1, 2, 3]]}') q; + +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": null}') q; + +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": 123}') q; + +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": [1, "2", null, 4]}') q; + +SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": [1, "2", null]}') q; + +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [1, "2", null, 4]}') q; + +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], [null, 4]]}') q; + +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[], []]}') q; + +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], [3]]}') q; + +SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], 3, 4]}') q; + +SELECT ia2d FROM json_populate_record(NULL::jsrec, '{"ia2d": [[1, "2"], [null, 4]]}') q; + +SELECT ia2d FROM json_populate_record(NULL::jsrec, '{"ia2d": [[1, "2", 3], [null, 5, 6]]}') q; + +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [1, "2", null, 4]}') q; + +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [[1, 2], [null, 4]]}') q; + +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[], []], [[], []], [[], []] ]}') q; + +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2]], [[3, 4]] ]}') q; + +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]}') q; + +SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q; + +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": null}') q; + +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": 123}') q; + +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [1, "2", null, 4]}') q; + +SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q; + +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": null}') q; + +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaa"}') q; + +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaaaaaaaaa"}') q; + +SELECT c FROM json_populate_record(NULL::jsrec, '{"c": "aaaaaaaaaaaaa"}') q; + +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": null}') q; + +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": 123}') q; + +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [1, "2", null, 4]}') q; + +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q; + +SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q; + +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": null}') q; + +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": true}') q; + +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": 123.45}') q; + +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": "123.45"}') q; + +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": "abc"}') q; + +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": [123, "123", null, {"key": "value"}]}') q; + +SELECT js FROM json_populate_record(NULL::jsrec, '{"js": {"a": "bbb", "b": null, "c": 123.45}}') q; + +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": null}') q; + +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": true}') q; + +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": 123.45}') q; + +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": "123.45"}') q; + +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": "abc"}') q; + +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": [123, "123", null, {"key": "value"}]}') q; + +SELECT jsb FROM json_populate_record(NULL::jsrec, '{"jsb": {"a": "bbb", "b": null, "c": 123.45}}') q; + +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": null}') q; + +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": 123}') q; + +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": [1, "2", null, 4]}') q; + +SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": ["aaa", null, [1, 2, "3", {}], { "k" : "v" }]}') q; + +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": 123}') q; + +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": [1, 2]}') q; + +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}') q; + +SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": "(abc,42,01.02.2003)"}') q; + +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": 123}') q; + +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": [1, 2]}') q; + +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}]}') q; + +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": ["(abc,42,01.02.2003)"]}') q; + +SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": "{\"(abc,42,01.02.2003)\"}"}') q; + +SELECT rec FROM json_populate_record( + row(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + row('x',3,'2012-12-31 15:30:56')::jpop,NULL)::jsrec, + '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}' +) q; + +SELECT json_populate_record(null::record, '{"x": 0, "y": 1}'); + +SELECT json_populate_record(row(1,2), '{"f1": 0, "f2": 1}'); + +SELECT * FROM + json_populate_record(null::record, '{"x": 776}') AS (x int, y int); + +SELECT json_populate_record(null::j_ordered_pair, '{"x": 0, "y": 1}'); + +SELECT json_populate_record(row(1,2)::j_ordered_pair, '{"x": 0}'); + +SELECT json_populate_record(row(1,2)::j_ordered_pair, '{"x": 1, "y": 0}'); + +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; + +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; + +create type jpop2 as (a int, b json, c int, d int); + +select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]') q; + +select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT json_populate_recordset(null::record, '[{"x": 0, "y": 1}]'); + +SELECT json_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]'); + +SELECT i, json_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i); + +SELECT * FROM + json_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int); + +SELECT json_populate_recordset(null::record, '[]'); + +SELECT json_populate_recordset(row(1,2), '[]'); + +SELECT * FROM json_populate_recordset(NULL::jpop,'[]') q; + +SELECT * FROM + json_populate_recordset(null::record, '[]') AS (x int, y int); + +SELECT json_populate_recordset(null::j_ordered_pair, '[{"x": 0, "y": 1}]'); + +SELECT json_populate_recordset(row(1,2)::j_ordered_pair, '[{"x": 0}, {"y": 3}]'); + +SELECT json_populate_recordset(row(1,2)::j_ordered_pair, '[{"x": 1, "y": 0}]'); + +select * from json_populate_recordset(row(0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text); + +select * from json_populate_recordset(row(0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text); + +select * from json_populate_recordset(row(0::int,0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text); + +select * from json_populate_recordset(row(1000000000::int,50::int),'[{"b":"2"},{"a":"3"}]') q (a text, b text); + +CREATE TEMP TABLE jspoptest (js json); + +INSERT INTO jspoptest +SELECT '{ + "jsa": [1, "2", null, 4], + "rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}, + "reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}] +}'::json +FROM generate_series(1, 3); + +SELECT (json_populate_record(NULL::jsrec, js)).* FROM jspoptest; + +DROP TYPE jsrec; + +DROP TYPE jsrec_i_not_null; + +DROP DOMAIN js_int_not_null; + +DROP DOMAIN js_int_array_1d; + +DROP DOMAIN js_int_array_2d; + +DROP DOMAIN j_ordered_pair; + +DROP TYPE j_unordered_pair; + +select value, json_typeof(value) + from (values (json '123.4'), + (json '-1'), + (json '"foo"'), + (json 'true'), + (json 'false'), + (json 'null'), + (json '[1, 2, 3]'), + (json '[]'), + (json '{"x":"foo", "y":123}'), + (json '{}'), + (NULL::json)) + as data(value); + +SELECT json_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}'); + +SELECT json_build_array('a', NULL); + +SELECT json_build_array(VARIADIC NULL::text[]); + +SELECT json_build_array(VARIADIC '{}'::text[]); + +SELECT json_build_array(VARIADIC '{a,b,c}'::text[]); + +SELECT json_build_array(VARIADIC ARRAY['a', NULL]::text[]); + +SELECT json_build_array(VARIADIC '{1,2,3,4}'::text[]); + +SELECT json_build_array(VARIADIC '{1,2,3,4}'::int[]); + +SELECT json_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); + +SELECT json_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}'); + +SELECT json_build_object( + 'a', json_build_object('b',false,'c',99), + 'd', json_build_object('e',array[9,8,7]::int[], + 'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r))); + +SELECT json_build_object('{a,b,c}'::text[]); + +SELECT json_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]); + +SELECT json_build_object('a', 'b', 'c'); + +SELECT json_build_object(NULL, 'a'); + +SELECT json_build_object('a', NULL); + +SELECT json_build_object(VARIADIC NULL::text[]); + +SELECT json_build_object(VARIADIC '{}'::text[]); + +SELECT json_build_object(VARIADIC '{a,b,c}'::text[]); + +SELECT json_build_object(VARIADIC ARRAY['a', NULL]::text[]); + +SELECT json_build_object(VARIADIC ARRAY[NULL, 'a']::text[]); + +SELECT json_build_object(VARIADIC '{1,2,3,4}'::text[]); + +SELECT json_build_object(VARIADIC '{1,2,3,4}'::int[]); + +SELECT json_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); + +SELECT json_build_array(); + +SELECT json_build_object(); + +SELECT json_build_object(1,2); + +SELECT json_build_object(null,2); + +SELECT json_build_object(r,2) FROM (SELECT 1 AS a, 2 AS b) r; + +SELECT json_build_object(json '{"a":1,"b":2}', 3); + +SELECT json_build_object('{1,2,3}'::int[], 3); + +CREATE TEMP TABLE foo (serial_num int, name text, type text); + +INSERT INTO foo VALUES (847001,'t15','GE1043'); + +INSERT INTO foo VALUES (847002,'t16','GE1043'); + +INSERT INTO foo VALUES (847003,'sub-alpha','GESS90'); + +SELECT json_build_object('turbines',json_object_agg(serial_num,json_build_object('name',name,'type',type))) +FROM foo; + +SELECT json_object_agg(name, type) FROM foo; + +INSERT INTO foo VALUES (999999, NULL, 'bar'); + +SELECT json_object_agg(name, type) FROM foo; + +SELECT json_object('{}'); + +SELECT json_object('{}', '{}'); + +SELECT json_object('{a,1,b,2,3,NULL,"d e f","a b c"}'); + +SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}'); + +SELECT json_object('{a,b,c}'); + +SELECT json_object('{{a},{b}}'); + +SELECT json_object('{{a,b,c},{b,c,d}}'); + +SELECT json_object('{{{a,b},{c,d}},{{b,c},{d,e}}}'); + +select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c"}'); + +SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}', '{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}'); + +select json_object('{a,b,c,"d e f",g}','{1,2,3,"a b c"}'); + +select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c",g}'); + +select json_object('{a,b,NULL,"d e f"}','{1,2,3,"a b c"}'); + +select json_object('{a,b,"","d e f"}','{1,2,3,"a b c"}'); + +select json_object_agg_unique(mod(i,100), i) from generate_series(0, 199) i; + +select * from json_to_record('{"a":1,"b":"foo","c":"bar"}') + as x(a int, b text, d text); + +select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') + as x(a int, b text, c boolean); + +select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]') + as x(a int, b json, c boolean); + +select *, c is null as c_is_null +from json_to_record('{"a":1, "b":{"c":16, "d":2}, "x":8, "ca": ["1 2", 3], "ia": [[1,2],[3,4]], "r": {"a": "aaa", "b": 123}}'::json) + as t(a int, b json, c text, x int, ca char(5)[], ia int[][], r jpop); + +select *, c is null as c_is_null +from json_to_recordset('[{"a":1, "b":{"c":16, "d":2}, "x":8}]'::json) + as t(a int, b json, c text, x int); + +select * from json_to_record('{"ia": null}') as x(ia _int4); + +select * from json_to_record('{"ia": 123}') as x(ia _int4); + +select * from json_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4); + +select * from json_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4); + +select * from json_to_record('{"ia": [[1], 2]}') as x(ia _int4); + +select * from json_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4); + +select * from json_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); + +select * from json_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]); + +select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); + +select * from json_to_record('{"out": {"key": 1}}') as x(out json); + +select * from json_to_record('{"out": [{"key": 1}]}') as x(out json); + +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out json); + +select * from json_to_record('{"out": {"key": 1}}') as x(out jsonb); + +select * from json_to_record('{"out": [{"key": 1}]}') as x(out jsonb); + +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + +select json_strip_nulls(null); + +select json_strip_nulls('1'); + +select json_strip_nulls('"a string"'); + +select json_strip_nulls('null'); + +select json_strip_nulls('[1,2,null,3,4]'); + +select json_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}'); + +select json_strip_nulls('[1,{"a":1,"b":null,"c":2},3]'); + +select json_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }'); + +select json_strip_nulls(null, true); + +select json_strip_nulls('1', true); + +select json_strip_nulls('"a string"', true); + +select json_strip_nulls('null', true); + +select json_strip_nulls('[1,2,null,3,4]', true); + +select json_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}', true); + +select json_strip_nulls('[1,{"a":1,"b":null,"c":2},3]', true); + +select json_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }', true); + +select to_tsvector('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::json); + +select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::json); + +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::json); + +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::json); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"all"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"key"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"string"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"numeric"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]'); + +select to_tsvector('""'::json); + +select to_tsvector('{}'::json); + +select to_tsvector('[]'::json); + +select to_tsvector('null'::json); + +select json_to_tsvector('""'::json, '"all"'); + +select json_to_tsvector('{}'::json, '"all"'); + +select json_to_tsvector('[]'::json, '"all"'); + +select json_to_tsvector('null'::json, '"all"'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '""'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '{}'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '[]'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, 'null'); + +select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["all", null]'); + +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh')); + +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh')); + +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >'); + +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >'); + +select ts_headline('null'::json, tsquery('aaa & bbb')); + +select ts_headline('{}'::json, tsquery('aaa & bbb')); + +select ts_headline('[]'::json, tsquery('aaa & bbb')); diff --git a/crates/pgt_pretty_print/tests/data/multi/json_encoding_60.sql b/crates/pgt_pretty_print/tests/data/multi/json_encoding_60.sql new file mode 100644 index 000000000..2fdf2f225 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/json_encoding_60.sql @@ -0,0 +1,88 @@ +SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') + AS skip_test ; + +SELECT getdatabaseencoding(); + +SELECT '"\u"'::json; + +SELECT '"\u00"'::json; + +SELECT '"\u000g"'::json; + +SELECT '"\u0000"'::json; + +SELECT '"\uaBcD"'::json; + +select json '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8; + +select json '{ "a": "\ud83d\ud83d" }' -> 'a'; + +select json '{ "a": "\ude04\ud83d" }' -> 'a'; + +select json '{ "a": "\ud83dX" }' -> 'a'; + +select json '{ "a": "\ude04X" }' -> 'a'; + +select json '{ "a": "the Copyright \u00a9 sign" }' as correct_in_utf8; + +select json '{ "a": "dollar \u0024 character" }' as correct_everywhere; + +select json '{ "a": "dollar \\u0024 character" }' as not_an_escape; + +select json '{ "a": "null \u0000 escape" }' as not_unescaped; + +select json '{ "a": "null \\u0000 escape" }' as not_an_escape; + +select json '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8; + +select json '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere; + +select json '{ "a": "dollar \\u0024 character" }' ->> 'a' as not_an_escape; + +select json '{ "a": "null \u0000 escape" }' ->> 'a' as fails; + +select json '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape; + +SELECT '"\u"'::jsonb; + +SELECT '"\u00"'::jsonb; + +SELECT '"\u000g"'::jsonb; + +SELECT '"\u0045"'::jsonb; + +SELECT '"\u0000"'::jsonb; + +SELECT octet_length('"\uaBcD"'::jsonb::text); + +SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8; + +SELECT jsonb '{ "a": "\ud83d\ud83d" }' -> 'a'; + +SELECT jsonb '{ "a": "\ude04\ud83d" }' -> 'a'; + +SELECT jsonb '{ "a": "\ud83dX" }' -> 'a'; + +SELECT jsonb '{ "a": "\ude04X" }' -> 'a'; + +SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' as correct_in_utf8; + +SELECT jsonb '{ "a": "dollar \u0024 character" }' as correct_everywhere; + +SELECT jsonb '{ "a": "dollar \\u0024 character" }' as not_an_escape; + +SELECT jsonb '{ "a": "null \u0000 escape" }' as fails; + +SELECT jsonb '{ "a": "null \\u0000 escape" }' as not_an_escape; + +SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8; + +SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere; + +SELECT jsonb '{ "a": "dollar \\u0024 character" }' ->> 'a' as not_an_escape; + +SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' as fails; + +SELECT jsonb '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape; + +select * from pg_input_error_info('{ "a": "\ud83d\ude04\ud83d\udc36" }', 'jsonb'); diff --git a/crates/pgt_pretty_print/tests/data/multi/jsonb_60.sql b/crates/pgt_pretty_print/tests/data/multi/jsonb_60.sql new file mode 100644 index 000000000..edf4bd8af --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/jsonb_60.sql @@ -0,0 +1,2256 @@ +CREATE TABLE testjsonb ( + j jsonb +); + +COPY testjsonb FROM 'filename'; + +SELECT '""'::jsonb; + +SELECT $$''$$::jsonb; + +SELECT '"abc"'::jsonb; + +SELECT '"abc'::jsonb; + +SELECT '"abc +def"'::jsonb; + +SELECT '"\n\"\\"'::jsonb; + +SELECT '"\v"'::jsonb; + +SELECT '1'::jsonb; + +SELECT '0'::jsonb; + +SELECT '01'::jsonb; + +SELECT '0.1'::jsonb; + +SELECT '9223372036854775808'::jsonb; + +SELECT '1e100'::jsonb; + +SELECT '1.3e100'::jsonb; + +SELECT '1f2'::jsonb; + +SELECT '0.x1'::jsonb; + +SELECT '1.3ex100'::jsonb; + +SELECT '[]'::jsonb; + +SELECT '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'::jsonb; + +SELECT '[1,2]'::jsonb; + +SELECT '[1,2,]'::jsonb; + +SELECT '[1,2'::jsonb; + +SELECT '[1,[2]'::jsonb; + +SELECT '{}'::jsonb; + +SELECT '{"abc"}'::jsonb; + +SELECT '{"abc":1}'::jsonb; + +SELECT '{1:"abc"}'::jsonb; + +SELECT '{"abc",1}'::jsonb; + +SELECT '{"abc"=1}'::jsonb; + +SELECT '{"abc"::1}'::jsonb; + +SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::jsonb; + +SELECT '{"abc":1:2}'::jsonb; + +SELECT '{"abc":1,3}'::jsonb; + +SET max_stack_depth = '100kB'; + +SELECT repeat('[', 10000)::jsonb; + +SELECT repeat('{"a":', 10000)::jsonb; + +RESET max_stack_depth; + +SELECT 'true'::jsonb; + +SELECT 'false'::jsonb; + +SELECT 'null'::jsonb; + +SELECT ' true '::jsonb; + +SELECT 'true false'::jsonb; + +SELECT 'true, false'::jsonb; + +SELECT 'truf'::jsonb; + +SELECT 'trues'::jsonb; + +SELECT ''::jsonb; + +SELECT ' '::jsonb; + +SELECT '{ + "one": 1, + "two":"two", + "three": + true}'::jsonb; + +SELECT '{ + "one": 1, + "two":,"two", -- ERROR extraneous comma before field "two" + "three": + true}'::jsonb; + +SELECT '{ + "one": 1, + "two":"two", + "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::jsonb; + +select pg_input_is_valid('{"a":true}', 'jsonb'); + +select pg_input_is_valid('{"a":true', 'jsonb'); + +select * from pg_input_error_info('{"a":true', 'jsonb'); + +select * from pg_input_error_info('{"a":1e1000000}', 'jsonb'); + +SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']); + +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x; + +analyze rows; + +select attname, to_jsonb(histogram_bounds) histogram_bounds +from pg_stats +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1; + +select to_jsonb(timestamp '2014-05-28 12:22:35.614298'); + +BEGIN; + +SET LOCAL TIME ZONE 10.5; + +select to_jsonb(timestamptz '2014-05-28 12:22:35.614298-04'); + +SET LOCAL TIME ZONE -8; + +select to_jsonb(timestamptz '2014-05-28 12:22:35.614298-04'); + +COMMIT; + +select to_jsonb(date '2014-05-28'); + +select to_jsonb(date 'Infinity'); + +select to_jsonb(date '-Infinity'); + +select to_jsonb(timestamp 'Infinity'); + +select to_jsonb(timestamp '-Infinity'); + +select to_jsonb(timestamptz 'Infinity'); + +select to_jsonb(timestamptz '-Infinity'); + +SELECT jsonb_agg(q) + FROM ( SELECT $$a$$ || x AS b, y AS c, + ARRAY[ROW(x.*,ARRAY[1,2,3]), + ROW(y.*,ARRAY[4,5,6])] AS z + FROM generate_series(1,2) x, + generate_series(4,5) y) q; + +SELECT jsonb_agg(q ORDER BY x, y) + FROM rows q; + +UPDATE rows SET x = NULL WHERE x = 1; + +SELECT jsonb_agg(q ORDER BY x NULLS FIRST, y) + FROM rows q; + +CREATE TEMP TABLE test_jsonb ( + json_type text, + test_json jsonb +); + +INSERT INTO test_jsonb VALUES +('scalar','"a scalar"'), +('array','["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}]'), +('object','{"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}}'); + +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'scalar'; + +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'array'; + +SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'object'; + +SELECT test_json -> 'field2' FROM test_jsonb WHERE json_type = 'object'; + +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'scalar'; + +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'array'; + +SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object'; + +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'scalar'; + +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'array'; + +SELECT test_json -> 9 FROM test_jsonb WHERE json_type = 'array'; + +SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'object'; + +SELECT test_json ->> 6 FROM test_jsonb WHERE json_type = 'array'; + +SELECT test_json ->> 7 FROM test_jsonb WHERE json_type = 'array'; + +SELECT test_json ->> 'field4' FROM test_jsonb WHERE json_type = 'object'; + +SELECT test_json ->> 'field5' FROM test_jsonb WHERE json_type = 'object'; + +SELECT test_json ->> 'field6' FROM test_jsonb WHERE json_type = 'object'; + +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'scalar'; + +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'array'; + +SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'object'; + +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'scalar'; + +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'array'; + +SELECT jsonb_object_keys(test_json) FROM test_jsonb WHERE json_type = 'object'; + +SELECT (test_json->'field3') IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'object'; + +SELECT (test_json->>'field3') IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'object'; + +SELECT (test_json->3) IS NULL AS expect_false FROM test_jsonb WHERE json_type = 'array'; + +SELECT (test_json->>3) IS NULL AS expect_true FROM test_jsonb WHERE json_type = 'array'; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> null::text; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> null::int; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> 1; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> 'z'; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb -> ''; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 1; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 3; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb -> 'z'; + +select '{"a": "c", "b": null}'::jsonb -> 'b'; + +select '"foo"'::jsonb -> 1; + +select '"foo"'::jsonb -> 'z'; + +select '[]'::jsonb -> -2147483648; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> null::text; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> null::int; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> 1; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> 'z'; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb ->> ''; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 1; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 3; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb ->> 'z'; + +select '{"a": "c", "b": null}'::jsonb ->> 'b'; + +select '"foo"'::jsonb ->> 1; + +select '"foo"'::jsonb ->> 'z'; + +select '[]'::jsonb ->> -2147483648; + +SELECT '{"x":"y"}'::jsonb = '{"x":"y"}'::jsonb; + +SELECT '{"x":"y"}'::jsonb = '{"x":"z"}'::jsonb; + +SELECT '{"x":"y"}'::jsonb <> '{"x":"y"}'::jsonb; + +SELECT '{"x":"y"}'::jsonb <> '{"x":"z"}'::jsonb; + +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}'); + +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "c":null}'); + +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "g":null}'); + +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"g":null}'); + +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"c"}'); + +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b"}'); + +SELECT jsonb_contains('{"a":"b", "b":1, "c":null}', '{"a":"b", "c":"q"}'); + +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b"}'; + +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "c":null}'; + +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "g":null}'; + +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"g":null}'; + +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"c"}'; + +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b"}'; + +SELECT '{"a":"b", "b":1, "c":null}'::jsonb @> '{"a":"b", "c":"q"}'; + +SELECT '[1,2]'::jsonb @> '[1,2,2]'::jsonb; + +SELECT '[1,1,2]'::jsonb @> '[1,2,2]'::jsonb; + +SELECT '[[1,2]]'::jsonb @> '[[1,2,2]]'::jsonb; + +SELECT '[1,2,2]'::jsonb <@ '[1,2]'::jsonb; + +SELECT '[1,2,2]'::jsonb <@ '[1,1,2]'::jsonb; + +SELECT '[[1,2,2]]'::jsonb <@ '[[1,2]]'::jsonb; + +SELECT jsonb_contained('{"a":"b"}', '{"a":"b", "b":1, "c":null}'); + +SELECT jsonb_contained('{"a":"b", "c":null}', '{"a":"b", "b":1, "c":null}'); + +SELECT jsonb_contained('{"a":"b", "g":null}', '{"a":"b", "b":1, "c":null}'); + +SELECT jsonb_contained('{"g":null}', '{"a":"b", "b":1, "c":null}'); + +SELECT jsonb_contained('{"a":"c"}', '{"a":"b", "b":1, "c":null}'); + +SELECT jsonb_contained('{"a":"b"}', '{"a":"b", "b":1, "c":null}'); + +SELECT jsonb_contained('{"a":"b", "c":"q"}', '{"a":"b", "b":1, "c":null}'); + +SELECT '{"a":"b"}'::jsonb <@ '{"a":"b", "b":1, "c":null}'; + +SELECT '{"a":"b", "c":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}'; + +SELECT '{"a":"b", "g":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}'; + +SELECT '{"g":null}'::jsonb <@ '{"a":"b", "b":1, "c":null}'; + +SELECT '{"a":"c"}'::jsonb <@ '{"a":"b", "b":1, "c":null}'; + +SELECT '{"a":"b"}'::jsonb <@ '{"a":"b", "b":1, "c":null}'; + +SELECT '{"a":"b", "c":"q"}'::jsonb <@ '{"a":"b", "b":1, "c":null}'; + +SELECT '[5]'::jsonb @> '[5]'; + +SELECT '5'::jsonb @> '5'; + +SELECT '[5]'::jsonb @> '5'; + +SELECT '5'::jsonb @> '[5]'; + +SELECT '["9", ["7", "3"], 1]'::jsonb @> '["9", ["7", "3"], 1]'::jsonb; + +SELECT '["9", ["7", "3"], ["1"]]'::jsonb @> '["9", ["7", "3"], ["1"]]'::jsonb; + +SELECT '{ "name": "Bob", "tags": [ "enim", "qui"]}'::jsonb @> '{"tags":["qu"]}'; + +SELECT jsonb_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]'); + +SELECT jsonb_array_length('[]'); + +SELECT jsonb_array_length('{"f1":1,"f2":[5,6]}'); + +SELECT jsonb_array_length('4'); + +SELECT jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null}'); + +SELECT jsonb_each('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q; + +SELECT * FROM jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q; + +SELECT * FROM jsonb_each('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q; + +SELECT jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}'); + +SELECT jsonb_each_text('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q; + +SELECT * FROM jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q; + +SELECT * FROM jsonb_each_text('{"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null}'::jsonb) AS q; + +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'a'); + +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'b'); + +SELECT jsonb_exists('{"a":null, "b":"qq"}', 'c'); + +SELECT jsonb_exists('{"a":"null", "b":"qq"}', 'a'); + +SELECT jsonb '{"a":null, "b":"qq"}' ? 'a'; + +SELECT jsonb '{"a":null, "b":"qq"}' ? 'b'; + +SELECT jsonb '{"a":null, "b":"qq"}' ? 'c'; + +SELECT jsonb '{"a":"null", "b":"qq"}' ? 'a'; + +SELECT count(*) from testjsonb WHERE j->'array' ? 'bar'; + +SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text; + +SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb; + +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['a','b']); + +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['b','a']); + +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['c','a']); + +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', ARRAY['c','d']); + +SELECT jsonb_exists_any('{"a":null, "b":"qq"}', '{}'::text[]); + +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['a','b']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['b','a']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['c','a']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?| ARRAY['c','d']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?| '{}'::text[]; + +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['a','b']); + +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['b','a']); + +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['c','a']); + +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', ARRAY['c','d']); + +SELECT jsonb_exists_all('{"a":null, "b":"qq"}', '{}'::text[]); + +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['a','b']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['b','a']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['c','a']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['c','d']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?& ARRAY['a','a', 'b', 'b', 'b']; + +SELECT jsonb '{"a":null, "b":"qq"}' ?& '{}'::text[]; + +SELECT jsonb_typeof('{}') AS object; + +SELECT jsonb_typeof('{"c":3,"p":"o"}') AS object; + +SELECT jsonb_typeof('[]') AS array; + +SELECT jsonb_typeof('["a", 1]') AS array; + +SELECT jsonb_typeof('null') AS "null"; + +SELECT jsonb_typeof('1') AS number; + +SELECT jsonb_typeof('-1') AS number; + +SELECT jsonb_typeof('1.0') AS number; + +SELECT jsonb_typeof('1e2') AS number; + +SELECT jsonb_typeof('-1.0') AS number; + +SELECT jsonb_typeof('true') AS boolean; + +SELECT jsonb_typeof('false') AS boolean; + +SELECT jsonb_typeof('"hello"') AS string; + +SELECT jsonb_typeof('"true"') AS string; + +SELECT jsonb_typeof('"1.0"') AS string; + +SELECT jsonb_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}'); + +SELECT jsonb_build_array('a', NULL); + +SELECT jsonb_build_array(VARIADIC NULL::text[]); + +SELECT jsonb_build_array(VARIADIC '{}'::text[]); + +SELECT jsonb_build_array(VARIADIC '{a,b,c}'::text[]); + +SELECT jsonb_build_array(VARIADIC ARRAY['a', NULL]::text[]); + +SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::text[]); + +SELECT jsonb_build_array(VARIADIC '{1,2,3,4}'::int[]); + +SELECT jsonb_build_array(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); + +SELECT jsonb_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}'); + +SELECT jsonb_build_object( + 'a', jsonb_build_object('b',false,'c',99), + 'd', jsonb_build_object('e',array[9,8,7]::int[], + 'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r))); + +SELECT jsonb_build_object('{a,b,c}'::text[]); + +SELECT jsonb_build_object('{a,b,c}'::text[], '{d,e,f}'::text[]); + +SELECT jsonb_build_object('a', 'b', 'c'); + +SELECT jsonb_build_object(NULL, 'a'); + +SELECT jsonb_build_object('a', NULL); + +SELECT jsonb_build_object(VARIADIC NULL::text[]); + +SELECT jsonb_build_object(VARIADIC '{}'::text[]); + +SELECT jsonb_build_object(VARIADIC '{a,b,c}'::text[]); + +SELECT jsonb_build_object(VARIADIC ARRAY['a', NULL]::text[]); + +SELECT jsonb_build_object(VARIADIC ARRAY[NULL, 'a']::text[]); + +SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::text[]); + +SELECT jsonb_build_object(VARIADIC '{1,2,3,4}'::int[]); + +SELECT jsonb_build_object(VARIADIC '{{1,4},{2,5},{3,6}}'::int[][]); + +SELECT jsonb_build_array(); + +SELECT jsonb_build_object(); + +SELECT jsonb_build_object(1,2); + +SELECT jsonb_build_object(null,2); + +SELECT jsonb_build_object(r,2) FROM (SELECT 1 AS a, 2 AS b) r; + +SELECT jsonb_build_object(json '{"a":1,"b":2}', 3); + +SELECT jsonb_build_object('{1,2,3}'::int[], 3); + +SELECT jsonb_object_agg(1, NULL::jsonb); + +SELECT jsonb_object_agg(NULL, '{"a":1}'); + +CREATE TEMP TABLE foo (serial_num int, name text, type text); + +INSERT INTO foo VALUES (847001,'t15','GE1043'); + +INSERT INTO foo VALUES (847002,'t16','GE1043'); + +INSERT INTO foo VALUES (847003,'sub-alpha','GESS90'); + +SELECT jsonb_build_object('turbines',jsonb_object_agg(serial_num,jsonb_build_object('name',name,'type',type))) +FROM foo; + +SELECT jsonb_object_agg(name, type) FROM foo; + +INSERT INTO foo VALUES (999999, NULL, 'bar'); + +SELECT jsonb_object_agg(name, type) FROM foo; + +SELECT jsonb_object_agg(DISTINCT 'a', 'abc'); + +SELECT jsonb_object('{}'); + +SELECT jsonb_object('{}', '{}'); + +SELECT jsonb_object('{a,1,b,2,3,NULL,"d e f","a b c"}'); + +SELECT jsonb_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}'); + +SELECT jsonb_object('{a,b,c}'); + +SELECT jsonb_object('{{a},{b}}'); + +SELECT jsonb_object('{{a,b,c},{b,c,d}}'); + +SELECT jsonb_object('{{{a,b},{c,d}},{{b,c},{d,e}}}'); + +select jsonb_object('{a,b,c,"d e f"}','{1,2,3,"a b c"}'); + +SELECT jsonb_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}', '{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}'); + +select jsonb_object('{a,b,c,"d e f",g}','{1,2,3,"a b c"}'); + +select jsonb_object('{a,b,c,"d e f"}','{1,2,3,"a b c",g}'); + +select jsonb_object('{a,b,NULL,"d e f"}','{1,2,3,"a b c"}'); + +select jsonb_object('{a,b,"","d e f"}','{1,2,3,"a b c"}'); + +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6'); + +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2'); + +SELECT jsonb_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text); + +SELECT jsonb_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text); + +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6'); + +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2'); + +SELECT jsonb_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text); + +SELECT jsonb_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text); + +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') IS NULL AS expect_false; + +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') IS NULL AS expect_true; + +SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') IS NULL AS expect_false; + +SELECT jsonb_extract_path_text('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') IS NULL AS expect_true; + +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f4','f6']; + +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2']; + +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2','0']; + +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>array['f2','1']; + +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f4','f6']; + +SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2']; + +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2','0']; + +SELECT '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::jsonb#>>array['f2','1']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> '{}'; + +select '[1,2,3]'::jsonb #> '{}'; + +select '"foo"'::jsonb #> '{}'; + +select '42'::jsonb #> '{}'; + +select 'null'::jsonb #> '{}'; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a', null]; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a', '']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b','c']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','b','c','d']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #> array['a','z','c']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #> array['a','1','b']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #> array['a','z','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #> array['1','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #> array['z','b']; + +select '[{"b": "c"}, {"b": null}]'::jsonb #> array['1','b']; + +select '"foo"'::jsonb #> array['z']; + +select '42'::jsonb #> array['f2']; + +select '42'::jsonb #> array['0']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> '{}'; + +select '[1,2,3]'::jsonb #>> '{}'; + +select '"foo"'::jsonb #>> '{}'; + +select '42'::jsonb #>> '{}'; + +select 'null'::jsonb #>> '{}'; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a', null]; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a', '']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b','c']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','b','c','d']; + +select '{"a": {"b":{"c": "foo"}}}'::jsonb #>> array['a','z','c']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #>> array['a','1','b']; + +select '{"a": [{"b": "c"}, {"b": "cc"}]}'::jsonb #>> array['a','z','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #>> array['1','b']; + +select '[{"b": "c"}, {"b": "cc"}]'::jsonb #>> array['z','b']; + +select '[{"b": "c"}, {"b": null}]'::jsonb #>> array['1','b']; + +select '"foo"'::jsonb #>> array['z']; + +select '42'::jsonb #>> array['f2']; + +select '42'::jsonb #>> array['0']; + +SELECT jsonb_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false]'); + +SELECT * FROM jsonb_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false]') q; + +SELECT jsonb_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]'); + +SELECT * FROM jsonb_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q; + +CREATE TYPE jbpop AS (a text, b int, c timestamp); + +CREATE DOMAIN jsb_int_not_null AS int NOT NULL; + +CREATE DOMAIN jsb_int_array_1d AS int[] CHECK(array_length(VALUE, 1) = 3); + +CREATE DOMAIN jsb_int_array_2d AS int[][] CHECK(array_length(VALUE, 2) = 3); + +create type jb_unordered_pair as (x int, y int); + +create domain jb_ordered_pair as jb_unordered_pair check((value).x <= (value).y); + +CREATE TYPE jsbrec AS ( + i int, + ia _int4, + ia1 int[], + ia2 int[][], + ia3 int[][][], + ia1d jsb_int_array_1d, + ia2d jsb_int_array_2d, + t text, + ta text[], + c char(10), + ca char(10)[], + ts timestamp, + js json, + jsb jsonb, + jsa json[], + rec jbpop, + reca jbpop[] +); + +CREATE TYPE jsbrec_i_not_null AS ( + i jsb_int_not_null +); + +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q; + +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q; + +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":"blurfl","x":43.2}') q; + +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":"blurfl","x":43.2}') q; + +SELECT * FROM jsonb_populate_record(NULL::jbpop,'{"a":[100,200,false],"x":43.2}') q; + +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"a":[100,200,false],"x":43.2}') q; + +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop,'{"c":[100,200,false],"x":43.2}') q; + +SELECT * FROM jsonb_populate_record(row('x',3,'2012-12-31 15:30:56')::jbpop, '{}') q; + +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"x": 43.2}') q; + +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"i": null}') q; + +SELECT i FROM jsonb_populate_record(NULL::jsbrec_i_not_null, '{"i": 12345}') q; + +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": null}') q; + +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": 123}') q; + +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [1, "2", null, 4]}') q; + +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1, 2], [3, 4]]}') q; + +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], 2]}') q; + +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], [2, 3]]}') q; + +SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": "{1,2,3}"}') q; + +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": null}') q; + +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": 123}') q; + +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": [1, "2", null, 4]}') q; + +SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": [[1, 2, 3]]}') q; + +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": null}') q; + +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": 123}') q; + +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": [1, "2", null, 4]}') q; + +SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": [1, "2", null]}') q; + +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [1, "2", null, 4]}') q; + +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], [null, 4]]}') q; + +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[], []]}') q; + +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], [3]]}') q; + +SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], 3, 4]}') q; + +SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{"ia2d": [[1, "2"], [null, 4]]}') q; + +SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{"ia2d": [[1, "2", 3], [null, 5, 6]]}') q; + +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [1, "2", null, 4]}') q; + +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [[1, 2], [null, 4]]}') q; + +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[], []], [[], []], [[], []] ]}') q; + +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2]], [[3, 4]] ]}') q; + +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8]] ]}') q; + +SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q; + +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": null}') q; + +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": 123}') q; + +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [1, "2", null, 4]}') q; + +SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q; + +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": null}') q; + +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaa"}') q; + +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaaaaaaaaa"}') q; + +SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": "aaaaaaaaaaaaa"}') q; + +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": null}') q; + +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": 123}') q; + +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [1, "2", null, 4]}') q; + +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q; + +SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q; + +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": null}') q; + +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": true}') q; + +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": 123.45}') q; + +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": "123.45"}') q; + +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": "abc"}') q; + +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": [123, "123", null, {"key": "value"}]}') q; + +SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": {"a": "bbb", "b": null, "c": 123.45}}') q; + +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": null}') q; + +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": true}') q; + +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": 123.45}') q; + +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": "123.45"}') q; + +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": "abc"}') q; + +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": [123, "123", null, {"key": "value"}]}') q; + +SELECT jsb FROM jsonb_populate_record(NULL::jsbrec, '{"jsb": {"a": "bbb", "b": null, "c": 123.45}}') q; + +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": null}') q; + +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": 123}') q; + +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": [1, "2", null, 4]}') q; + +SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": ["aaa", null, [1, 2, "3", {}], { "k" : "v" }]}') q; + +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": 123}') q; + +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": [1, 2]}') q; + +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}') q; + +SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": "(abc,42,01.02.2003)"}') q; + +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": 123}') q; + +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": [1, 2]}') q; + +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}]}') q; + +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": ["(abc,42,01.02.2003)"]}') q; + +SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": "{\"(abc,42,01.02.2003)\"}"}') q; + +SELECT rec FROM jsonb_populate_record( + row(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + row('x',3,'2012-12-31 15:30:56')::jbpop,NULL)::jsbrec, + '{"rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}}' +) q; + +create type jsb_char2 as (a char(2)); + +select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aaa"}'); + +select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aaa"}') q; + +select jsonb_populate_record_valid(NULL::jsb_char2, '{"a": "aa"}'); + +select * from jsonb_populate_record(NULL::jsb_char2, '{"a": "aa"}') q; + +create type jsb_ia as (a int[]); + +create type jsb_ia2 as (a int[][]); + +select jsonb_populate_record_valid(NULL::jsb_ia, '{"a": 43.2}'); + +select * from jsonb_populate_record(NULL::jsb_ia, '{"a": 43.2}') q; + +select jsonb_populate_record_valid(NULL::jsb_ia, '{"a": [1, 2]}'); + +select * from jsonb_populate_record(NULL::jsb_ia, '{"a": [1, 2]}') q; + +select jsonb_populate_record_valid(NULL::jsb_ia2, '{"a": [[1], [2, 3]]}'); + +select * from jsonb_populate_record(NULL::jsb_ia2, '{"a": [[1], [2, 3]]}') q; + +select jsonb_populate_record_valid(NULL::jsb_ia2, '{"a": [[1, 0], [2, 3]]}'); + +select * from jsonb_populate_record(NULL::jsb_ia2, '{"a": [[1, 0], [2, 3]]}') q; + +create domain jsb_i_not_null as int not null; + +create domain jsb_i_gt_1 as int check (value > 1); + +create type jsb_i_not_null_rec as (a jsb_i_not_null); + +create type jsb_i_gt_1_rec as (a jsb_i_gt_1); + +select jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{"a": null}'); + +select * from jsonb_populate_record(NULL::jsb_i_not_null_rec, '{"a": null}') q; + +select jsonb_populate_record_valid(NULL::jsb_i_not_null_rec, '{"a": 1}'); + +select * from jsonb_populate_record(NULL::jsb_i_not_null_rec, '{"a": 1}') q; + +select jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{"a": 1}'); + +select * from jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{"a": 1}') q; + +select jsonb_populate_record_valid(NULL::jsb_i_gt_1_rec, '{"a": 2}'); + +select * from jsonb_populate_record(NULL::jsb_i_gt_1_rec, '{"a": 2}') q; + +drop type jsb_ia, jsb_ia2, jsb_char2, jsb_i_not_null_rec, jsb_i_gt_1_rec; + +drop domain jsb_i_not_null, jsb_i_gt_1; + +SELECT jsonb_populate_record(null::record, '{"x": 0, "y": 1}'); + +SELECT jsonb_populate_record(row(1,2), '{"f1": 0, "f2": 1}'); + +SELECT * FROM + jsonb_populate_record(null::record, '{"x": 776}') AS (x int, y int); + +SELECT jsonb_populate_record(null::jb_ordered_pair, '{"x": 0, "y": 1}'); + +SELECT jsonb_populate_record(row(1,2)::jb_ordered_pair, '{"x": 0}'); + +SELECT jsonb_populate_record(row(1,2)::jb_ordered_pair, '{"x": 1, "y": 0}'); + +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q; + +SELECT jsonb_populate_recordset(null::record, '[{"x": 0, "y": 1}]'); + +SELECT jsonb_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]'); + +SELECT i, jsonb_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i); + +SELECT * FROM + jsonb_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int); + +SELECT jsonb_populate_recordset(null::record, '[]'); + +SELECT jsonb_populate_recordset(row(1,2), '[]'); + +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[]') q; + +SELECT * FROM + jsonb_populate_recordset(null::record, '[]') AS (x int, y int); + +SELECT jsonb_populate_recordset(null::jb_ordered_pair, '[{"x": 0, "y": 1}]'); + +SELECT jsonb_populate_recordset(row(1,2)::jb_ordered_pair, '[{"x": 0}, {"y": 3}]'); + +SELECT jsonb_populate_recordset(row(1,2)::jb_ordered_pair, '[{"x": 1, "y": 0}]'); + +select * from jsonb_populate_recordset(row(0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text); + +select * from jsonb_populate_recordset(row(0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text); + +select * from jsonb_populate_recordset(row(0::int,0::int,0::int),'[{"a":"1","b":"2"},{"a":"3"}]') q (a text, b text); + +select * from jsonb_populate_recordset(row(1000000000::int,50::int),'[{"b":"2"},{"a":"3"}]') q (a text, b text); + +select * from jsonb_to_record('{"a":1,"b":"foo","c":"bar"}') + as x(a int, b text, d text); + +select * from jsonb_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]') + as x(a int, b text, c boolean); + +select *, c is null as c_is_null +from jsonb_to_record('{"a":1, "b":{"c":16, "d":2}, "x":8, "ca": ["1 2", 3], "ia": [[1,2],[3,4]], "r": {"a": "aaa", "b": 123}}'::jsonb) + as t(a int, b jsonb, c text, x int, ca char(5)[], ia int[][], r jbpop); + +select *, c is null as c_is_null +from jsonb_to_recordset('[{"a":1, "b":{"c":16, "d":2}, "x":8}]'::jsonb) + as t(a int, b jsonb, c text, x int); + +select * from jsonb_to_record('{"ia": null}') as x(ia _int4); + +select * from jsonb_to_record('{"ia": 123}') as x(ia _int4); + +select * from jsonb_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4); + +select * from jsonb_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4); + +select * from jsonb_to_record('{"ia": [[1], 2]}') as x(ia _int4); + +select * from jsonb_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4); + +select * from jsonb_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); + +select * from jsonb_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]); + +select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); + +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out json); + +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out json); + +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out json); + +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out jsonb); + +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out jsonb); + +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + +CREATE TEMP TABLE jsbpoptest (js jsonb); + +INSERT INTO jsbpoptest +SELECT '{ + "jsa": [1, "2", null, 4], + "rec": {"a": "abc", "c": "01.02.2003", "x": 43.2}, + "reca": [{"a": "abc", "b": 456}, null, {"c": "01.02.2003", "x": 43.2}] +}'::jsonb +FROM generate_series(1, 3); + +SELECT (jsonb_populate_record(NULL::jsbrec, js)).* FROM jsbpoptest; + +DROP TYPE jsbrec; + +DROP TYPE jsbrec_i_not_null; + +DROP DOMAIN jsb_int_not_null; + +DROP DOMAIN jsb_int_array_1d; + +DROP DOMAIN jsb_int_array_2d; + +DROP DOMAIN jb_ordered_pair; + +DROP TYPE jb_unordered_pair; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}'; + +SELECT count(*) FROM testjsonb WHERE j ? 'public'; + +SELECT count(*) FROM testjsonb WHERE j ? 'bar'; + +SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled']; + +SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + +CREATE INDEX jidx ON testjsonb USING gin (j); + +SET enable_seqscan = off; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"array":["foo"]}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"array":["bar"]}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{}'; + +SELECT count(*) FROM testjsonb WHERE j ? 'public'; + +SELECT count(*) FROM testjsonb WHERE j ? 'bar'; + +SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled']; + +SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'; + +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")'; + +SELECT count(*) FROM testjsonb WHERE j @? '$'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + +CREATE INDEX jidx_array ON testjsonb USING gin((j->'array')); + +SELECT count(*) from testjsonb WHERE j->'array' ? 'bar'; + +SELECT count(*) from testjsonb WHERE j->'array' ? '5'::text; + +SELECT count(*) from testjsonb WHERE j->'array' @> '5'::jsonb; + +RESET enable_seqscan; + +SELECT count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow; + +SELECT key, count(*) FROM (SELECT (jsonb_each(j)).key FROM testjsonb) AS wow GROUP BY key ORDER BY count DESC, key; + +SELECT count(distinct j) FROM testjsonb; + +SET enable_hashagg = off; + +SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2; + +SET enable_hashagg = on; + +SET enable_sort = off; + +SELECT count(*) FROM (SELECT j FROM (SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb) js GROUP BY j) js2; + +SELECT distinct * FROM (values (jsonb '{}' || ''::text),('{}')) v(j); + +SET enable_sort = on; + +RESET enable_hashagg; + +RESET enable_sort; + +DROP INDEX jidx; + +DROP INDEX jidx_array; + +CREATE INDEX jidx ON testjsonb USING btree (j); + +SET enable_seqscan = off; + +SELECT count(*) FROM testjsonb WHERE j > '{"p":1}'; + +SELECT count(*) FROM testjsonb WHERE j = '{"pos":98, "line":371, "node":"CBA", "indexed":true}'; + +DROP INDEX jidx; + +CREATE INDEX jidx ON testjsonb USING gin (j jsonb_path_ops); + +SET enable_seqscan = off; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC"}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"wait":"CC", "public":true}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}'; + +SELECT count(*) FROM testjsonb WHERE j @> '{}'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'; + +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"'; + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))'; + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")'; + +SELECT count(*) FROM testjsonb WHERE j @? '$'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; + +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + +RESET enable_seqscan; + +DROP INDEX jidx; + +SELECT '{"ff":{"a":12,"b":16}}'::jsonb; + +SELECT '{"ff":{"a":12,"b":16},"qq":123}'::jsonb; + +SELECT '{"aa":["a","aaa"],"qq":{"a":12,"b":16,"c":["c1","c2"],"d":{"d1":"d1","d2":"d2","d1":"d3"}}}'::jsonb; + +SELECT '{"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2"],"d":{"d1":"d1","d2":"d2"}}}'::jsonb; + +SELECT '{"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2",["c3"],{"c4":4}],"d":{"d1":"d1","d2":"d2"}}}'::jsonb; + +SELECT '{"ff":["a","aaa"]}'::jsonb; + +SELECT + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'ff', + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'qq', + ('{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'Y') IS NULL AS f, + ('{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb ->> 'Y') IS NULL AS t, + '{"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null}'::jsonb -> 'x'; + +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[1,2]}'; + +SELECT '{"a":[2,1],"c":"b"}'::jsonb @> '{"a":[1,2]}'; + +SELECT '{"a":{"1":2},"c":"b"}'::jsonb @> '{"a":[1,2]}'; + +SELECT '{"a":{"2":1},"c":"b"}'::jsonb @> '{"a":[1,2]}'; + +SELECT '{"a":{"1":2},"c":"b"}'::jsonb @> '{"a":{"1":2}}'; + +SELECT '{"a":{"2":1},"c":"b"}'::jsonb @> '{"a":{"1":2}}'; + +SELECT '["a","b"]'::jsonb @> '["a","b","c","b"]'; + +SELECT '["a","b","c","b"]'::jsonb @> '["a","b"]'; + +SELECT '["a","b","c",[1,2]]'::jsonb @> '["a",[1,2]]'; + +SELECT '["a","b","c",[1,2]]'::jsonb @> '["b",[1,2]]'; + +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[1]}'; + +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[2]}'; + +SELECT '{"a":[1,2],"c":"b"}'::jsonb @> '{"a":[3]}'; + +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"c":3}]}'; + +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4}]}'; + +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},3]}'; + +SELECT '{"a":[1,2,{"c":3,"x":4}],"c":"b"}'::jsonb @> '{"a":[{"x":4},1]}'; + +create temp table nestjsonb (j jsonb); + +insert into nestjsonb (j) values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}'); + +insert into nestjsonb (j) values ('[[14,2,3]]'); + +insert into nestjsonb (j) values ('[1,[14,2,3]]'); + +create index on nestjsonb using gin(j jsonb_path_ops); + +set enable_seqscan = on; + +set enable_bitmapscan = off; + +select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb; + +select * from nestjsonb where j @> '{"c":3}'; + +select * from nestjsonb where j @> '[[14]]'; + +set enable_seqscan = off; + +set enable_bitmapscan = on; + +select * from nestjsonb where j @> '{"a":[[{"x":2}]]}'::jsonb; + +select * from nestjsonb where j @> '{"c":3}'; + +select * from nestjsonb where j @> '[[14]]'; + +reset enable_seqscan; + +reset enable_bitmapscan; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'n'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'a'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'b'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'c'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'd'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'd' -> '1'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'e'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 0; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 0; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 1; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 2; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 3; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 3 -> 1; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 4; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> 5; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> -1; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> -5; + +SELECT '["a","b","c",[1,2],null]'::jsonb -> -6; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{0}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{a}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,0}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,1}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,2}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,3}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-1}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-3}'; + +SELECT '{"a":"b","c":[1,2,3]}'::jsonb #> '{c,-4}'; + +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{0}'; + +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{3}'; + +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{4}'; + +SELECT '[0,1,2,[3,4],{"5":"five"}]'::jsonb #> '{4,5}'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'n'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'a'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'b'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'c'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'd'; + +SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb ? 'e'; + +select jsonb_strip_nulls(null); + +select jsonb_strip_nulls('1'); + +select jsonb_strip_nulls('"a string"'); + +select jsonb_strip_nulls('null'); + +select jsonb_strip_nulls('[1,2,null,3,4]'); + +select jsonb_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}'); + +select jsonb_strip_nulls('[1,{"a":1,"b":null,"c":2},3]'); + +select jsonb_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }'); + +select jsonb_strip_nulls(null, true); + +select jsonb_strip_nulls('1', true); + +select jsonb_strip_nulls('"a string"', true); + +select jsonb_strip_nulls('null', true); + +select jsonb_strip_nulls('[1,2,null,3,4]', true); + +select jsonb_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}', true); + +select jsonb_strip_nulls('[1,{"a":1,"b":null,"c":2},3]', true); + +select jsonb_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }', true); + +select jsonb_pretty('{"a": "test", "b": [1, 2, 3], "c": "test3", "d":{"dd": "test4", "dd2":{"ddd": "test5"}}}'); + +select jsonb_pretty('[{"f1":1,"f2":null},2,null,[[{"x":true},6,7],8],3]'); + +select jsonb_pretty('{"a":["b", "c"], "d": {"e":"f"}}'); + +select jsonb_concat('{"d": "test", "a": [1, 2]}', '{"g": "test2", "c": {"c1":1, "c2":2}}'); + +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"cq":"l", "b":"g", "fg":false}'; + +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"aq":"l"}'; + +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{"aa":"l"}'; + +select '{"aa":1 , "b":2, "cq":3}'::jsonb || '{}'; + +select '["a", "b"]'::jsonb || '["c"]'; + +select '["a", "b"]'::jsonb || '["c", "d"]'; + +select '["c"]' || '["a", "b"]'::jsonb; + +select '["a", "b"]'::jsonb || '"c"'; + +select '"c"' || '["a", "b"]'::jsonb; + +select '[]'::jsonb || '["a"]'::jsonb; + +select '[]'::jsonb || '"a"'::jsonb; + +select '"b"'::jsonb || '"a"'::jsonb; + +select '{}'::jsonb || '{"a":"b"}'::jsonb; + +select '[]'::jsonb || '{"a":"b"}'::jsonb; + +select '{"a":"b"}'::jsonb || '[]'::jsonb; + +select '"a"'::jsonb || '{"a":1}'; + +select '{"a":1}' || '"a"'::jsonb; + +select '[3]'::jsonb || '{}'::jsonb; + +select '3'::jsonb || '[]'::jsonb; + +select '3'::jsonb || '4'::jsonb; + +select '3'::jsonb || '{}'::jsonb; + +select '["a", "b"]'::jsonb || '{"c":1}'; + +select '{"c": 1}'::jsonb || '["a", "b"]'; + +select '{}'::jsonb || '{"cq":"l", "b":"g", "fg":false}'; + +select pg_column_size('{}'::jsonb || '{}'::jsonb) = pg_column_size('{}'::jsonb); + +select pg_column_size('{"aa":1}'::jsonb || '{"b":2}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb); + +select pg_column_size('{"aa":1, "b":2}'::jsonb || '{}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb); + +select pg_column_size('{}'::jsonb || '{"aa":1, "b":2}'::jsonb) = pg_column_size('{"aa":1, "b":2}'::jsonb); + +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'a'); + +select jsonb_delete('{"a":null , "b":2, "c":3}'::jsonb, 'a'); + +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'b'); + +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'c'); + +select jsonb_delete('{"a":1 , "b":2, "c":3}'::jsonb, 'd'); + +select '{"a":1 , "b":2, "c":3}'::jsonb - 'a'; + +select '{"a":null , "b":2, "c":3}'::jsonb - 'a'; + +select '{"a":1 , "b":2, "c":3}'::jsonb - 'b'; + +select '{"a":1 , "b":2, "c":3}'::jsonb - 'c'; + +select '{"a":1 , "b":2, "c":3}'::jsonb - 'd'; + +select pg_column_size('{"a":1 , "b":2, "c":3}'::jsonb - 'b') = pg_column_size('{"a":1, "b":2}'::jsonb); + +select '["a","b","c"]'::jsonb - 3; + +select '["a","b","c"]'::jsonb - 2; + +select '["a","b","c"]'::jsonb - 1; + +select '["a","b","c"]'::jsonb - 0; + +select '["a","b","c"]'::jsonb - -1; + +select '["a","b","c"]'::jsonb - -2; + +select '["a","b","c"]'::jsonb - -3; + +select '["a","b","c"]'::jsonb - -4; + +select '{"a":1 , "b":2, "c":3}'::jsonb - '{b}'::text[]; + +select '{"a":1 , "b":2, "c":3}'::jsonb - '{c,b}'::text[]; + +select '{"a":1 , "b":2, "c":3}'::jsonb - '{}'::text[]; + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '[1,2,3]'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '[1,2,3]'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,1,0}', '[1,2,3]'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '[1,2,3]'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '{"1": 2}'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '{"1": 2}'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,1,0}', '{"1": 2}'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '{"1": 2}'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '"test"'); + +select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '{"f": "test"}'); + +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{n}'); + +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{b,-1}'); + +select jsonb_delete_path('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}', '{d,1,0}'); + +select jsonb_delete_path('{"a":[]}', '{"a",-2147483648}'); + +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{n}'; + +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1}'; + +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1e}'; + +select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{d,1,0}'; + +select '"a"'::jsonb - 'a'; + +select '{}'::jsonb - 'a'; + +select '[]'::jsonb - 'a'; + +select '"a"'::jsonb - 1; + +select '{}'::jsonb - 1; + +select '[]'::jsonb - 1; + +select '"a"'::jsonb #- '{a}'; + +select '{}'::jsonb #- '{a}'; + +select '[]'::jsonb #- '{a}'; + +select jsonb_set('"a"','{a}','"b"'); + +select jsonb_set('{}','{a}','"b"', false); + +select jsonb_set('[]','{1}','"b"', false); + +select jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0}','[2,3,4]', false); + +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{b,-33}','{"foo":123}'); + +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{b,33}','{"foo":123}'); + +select jsonb_set('{"a":1,"b":[4,5,[0,1,2],6,7],"c":{"d":4}}','{b,2,33}','{"foo":123}'); + +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{c,e}','{"foo":123}'); + +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{x,-33}','{"foo":123}'); + +select jsonb_set('{"a":1,"b":[0,1,2],"c":{"d":4}}','{x,y}','{"foo":123}'); + +select jsonb_set('{}','{x}','{"foo":123}'); + +select jsonb_set('[]','{0}','{"foo":123}'); + +select jsonb_set('[]','{99}','{"foo":123}'); + +select jsonb_set('[]','{-99}','{"foo":123}'); + +select jsonb_set('{"a": [1, 2, 3]}', '{a, non_integer}', '"new_value"'); + +select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, non_integer}', '"new_value"'); + +select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, NULL}', '"new_value"'); + +select jsonb_set_lax('{"a":1,"b":2}','{b}','5') ; + +select jsonb_set_lax('{"a":1,"b":2}','{d}','6', true) ; + +select jsonb_set_lax('{"a":1,"b":2}','{b}',null); + +select jsonb_set_lax('{"a":1,"b":2}','{d}',null,true); + +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, true, null); + +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, true, 'no_such_treatment'); + +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'raise_exception') as raise_exception; + +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'return_target') as return_target; + +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'delete_key') as delete_key; + +select jsonb_set_lax('{"a":1,"b":2}', '{b}', null, null_value_treatment => 'use_json_null') as use_json_null; + +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"'); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true); + +select jsonb_insert('{"a": {"b": {"c": [0, 1, "test1", "test2"]}}}', '{a, b, c, 2}', '"new_value"'); + +select jsonb_insert('{"a": {"b": {"c": [0, 1, "test1", "test2"]}}}', '{a, b, c, 2}', '"new_value"', true); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '{"b": "value"}'); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '["value1", "value2"]'); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 0}', '"new_value"'); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 0}', '"new_value"', true); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 2}', '"new_value"'); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 2}', '"new_value"', true); + +select jsonb_insert('{"a": [0,1,2]}', '{a, -1}', '"new_value"'); + +select jsonb_insert('{"a": [0,1,2]}', '{a, -1}', '"new_value"', true); + +select jsonb_insert('[]', '{1}', '"new_value"'); + +select jsonb_insert('[]', '{1}', '"new_value"', true); + +select jsonb_insert('{"a": []}', '{a, 1}', '"new_value"'); + +select jsonb_insert('{"a": []}', '{a, 1}', '"new_value"', true); + +select jsonb_insert('{"a": [0,1,2]}', '{a, 10}', '"new_value"'); + +select jsonb_insert('{"a": [0,1,2]}', '{a, -10}', '"new_value"'); + +select jsonb_insert('{"a": {"b": "value"}}', '{a, c}', '"new_value"'); + +select jsonb_insert('{"a": {"b": "value"}}', '{a, c}', '"new_value"', true); + +select jsonb_insert('{"a": {"b": "value"}}', '{a, b}', '"new_value"'); + +select jsonb_insert('{"a": {"b": "value"}}', '{a, b}', '"new_value"', true); + +select ('123'::jsonb)['a']; + +select ('123'::jsonb)[0]; + +select ('123'::jsonb)[NULL]; + +select ('{"a": 1}'::jsonb)['a']; + +select ('{"a": 1}'::jsonb)[0]; + +select ('{"a": 1}'::jsonb)['not_exist']; + +select ('{"a": 1}'::jsonb)[NULL]; + +select ('[1, "2", null]'::jsonb)['a']; + +select ('[1, "2", null]'::jsonb)[0]; + +select ('[1, "2", null]'::jsonb)['1']; + +select ('[1, "2", null]'::jsonb)[1.0]; + +select ('[1, "2", null]'::jsonb)[2]; + +select ('[1, "2", null]'::jsonb)[3]; + +select ('[1, "2", null]'::jsonb)[-2]; + +select ('[1, "2", null]'::jsonb)[1]['a']; + +select ('[1, "2", null]'::jsonb)[1][0]; + +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['b']; + +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d']; + +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d'][1]; + +select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d']['a']; + +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1']; + +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1']['a2']; + +select ('{"a": {"a1": {"a2": "aaa"}}, "b": "bbb", "c": "ccc"}'::jsonb)['a']['a1']['a2']['a3']; + +select ('{"a": ["a1", {"b1": ["aaa", "bbb", "ccc"]}], "b": "bb"}'::jsonb)['a'][1]['b1']; + +select ('{"a": ["a1", {"b1": ["aaa", "bbb", "ccc"]}], "b": "bb"}'::jsonb)['a'][1]['b1'][2]; + +select ('{"a": 1}'::jsonb)['a':'b']; + +select ('[1, "2", null]'::jsonb)[1:2]; + +select ('[1, "2", null]'::jsonb)[:2]; + +select ('[1, "2", null]'::jsonb)[1:]; + +select ('[1, "2", null]'::jsonb)[:]; + +create TEMP TABLE test_jsonb_subscript ( + id int, + test_json jsonb +); + +insert into test_jsonb_subscript values +(1, '{}'), -- empty jsonb +(2, '{"key": "value"}'); + +update test_jsonb_subscript set test_json['a'] = '1' where id = 1; + +select * from test_jsonb_subscript; + +update test_jsonb_subscript set test_json['a'] = '1' where id = 2; + +select * from test_jsonb_subscript; + +update test_jsonb_subscript set test_json['a'] = '"test"'; + +select * from test_jsonb_subscript; + +update test_jsonb_subscript set test_json['a'] = '{"b": 1}'::jsonb; + +select * from test_jsonb_subscript; + +update test_jsonb_subscript set test_json['a'] = '[1, 2, 3]'::jsonb; + +select * from test_jsonb_subscript; + +select * from test_jsonb_subscript where test_json['key'] = '"value"'; + +select * from test_jsonb_subscript where test_json['key_doesnt_exists'] = '"value"'; + +select * from test_jsonb_subscript where test_json['key'] = '"wrong_value"'; + +update test_jsonb_subscript set test_json[NULL] = '1'; + +update test_jsonb_subscript set test_json['another_key'] = NULL; + +select * from test_jsonb_subscript; + +insert into test_jsonb_subscript values (3, NULL); + +update test_jsonb_subscript set test_json['a'] = '1' where id = 3; + +select * from test_jsonb_subscript; + +update test_jsonb_subscript set test_json = NULL where id = 3; + +update test_jsonb_subscript set test_json[0] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '[0]'); + +update test_jsonb_subscript set test_json[5] = '1'; + +select * from test_jsonb_subscript; + +update test_jsonb_subscript set test_json[-4] = '1'; + +select * from test_jsonb_subscript; + +update test_jsonb_subscript set test_json[-8] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '[]'); + +update test_jsonb_subscript set test_json[5] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{}'); + +update test_jsonb_subscript set test_json['a'][0]['b'][0]['c'] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{}'); + +update test_jsonb_subscript set test_json['a'][2]['b'][2]['c'][2] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{"b": 1}'); + +update test_jsonb_subscript set test_json['a'][0] = '2'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{}'); + +update test_jsonb_subscript set test_json[0]['a'] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '[]'); + +update test_jsonb_subscript set test_json[0]['a'] = '1'; + +update test_jsonb_subscript set test_json[2]['b'] = '2'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{}'); + +update test_jsonb_subscript set test_json['a']['b'][1] = '1'; + +update test_jsonb_subscript set test_json['a']['b'][10] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '[]'); + +update test_jsonb_subscript set test_json[0][0][0] = '1'; + +update test_jsonb_subscript set test_json[0][0][1] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{}'); + +update test_jsonb_subscript set test_json['a']['b'][10] = '1'; + +update test_jsonb_subscript set test_json['a'][10][10] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{"a": {}}'); + +update test_jsonb_subscript set test_json['a']['b']['c'][2] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{"a": []}'); + +update test_jsonb_subscript set test_json['a'][1]['c'][2] = '1'; + +select * from test_jsonb_subscript; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, '{"a": 1}'); + +update test_jsonb_subscript set test_json['a']['b'] = '1'; + +update test_jsonb_subscript set test_json['a']['b']['c'] = '1'; + +update test_jsonb_subscript set test_json['a'][0] = '1'; + +update test_jsonb_subscript set test_json['a'][0]['c'] = '1'; + +update test_jsonb_subscript set test_json['a'][0][0] = '1'; + +delete from test_jsonb_subscript; + +insert into test_jsonb_subscript values (1, 'null'); + +update test_jsonb_subscript set test_json[0] = '1'; + +update test_jsonb_subscript set test_json[0][0] = '1'; + +drop table test_jsonb_subscript; + +create temp table test_jsonb_subscript ( + id text, + test_json jsonb +); + +insert into test_jsonb_subscript values('foo', '{"foo": "bar"}'); + +insert into test_jsonb_subscript + select s, ('{"' || s || '": "bar"}')::jsonb from repeat('xyzzy', 500) s; + +select length(id), test_json[id] from test_jsonb_subscript; + +update test_jsonb_subscript set test_json[id] = '"baz"'; + +select length(id), test_json[id] from test_jsonb_subscript; + +table test_jsonb_subscript; + +select to_tsvector('{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::jsonb); + +select to_tsvector('simple', '{"a": "aaa bbb ddd ccc", "b": ["eee fff ggg"], "c": {"d": "hhh iii"}}'::jsonb); + +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": ["the eee fff ggg"], "c": {"d": "hhh. iii"}}'::jsonb); + +select to_tsvector('english', '{"a": "aaa in bbb ddd ccc", "b": 123, "c": 456}'::jsonb); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"all"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"key"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"string"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"numeric"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]'); + +select to_tsvector('""'::jsonb); + +select to_tsvector('{}'::jsonb); + +select to_tsvector('[]'::jsonb); + +select to_tsvector('null'::jsonb); + +select jsonb_to_tsvector('""'::jsonb, '"all"'); + +select jsonb_to_tsvector('{}'::jsonb, '"all"'); + +select jsonb_to_tsvector('[]'::jsonb, '"all"'); + +select jsonb_to_tsvector('null'::jsonb, '"all"'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '""'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '{}'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '[]'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, 'null'); + +select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["all", null]'); + +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh')); + +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh')); + +select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >'); + +select ts_headline('english', '{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh'), 'StartSel = <, StopSel = >'); + +select ts_headline('null'::jsonb, tsquery('aaa & bbb')); + +select ts_headline('{}'::jsonb, tsquery('aaa & bbb')); + +select ts_headline('[]'::jsonb, tsquery('aaa & bbb')); + +select 'true'::jsonb::bool; + +select 'null'::jsonb::bool; + +select '[]'::jsonb::bool; + +select '1.0'::jsonb::float; + +select 'null'::jsonb::float; + +select '[1.0]'::jsonb::float; + +select '1.0'::jsonb::float4; + +select 'null'::jsonb::float4; + +select '[1.0]'::jsonb::float4; + +select '12345'::jsonb::int2; + +select 'null'::jsonb::int2; + +select '"hello"'::jsonb::int2; + +select '12345'::jsonb::int4; + +select 'null'::jsonb::int4; + +select '"hello"'::jsonb::int4; + +select '12345'::jsonb::int8; + +select 'null'::jsonb::int8; + +select '"hello"'::jsonb::int8; + +select '12345'::jsonb::numeric; + +select 'null'::jsonb::numeric; + +select '{}'::jsonb::numeric; + +select '12345.05'::jsonb::numeric; + +select '12345.05'::jsonb::float4; + +select '12345.05'::jsonb::float8; + +select '12345.05'::jsonb::int2; + +select '12345.05'::jsonb::int4; + +select '12345.05'::jsonb::int8; + +select '12345.0000000000000000000000000000000000000000000005'::jsonb::numeric; + +select '12345.0000000000000000000000000000000000000000000005'::jsonb::float4; + +select '12345.0000000000000000000000000000000000000000000005'::jsonb::float8; + +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int2; + +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int4; + +select '12345.0000000000000000000000000000000000000000000005'::jsonb::int8; diff --git a/crates/pgt_pretty_print/tests/data/multi/jsonb_jsonpath_60.sql b/crates/pgt_pretty_print/tests/data/multi/jsonb_jsonpath_60.sql new file mode 100644 index 000000000..a0fcba200 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/jsonb_jsonpath_60.sql @@ -0,0 +1,1860 @@ +select jsonb '{"a": 12}' @? '$'; + +select jsonb '{"a": 12}' @? '1'; + +select jsonb '{"a": 12}' @? '$.a.b'; + +select jsonb '{"a": 12}' @? '$.b'; + +select jsonb '{"a": 12}' @? '$.a + 2'; + +select jsonb '{"a": 12}' @? '$.b + 2'; + +select jsonb '{"a": {"a": 12}}' @? '$.a.a'; + +select jsonb '{"a": {"a": 12}}' @? '$.*.a'; + +select jsonb '{"b": {"a": 12}}' @? '$.*.a'; + +select jsonb '{"b": {"a": 12}}' @? '$.*.b'; + +select jsonb '{"b": {"a": 12}}' @? 'strict $.*.b'; + +select jsonb '{}' @? '$.*'; + +select jsonb '{"a": 1}' @? '$.*'; + +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{1}'; + +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{2}'; + +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{3}'; + +select jsonb '[]' @? '$[*]'; + +select jsonb '[1]' @? '$[*]'; + +select jsonb '[1]' @? '$[1]'; + +select jsonb '[1]' @? 'strict $[1]'; + +select jsonb_path_query('[1]', 'strict $[1]'); + +select jsonb_path_query('[1]', 'strict $[1]', silent => true); + +select jsonb '[1]' @? 'lax $[10000000000000000]'; + +select jsonb '[1]' @? 'strict $[10000000000000000]'; + +select jsonb_path_query('[1]', 'lax $[10000000000000000]'); + +select jsonb_path_query('[1]', 'strict $[10000000000000000]'); + +select jsonb '[1]' @? '$[0]'; + +select jsonb '[1]' @? '$[0.3]'; + +select jsonb '[1]' @? '$[0.5]'; + +select jsonb '[1]' @? '$[0.9]'; + +select jsonb '[1]' @? '$[1.2]'; + +select jsonb '[1]' @? 'strict $[1.2]'; + +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] > @.b[*])'; + +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] >= @.b[*])'; + +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? '$ ? (@.a[*] >= @.b[*])'; + +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? 'strict $ ? (@.a[*] >= @.b[*])'; + +select jsonb '{"a": [1,2,3], "b": [3,4,null]}' @? '$ ? (@.a[*] >= @.b[*])'; + +select jsonb '1' @? '$ ? ((@ == "1") is unknown)'; + +select jsonb '1' @? '$ ? ((@ == 1) is unknown)'; + +select jsonb '[{"a": 1}, {"a": 2}]' @? '$[0 to 1] ? (@.a > 1)'; + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => false); + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => true); + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => false); + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => true); + +select jsonb_path_query('1', 'lax $.a'); + +select jsonb_path_query('1', 'strict $.a'); + +select jsonb_path_query('1', 'strict $.*'); + +select jsonb_path_query('1', 'strict $.a', silent => true); + +select jsonb_path_query('1', 'strict $.*', silent => true); + +select jsonb_path_query('[]', 'lax $.a'); + +select jsonb_path_query('[]', 'strict $.a'); + +select jsonb_path_query('[]', 'strict $.a', silent => true); + +select jsonb_path_query('{}', 'lax $.a'); + +select jsonb_path_query('{}', 'strict $.a'); + +select jsonb_path_query('{}', 'strict $.a', silent => true); + +select jsonb_path_query('1', 'strict $[1]'); + +select jsonb_path_query('1', 'strict $[*]'); + +select jsonb_path_query('[]', 'strict $[1]'); + +select jsonb_path_query('[]', 'strict $["a"]'); + +select jsonb_path_query('1', 'strict $[1]', silent => true); + +select jsonb_path_query('1', 'strict $[*]', silent => true); + +select jsonb_path_query('[]', 'strict $[1]', silent => true); + +select jsonb_path_query('[]', 'strict $["a"]', silent => true); + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.a'); + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.b'); + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.*'); + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', 'lax $.*.a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].*'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0].a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[1].a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[2].a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0,1].a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10].a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10 / 0].a'); + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}, "ccc", true]', '$[2.5 - 1 to $.size() - 2]'); + +select jsonb_path_query('1', 'lax $[0]'); + +select jsonb_path_query('1', 'lax $[*]'); + +select jsonb_path_query('[1]', 'lax $[0]'); + +select jsonb_path_query('[1]', 'lax $[*]'); + +select jsonb_path_query('[1,2,3]', 'lax $[*]'); + +select jsonb_path_query('[1,2,3]', 'strict $[*].a'); + +select jsonb_path_query('[1,2,3]', 'strict $[*].a', silent => true); + +select jsonb_path_query('[]', '$[last]'); + +select jsonb_path_query('[]', '$[last ? (exists(last))]'); + +select jsonb_path_query('[]', 'strict $[last]'); + +select jsonb_path_query('[]', 'strict $[last]', silent => true); + +select jsonb_path_query('[1]', '$[last]'); + +select jsonb_path_query('[1,2,3]', '$[last]'); + +select jsonb_path_query('[1,2,3]', '$[last - 1]'); + +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "number")]'); + +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]'); + +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]', silent => true); + +select * from jsonb_path_query('{"a": 10}', '$'); + +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)'); + +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1'); + +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '[{"value" : 13}]'); + +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 13}'); + +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 8}'); + +select * from jsonb_path_query('{"a": 10}', '$.a ? (@ < $value)', '{"value" : 13}'); + +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[*] ? (@ < $value)', '{"value" : 13}'); + +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0,1] ? (@ < $x.value)', '{"x": {"value" : 13}}'); + +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0 to 2] ? (@ < $value)', '{"value" : 15}'); + +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == "1")'); + +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : "1"}'); + +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : null}'); + +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ != null)'); + +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ == null)'); + +select * from jsonb_path_query('{}', '$ ? (@ == @)'); + +select * from jsonb_path_query('[]', 'strict $ ? (@ == @)'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2 to last}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{3 to last}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{last}'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to 2}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0 to last}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to last}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to 2}.b ? (@ > 0)'); + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{2 to 3}.b ? (@ > 0)'); + +select jsonb '{"a": {"b": 1}}' @? '$.**.b ? ( @ > 0)'; + +select jsonb '{"a": {"b": 1}}' @? '$.**{0}.b ? ( @ > 0)'; + +select jsonb '{"a": {"b": 1}}' @? '$.**{1}.b ? ( @ > 0)'; + +select jsonb '{"a": {"b": 1}}' @? '$.**{0 to last}.b ? ( @ > 0)'; + +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to last}.b ? ( @ > 0)'; + +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to 2}.b ? ( @ > 0)'; + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**.b ? ( @ > 0)'; + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0}.b ? ( @ > 0)'; + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1}.b ? ( @ > 0)'; + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0 to last}.b ? ( @ > 0)'; + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to last}.b ? ( @ > 0)'; + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to 2}.b ? ( @ > 0)'; + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2 to 3}.b ? ( @ > 0)'; + +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x))'); + +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.y))'); + +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x ? (@ >= 2) ))'); + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x))'); + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x + "3"))'); + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? ((exists (@.x + "3")) is unknown)'); + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? (exists (@.x))'); + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? ((exists (@.x)) is unknown)'); + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? (exists (@[*].x))'); + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? ((exists (@[*].x)) is unknown)'); + +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true && $y == true) || + @ == false && !($x == true && $y == true) || + @ == null && ($x == true && $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x && y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y); + +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true || $y == true) || + @ == false && !($x == true || $y == true) || + @ == null && ($x == true || $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x || y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y); + +select jsonb '{"a": 1, "b":1}' @? '$ ? (@.a == @.b)'; + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$ ? (@.a == @.b)'; + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? (@.a == @.b)'; + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? ($.c.a == @.b)'; + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.* ? (@.a == @.b)'; + +select jsonb '{"a": 1, "b":1}' @? '$.** ? (@.a == @.b)'; + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.** ? (@.a == @.b)'; + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == 1 + 1)'); + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (1 + 1))'); + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == @.b + 1)'); + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (@.b + 1))'); + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - 1)'; + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -1)'; + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -@.b)'; + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - @.b)'; + +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - @.b)'; + +select jsonb '{"c": {"a": 2, "b":1}}' @? '$.** ? (@.a == 1 - - @.b)'; + +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - +@.b)'; + +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +2)'; + +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +3)'; + +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -2)'; + +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -3)'; + +select jsonb '1' @? '$ ? ($ > 0)'; + +select jsonb_path_query('[1,2,0,3]', '$[*] ? (2 / @ > 0)'); + +select jsonb_path_query('[1,2,0,3]', '$[*] ? ((2 / @ > 0) is unknown)'); + +select jsonb_path_query('0', '1 / $'); + +select jsonb_path_query('0', '1 / $ + 2'); + +select jsonb_path_query('0', '-(3 + 1 % $)'); + +select jsonb_path_query('1', '$ + "2"'); + +select jsonb_path_query('[1, 2]', '3 * $'); + +select jsonb_path_query('"a"', '-$'); + +select jsonb_path_query('[1,"2",3]', '+$'); + +select jsonb_path_query('1', '$ + "2"', silent => true); + +select jsonb_path_query('[1, 2]', '3 * $', silent => true); + +select jsonb_path_query('"a"', '-$', silent => true); + +select jsonb_path_query('[1,"2",3]', '+$', silent => true); + +select jsonb '["1",2,0,3]' @? '-$[*]'; + +select jsonb '[1,"2",0,3]' @? '-$[*]'; + +select jsonb '["1",2,0,3]' @? 'strict -$[*]'; + +select jsonb '[1,"2",0,3]' @? 'strict -$[*]'; + +select jsonb_path_query('{"a": [2]}', 'lax $.a * 3'); + +select jsonb_path_query('{"a": [2]}', 'lax $.a + 3'); + +select jsonb_path_query('{"a": [2, 3, 4]}', 'lax -$.a'); + +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3'); + +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true); + +select jsonb_path_query('{"a": [1,2,3], "b": [3,4,5]}', '$.*'); + +select jsonb_path_query('[1,2,3]', '$.*'); + +select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'lax $.*'); + +select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'strict $.*'); + +select jsonb_path_query('[1,2,3,{"b": [3,4,5]}]', 'strict $.*', NULL, true); + +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$.*'; + +select jsonb '[1,2,3]' @? '$.*'; + +select jsonb '[1,2,3,{"b": [3,4,5]}]' @? 'lax $.*'; + +select jsonb '[1,2,3,{"b": [3,4,5]}]' @? 'strict $.*'; + +select jsonb_path_query('2', '$ > 1'); + +select jsonb_path_query('2', '$ <= 1'); + +select jsonb_path_query('2', '$ == "2"'); + +select jsonb '2' @? '$ == "2"'; + +select jsonb '2' @@ '$ > 1'; + +select jsonb '2' @@ '$ <= 1'; + +select jsonb '2' @@ '$ == "2"'; + +select jsonb '2' @@ '1'; + +select jsonb '{}' @@ '$'; + +select jsonb '[]' @@ '$'; + +select jsonb '[1,2,3]' @@ '$[*]'; + +select jsonb '[]' @@ '$[*]'; + +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}'); + +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}'); + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => false); + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => true); + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => false); + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => true); + +select jsonb_path_query('[null,1,true,"a",[],{}]', '$.type()'); + +select jsonb_path_query('[null,1,true,"a",[],{}]', 'lax $.type()'); + +select jsonb_path_query('[null,1,true,"a",[],{}]', '$[*].type()'); + +select jsonb_path_query('null', 'null.type()'); + +select jsonb_path_query('null', 'true.type()'); + +select jsonb_path_query('null', '(123).type()'); + +select jsonb_path_query('null', '"123".type()'); + +select jsonb_path_query('{"a": 2}', '($.a - 5).abs() + 10'); + +select jsonb_path_query('{"a": 2.5}', '-($.a * $.a).floor() % 4.3'); + +select jsonb_path_query('[1, 2, 3]', '($[*] > 2) ? (@ == true)'); + +select jsonb_path_query('[1, 2, 3]', '($[*] > 3).type()'); + +select jsonb_path_query('[1, 2, 3]', '($[*].a > 3).type()'); + +select jsonb_path_query('[1, 2, 3]', 'strict ($[*].a > 3).type()'); + +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()'); + +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()', silent => true); + +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'lax $[*].size()'); + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].abs()'); + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].floor()'); + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling()'); + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs()'); + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs().type()'); + +select jsonb_path_query('[{},1]', '$[*].keyvalue()'); + +select jsonb_path_query('[{},1]', '$[*].keyvalue()', silent => true); + +select jsonb_path_query('{}', '$.keyvalue()'); + +select jsonb_path_query('{"a": 1, "b": [1, 2], "c": {"a": "bbb"}}', '$.keyvalue()'); + +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', '$[*].keyvalue()'); + +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue()'); + +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'lax $.keyvalue()'); + +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue().a'); + +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue()'; + +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue().key'; + +select jsonb_path_query('null', '$.double()'); + +select jsonb_path_query('true', '$.double()'); + +select jsonb_path_query('null', '$.double()', silent => true); + +select jsonb_path_query('true', '$.double()', silent => true); + +select jsonb_path_query('[]', '$.double()'); + +select jsonb_path_query('[]', 'strict $.double()'); + +select jsonb_path_query('{}', '$.double()'); + +select jsonb_path_query('[]', 'strict $.double()', silent => true); + +select jsonb_path_query('{}', '$.double()', silent => true); + +select jsonb_path_query('1.23', '$.double()'); + +select jsonb_path_query('"1.23"', '$.double()'); + +select jsonb_path_query('"1.23aaa"', '$.double()'); + +select jsonb_path_query('1e1000', '$.double()'); + +select jsonb_path_query('"nan"', '$.double()'); + +select jsonb_path_query('"NaN"', '$.double()'); + +select jsonb_path_query('"inf"', '$.double()'); + +select jsonb_path_query('"-inf"', '$.double()'); + +select jsonb_path_query('"inf"', '$.double()', silent => true); + +select jsonb_path_query('"-inf"', '$.double()', silent => true); + +select jsonb_path_query('{}', '$.abs()'); + +select jsonb_path_query('true', '$.floor()'); + +select jsonb_path_query('"1.2"', '$.ceiling()'); + +select jsonb_path_query('{}', '$.abs()', silent => true); + +select jsonb_path_query('true', '$.floor()', silent => true); + +select jsonb_path_query('"1.2"', '$.ceiling()', silent => true); + +select jsonb_path_query('["", "a", "abc", "abcabc"]', '$[*] ? (@ starts with "abc")'); + +select jsonb_path_query('["", "a", "abc", "abcabc"]', 'strict $ ? (@[*] starts with "abc")'); + +select jsonb_path_query('["", "a", "abd", "abdabc"]', 'strict $ ? (@[*] starts with "abc")'); + +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? (@[*] starts with "abc")'); + +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? ((@[*] starts with "abc") is unknown)'); + +select jsonb_path_query('[[null, 1, "abc", "abcabc"]]', 'lax $ ? (@[*] starts with "abc")'); + +select jsonb_path_query('[[null, 1, "abd", "abdabc"]]', 'lax $ ? ((@[*] starts with "abc") is unknown)'); + +select jsonb_path_query('[null, 1, "abd", "abdabc"]', 'lax $[*] ? ((@ starts with "abc") is unknown)'); + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c")'); + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "i")'); + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "m")'); + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "s")'); + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")'); + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")'); + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")'); + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")'); + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")'); + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")'); + +select jsonb_path_query('null', '$.datetime()'); + +select jsonb_path_query('true', '$.datetime()'); + +select jsonb_path_query('1', '$.datetime()'); + +select jsonb_path_query('[]', '$.datetime()'); + +select jsonb_path_query('[]', 'strict $.datetime()'); + +select jsonb_path_query('{}', '$.datetime()'); + +select jsonb_path_query('"bogus"', '$.datetime()'); + +select jsonb_path_query('"12:34"', '$.datetime("aaa")'); + +select jsonb_path_query('"aaaa"', '$.datetime("HH24")'); + +select jsonb '"10-03-2017"' @? '$.datetime("dd-mm-yyyy")'; + +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy")'); + +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy").type()'); + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy")'); + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy").type()'); + +select jsonb_path_query('"10-03-2017 12:34"', ' $.datetime("dd-mm-yyyy HH24:MI").type()'); + +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM").type()'); + +select jsonb_path_query('"12:34:56"', '$.datetime("HH24:MI:SS").type()'); + +select jsonb_path_query('"12:34:56 +05:20"', '$.datetime("HH24:MI:SS TZH:TZM").type()'); + +select jsonb_path_query('"10-03-2017T12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")'); + +select jsonb_path_query('"10-03-2017t12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")'); + +select jsonb_path_query('"10-03-2017 12:34:56"', '$.datetime("dd-mm-yyyy\"T\"HH24:MI:SS")'); + +select jsonb_path_query('null', '$.bigint()'); + +select jsonb_path_query('true', '$.bigint()'); + +select jsonb_path_query('null', '$.bigint()', silent => true); + +select jsonb_path_query('true', '$.bigint()', silent => true); + +select jsonb_path_query('[]', '$.bigint()'); + +select jsonb_path_query('[]', 'strict $.bigint()'); + +select jsonb_path_query('{}', '$.bigint()'); + +select jsonb_path_query('[]', 'strict $.bigint()', silent => true); + +select jsonb_path_query('{}', '$.bigint()', silent => true); + +select jsonb_path_query('"1.23"', '$.bigint()'); + +select jsonb_path_query('"1.23aaa"', '$.bigint()'); + +select jsonb_path_query('1e1000', '$.bigint()'); + +select jsonb_path_query('"nan"', '$.bigint()'); + +select jsonb_path_query('"NaN"', '$.bigint()'); + +select jsonb_path_query('"inf"', '$.bigint()'); + +select jsonb_path_query('"-inf"', '$.bigint()'); + +select jsonb_path_query('"inf"', '$.bigint()', silent => true); + +select jsonb_path_query('"-inf"', '$.bigint()', silent => true); + +select jsonb_path_query('123', '$.bigint()'); + +select jsonb_path_query('"123"', '$.bigint()'); + +select jsonb_path_query('1.23', '$.bigint()'); + +select jsonb_path_query('1.83', '$.bigint()'); + +select jsonb_path_query('1234567890123', '$.bigint()'); + +select jsonb_path_query('"1234567890123"', '$.bigint()'); + +select jsonb_path_query('12345678901234567890', '$.bigint()'); + +select jsonb_path_query('"12345678901234567890"', '$.bigint()'); + +select jsonb_path_query('"+123"', '$.bigint()'); + +select jsonb_path_query('-123', '$.bigint()'); + +select jsonb_path_query('"-123"', '$.bigint()'); + +select jsonb_path_query('123', '$.bigint() * 2'); + +select jsonb_path_query('null', '$.boolean()'); + +select jsonb_path_query('null', '$.boolean()', silent => true); + +select jsonb_path_query('[]', '$.boolean()'); + +select jsonb_path_query('[]', 'strict $.boolean()'); + +select jsonb_path_query('{}', '$.boolean()'); + +select jsonb_path_query('[]', 'strict $.boolean()', silent => true); + +select jsonb_path_query('{}', '$.boolean()', silent => true); + +select jsonb_path_query('1.23', '$.boolean()'); + +select jsonb_path_query('"1.23"', '$.boolean()'); + +select jsonb_path_query('"1.23aaa"', '$.boolean()'); + +select jsonb_path_query('1e1000', '$.boolean()'); + +select jsonb_path_query('"nan"', '$.boolean()'); + +select jsonb_path_query('"NaN"', '$.boolean()'); + +select jsonb_path_query('"inf"', '$.boolean()'); + +select jsonb_path_query('"-inf"', '$.boolean()'); + +select jsonb_path_query('"inf"', '$.boolean()', silent => true); + +select jsonb_path_query('"-inf"', '$.boolean()', silent => true); + +select jsonb_path_query('"100"', '$.boolean()'); + +select jsonb_path_query('true', '$.boolean()'); + +select jsonb_path_query('false', '$.boolean()'); + +select jsonb_path_query('1', '$.boolean()'); + +select jsonb_path_query('0', '$.boolean()'); + +select jsonb_path_query('-1', '$.boolean()'); + +select jsonb_path_query('100', '$.boolean()'); + +select jsonb_path_query('"1"', '$.boolean()'); + +select jsonb_path_query('"0"', '$.boolean()'); + +select jsonb_path_query('"true"', '$.boolean()'); + +select jsonb_path_query('"false"', '$.boolean()'); + +select jsonb_path_query('"TRUE"', '$.boolean()'); + +select jsonb_path_query('"FALSE"', '$.boolean()'); + +select jsonb_path_query('"yes"', '$.boolean()'); + +select jsonb_path_query('"NO"', '$.boolean()'); + +select jsonb_path_query('"T"', '$.boolean()'); + +select jsonb_path_query('"f"', '$.boolean()'); + +select jsonb_path_query('"y"', '$.boolean()'); + +select jsonb_path_query('"N"', '$.boolean()'); + +select jsonb_path_query('true', '$.boolean().type()'); + +select jsonb_path_query('123', '$.boolean().type()'); + +select jsonb_path_query('"Yes"', '$.boolean().type()'); + +select jsonb_path_query_array('[1, "yes", false]', '$[*].boolean()'); + +select jsonb_path_query('null', '$.date()'); + +select jsonb_path_query('true', '$.date()'); + +select jsonb_path_query('1', '$.date()'); + +select jsonb_path_query('[]', '$.date()'); + +select jsonb_path_query('[]', 'strict $.date()'); + +select jsonb_path_query('{}', '$.date()'); + +select jsonb_path_query('"bogus"', '$.date()'); + +select jsonb '"2023-08-15"' @? '$.date()'; + +select jsonb_path_query('"2023-08-15"', '$.date()'); + +select jsonb_path_query('"2023-08-15"', '$.date().type()'); + +select jsonb_path_query('"12:34:56"', '$.date()'); + +select jsonb_path_query('"12:34:56 +05:30"', '$.date()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.date()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.date()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.date()'); + +select jsonb_path_query('"2023-08-15"', '$.date(2)'); + +select jsonb_path_query('null', '$.decimal()'); + +select jsonb_path_query('true', '$.decimal()'); + +select jsonb_path_query('null', '$.decimal()', silent => true); + +select jsonb_path_query('true', '$.decimal()', silent => true); + +select jsonb_path_query('[]', '$.decimal()'); + +select jsonb_path_query('[]', 'strict $.decimal()'); + +select jsonb_path_query('{}', '$.decimal()'); + +select jsonb_path_query('[]', 'strict $.decimal()', silent => true); + +select jsonb_path_query('{}', '$.decimal()', silent => true); + +select jsonb_path_query('1.23', '$.decimal()'); + +select jsonb_path_query('"1.23"', '$.decimal()'); + +select jsonb_path_query('"1.23aaa"', '$.decimal()'); + +select jsonb_path_query('1e1000', '$.decimal()'); + +select jsonb_path_query('"nan"', '$.decimal()'); + +select jsonb_path_query('"NaN"', '$.decimal()'); + +select jsonb_path_query('"inf"', '$.decimal()'); + +select jsonb_path_query('"-inf"', '$.decimal()'); + +select jsonb_path_query('"inf"', '$.decimal()', silent => true); + +select jsonb_path_query('"-inf"', '$.decimal()', silent => true); + +select jsonb_path_query('123', '$.decimal()'); + +select jsonb_path_query('"123"', '$.decimal()'); + +select jsonb_path_query('12345678901234567890', '$.decimal()'); + +select jsonb_path_query('"12345678901234567890"', '$.decimal()'); + +select jsonb_path_query('"+12.3"', '$.decimal()'); + +select jsonb_path_query('-12.3', '$.decimal()'); + +select jsonb_path_query('"-12.3"', '$.decimal()'); + +select jsonb_path_query('12.3', '$.decimal() * 2'); + +select jsonb_path_query('12345.678', '$.decimal(6, 1)'); + +select jsonb_path_query('12345.678', '$.decimal(6, 2)'); + +select jsonb_path_query('1234.5678', '$.decimal(6, 2)'); + +select jsonb_path_query('12345.678', '$.decimal(4, 6)'); + +select jsonb_path_query('12345.678', '$.decimal(0, 6)'); + +select jsonb_path_query('12345.678', '$.decimal(1001, 6)'); + +select jsonb_path_query('1234.5678', '$.decimal(+6, +2)'); + +select jsonb_path_query('1234.5678', '$.decimal(+6, -2)'); + +select jsonb_path_query('1234.5678', '$.decimal(-6, +2)'); + +select jsonb_path_query('1234.5678', '$.decimal(6, -1001)'); + +select jsonb_path_query('1234.5678', '$.decimal(6, 1001)'); + +select jsonb_path_query('-1234.5678', '$.decimal(+6, -2)'); + +select jsonb_path_query('0.0123456', '$.decimal(1,2)'); + +select jsonb_path_query('0.0012345', '$.decimal(2,4)'); + +select jsonb_path_query('-0.00123456', '$.decimal(2,-4)'); + +select jsonb_path_query('12.3', '$.decimal(12345678901,1)'); + +select jsonb_path_query('12.3', '$.decimal(1,12345678901)'); + +select jsonb_path_query('null', '$.integer()'); + +select jsonb_path_query('true', '$.integer()'); + +select jsonb_path_query('null', '$.integer()', silent => true); + +select jsonb_path_query('true', '$.integer()', silent => true); + +select jsonb_path_query('[]', '$.integer()'); + +select jsonb_path_query('[]', 'strict $.integer()'); + +select jsonb_path_query('{}', '$.integer()'); + +select jsonb_path_query('[]', 'strict $.integer()', silent => true); + +select jsonb_path_query('{}', '$.integer()', silent => true); + +select jsonb_path_query('"1.23"', '$.integer()'); + +select jsonb_path_query('"1.23aaa"', '$.integer()'); + +select jsonb_path_query('1e1000', '$.integer()'); + +select jsonb_path_query('"nan"', '$.integer()'); + +select jsonb_path_query('"NaN"', '$.integer()'); + +select jsonb_path_query('"inf"', '$.integer()'); + +select jsonb_path_query('"-inf"', '$.integer()'); + +select jsonb_path_query('"inf"', '$.integer()', silent => true); + +select jsonb_path_query('"-inf"', '$.integer()', silent => true); + +select jsonb_path_query('123', '$.integer()'); + +select jsonb_path_query('"123"', '$.integer()'); + +select jsonb_path_query('1.23', '$.integer()'); + +select jsonb_path_query('1.83', '$.integer()'); + +select jsonb_path_query('12345678901', '$.integer()'); + +select jsonb_path_query('"12345678901"', '$.integer()'); + +select jsonb_path_query('"+123"', '$.integer()'); + +select jsonb_path_query('-123', '$.integer()'); + +select jsonb_path_query('"-123"', '$.integer()'); + +select jsonb_path_query('123', '$.integer() * 2'); + +select jsonb_path_query('null', '$.number()'); + +select jsonb_path_query('true', '$.number()'); + +select jsonb_path_query('null', '$.number()', silent => true); + +select jsonb_path_query('true', '$.number()', silent => true); + +select jsonb_path_query('[]', '$.number()'); + +select jsonb_path_query('[]', 'strict $.number()'); + +select jsonb_path_query('{}', '$.number()'); + +select jsonb_path_query('[]', 'strict $.number()', silent => true); + +select jsonb_path_query('{}', '$.number()', silent => true); + +select jsonb_path_query('1.23', '$.number()'); + +select jsonb_path_query('"1.23"', '$.number()'); + +select jsonb_path_query('"1.23aaa"', '$.number()'); + +select jsonb_path_query('1e1000', '$.number()'); + +select jsonb_path_query('"nan"', '$.number()'); + +select jsonb_path_query('"NaN"', '$.number()'); + +select jsonb_path_query('"inf"', '$.number()'); + +select jsonb_path_query('"-inf"', '$.number()'); + +select jsonb_path_query('"inf"', '$.number()', silent => true); + +select jsonb_path_query('"-inf"', '$.number()', silent => true); + +select jsonb_path_query('123', '$.number()'); + +select jsonb_path_query('"123"', '$.number()'); + +select jsonb_path_query('12345678901234567890', '$.number()'); + +select jsonb_path_query('"12345678901234567890"', '$.number()'); + +select jsonb_path_query('"+12.3"', '$.number()'); + +select jsonb_path_query('-12.3', '$.number()'); + +select jsonb_path_query('"-12.3"', '$.number()'); + +select jsonb_path_query('12.3', '$.number() * 2'); + +select jsonb_path_query('null', '$.string()'); + +select jsonb_path_query('null', '$.string()', silent => true); + +select jsonb_path_query('[]', '$.string()'); + +select jsonb_path_query('[]', 'strict $.string()'); + +select jsonb_path_query('{}', '$.string()'); + +select jsonb_path_query('[]', 'strict $.string()', silent => true); + +select jsonb_path_query('{}', '$.string()', silent => true); + +select jsonb_path_query('1.23', '$.string()'); + +select jsonb_path_query('"1.23"', '$.string()'); + +select jsonb_path_query('"1.23aaa"', '$.string()'); + +select jsonb_path_query('1234', '$.string()'); + +select jsonb_path_query('true', '$.string()'); + +select jsonb_path_query('1234', '$.string().type()'); + +select jsonb_path_query('[2, true]', '$.string()'); + +select jsonb_path_query_array('[1.23, "yes", false]', '$[*].string()'); + +select jsonb_path_query_array('[1.23, "yes", false]', '$[*].string().type()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +5:30"', '$.timestamp().string()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz().string()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz().string()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()'); + +select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()'); + +begin; + +set local timezone = 'UTC-10'; + +select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()'); + +rollback; + +select jsonb_path_query('"12:34:56"', '$.time().string()'); + +select jsonb_path_query('"2023-08-15"', '$.date().string()'); + +begin; + +set local timezone = 'UTC'; + +set local datestyle = 'German'; + +select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()'); + +rollback; + +select jsonb_path_query('null', '$.time()'); + +select jsonb_path_query('true', '$.time()'); + +select jsonb_path_query('1', '$.time()'); + +select jsonb_path_query('[]', '$.time()'); + +select jsonb_path_query('[]', 'strict $.time()'); + +select jsonb_path_query('{}', '$.time()'); + +select jsonb_path_query('"bogus"', '$.time()'); + +select jsonb '"12:34:56"' @? '$.time()'; + +select jsonb_path_query('"12:34:56"', '$.time()'); + +select jsonb_path_query('"12:34:56"', '$.time().type()'); + +select jsonb_path_query('"2023-08-15"', '$.time()'); + +select jsonb_path_query('"12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query_tz('"12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.time()'); + +select jsonb_path_query('"12:34:56.789"', '$.time(-1)'); + +select jsonb_path_query('"12:34:56.789"', '$.time(2.0)'); + +select jsonb_path_query('"12:34:56.789"', '$.time(12345678901)'); + +select jsonb_path_query('"12:34:56.789"', '$.time(0)'); + +select jsonb_path_query('"12:34:56.789"', '$.time(2)'); + +select jsonb_path_query('"12:34:56.789"', '$.time(5)'); + +select jsonb_path_query('"12:34:56.789"', '$.time(10)'); + +select jsonb_path_query('"12:34:56.789012"', '$.time(8)'); + +select jsonb_path_query('null', '$.time_tz()'); + +select jsonb_path_query('true', '$.time_tz()'); + +select jsonb_path_query('1', '$.time_tz()'); + +select jsonb_path_query('[]', '$.time_tz()'); + +select jsonb_path_query('[]', 'strict $.time_tz()'); + +select jsonb_path_query('{}', '$.time_tz()'); + +select jsonb_path_query('"bogus"', '$.time_tz()'); + +select jsonb '"12:34:56 +05:30"' @? '$.time_tz()'; + +select jsonb_path_query('"12:34:56 +05:30"', '$.time_tz()'); + +select jsonb_path_query('"12:34:56 +05:30"', '$.time_tz().type()'); + +select jsonb_path_query('"2023-08-15"', '$.time_tz()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.time_tz()'); + +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(-1)'); + +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2.0)'); + +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(12345678901)'); + +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(0)'); + +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(2)'); + +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(5)'); + +select jsonb_path_query('"12:34:56.789 +05:30"', '$.time_tz(10)'); + +select jsonb_path_query('"12:34:56.789012 +05:30"', '$.time_tz(8)'); + +select jsonb_path_query('null', '$.timestamp()'); + +select jsonb_path_query('true', '$.timestamp()'); + +select jsonb_path_query('1', '$.timestamp()'); + +select jsonb_path_query('[]', '$.timestamp()'); + +select jsonb_path_query('[]', 'strict $.timestamp()'); + +select jsonb_path_query('{}', '$.timestamp()'); + +select jsonb_path_query('"bogus"', '$.timestamp()'); + +select jsonb '"2023-08-15 12:34:56"' @? '$.timestamp()'; + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().type()'); + +select jsonb_path_query('"2023-08-15"', '$.timestamp()'); + +select jsonb_path_query('"12:34:56"', '$.timestamp()'); + +select jsonb_path_query('"12:34:56 +05:30"', '$.timestamp()'); + +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(-1)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2.0)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(12345678901)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(0)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(2)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(5)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789"', '$.timestamp(10)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789012"', '$.timestamp(8)'); + +select jsonb_path_query('null', '$.timestamp_tz()'); + +select jsonb_path_query('true', '$.timestamp_tz()'); + +select jsonb_path_query('1', '$.timestamp_tz()'); + +select jsonb_path_query('[]', '$.timestamp_tz()'); + +select jsonb_path_query('[]', 'strict $.timestamp_tz()'); + +select jsonb_path_query('{}', '$.timestamp_tz()'); + +select jsonb_path_query('"bogus"', '$.timestamp_tz()'); + +select jsonb '"2023-08-15 12:34:56 +05:30"' @? '$.timestamp_tz()'; + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz().type()'); + +select jsonb_path_query('"2023-08-15"', '$.timestamp_tz()'); + +select jsonb_path_query_tz('"2023-08-15"', '$.timestamp_tz()'); + +select jsonb_path_query('"12:34:56"', '$.timestamp_tz()'); + +select jsonb_path_query('"12:34:56 +05:30"', '$.timestamp_tz()'); + +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(-1)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2.0)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(12345678901)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(0)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(2)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(5)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789 +05:30"', '$.timestamp_tz(10)'); + +select jsonb_path_query('"2023-08-15 12:34:56.789012 +05:30"', '$.timestamp_tz(8)'); + +set time zone '+00'; + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()'); + +select jsonb_path_query('"12:34:56"', '$.time_tz()'); + +select jsonb_path_query_tz('"12:34:56"', '$.time_tz()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()'); + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")'); + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")'); + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")'); + +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")'); + +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")'); + +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")'); + +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")'); + +set time zone '+10'; + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()'); + +select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp_tz()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()'); + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")'); + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")'); + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")'); + +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")'); + +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")'); + +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")'); + +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")'); + +set time zone default; + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.time()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.time_tz()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp()'); + +select jsonb_path_query_tz('"2023-08-15 12:34:56 +05:30"', '$.timestamp()'); + +select jsonb_path_query('"2023-08-15 12:34:56 +05:30"', '$.timestamp_tz()'); + +select jsonb_path_query('"2017-03-10"', '$.datetime().type()'); + +select jsonb_path_query('"2017-03-10"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime().type()'); + +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime().type()'); + +select jsonb_path_query('"2017-03-10 12:34:56+3"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime().type()'); + +select jsonb_path_query('"2017-03-10 12:34:56+3:10"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10T12:34:56+3:10"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10t12:34:56+3:10"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10 12:34:56.789+3:10"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10T12:34:56.789+3:10"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10t12:34:56.789+3:10"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10T12:34:56.789EST"', '$.datetime()'); + +select jsonb_path_query('"2017-03-10T12:34:56.789Z"', '$.datetime()'); + +select jsonb_path_query('"12:34:56"', '$.datetime().type()'); + +select jsonb_path_query('"12:34:56"', '$.datetime()'); + +select jsonb_path_query('"12:34:56+3"', '$.datetime().type()'); + +select jsonb_path_query('"12:34:56+3"', '$.datetime()'); + +select jsonb_path_query('"12:34:56+3:10"', '$.datetime().type()'); + +select jsonb_path_query('"12:34:56+3:10"', '$.datetime()'); + +set time zone '+00'; + +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))'); + +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))'); + +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03+04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ == "2017-03-10".date())'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ >= "2017-03-10".date())'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].datetime() ? (@ < "2017-03-10".date())'); + +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ == "2017-03-10".date())'); + +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ >= "2017-03-10".date())'); + +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ < "2017-03-10".date())'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ == "2017-03-10".date())'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ >= "2017-03-10".date())'); + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03+04", "2017-03-10 03:00:00+03"]', + '$[*].date() ? (@ < "2017-03-10".date())'); + +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))'); + +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))'); + +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ == "12:35:00".time())'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ >= "12:35:00".time())'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].datetime() ? (@ < "12:35:00".time())'); + +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ == "12:35:00".time())'); + +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ >= "12:35:00".time())'); + +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ < "12:35:00".time())'); + +select jsonb_path_query( + '["12:34:00.123", "12:35:00.123", "12:36:00.1123", "12:35:00.1123+00", "12:35:00.123+01", "13:35:00.123+01", "2017-03-10 12:35:00.1", "2017-03-10 12:35:00.123+01"]', + '$[*].time(2) ? (@ >= "12:35:00.123".time(2))'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ == "12:35:00".time())'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ >= "12:35:00".time())'); + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00+00", "12:35:00+01", "13:35:00+01", "2017-03-10 12:35:00", "2017-03-10 12:35:00+01"]', + '$[*].time() ? (@ < "12:35:00".time())'); + +select jsonb_path_query_tz( + '["12:34:00.123", "12:35:00.123", "12:36:00.1123", "12:35:00.1123+00", "12:35:00.123+01", "13:35:00.123+01", "2017-03-10 12:35:00.1", "2017-03-10 12:35:00.123+01"]', + '$[*].time(2) ? (@ >= "12:35:00.123".time(2))'); + +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))'); + +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))'); + +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35:00 +1".time_tz())'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35:00 +1".time_tz())'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35:00 +1".time_tz())'); + +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ == "12:35:00 +1".time_tz())'); + +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ >= "12:35:00 +1".time_tz())'); + +select jsonb_path_query( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ < "12:35:00 +1".time_tz())'); + +select jsonb_path_query( + '["12:34:00.123+01", "12:35:00.123+01", "12:36:00.1123+01", "12:35:00.1123+02", "12:35:00.123-02", "10:35:00.123", "11:35:00.1", "12:35:00.123", "2017-03-10 12:35:00.123 +1"]', + '$[*].time_tz(2) ? (@ >= "12:35:00.123 +1".time_tz(2))'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ == "12:35:00 +1".time_tz())'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ >= "12:35:00 +1".time_tz())'); + +select jsonb_path_query_tz( + '["12:34:00+01", "12:35:00+01", "12:36:00+01", "12:35:00+02", "12:35:00-02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].time_tz() ? (@ < "12:35:00 +1".time_tz())'); + +select jsonb_path_query_tz( + '["12:34:00.123+01", "12:35:00.123+01", "12:36:00.1123+01", "12:35:00.1123+02", "12:35:00.123-02", "10:35:00.123", "11:35:00.1", "12:35:00.123", "2017-03-10 12:35:00.123 +1"]', + '$[*].time_tz(2) ? (@ >= "12:35:00.123 +1".time_tz(2))'); + +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ == "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ >= "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ < "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ == "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ >= "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ < "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00.123", "2017-03-10 12:35:00.123", "2017-03-10 12:36:00.1123", "2017-03-10 12:35:00.1123+01", "2017-03-10 13:35:00.123+01", "2017-03-10 12:35:00.1-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp(2) ? (@ >= "2017-03-10 12:35:00.123".timestamp(2))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ == "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ >= "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00+01", "2017-03-10 13:35:00+01", "2017-03-10 12:35:00-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp() ? (@ < "2017-03-10 12:35:00".timestamp())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00.123", "2017-03-10 12:35:00.123", "2017-03-10 12:36:00.1123", "2017-03-10 12:35:00.1123+01", "2017-03-10 13:35:00.123+01", "2017-03-10 12:35:00.1-01", "2017-03-10", "2017-03-11"]', + '$[*].timestamp(2) ? (@ >= "2017-03-10 12:35:00.123".timestamp(2))'); + +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56+01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].datetime() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query( + '["2017-03-10 12:34:00.123+01", "2017-03-10 12:35:00.123+01", "2017-03-10 12:36:00.1123+01", "2017-03-10 12:35:00.1123+02", "2017-03-10 12:35:00.123-02", "2017-03-10 10:35:00.123", "2017-03-10 11:35:00.1", "2017-03-10 12:35:00.123", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz(2) ? (@ >= "2017-03-10 12:35:00.123 +1".timestamp_tz(2))'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ == "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ >= "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00+01", "2017-03-10 12:35:00+01", "2017-03-10 12:36:00+01", "2017-03-10 12:35:00+02", "2017-03-10 12:35:00-02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz() ? (@ < "2017-03-10 12:35:00 +1".timestamp_tz())'); + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00.123+01", "2017-03-10 12:35:00.123+01", "2017-03-10 12:36:00.1123+01", "2017-03-10 12:35:00.1123+02", "2017-03-10 12:35:00.123-02", "2017-03-10 10:35:00.123", "2017-03-10 11:35:00.1", "2017-03-10 12:35:00.123", "2017-03-10", "2017-03-11"]', + '$[*].timestamp_tz(2) ? (@ >= "2017-03-10 12:35:00.123 +1".timestamp_tz(2))'); + +select jsonb_path_query('"1000000-01-01"', '$.datetime() > "2020-01-01 12:00:00".datetime()'::jsonpath); + +set time zone default; + +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]'); + +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)'); + +SELECT jsonb_path_query('[{"a": 1}]', '$undefined_var'); + +SELECT jsonb_path_query('[{"a": 1}]', 'false'); + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a'); + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)'); + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)'); + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}'); + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}'); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a', silent => true); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a'); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)'); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)'); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}'); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}'); + +SELECT jsonb_path_query_first('[{"a": 1}]', '$undefined_var'); + +SELECT jsonb_path_query_first('[{"a": 1}]', 'false'); + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)'; + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*] ? (@.a > 2)'; + +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 1)'); + +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 1, "max": 4}'); + +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 3, "max": 4}'); + +SELECT jsonb_path_exists('[{"a": 1}]', '$undefined_var'); + +SELECT jsonb_path_exists('[{"a": 1}]', 'false'); + +SELECT jsonb_path_match('true', '$', silent => false); + +SELECT jsonb_path_match('false', '$', silent => false); + +SELECT jsonb_path_match('null', '$', silent => false); + +SELECT jsonb_path_match('1', '$', silent => true); + +SELECT jsonb_path_match('1', '$', silent => false); + +SELECT jsonb_path_match('"a"', '$', silent => false); + +SELECT jsonb_path_match('{}', '$', silent => false); + +SELECT jsonb_path_match('[true]', '$', silent => false); + +SELECT jsonb_path_match('{}', 'lax $.a', silent => false); + +SELECT jsonb_path_match('{}', 'strict $.a', silent => false); + +SELECT jsonb_path_match('{}', 'strict $.a', silent => true); + +SELECT jsonb_path_match('[true, true]', '$[*]', silent => false); + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1'; + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 2'; + +SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1'); + +SELECT jsonb_path_match('[{"a": 1}]', '$undefined_var'); + +SELECT jsonb_path_match('[{"a": 1}]', 'false'); + +WITH str(j, num) AS +( + SELECT jsonb_build_object('s', s), num + FROM unnest('{"", "a", "ab", "abc", "abcd", "b", "A", "AB", "ABC", "ABc", "ABcD", "B"}'::text[]) WITH ORDINALITY AS a(s, num) +) +SELECT + s1.j, s2.j, + jsonb_path_query_first(s1.j, '$.s < $s', vars => s2.j) lt, + jsonb_path_query_first(s1.j, '$.s <= $s', vars => s2.j) le, + jsonb_path_query_first(s1.j, '$.s == $s', vars => s2.j) eq, + jsonb_path_query_first(s1.j, '$.s >= $s', vars => s2.j) ge, + jsonb_path_query_first(s1.j, '$.s > $s', vars => s2.j) gt +FROM str s1, str s2 +ORDER BY s1.num, s2.num; diff --git a/crates/pgt_pretty_print/tests/data/multi/jsonpath_60.sql b/crates/pgt_pretty_print/tests/data/multi/jsonpath_60.sql new file mode 100644 index 000000000..0ba0effb8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/jsonpath_60.sql @@ -0,0 +1,458 @@ +select ''::jsonpath; + +select '$'::jsonpath; + +select 'strict $'::jsonpath; + +select 'lax $'::jsonpath; + +select '$.a'::jsonpath; + +select '$.a.v'::jsonpath; + +select '$.a.*'::jsonpath; + +select '$.*[*]'::jsonpath; + +select '$.a[*]'::jsonpath; + +select '$.a[*][*]'::jsonpath; + +select '$[*]'::jsonpath; + +select '$[0]'::jsonpath; + +select '$[*][0]'::jsonpath; + +select '$[*].a'::jsonpath; + +select '$[*][0].a.b'::jsonpath; + +select '$.a.**.b'::jsonpath; + +select '$.a.**{2}.b'::jsonpath; + +select '$.a.**{2 to 2}.b'::jsonpath; + +select '$.a.**{2 to 5}.b'::jsonpath; + +select '$.a.**{0 to 5}.b'::jsonpath; + +select '$.a.**{5 to last}.b'::jsonpath; + +select '$.a.**{last}.b'::jsonpath; + +select '$.a.**{last to 5}.b'::jsonpath; + +select '$+1'::jsonpath; + +select '$-1'::jsonpath; + +select '$--+1'::jsonpath; + +select '$.a/+-1'::jsonpath; + +select '1 * 2 + 4 % -3 != false'::jsonpath; + +select '"\b\f\r\n\t\v\"\''\\"'::jsonpath; + +select '"\x50\u0067\u{53}\u{051}\u{00004C}"'::jsonpath; + +select '$.foo\x50\u0067\u{53}\u{051}\u{00004C}\t\"bar'::jsonpath; + +select '"\z"'::jsonpath; + +select '$.g ? ($.a == 1)'::jsonpath; + +select '$.g ? (@ == 1)'::jsonpath; + +select '$.g ? (@.a == 1)'::jsonpath; + +select '$.g ? (@.a == 1 || @.a == 4)'::jsonpath; + +select '$.g ? (@.a == 1 && @.a == 4)'::jsonpath; + +select '$.g ? (@.a == 1 || @.a == 4 && @.b == 7)'::jsonpath; + +select '$.g ? (@.a == 1 || !(@.a == 4) && @.b == 7)'::jsonpath; + +select '$.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7)'::jsonpath; + +select '$.g ? (@.x >= @[*]?(@.a > "abc"))'::jsonpath; + +select '$.g ? ((@.x >= 123 || @.a == 4) is unknown)'::jsonpath; + +select '$.g ? (exists (@.x))'::jsonpath; + +select '$.g ? (exists (@.x ? (@ == 14)))'::jsonpath; + +select '$.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14)))'::jsonpath; + +select '$.g ? (+@.x >= +-(+@.a + 2))'::jsonpath; + +select '$a'::jsonpath; + +select '$a.b'::jsonpath; + +select '$a[*]'::jsonpath; + +select '$.g ? (@.zip == $zip)'::jsonpath; + +select '$.a[1,2, 3 to 16]'::jsonpath; + +select '$.a[$a + 1, ($b[*]) to -($[0] * 2)]'::jsonpath; + +select '$.a[$.a.size() - 3]'::jsonpath; + +select 'last'::jsonpath; + +select '"last"'::jsonpath; + +select '$.last'::jsonpath; + +select '$ ? (last > 0)'::jsonpath; + +select '$[last]'::jsonpath; + +select '$[$[0] ? (last > 0)]'::jsonpath; + +select 'null.type()'::jsonpath; + +select '1.type()'::jsonpath; + +select '(1).type()'::jsonpath; + +select '1.2.type()'::jsonpath; + +select '"aaa".type()'::jsonpath; + +select 'true.type()'::jsonpath; + +select '$.double().floor().ceiling().abs()'::jsonpath; + +select '$.keyvalue().key'::jsonpath; + +select '$.datetime()'::jsonpath; + +select '$.datetime("datetime template")'::jsonpath; + +select '$.bigint().integer().number().decimal()'::jsonpath; + +select '$.boolean()'::jsonpath; + +select '$.date()'::jsonpath; + +select '$.decimal(4,2)'::jsonpath; + +select '$.string()'::jsonpath; + +select '$.time()'::jsonpath; + +select '$.time(6)'::jsonpath; + +select '$.time_tz()'::jsonpath; + +select '$.time_tz(4)'::jsonpath; + +select '$.timestamp()'::jsonpath; + +select '$.timestamp(2)'::jsonpath; + +select '$.timestamp_tz()'::jsonpath; + +select '$.timestamp_tz(0)'::jsonpath; + +select '$ ? (@ starts with "abc")'::jsonpath; + +select '$ ? (@ starts with $var)'::jsonpath; + +select '$ ? (@ like_regex "(invalid pattern")'::jsonpath; + +select '$ ? (@ like_regex "pattern")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "i")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "is")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "isim")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath; + +select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; + +select '$ < 1'::jsonpath; + +select '($ < 1) || $.a.b <= $x'::jsonpath; + +select '@ + 1'::jsonpath; + +select '($).a.b'::jsonpath; + +select '($.a.b).c.d'::jsonpath; + +select '($.a.b + -$.x.y).c.d'::jsonpath; + +select '(-+$.a.b).c.d'::jsonpath; + +select '1 + ($.a.b + 2).c.d'::jsonpath; + +select '1 + ($.a.b > 2).c.d'::jsonpath; + +select '($)'::jsonpath; + +select '(($))'::jsonpath; + +select '((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c)))))'::jsonpath; + +select '$ ? (@.a < 1)'::jsonpath; + +select '$ ? (@.a < -1)'::jsonpath; + +select '$ ? (@.a < +1)'::jsonpath; + +select '$ ? (@.a < .1)'::jsonpath; + +select '$ ? (@.a < -.1)'::jsonpath; + +select '$ ? (@.a < +.1)'::jsonpath; + +select '$ ? (@.a < 0.1)'::jsonpath; + +select '$ ? (@.a < -0.1)'::jsonpath; + +select '$ ? (@.a < +0.1)'::jsonpath; + +select '$ ? (@.a < 10.1)'::jsonpath; + +select '$ ? (@.a < -10.1)'::jsonpath; + +select '$ ? (@.a < +10.1)'::jsonpath; + +select '$ ? (@.a < 1e1)'::jsonpath; + +select '$ ? (@.a < -1e1)'::jsonpath; + +select '$ ? (@.a < +1e1)'::jsonpath; + +select '$ ? (@.a < .1e1)'::jsonpath; + +select '$ ? (@.a < -.1e1)'::jsonpath; + +select '$ ? (@.a < +.1e1)'::jsonpath; + +select '$ ? (@.a < 0.1e1)'::jsonpath; + +select '$ ? (@.a < -0.1e1)'::jsonpath; + +select '$ ? (@.a < +0.1e1)'::jsonpath; + +select '$ ? (@.a < 10.1e1)'::jsonpath; + +select '$ ? (@.a < -10.1e1)'::jsonpath; + +select '$ ? (@.a < +10.1e1)'::jsonpath; + +select '$ ? (@.a < 1e-1)'::jsonpath; + +select '$ ? (@.a < -1e-1)'::jsonpath; + +select '$ ? (@.a < +1e-1)'::jsonpath; + +select '$ ? (@.a < .1e-1)'::jsonpath; + +select '$ ? (@.a < -.1e-1)'::jsonpath; + +select '$ ? (@.a < +.1e-1)'::jsonpath; + +select '$ ? (@.a < 0.1e-1)'::jsonpath; + +select '$ ? (@.a < -0.1e-1)'::jsonpath; + +select '$ ? (@.a < +0.1e-1)'::jsonpath; + +select '$ ? (@.a < 10.1e-1)'::jsonpath; + +select '$ ? (@.a < -10.1e-1)'::jsonpath; + +select '$ ? (@.a < +10.1e-1)'::jsonpath; + +select '$ ? (@.a < 1e+1)'::jsonpath; + +select '$ ? (@.a < -1e+1)'::jsonpath; + +select '$ ? (@.a < +1e+1)'::jsonpath; + +select '$ ? (@.a < .1e+1)'::jsonpath; + +select '$ ? (@.a < -.1e+1)'::jsonpath; + +select '$ ? (@.a < +.1e+1)'::jsonpath; + +select '$ ? (@.a < 0.1e+1)'::jsonpath; + +select '$ ? (@.a < -0.1e+1)'::jsonpath; + +select '$ ? (@.a < +0.1e+1)'::jsonpath; + +select '$ ? (@.a < 10.1e+1)'::jsonpath; + +select '$ ? (@.a < -10.1e+1)'::jsonpath; + +select '$ ? (@.a < +10.1e+1)'::jsonpath; + +select '0'::jsonpath; + +select '00'::jsonpath; + +select '0755'::jsonpath; + +select '0.0'::jsonpath; + +select '0.000'::jsonpath; + +select '0.000e1'::jsonpath; + +select '0.000e2'::jsonpath; + +select '0.000e3'::jsonpath; + +select '0.0010'::jsonpath; + +select '0.0010e-1'::jsonpath; + +select '0.0010e+1'::jsonpath; + +select '0.0010e+2'::jsonpath; + +select '.001'::jsonpath; + +select '.001e1'::jsonpath; + +select '1.'::jsonpath; + +select '1.e1'::jsonpath; + +select '1a'::jsonpath; + +select '1e'::jsonpath; + +select '1.e'::jsonpath; + +select '1.2a'::jsonpath; + +select '1.2e'::jsonpath; + +select '1.2.e'::jsonpath; + +select '(1.2).e'::jsonpath; + +select '1e3'::jsonpath; + +select '1.e3'::jsonpath; + +select '1.e3.e'::jsonpath; + +select '1.e3.e4'::jsonpath; + +select '1.2e3'::jsonpath; + +select '1.2e3a'::jsonpath; + +select '1.2.e3'::jsonpath; + +select '(1.2).e3'::jsonpath; + +select '1..e'::jsonpath; + +select '1..e3'::jsonpath; + +select '(1.).e'::jsonpath; + +select '(1.).e3'::jsonpath; + +select '1?(2>3)'::jsonpath; + +select '0b100101'::jsonpath; + +select '0o273'::jsonpath; + +select '0x42F'::jsonpath; + +select '0b'::jsonpath; + +select '1b'::jsonpath; + +select '0b0x'::jsonpath; + +select '0o'::jsonpath; + +select '1o'::jsonpath; + +select '0o0x'::jsonpath; + +select '0x'::jsonpath; + +select '1x'::jsonpath; + +select '0x0y'::jsonpath; + +select '1_000_000'::jsonpath; + +select '1_2_3'::jsonpath; + +select '0x1EEE_FFFF'::jsonpath; + +select '0o2_73'::jsonpath; + +select '0b10_0101'::jsonpath; + +select '1_000.000_005'::jsonpath; + +select '1_000.'::jsonpath; + +select '.000_005'::jsonpath; + +select '1_000.5e0_1'::jsonpath; + +select '_100'::jsonpath; + +select '100_'::jsonpath; + +select '100__000'::jsonpath; + +select '_1_000.5'::jsonpath; + +select '1_000_.5'::jsonpath; + +select '1_000._5'::jsonpath; + +select '1_000.5_'::jsonpath; + +select '1_000.5e_1'::jsonpath; + +select '0b_10_0101'::jsonpath; + +select '0o_273'::jsonpath; + +select '0x_42F'::jsonpath; + +SELECT str as jsonpath, + pg_input_is_valid(str,'jsonpath') as ok, + errinfo.sql_error_code, + errinfo.message, + errinfo.detail, + errinfo.hint +FROM unnest(ARRAY['$ ? (@ like_regex "pattern" flag "smixq")'::text, + '$ ? (@ like_regex "pattern" flag "a")', + '@ + 1', + '00', + '1a']) str, + LATERAL pg_input_error_info(str, 'jsonpath') as errinfo; diff --git a/crates/pgt_pretty_print/tests/data/multi/jsonpath_encoding_60.sql b/crates/pgt_pretty_print/tests/data/multi/jsonpath_encoding_60.sql new file mode 100644 index 000000000..c5ed7a425 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/jsonpath_encoding_60.sql @@ -0,0 +1,64 @@ +SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII') + AS skip_test ; + +SELECT getdatabaseencoding(); + +SELECT '"\u"'::jsonpath; + +SELECT '"\u00"'::jsonpath; + +SELECT '"\u000g"'::jsonpath; + +SELECT '"\u0000"'::jsonpath; + +SELECT '"\uaBcD"'::jsonpath; + +select '"\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; + +select '"\ud83d\ud83d"'::jsonpath; + +select '"\ude04\ud83d"'::jsonpath; + +select '"\ud83dX"'::jsonpath; + +select '"\ude04X"'::jsonpath; + +select '"the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; + +select '"dollar \u0024 character"'::jsonpath as correct_everywhere; + +select '"dollar \\u0024 character"'::jsonpath as not_an_escape; + +select '"null \u0000 escape"'::jsonpath as not_unescaped; + +select '"null \\u0000 escape"'::jsonpath as not_an_escape; + +SELECT '$."\u"'::jsonpath; + +SELECT '$."\u00"'::jsonpath; + +SELECT '$."\u000g"'::jsonpath; + +SELECT '$."\u0000"'::jsonpath; + +SELECT '$."\uaBcD"'::jsonpath; + +select '$."\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; + +select '$."\ud83d\ud83d"'::jsonpath; + +select '$."\ude04\ud83d"'::jsonpath; + +select '$."\ud83dX"'::jsonpath; + +select '$."\ude04X"'::jsonpath; + +select '$."the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; + +select '$."dollar \u0024 character"'::jsonpath as correct_everywhere; + +select '$."dollar \\u0024 character"'::jsonpath as not_an_escape; + +select '$."null \u0000 escape"'::jsonpath as not_unescaped; + +select '$."null \\u0000 escape"'::jsonpath as not_an_escape; diff --git a/crates/pgt_pretty_print/tests/data/multi/largeobject_60.sql b/crates/pgt_pretty_print/tests/data/multi/largeobject_60.sql new file mode 100644 index 000000000..b16072178 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/largeobject_60.sql @@ -0,0 +1,283 @@ +SET bytea_output TO escape; + +CREATE ROLE regress_lo_user; + +SELECT lo_create(42); + +ALTER LARGE OBJECT 42 OWNER TO regress_lo_user; + +SET SESSION AUTHORIZATION regress_lo_user; + +GRANT SELECT ON LARGE OBJECT 42 TO public; + +COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer'; + +RESET SESSION AUTHORIZATION; + +CREATE TABLE lotest_stash_values (loid oid, fd integer); + +INSERT INTO lotest_stash_values (loid) SELECT lo_creat(42); + +BEGIN; + +UPDATE lotest_stash_values SET fd = lo_open(loid, CAST(x'20000' | x'40000' AS integer)); + +SELECT lowrite(fd, ' +I wandered lonely as a cloud +That floats on high o''er vales and hills, +When all at once I saw a crowd, +A host, of golden daffodils; +Beside the lake, beneath the trees, +Fluttering and dancing in the breeze. + +Continuous as the stars that shine +And twinkle on the milky way, +They stretched in never-ending line +Along the margin of a bay: +Ten thousand saw I at a glance, +Tossing their heads in sprightly dance. + +The waves beside them danced; but they +Out-did the sparkling waves in glee: +A poet could not but be gay, +In such a jocund company: +I gazed--and gazed--but little thought +What wealth the show to me had brought: + +For oft, when on my couch I lie +In vacant or in pensive mood, +They flash upon that inward eye +Which is the bliss of solitude; +And then my heart with pleasure fills, +And dances with the daffodils. + + -- William Wordsworth +') FROM lotest_stash_values; + +SELECT lo_close(fd) FROM lotest_stash_values; + +END; + +SELECT lo_from_bytea(0, lo_get(loid)) AS newloid FROM lotest_stash_values + +BEGIN; + +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)); + +SELECT lo_lseek(fd, 104, 0) FROM lotest_stash_values; + +SELECT loread(fd, 28) FROM lotest_stash_values; + +SELECT lo_lseek(fd, -19, 1) FROM lotest_stash_values; + +SELECT lowrite(fd, 'n') FROM lotest_stash_values; + +SELECT lo_tell(fd) FROM lotest_stash_values; + +SELECT lo_lseek(fd, -744, 2) FROM lotest_stash_values; + +SELECT loread(fd, 28) FROM lotest_stash_values; + +SELECT lo_close(fd) FROM lotest_stash_values; + +END; + +BEGIN; + +SELECT lo_open(loid, x'40000'::int) from lotest_stash_values; + +ABORT; + +DO 'dobody'; + +BEGIN; + +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)); + +SELECT lo_truncate(fd, 11) FROM lotest_stash_values; + +SELECT loread(fd, 15) FROM lotest_stash_values; + +SELECT lo_truncate(fd, 10000) FROM lotest_stash_values; + +SELECT loread(fd, 10) FROM lotest_stash_values; + +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values; + +SELECT lo_tell(fd) FROM lotest_stash_values; + +SELECT lo_truncate(fd, 5000) FROM lotest_stash_values; + +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values; + +SELECT lo_tell(fd) FROM lotest_stash_values; + +SELECT lo_close(fd) FROM lotest_stash_values; + +END; + +BEGIN; + +UPDATE lotest_stash_values SET fd = lo_open(loid, CAST(x'20000' | x'40000' AS integer)); + +SELECT lo_lseek64(fd, 4294967296, 0) FROM lotest_stash_values; + +SELECT lowrite(fd, 'offset:4GB') FROM lotest_stash_values; + +SELECT lo_tell64(fd) FROM lotest_stash_values; + +SELECT lo_lseek64(fd, -10, 1) FROM lotest_stash_values; + +SELECT lo_tell64(fd) FROM lotest_stash_values; + +SELECT loread(fd, 10) FROM lotest_stash_values; + +SELECT lo_truncate64(fd, 5000000000) FROM lotest_stash_values; + +SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values; + +SELECT lo_tell64(fd) FROM lotest_stash_values; + +SELECT lo_truncate64(fd, 3000000000) FROM lotest_stash_values; + +SELECT lo_lseek64(fd, 0, 2) FROM lotest_stash_values; + +SELECT lo_tell64(fd) FROM lotest_stash_values; + +SELECT lo_close(fd) FROM lotest_stash_values; + +END; + +SELECT lo_unlink(loid) from lotest_stash_values; + +TRUNCATE lotest_stash_values; + +INSERT INTO lotest_stash_values (loid) SELECT lo_import('filename'); + +BEGIN; + +UPDATE lotest_stash_values SET fd=lo_open(loid, CAST(x'20000' | x'40000' AS integer)); + +SELECT lo_lseek(fd, 0, 2) FROM lotest_stash_values; + +SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values; + +SELECT loread(fd, 36) FROM lotest_stash_values; + +SELECT lo_tell(fd) FROM lotest_stash_values; + +SELECT lo_lseek(fd, -26, 1) FROM lotest_stash_values; + +SELECT lowrite(fd, 'abcdefghijklmnop') FROM lotest_stash_values; + +SELECT lo_lseek(fd, 2030, 0) FROM lotest_stash_values; + +SELECT loread(fd, 36) FROM lotest_stash_values; + +SELECT lo_close(fd) FROM lotest_stash_values; + +END; + +SELECT lo_export(loid, 'filename') FROM lotest_stash_values; + +SELECT pageno, data FROM pg_largeobject WHERE loid = (SELECT loid from lotest_stash_values) +EXCEPT +SELECT pageno, data FROM pg_largeobject WHERE loid = 'newloid'; + +SELECT lo_unlink(loid) FROM lotest_stash_values; + +TRUNCATE lotest_stash_values; + +SELECT lo_from_bytea(0, lo_get('newloid_1')) AS newloid_2 + +SELECT fipshash(lo_get('newloid_1')) = fipshash(lo_get('newloid_2')); + +SELECT lo_get('newloid_1', 0, 20); + +SELECT lo_get('newloid_1', 10, 20); + +SELECT lo_put('newloid_1', 5, decode('afafafaf', 'hex')); + +SELECT lo_get('newloid_1', 0, 20); + +SELECT lo_put('newloid_1', 4294967310, 'foo'); + +SELECT lo_get('newloid_1'); + +SELECT lo_get('newloid_1', 4294967294, 100); + +SELECT lo_from_bytea(0, E'\\xdeadbeef') AS newloid + +SET bytea_output TO hex; + +SELECT lo_get('newloid'); + +SELECT lo_create(2121); + +COMMENT ON LARGE OBJECT 2121 IS 'testing comments'; + +START TRANSACTION READ ONLY; + +SELECT lo_open(2121, x'40000'::int); + +SELECT lo_open(2121, x'20000'::int); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_create(42); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_creat(42); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_unlink(42); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lowrite(42, 'x'); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_import('filename'); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_truncate(42, 0); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_truncate64(42, 0); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_from_bytea(0, 'x'); + +ROLLBACK; + +START TRANSACTION READ ONLY; + +SELECT lo_put(42, 0, 'x'); + +ROLLBACK; + +DROP TABLE lotest_stash_values; + +DROP ROLE regress_lo_user; diff --git a/crates/pgt_pretty_print/tests/data/multi/limit_60.sql b/crates/pgt_pretty_print/tests/data/multi/limit_60.sql new file mode 100644 index 000000000..d0a4e6b40 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/limit_60.sql @@ -0,0 +1,97 @@ +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 50 + ORDER BY unique1 LIMIT 2; + +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 60 + ORDER BY unique1 LIMIT 5; + +SELECT ''::text AS two, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 60 AND unique1 < 63 + ORDER BY unique1 LIMIT 5; + +SELECT ''::text AS three, unique1, unique2, stringu1 + FROM onek WHERE unique1 > 100 + ORDER BY unique1 LIMIT 3 OFFSET 20; + +SELECT ''::text AS zero, unique1, unique2, stringu1 + FROM onek WHERE unique1 < 50 + ORDER BY unique1 DESC LIMIT 8 OFFSET 99; + +SELECT ''::text AS eleven, unique1, unique2, stringu1 + FROM onek WHERE unique1 < 50 + ORDER BY unique1 DESC LIMIT 20 OFFSET 39; + +SELECT ''::text AS ten, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 OFFSET 990; + +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 OFFSET 990 LIMIT 5; + +SELECT ''::text AS five, unique1, unique2, stringu1 + FROM onek + ORDER BY unique1 LIMIT 5 OFFSET 900; + +select * from int8_tbl limit (case when random() < 0.5 then null::bigint end); + +select * from int8_tbl offset (case when random() < 0.5 then null::bigint end); + +begin; + +declare c1 cursor for select * from int8_tbl limit 10; + +fetch all in c1; + +fetch 1 in c1; + +fetch backward 1 in c1; + +fetch backward all in c1; + +fetch backward 1 in c1; + +fetch all in c1; + +declare c2 cursor for select * from int8_tbl limit 3; + +fetch all in c2; + +fetch 1 in c2; + +fetch backward 1 in c2; + +fetch backward all in c2; + +fetch backward 1 in c2; + +fetch all in c2; + +declare c3 cursor for select * from int8_tbl offset 3; + +fetch all in c3; + +fetch 1 in c3; + +fetch backward 1 in c3; + +fetch backward all in c3; + +fetch backward 1 in c3; + +fetch all in c3; + +declare c4 cursor for select * from int8_tbl offset 10; + +fetch all in c4; + +fetch 1 in c4; + +fetch backward 1 in c4; + +fetch backward all in c4; + +fetch backward 1 in c4; + +fetch all in c4; diff --git a/crates/pgt_pretty_print/tests/data/multi/line_60.sql b/crates/pgt_pretty_print/tests/data/multi/line_60.sql new file mode 100644 index 000000000..fdcf99ccd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/line_60.sql @@ -0,0 +1,70 @@ +CREATE TABLE LINE_TBL (s line); + +INSERT INTO LINE_TBL VALUES ('{0,-1,5}'); + +INSERT INTO LINE_TBL VALUES ('{1,0,5}'); + +INSERT INTO LINE_TBL VALUES ('{0,3,0}'); + +INSERT INTO LINE_TBL VALUES (' (0,0), (6,6)'); + +INSERT INTO LINE_TBL VALUES ('10,-10 ,-5,-4'); + +INSERT INTO LINE_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); + +INSERT INTO LINE_TBL VALUES ('{3,NaN,5}'); + +INSERT INTO LINE_TBL VALUES ('{NaN,NaN,NaN}'); + +INSERT INTO LINE_TBL VALUES ('[(1,3),(2,3)]'); + +INSERT INTO LINE_TBL VALUES (line(point '(3,1)', point '(3,2)')); + +INSERT INTO LINE_TBL VALUES ('{}'); + +INSERT INTO LINE_TBL VALUES ('{0'); + +INSERT INTO LINE_TBL VALUES ('{0,0}'); + +INSERT INTO LINE_TBL VALUES ('{0,0,1'); + +INSERT INTO LINE_TBL VALUES ('{0,0,1}'); + +INSERT INTO LINE_TBL VALUES ('{0,0,1} x'); + +INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)'); + +INSERT INTO LINE_TBL VALUES ('[1,2,3, 4'); + +INSERT INTO LINE_TBL VALUES ('[(,2),(3,4)]'); + +INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)'); + +INSERT INTO LINE_TBL VALUES ('[(1,2),(1,2)]'); + +INSERT INTO LINE_TBL VALUES (line(point '(1,0)', point '(1,0)')); + +select * from LINE_TBL; + +select '{nan, 1, nan}'::line = '{nan, 1, nan}'::line as true, + '{nan, 1, nan}'::line = '{nan, 2, nan}'::line as false; + +SELECT pg_input_is_valid('{1, 1}', 'line'); + +SELECT * FROM pg_input_error_info('{1, 1}', 'line'); + +SELECT pg_input_is_valid('{0, 0, 0}', 'line'); + +SELECT * FROM pg_input_error_info('{0, 0, 0}', 'line'); + +SELECT pg_input_is_valid('{1, 1, a}', 'line'); + +SELECT * FROM pg_input_error_info('{1, 1, a}', 'line'); + +SELECT pg_input_is_valid('{1, 1, 1e400}', 'line'); + +SELECT * FROM pg_input_error_info('{1, 1, 1e400}', 'line'); + +SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line'); + +SELECT * FROM pg_input_error_info('(1, 1), (1, 1e400)', 'line'); diff --git a/crates/pgt_pretty_print/tests/data/multi/lock_60.sql b/crates/pgt_pretty_print/tests/data/multi/lock_60.sql new file mode 100644 index 000000000..1ce54148b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/lock_60.sql @@ -0,0 +1,276 @@ +CREATE SCHEMA lock_schema1; + +SET search_path = lock_schema1; + +CREATE TABLE lock_tbl1 (a BIGINT); + +CREATE TABLE lock_tbl1a (a BIGINT); + +CREATE VIEW lock_view1 AS SELECT * FROM lock_tbl1; + +CREATE VIEW lock_view2(a,b) AS SELECT * FROM lock_tbl1, lock_tbl1a; + +CREATE VIEW lock_view3 AS SELECT * from lock_view2; + +CREATE VIEW lock_view4 AS SELECT (select a from lock_tbl1a limit 1) from lock_tbl1; + +CREATE VIEW lock_view5 AS SELECT * from lock_tbl1 where a in (select * from lock_tbl1a); + +CREATE VIEW lock_view6 AS SELECT * from (select * from lock_tbl1) sub; + +CREATE ROLE regress_rol_lock1; + +ALTER ROLE regress_rol_lock1 SET search_path = lock_schema1; + +GRANT USAGE ON SCHEMA lock_schema1 TO regress_rol_lock1; + +BEGIN TRANSACTION; + +LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE; + +LOCK lock_tbl1 IN ROW SHARE MODE; + +LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE; + +LOCK TABLE lock_tbl1 IN SHARE MODE; + +LOCK lock_tbl1 IN SHARE ROW EXCLUSIVE MODE; + +LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE; + +LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE; + +ROLLBACK; + +BEGIN TRANSACTION; + +LOCK TABLE lock_tbl1 IN ACCESS SHARE MODE NOWAIT; + +LOCK TABLE lock_tbl1 IN ROW SHARE MODE NOWAIT; + +LOCK TABLE lock_tbl1 IN ROW EXCLUSIVE MODE NOWAIT; + +LOCK TABLE lock_tbl1 IN SHARE MODE NOWAIT; + +LOCK TABLE lock_tbl1 IN SHARE ROW EXCLUSIVE MODE NOWAIT; + +LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE NOWAIT; + +LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE NOWAIT; + +ROLLBACK; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view1 IN EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname; + +ROLLBACK; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view2 IN EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname; + +ROLLBACK; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view3 IN EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname; + +ROLLBACK; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view4 IN EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname; + +ROLLBACK; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view5 IN EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname; + +ROLLBACK; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view6 IN EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' + order by relname; + +ROLLBACK; + +CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view2 IN EXCLUSIVE MODE; + +ROLLBACK; + +CREATE VIEW lock_view7 AS SELECT * from lock_view2; + +BEGIN TRANSACTION; + +LOCK TABLE lock_view7 IN EXCLUSIVE MODE; + +ROLLBACK; + +CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1); + +CREATE TABLE lock_tbl3 () INHERITS (lock_tbl2); + +BEGIN TRANSACTION; + +LOCK TABLE lock_tbl1 * IN ACCESS EXCLUSIVE MODE; + +ROLLBACK; + +GRANT UPDATE ON TABLE lock_tbl1 TO regress_rol_lock1; + +SET ROLE regress_rol_lock1; + +BEGIN; + +LOCK TABLE lock_tbl2; + +ROLLBACK; + +BEGIN; + +LOCK TABLE lock_tbl1 * IN ACCESS EXCLUSIVE MODE; + +ROLLBACK; + +BEGIN; + +LOCK TABLE ONLY lock_tbl1; + +ROLLBACK; + +RESET ROLE; + +REVOKE UPDATE ON TABLE lock_tbl1 FROM regress_rol_lock1; + +SET ROLE regress_rol_lock1; + +BEGIN; + +LOCK TABLE lock_view1; + +ROLLBACK; + +RESET ROLE; + +GRANT UPDATE ON TABLE lock_view1 TO regress_rol_lock1; + +SET ROLE regress_rol_lock1; + +BEGIN; + +LOCK TABLE lock_view1 IN ACCESS EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'AccessExclusiveLock' + order by relname; + +ROLLBACK; + +RESET ROLE; + +REVOKE UPDATE ON TABLE lock_view1 FROM regress_rol_lock1; + +CREATE VIEW lock_view8 WITH (security_invoker) AS SELECT * FROM lock_tbl1; + +SET ROLE regress_rol_lock1; + +BEGIN; + +LOCK TABLE lock_view8; + +ROLLBACK; + +RESET ROLE; + +GRANT UPDATE ON TABLE lock_view8 TO regress_rol_lock1; + +SET ROLE regress_rol_lock1; + +BEGIN; + +LOCK TABLE lock_view8; + +ROLLBACK; + +RESET ROLE; + +GRANT UPDATE ON TABLE lock_tbl1 TO regress_rol_lock1; + +BEGIN; + +LOCK TABLE lock_view8 IN ACCESS EXCLUSIVE MODE; + +select relname from pg_locks l, pg_class c + where l.relation = c.oid and relname like '%lock_%' and mode = 'AccessExclusiveLock' + order by relname; + +ROLLBACK; + +RESET ROLE; + +REVOKE UPDATE ON TABLE lock_view8 FROM regress_rol_lock1; + +DROP VIEW lock_view8; + +DROP VIEW lock_view7; + +DROP VIEW lock_view6; + +DROP VIEW lock_view5; + +DROP VIEW lock_view4; + +DROP VIEW lock_view3 CASCADE; + +DROP VIEW lock_view1; + +DROP TABLE lock_tbl3; + +DROP TABLE lock_tbl2; + +DROP TABLE lock_tbl1; + +DROP TABLE lock_tbl1a; + +DROP SCHEMA lock_schema1 CASCADE; + +DROP ROLE regress_rol_lock1; + +RESET search_path; + +CREATE FUNCTION test_atomic_ops() + RETURNS bool + AS 'regresslib' + LANGUAGE C; + +SELECT test_atomic_ops(); diff --git a/crates/pgt_pretty_print/tests/data/multi/lseg_60.sql b/crates/pgt_pretty_print/tests/data/multi/lseg_60.sql new file mode 100644 index 000000000..4c97ee28c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/lseg_60.sql @@ -0,0 +1,31 @@ +CREATE TABLE LSEG_TBL (s lseg); + +INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)]'); + +INSERT INTO LSEG_TBL VALUES ('(0,0),(6,6)'); + +INSERT INTO LSEG_TBL VALUES ('10,-10 ,-3,-4'); + +INSERT INTO LSEG_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); + +INSERT INTO LSEG_TBL VALUES (lseg(point(11, 22), point(33,44))); + +INSERT INTO LSEG_TBL VALUES ('[(-10,2),(-10,3)]'); + +INSERT INTO LSEG_TBL VALUES ('[(0,-20),(30,-20)]'); + +INSERT INTO LSEG_TBL VALUES ('[(NaN,1),(NaN,90)]'); + +INSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)'); + +INSERT INTO LSEG_TBL VALUES ('[1,2,3, 4'); + +INSERT INTO LSEG_TBL VALUES ('[(,2),(3,4)]'); + +INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)'); + +select * from LSEG_TBL; + +SELECT pg_input_is_valid('[(1,2),(3)]', 'lseg'); + +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'lseg'); diff --git a/crates/pgt_pretty_print/tests/data/multi/macaddr8_60.sql b/crates/pgt_pretty_print/tests/data/multi/macaddr8_60.sql new file mode 100644 index 000000000..18ea24213 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/macaddr8_60.sql @@ -0,0 +1,141 @@ +SELECT '08:00:2b:01:02:03 '::macaddr8; + +SELECT ' 08:00:2b:01:02:03 '::macaddr8; + +SELECT ' 08:00:2b:01:02:03'::macaddr8; + +SELECT '08:00:2b:01:02:03:04:05 '::macaddr8; + +SELECT ' 08:00:2b:01:02:03:04:05 '::macaddr8; + +SELECT ' 08:00:2b:01:02:03:04:05'::macaddr8; + +SELECT '123 08:00:2b:01:02:03'::macaddr8; + +SELECT '08:00:2b:01:02:03 123'::macaddr8; + +SELECT '123 08:00:2b:01:02:03:04:05'::macaddr8; + +SELECT '08:00:2b:01:02:03:04:05 123'::macaddr8; + +SELECT '08:00:2b:01:02:03:04:05:06:07'::macaddr8; + +SELECT '08-00-2b-01-02-03-04-05-06-07'::macaddr8; + +SELECT '08002b:01020304050607'::macaddr8; + +SELECT '08002b01020304050607'::macaddr8; + +SELECT '0z002b0102030405'::macaddr8; + +SELECT '08002b010203xyza'::macaddr8; + +SELECT '08:00-2b:01:02:03:04:05'::macaddr8; + +SELECT '08:00-2b:01:02:03:04:05'::macaddr8; + +SELECT '08:00:2b:01.02:03:04:05'::macaddr8; + +SELECT '08:00:2b:01.02:03:04:05'::macaddr8; + +SELECT macaddr8_set7bit('00:08:2b:01:02:03'::macaddr8); + +CREATE TABLE macaddr8_data (a int, b macaddr8); + +INSERT INTO macaddr8_data VALUES (1, '08:00:2b:01:02:03'); + +INSERT INTO macaddr8_data VALUES (2, '08-00-2b-01-02-03'); + +INSERT INTO macaddr8_data VALUES (3, '08002b:010203'); + +INSERT INTO macaddr8_data VALUES (4, '08002b-010203'); + +INSERT INTO macaddr8_data VALUES (5, '0800.2b01.0203'); + +INSERT INTO macaddr8_data VALUES (6, '0800-2b01-0203'); + +INSERT INTO macaddr8_data VALUES (7, '08002b010203'); + +INSERT INTO macaddr8_data VALUES (8, '0800:2b01:0203'); + +INSERT INTO macaddr8_data VALUES (9, 'not even close'); + +INSERT INTO macaddr8_data VALUES (10, '08:00:2b:01:02:04'); + +INSERT INTO macaddr8_data VALUES (11, '08:00:2b:01:02:02'); + +INSERT INTO macaddr8_data VALUES (12, '08:00:2a:01:02:03'); + +INSERT INTO macaddr8_data VALUES (13, '08:00:2c:01:02:03'); + +INSERT INTO macaddr8_data VALUES (14, '08:00:2a:01:02:04'); + +INSERT INTO macaddr8_data VALUES (15, '08:00:2b:01:02:03:04:05'); + +INSERT INTO macaddr8_data VALUES (16, '08-00-2b-01-02-03-04-05'); + +INSERT INTO macaddr8_data VALUES (17, '08002b:0102030405'); + +INSERT INTO macaddr8_data VALUES (18, '08002b-0102030405'); + +INSERT INTO macaddr8_data VALUES (19, '0800.2b01.0203.0405'); + +INSERT INTO macaddr8_data VALUES (20, '08002b01:02030405'); + +INSERT INTO macaddr8_data VALUES (21, '08002b0102030405'); + +SELECT * FROM macaddr8_data ORDER BY 1; + +CREATE INDEX macaddr8_data_btree ON macaddr8_data USING btree (b); + +CREATE INDEX macaddr8_data_hash ON macaddr8_data USING hash (b); + +SELECT a, b, trunc(b) FROM macaddr8_data ORDER BY 2, 1; + +SELECT b < '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; + +SELECT b > '08:00:2b:ff:fe:01:02:04' FROM macaddr8_data WHERE a = 1; + +SELECT b > '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1; + +SELECT b::macaddr <= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; + +SELECT b::macaddr >= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; + +SELECT b = '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1; + +SELECT b::macaddr <> '08:00:2b:01:02:04'::macaddr FROM macaddr8_data WHERE a = 1; + +SELECT b::macaddr <> '08:00:2b:01:02:03'::macaddr FROM macaddr8_data WHERE a = 1; + +SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; + +SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; + +SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; + +SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; + +SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; + +SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; + +SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; + +SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; + +SELECT ~b FROM macaddr8_data; + +SELECT b & '00:00:00:ff:ff:ff' FROM macaddr8_data; + +SELECT b | '01:02:03:04:05:06' FROM macaddr8_data; + +DROP TABLE macaddr8_data; + +SELECT pg_input_is_valid('08:00:2b:01:02:03:04:ZZ', 'macaddr8'); + +SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:ZZ', 'macaddr8'); + +SELECT pg_input_is_valid('08:00:2b:01:02:03:04:', 'macaddr8'); + +SELECT * FROM pg_input_error_info('08:00:2b:01:02:03:04:', 'macaddr8'); diff --git a/crates/pgt_pretty_print/tests/data/multi/macaddr_60.sql b/crates/pgt_pretty_print/tests/data/multi/macaddr_60.sql new file mode 100644 index 000000000..225f865fe --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/macaddr_60.sql @@ -0,0 +1,69 @@ +CREATE TABLE macaddr_data (a int, b macaddr); + +INSERT INTO macaddr_data VALUES (1, '08:00:2b:01:02:03'); + +INSERT INTO macaddr_data VALUES (2, '08-00-2b-01-02-03'); + +INSERT INTO macaddr_data VALUES (3, '08002b:010203'); + +INSERT INTO macaddr_data VALUES (4, '08002b-010203'); + +INSERT INTO macaddr_data VALUES (5, '0800.2b01.0203'); + +INSERT INTO macaddr_data VALUES (6, '0800-2b01-0203'); + +INSERT INTO macaddr_data VALUES (7, '08002b010203'); + +INSERT INTO macaddr_data VALUES (8, '0800:2b01:0203'); + +INSERT INTO macaddr_data VALUES (9, 'not even close'); + +INSERT INTO macaddr_data VALUES (10, '08:00:2b:01:02:04'); + +INSERT INTO macaddr_data VALUES (11, '08:00:2b:01:02:02'); + +INSERT INTO macaddr_data VALUES (12, '08:00:2a:01:02:03'); + +INSERT INTO macaddr_data VALUES (13, '08:00:2c:01:02:03'); + +INSERT INTO macaddr_data VALUES (14, '08:00:2a:01:02:04'); + +SELECT * FROM macaddr_data; + +CREATE INDEX macaddr_data_btree ON macaddr_data USING btree (b); + +CREATE INDEX macaddr_data_hash ON macaddr_data USING hash (b); + +SELECT a, b, trunc(b) FROM macaddr_data ORDER BY 2, 1; + +SELECT b < '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; + +SELECT b > '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; + +SELECT b > '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; + +SELECT b <= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; + +SELECT b >= '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; + +SELECT b = '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; + +SELECT b <> '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; + +SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; + +SELECT ~b FROM macaddr_data; + +SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data; + +SELECT b | '01:02:03:04:05:06' FROM macaddr_data; + +DROP TABLE macaddr_data; + +SELECT pg_input_is_valid('08:00:2b:01:02:ZZ', 'macaddr'); + +SELECT * FROM pg_input_error_info('08:00:2b:01:02:ZZ', 'macaddr'); + +SELECT pg_input_is_valid('08:00:2b:01:02:', 'macaddr'); + +SELECT * FROM pg_input_error_info('08:00:2b:01:02:', 'macaddr'); diff --git a/crates/pgt_pretty_print/tests/data/multi/maintain_every_60.sql b/crates/pgt_pretty_print/tests/data/multi/maintain_every_60.sql new file mode 100644 index 000000000..fe0b29329 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/maintain_every_60.sql @@ -0,0 +1,31 @@ +CREATE ROLE regress_maintain; + +SET ROLE regress_maintain; + +CREATE TEMP TABLE past_inh_db_other (); + +CREATE TEMP TABLE past_inh_db_child () INHERITS (past_inh_db_parent); + +CREATE INDEX ON past_inh_db_parent ((1)); + +ANALYZE past_inh_db_parent; + +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass; + +DROP TABLE past_inh_db_child; + +SET client_min_messages = error; + +ANALYZE; + +RESET client_min_messages; + +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_db_parent'::regclass; + +DROP TABLE past_inh_db_parent, past_inh_db_other; + +RESET ROLE; + +DROP ROLE regress_maintain; diff --git a/crates/pgt_pretty_print/tests/data/multi/matview_60.sql b/crates/pgt_pretty_print/tests/data/multi/matview_60.sql new file mode 100644 index 000000000..7f1895d08 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/matview_60.sql @@ -0,0 +1,112 @@ +CREATE TABLE mvtest_t (id int NOT NULL PRIMARY KEY, type text NOT NULL, amt numeric NOT NULL); + +INSERT INTO mvtest_t VALUES + (1, 'x', 2), + (2, 'x', 3), + (3, 'y', 5), + (4, 'y', 7), + (5, 'z', 11); + +CREATE VIEW mvtest_tv AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type; + +SELECT * FROM mvtest_tv ORDER BY type; + +CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type WITH NO DATA; + +CREATE MATERIALIZED VIEW mvtest_tm AS SELECT type, sum(amt) AS totamt FROM mvtest_t GROUP BY type WITH NO DATA; + +SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass; + +SELECT * FROM mvtest_tm ORDER BY type; + +REFRESH MATERIALIZED VIEW mvtest_tm; + +SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_tm'::regclass; + +CREATE UNIQUE INDEX mvtest_tm_type ON mvtest_tm (type); + +SELECT * FROM mvtest_tm ORDER BY type; + +CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type; + +CREATE MATERIALIZED VIEW mvtest_tvm AS SELECT * FROM mvtest_tv ORDER BY type; + +SELECT * FROM mvtest_tvm; + +CREATE MATERIALIZED VIEW mvtest_tmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tm; + +CREATE MATERIALIZED VIEW mvtest_tvmm AS SELECT sum(totamt) AS grandtot FROM mvtest_tvm; + +CREATE UNIQUE INDEX mvtest_tvmm_expr ON mvtest_tvmm ((grandtot > 0)); + +CREATE UNIQUE INDEX mvtest_tvmm_pred ON mvtest_tvmm (grandtot) WHERE grandtot < 0; + +CREATE VIEW mvtest_tvv AS SELECT sum(totamt) AS grandtot FROM mvtest_tv; + +CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv; + +CREATE MATERIALIZED VIEW mvtest_tvvm AS SELECT * FROM mvtest_tvv; + +CREATE VIEW mvtest_tvvmv AS SELECT * FROM mvtest_tvvm; + +CREATE MATERIALIZED VIEW mvtest_bb AS SELECT * FROM mvtest_tvvmv; + +CREATE INDEX mvtest_aa ON mvtest_bb (grandtot); + +CREATE SCHEMA mvtest_mvschema; + +ALTER MATERIALIZED VIEW mvtest_tvm SET SCHEMA mvtest_mvschema; + +SET search_path = mvtest_mvschema, public; + +INSERT INTO mvtest_t VALUES (6, 'z', 13); + +SELECT * FROM mvtest_tm ORDER BY type; + +SELECT * FROM mvtest_tvm ORDER BY type; + +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tm; + +REFRESH MATERIALIZED VIEW mvtest_tvm; + +SELECT * FROM mvtest_tm ORDER BY type; + +SELECT * FROM mvtest_tvm ORDER BY type; + +RESET search_path; + +SELECT * FROM mvtest_tmm; + +SELECT * FROM mvtest_tvmm; + +SELECT * FROM mvtest_tvvm; + +SELECT * FROM mvtest_tmm; + +SELECT * FROM mvtest_tvmm; + +SELECT * FROM mvtest_tvvm; + +REFRESH MATERIALIZED VIEW mvtest_tmm; + +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm; + +REFRESH MATERIALIZED VIEW mvtest_tvmm; + +REFRESH MATERIALIZED VIEW mvtest_tvvm; + +SELECT * FROM mvtest_tmm; + +SELECT * FROM mvtest_tvmm; + +SELECT * FROM mvtest_tvvm; + +SELECT * FROM mvtest_tmm; + +SELECT * FROM mvtest_tvmm; + +SELECT * FROM mvtest_tvvm; + +DROP MATERIALIZED VIEW IF EXISTS no_such_mv; + +REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_tvmm diff --git a/crates/pgt_pretty_print/tests/data/multi/md5_60.sql b/crates/pgt_pretty_print/tests/data/multi/md5_60.sql new file mode 100644 index 000000000..28aa1c44b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/md5_60.sql @@ -0,0 +1,27 @@ +select md5('') = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE"; + +select md5('a') = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE"; + +select md5('abc') = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE"; + +select md5('message digest') = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE"; + +select md5('abcdefghijklmnopqrstuvwxyz') = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE"; + +select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE"; + +select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890') = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE"; + +select md5(''::bytea) = 'd41d8cd98f00b204e9800998ecf8427e' AS "TRUE"; + +select md5('a'::bytea) = '0cc175b9c0f1b6a831c399e269772661' AS "TRUE"; + +select md5('abc'::bytea) = '900150983cd24fb0d6963f7d28e17f72' AS "TRUE"; + +select md5('message digest'::bytea) = 'f96b697d7cb7938d525a2f31aaf161d0' AS "TRUE"; + +select md5('abcdefghijklmnopqrstuvwxyz'::bytea) = 'c3fcd3d76192e4007dfb496cca67e13b' AS "TRUE"; + +select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'::bytea) = 'd174ab98d277d9f5a5611c2c9f419d9f' AS "TRUE"; + +select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890'::bytea) = '57edf4a22be3c955ac49da2e2107b67a' AS "TRUE"; diff --git a/crates/pgt_pretty_print/tests/data/multi/memoize_60.sql b/crates/pgt_pretty_print/tests/data/multi/memoize_60.sql new file mode 100644 index 000000000..c123669c3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/memoize_60.sql @@ -0,0 +1,259 @@ +create function explain_memoize(query text, hide_hitmiss bool) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s', + query) + loop + if hide_hitmiss = true then + ln := regexp_replace(ln, 'Hits: 0', 'Hits: Zero'); + ln := regexp_replace(ln, 'Hits: \d+', 'Hits: N'); + ln := regexp_replace(ln, 'Misses: 0', 'Misses: Zero'); + ln := regexp_replace(ln, 'Misses: \d+', 'Misses: N'); + end if; + ln := regexp_replace(ln, 'Evictions: 0', 'Evictions: Zero'); + ln := regexp_replace(ln, 'Evictions: \d+', 'Evictions: N'); + ln := regexp_replace(ln, 'Memory Usage: \d+', 'Memory Usage: N'); + ln := regexp_replace(ln, 'Heap Fetches: \d+', 'Heap Fetches: N'); + ln := regexp_replace(ln, 'loops=\d+', 'loops=N'); + ln := regexp_replace(ln, 'Index Searches: \d+', 'Index Searches: N'); + ln := regexp_replace(ln, 'Memory: \d+kB', 'Memory: NkB'); + return next ln; + end loop; +end; +$$; + +SET enable_hashjoin TO off; + +SET enable_bitmapscan TO off; + +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.twenty +WHERE t2.unique1 < 1000;', false); + +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.twenty +WHERE t2.unique1 < 1000; + +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 + WHERE t1.twenty = t2.unique1 OFFSET 0) t2 +WHERE t1.unique1 < 1000;', false); + +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 + WHERE t1.twenty = t2.unique1 OFFSET 0) t2 +WHERE t1.unique1 < 1000; + +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t2.t1two) FROM tenk1 t1 LEFT JOIN +LATERAL ( + SELECT t1.two as t1two, * FROM tenk1 t2 WHERE t2.unique1 < 4 OFFSET 0 +) t2 +ON t1.two = t2.two +WHERE t1.unique1 < 10;', false); + +SELECT COUNT(*),AVG(t2.t1two) FROM tenk1 t1 LEFT JOIN +LATERAL ( + SELECT t1.two as t1two, * FROM tenk1 t2 WHERE t2.unique1 < 4 OFFSET 0 +) t2 +ON t1.two = t2.two +WHERE t1.unique1 < 10; + +SELECT explain_memoize(' +SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN +LATERAL (SELECT t1.two+1 AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE +WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); + +SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN +LATERAL (SELECT t1.two+1 AS c1, t2.unique1 AS c2 FROM tenk1 t2) s ON TRUE +WHERE s.c1 = s.c2 AND t1.unique1 < 1000; + +SELECT explain_memoize(' +SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN +LATERAL (SELECT t1.twenty AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s +ON t1.two = s.two +WHERE s.c1 = s.c2 AND t1.unique1 < 1000;', false); + +SELECT COUNT(*), AVG(t1.twenty) FROM tenk1 t1 LEFT JOIN +LATERAL (SELECT t1.twenty AS c1, t2.unique1 AS c2, t2.two FROM tenk1 t2) s +ON t1.two = s.two +WHERE s.c1 = s.c2 AND t1.unique1 < 1000; + +SET enable_mergejoin TO off; + +CREATE TABLE expr_key (x numeric, t text); + +INSERT INTO expr_key (x, t) +SELECT d1::numeric, d1::text FROM ( + SELECT round((d / pi())::numeric, 7) AS d1 FROM generate_series(1, 20) AS d +) t; + +INSERT INTO expr_key SELECT * FROM expr_key; + +CREATE INDEX expr_key_idx_x_t ON expr_key (x, t); + +VACUUM ANALYZE expr_key; + +SELECT explain_memoize(' +SELECT * FROM expr_key t1 INNER JOIN expr_key t2 +ON t1.x = t2.t::numeric AND t1.t::numeric = t2.x;', false); + +DROP TABLE expr_key; + +SET work_mem TO '64kB'; + +SET hash_mem_multiplier TO 1.0; + +SELECT explain_memoize(' +SELECT COUNT(*),AVG(t1.unique1) FROM tenk1 t1 +INNER JOIN tenk1 t2 ON t1.unique1 = t2.thousand +WHERE t2.unique1 < 1200;', true); + +CREATE TABLE flt (f float); + +CREATE INDEX flt_f_idx ON flt (f); + +INSERT INTO flt VALUES('-0.0'::float),('+0.0'::float); + +ANALYZE flt; + +SET enable_seqscan TO off; + +SELECT explain_memoize(' +SELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f = f2.f;', false); + +SELECT explain_memoize(' +SELECT * FROM flt f1 INNER JOIN flt f2 ON f1.f >= f2.f;', false); + +DROP TABLE flt; + +CREATE TABLE strtest (n name, t text); + +CREATE INDEX strtest_n_idx ON strtest (n); + +CREATE INDEX strtest_t_idx ON strtest (t); + +INSERT INTO strtest VALUES('one','one'),('two','two'),('three',repeat(fipshash('three'),100)); + +INSERT INTO strtest SELECT * FROM strtest; + +ANALYZE strtest; + +SELECT explain_memoize(' +SELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.n >= s2.n;', false); + +SELECT explain_memoize(' +SELECT * FROM strtest s1 INNER JOIN strtest s2 ON s1.t >= s2.t;', false); + +DROP TABLE strtest; + +SET enable_partitionwise_join TO on; + +CREATE TABLE prt (a int) PARTITION BY RANGE(a); + +CREATE TABLE prt_p1 PARTITION OF prt FOR VALUES FROM (0) TO (10); + +CREATE TABLE prt_p2 PARTITION OF prt FOR VALUES FROM (10) TO (20); + +INSERT INTO prt VALUES (0), (0), (0), (0); + +INSERT INTO prt VALUES (10), (10), (10), (10); + +CREATE INDEX iprt_p1_a ON prt_p1 (a); + +CREATE INDEX iprt_p2_a ON prt_p2 (a); + +ANALYZE prt; + +SELECT explain_memoize(' +SELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false); + +SET enable_partitionwise_join TO off; + +SELECT explain_memoize(' +SELECT * FROM prt_p1 t1 INNER JOIN +(SELECT * FROM prt_p1 UNION ALL SELECT * FROM prt_p2) t2 +ON t1.a = t2.a;', false); + +DROP TABLE prt; + +RESET enable_partitionwise_join; + +SELECT unique1 FROM tenk1 t0 +WHERE unique1 < 3 + AND EXISTS ( + SELECT 1 FROM tenk1 t1 + INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred + WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0); + +SELECT unique1 FROM tenk1 t0 +WHERE unique1 < 3 + AND EXISTS ( + SELECT 1 FROM tenk1 t1 + INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred + WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0); + +RESET enable_seqscan; + +RESET enable_mergejoin; + +RESET work_mem; + +RESET hash_mem_multiplier; + +RESET enable_bitmapscan; + +RESET enable_hashjoin; + +SET min_parallel_table_scan_size TO 0; + +SET parallel_setup_cost TO 0; + +SET parallel_tuple_cost TO 0; + +SET max_parallel_workers_per_gather TO 2; + +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 WHERE t1.twenty = t2.unique1) t2 +WHERE t1.unique1 < 1000; + +SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, +LATERAL (SELECT t2.unique1 FROM tenk1 t2 WHERE t1.twenty = t2.unique1) t2 +WHERE t1.unique1 < 1000; + +RESET max_parallel_workers_per_gather; + +RESET parallel_tuple_cost; + +RESET parallel_setup_cost; + +RESET min_parallel_table_scan_size; + +CREATE TABLE tab_anti (a int, b boolean); + +INSERT INTO tab_anti SELECT i%3, false FROM generate_series(1,100)i; + +ANALYZE tab_anti; + +SELECT explain_memoize(' +SELECT COUNT(*) FROM tab_anti t1 LEFT JOIN +LATERAL (SELECT DISTINCT ON (a) a, b, t1.a AS x FROM tab_anti t2) t2 +ON t1.a+1 = t2.a +WHERE t2.a IS NULL;', false); + +SELECT COUNT(*) FROM tab_anti t1 LEFT JOIN +LATERAL (SELECT DISTINCT ON (a) a, b, t1.a AS x FROM tab_anti t2) t2 +ON t1.a+1 = t2.a +WHERE t2.a IS NULL; + +SELECT * FROM tab_anti t1 WHERE t1.a IN + (SELECT a FROM tab_anti t2 WHERE t2.b IN + (SELECT t1.b FROM tab_anti t3 WHERE t2.a > 1 OFFSET 0)); + +DROP TABLE tab_anti; diff --git a/crates/pgt_pretty_print/tests/data/multi/merge_60.sql b/crates/pgt_pretty_print/tests/data/multi/merge_60.sql new file mode 100644 index 000000000..04ccc3973 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/merge_60.sql @@ -0,0 +1,1319 @@ +CREATE USER regress_merge_privs; + +CREATE USER regress_merge_no_privs; + +CREATE USER regress_merge_none; + +DROP TABLE IF EXISTS target; + +DROP TABLE IF EXISTS source; + +CREATE TABLE target (tid integer, balance integer) + WITH (autovacuum_enabled=off); + +CREATE TABLE source (sid integer, delta integer) -- no index + WITH (autovacuum_enabled=off); + +INSERT INTO target VALUES (1, 10); + +INSERT INTO target VALUES (2, 20); + +INSERT INTO target VALUES (3, 30); + +SELECT t.ctid is not null as matched, t.*, s.* FROM source s FULL OUTER JOIN target t ON s.sid = t.tid ORDER BY t.tid, s.sid; + +ALTER TABLE target OWNER TO regress_merge_privs; + +ALTER TABLE source OWNER TO regress_merge_privs; + +CREATE TABLE target2 (tid integer, balance integer) + WITH (autovacuum_enabled=off); + +CREATE TABLE source2 (sid integer, delta integer) + WITH (autovacuum_enabled=off); + +ALTER TABLE target2 OWNER TO regress_merge_no_privs; + +ALTER TABLE source2 OWNER TO regress_merge_no_privs; + +GRANT INSERT ON target TO regress_merge_no_privs; + +SET SESSION AUTHORIZATION regress_merge_privs; + +INSERT INTO target DEFAULT VALUES; + +UPDATE target SET balance = 0; + +MERGE INTO target +USING target +ON tid = tid +WHEN MATCHED THEN DO NOTHING; + +WITH foo AS ( + MERGE INTO target USING source ON (true) + WHEN MATCHED THEN DELETE +) SELECT * FROM foo; + +COPY ( + MERGE INTO target USING source ON (true) + WHEN MATCHED THEN DELETE +) TO stdout; + +CREATE MATERIALIZED VIEW mv AS SELECT * FROM target; + +DROP MATERIALIZED VIEW mv; + +SET SESSION AUTHORIZATION regress_merge_none; + +MERGE INTO target +USING (SELECT 1) +ON true +WHEN MATCHED THEN + DO NOTHING; + +SET SESSION AUTHORIZATION regress_merge_privs; + +GRANT INSERT ON target TO regress_merge_no_privs; + +SET SESSION AUTHORIZATION regress_merge_no_privs; + +GRANT UPDATE ON target2 TO regress_merge_privs; + +SET SESSION AUTHORIZATION regress_merge_privs; + +BEGIN; + +ROLLBACK; + +INSERT INTO source VALUES (4, 40); + +SELECT * FROM source ORDER BY sid; + +SELECT * FROM target ORDER BY tid; + +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN NOT MATCHED THEN + DO NOTHING; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +INSERT INTO target SELECT generate_series(1000,2500), 0; + +ALTER TABLE target ADD PRIMARY KEY (tid); + +ANALYZE target; + +DELETE FROM target WHERE tid > 100; + +ANALYZE target; + +INSERT INTO source VALUES (2, 5); + +INSERT INTO source VALUES (3, 20); + +SELECT * FROM source ORDER BY sid; + +SELECT * FROM target ORDER BY tid; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED THEN + DO NOTHING; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +INSERT INTO source VALUES (2, 5); + +SELECT * FROM source ORDER BY sid; + +SELECT * FROM target ORDER BY tid; + +BEGIN; + +ROLLBACK; + +BEGIN; + +ROLLBACK; + +DELETE FROM source WHERE sid = 2; + +INSERT INTO source VALUES (2, 5); + +SELECT * FROM source ORDER BY sid; + +SELECT * FROM target ORDER BY tid; + +INSERT INTO source VALUES (4, 40); + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +DELETE FROM source WHERE sid = 4; + +INSERT INTO source VALUES (4, 40); + +SELECT * FROM source ORDER BY sid; + +SELECT * FROM target ORDER BY tid; + +alter table target drop CONSTRAINT target_pkey; + +alter table target alter column tid drop not null; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +INSERT INTO source VALUES (5, 50); + +INSERT INTO source VALUES (5, 50); + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +DELETE FROM source WHERE sid = 5; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +ROLLBACK; + +CREATE TABLE wq_target (tid integer not null, balance integer DEFAULT -1) + WITH (autovacuum_enabled=off); + +CREATE TABLE wq_source (balance integer, sid integer) + WITH (autovacuum_enabled=off); + +INSERT INTO wq_source (sid, balance) VALUES (1, 100); + +BEGIN; + +SELECT * FROM wq_target; + +ROLLBACK; + +SELECT * FROM wq_target; + +SELECT * FROM wq_target; + +BEGIN; + +SELECT * FROM wq_target; + +ROLLBACK; + +BEGIN; + +SELECT * FROM wq_target; + +ROLLBACK; + +SELECT * FROM wq_target; + +SELECT * FROM wq_source; + +SELECT * FROM wq_target; + +SELECT * FROM wq_target; + +SELECT * FROM wq_target; + +SELECT * FROM wq_target; + +SELECT * FROM wq_target; + +SELECT * FROM wq_target; + +BEGIN; + +SELECT * FROM wq_target; + +ROLLBACK; + +SELECT * FROM wq_target; + +DROP TABLE wq_target, wq_source; + +create or replace function merge_trigfunc () returns trigger +language plpgsql as +$$ +DECLARE + line text; +BEGIN + SELECT INTO line format('%s %s %s trigger%s', + TG_WHEN, TG_OP, TG_LEVEL, CASE + WHEN TG_OP = 'INSERT' AND TG_LEVEL = 'ROW' + THEN format(' row: %s', NEW) + WHEN TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW' + THEN format(' row: %s -> %s', OLD, NEW) + WHEN TG_OP = 'DELETE' AND TG_LEVEL = 'ROW' + THEN format(' row: %s', OLD) + END); + + RAISE NOTICE '%', line; + IF (TG_WHEN = 'BEFORE' AND TG_LEVEL = 'ROW') THEN + IF (TG_OP = 'DELETE') THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; + ELSE + RETURN NULL; + END IF; +END; +$$; + +CREATE TRIGGER merge_bsi BEFORE INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_bsu BEFORE UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_bsd BEFORE DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_asi AFTER INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_asu AFTER UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_asd AFTER DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_bri BEFORE INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_bru BEFORE UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_brd BEFORE DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_ari AFTER INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_aru AFTER UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); + +CREATE TRIGGER merge_ard AFTER DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); + +BEGIN; + +UPDATE target SET balance = 0 WHERE tid = 3; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +DELETE FROM SOURCE WHERE sid = 2; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +create or replace function skip_merge_op() returns trigger +language plpgsql as +$$ +BEGIN + RETURN NULL; +END; +$$; + +SELECT * FROM target full outer join source on (sid = tid); + +create trigger merge_skip BEFORE INSERT OR UPDATE or DELETE + ON target FOR EACH ROW EXECUTE FUNCTION skip_merge_op(); + +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND s.sid = 3 THEN UPDATE SET balance = t.balance + s.delta +WHEN MATCHED THEN DELETE +WHEN NOT MATCHED THEN INSERT VALUES (sid, delta); +IF FOUND THEN + RAISE NOTICE 'Found'; +ELSE + RAISE NOTICE 'Not found'; +END IF; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$; + +SELECT * FROM target FULL OUTER JOIN source ON (sid = tid); + +DROP TRIGGER merge_skip ON target; + +DROP FUNCTION skip_merge_op(); + +BEGIN; + +DO LANGUAGE plpgsql $$ +BEGIN +MERGE INTO target t +USING source AS s +ON t.tid = s.sid +WHEN MATCHED AND t.balance > s.delta THEN + UPDATE SET balance = t.balance - s.delta; +END; +$$; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION merge_func (p_id integer, p_bal integer) +RETURNS INTEGER +LANGUAGE plpgsql +AS $$ +DECLARE + result integer; +BEGIN +MERGE INTO target t +USING (SELECT p_id AS sid) AS s +ON t.tid = s.sid +WHEN MATCHED THEN + UPDATE SET balance = t.balance - p_bal; +IF FOUND THEN + GET DIAGNOSTICS result := ROW_COUNT; +END IF; +RETURN result; +END; +$$; + +SELECT merge_func(3, 4); + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +execute foom; + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +execute foom2 (1, 1); + +SELECT * FROM target ORDER BY tid; + +ROLLBACK; + +CREATE TABLE sq_target (tid integer NOT NULL, balance integer) + WITH (autovacuum_enabled=off); + +CREATE TABLE sq_source (delta integer, sid integer, balance integer DEFAULT 0) + WITH (autovacuum_enabled=off); + +INSERT INTO sq_target(tid, balance) VALUES (1,100), (2,200), (3,300); + +INSERT INTO sq_source(sid, delta) VALUES (1,10), (2,20), (4,40); + +BEGIN; + +SELECT * FROM sq_target; + +ROLLBACK; + +CREATE VIEW v AS SELECT * FROM sq_source WHERE sid < 2; + +BEGIN; + +SELECT * FROM sq_target; + +ROLLBACK; + +BEGIN; + +ROLLBACK; + +BEGIN; + +INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); + +SELECT * FROM sq_target; + +ROLLBACK; + +BEGIN; + +INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); + +WITH targq AS ( + SELECT * FROM v +) +MERGE INTO sq_target t +USING v +ON tid = sid +WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta +WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) +WHEN MATCHED AND tid < 2 THEN + DELETE; + +ROLLBACK; + +SELECT * FROM sq_source ORDER BY sid; + +SELECT * FROM sq_target ORDER BY tid; + +BEGIN; + +CREATE TABLE merge_actions(action text, abbrev text); + +INSERT INTO merge_actions VALUES ('INSERT', 'ins'), ('UPDATE', 'upd'), ('DELETE', 'del'); + +ROLLBACK; + +SELECT merge_action() FROM sq_target; + +UPDATE sq_target SET balance = balance + 1 RETURNING merge_action(); + +CREATE TABLE sq_target_merge_log (tid integer NOT NULL, last_change text); + +INSERT INTO sq_target_merge_log VALUES (1, 'Original value'); + +BEGIN; + +WITH m AS ( + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action() AS action, old AS old_data, new AS new_data, t.*, + CASE merge_action() + WHEN 'INSERT' THEN 'Inserted '||t + WHEN 'UPDATE' THEN 'Added '||delta||' to balance' + WHEN 'DELETE' THEN 'Removed '||t + END AS description +), m2 AS ( + MERGE INTO sq_target_merge_log l + USING m + ON l.tid = m.tid + WHEN MATCHED THEN + UPDATE SET last_change = description + WHEN NOT MATCHED THEN + INSERT VALUES (m.tid, description) + RETURNING m.*, merge_action() AS log_action, old AS old_log, new AS new_log, l.* +) +SELECT * FROM m2; + +SELECT * FROM sq_target_merge_log ORDER BY tid; + +ROLLBACK; + +BEGIN; + +COPY ( + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), old.*, new.* +) TO stdout; + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, + OUT action text, OUT tid int, OUT new_balance int) +LANGUAGE sql AS +$$ + MERGE INTO sq_target t + USING (VALUES ($1, $2, $3)) AS v(sid, balance, delta) + ON tid = v.sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + v.delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (v.balance + v.delta, v.sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.*; +$$; + +SELECT m.* +FROM (VALUES (1, 0, 0), (3, 0, 20), (4, 100, 10)) AS v(sid, balance, delta), +LATERAL (SELECT action, tid, new_balance FROM merge_into_sq_target(sid, balance, delta)) m; + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION merge_sq_source_into_sq_target() +RETURNS TABLE (action text, tid int, balance int) +LANGUAGE sql AS +$$ + MERGE INTO sq_target t + USING sq_source s + ON tid = sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (balance + delta, sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.*; +$$; + +SELECT * FROM merge_sq_source_into_sq_target(); + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION merge_into_sq_target(sid int, balance int, delta int, + OUT r_action text, OUT r_tid int, OUT r_balance int) +LANGUAGE plpgsql AS +$$ +BEGIN + MERGE INTO sq_target t + USING (VALUES ($1, $2, $3)) AS v(sid, balance, delta) + ON tid = v.sid + WHEN MATCHED AND tid >= 2 THEN + UPDATE SET balance = t.balance + v.delta + WHEN NOT MATCHED THEN + INSERT (balance, tid) VALUES (v.balance + v.delta, v.sid) + WHEN MATCHED AND tid < 2 THEN + DELETE + RETURNING merge_action(), t.* INTO r_action, r_tid, r_balance; +END; +$$; + +SELECT m.* +FROM (VALUES (1, 0, 0), (3, 0, 20), (4, 100, 10)) AS v(sid, balance, delta), +LATERAL (SELECT r_action, r_tid, r_balance FROM merge_into_sq_target(sid, balance, delta)) m; + +ROLLBACK; + +CREATE TABLE ex_mtarget (a int, b int) + WITH (autovacuum_enabled=off); + +CREATE TABLE ex_msource (a int, b int) + WITH (autovacuum_enabled=off); + +INSERT INTO ex_mtarget SELECT i, i*10 FROM generate_series(1,100,2) i; + +INSERT INTO ex_msource SELECT i, i*10 FROM generate_series(1,100,1) i; + +CREATE FUNCTION explain_merge(query text) RETURNS SETOF text +LANGUAGE plpgsql AS +$$ +DECLARE ln text; +BEGIN + FOR ln IN + EXECUTE 'explain (analyze, timing off, summary off, costs off, buffers off) ' || + query + LOOP + ln := regexp_replace(ln, '(Memory( Usage)?|Buckets|Batches): \S*', '\1: xxx', 'g'); + RETURN NEXT ln; + END LOOP; +END; +$$; + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED THEN + UPDATE SET b = t.b + 1'); + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1'); + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1 +WHEN MATCHED AND t.a >= 10 AND t.a <= 20 THEN + DELETE'); + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED AND s.a < 10 THEN + INSERT VALUES (a, b)'); + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN MATCHED AND t.a < 10 THEN + UPDATE SET b = t.b + 1 +WHEN MATCHED AND t.a >= 30 AND t.a <= 40 THEN + DELETE +WHEN NOT MATCHED AND s.a < 20 THEN + INSERT VALUES (a, b)'); + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED BY SOURCE and t.a < 10 THEN + DELETE'); + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a +WHEN NOT MATCHED BY SOURCE AND t.a < 10 THEN + DELETE +WHEN NOT MATCHED BY TARGET AND s.a < 20 THEN + INSERT VALUES (a, b)'); + +SELECT explain_merge(' +MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a AND t.a < -1000 +WHEN MATCHED AND t.a < 10 THEN + DO NOTHING'); + +DROP TABLE ex_msource, ex_mtarget; + +DROP FUNCTION explain_merge(text); + +CREATE TABLE src (a int, b int, c int, d int); + +CREATE TABLE tgt (a int, b int, c int, d int); + +CREATE TABLE ref (ab int, cd int); + +DROP TABLE src, tgt, ref; + +BEGIN; + +SELECT * FROM sq_target WHERE tid = 1; + +ROLLBACK; + +BEGIN; + +SELECT * FROM sq_target WHERE tid = 1; + +ROLLBACK; + +BEGIN; + +SELECT * FROM sq_target WHERE tid = 1; + +ROLLBACK; + +DROP TABLE sq_target, sq_target_merge_log, sq_source CASCADE; + +CREATE TABLE pa_target (tid integer, balance float, val text) + PARTITION BY LIST (tid); + +CREATE TABLE part1 PARTITION OF pa_target FOR VALUES IN (1,4) + WITH (autovacuum_enabled=off); + +CREATE TABLE part2 PARTITION OF pa_target FOR VALUES IN (2,5,6) + WITH (autovacuum_enabled=off); + +CREATE TABLE part3 PARTITION OF pa_target FOR VALUES IN (3,8,9) + WITH (autovacuum_enabled=off); + +CREATE TABLE part4 PARTITION OF pa_target DEFAULT + WITH (autovacuum_enabled=off); + +CREATE TABLE pa_source (sid integer, delta float); + +INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id; + +INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,15,2) AS id; + +BEGIN; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION merge_func() RETURNS integer LANGUAGE plpgsql AS $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET tid = 1, val = val || ' not matched by source'; +IF FOUND THEN + GET DIAGNOSTICS result := ROW_COUNT; +END IF; +RETURN result; +END; +$$; + +SELECT merge_func(); + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +SELECT * FROM pa_target ORDER BY tid; + +ROLLBACK; + +BEGIN; + +TRUNCATE pa_target; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +DROP TABLE pa_target CASCADE; + +CREATE TABLE pa_target (tid integer, balance float, val text) + PARTITION BY LIST (tid); + +CREATE TABLE part1 (tid integer, balance float, val text) + WITH (autovacuum_enabled=off); + +CREATE TABLE part2 (balance float, tid integer, val text) + WITH (autovacuum_enabled=off); + +CREATE TABLE part3 (tid integer, balance float, val text) + WITH (autovacuum_enabled=off); + +CREATE TABLE part4 (extraid text, tid integer, balance float, val text) + WITH (autovacuum_enabled=off); + +ALTER TABLE part4 DROP COLUMN extraid; + +ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4); + +ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6); + +ALTER TABLE pa_target ATTACH PARTITION part3 FOR VALUES IN (3,8,9); + +ALTER TABLE pa_target ATTACH PARTITION part4 DEFAULT; + +INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,15,2) AS id; + +BEGIN; + +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET tid = 1, val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS + $$ BEGIN RETURN NULL; END; $$; + +CREATE TRIGGER del_trig BEFORE DELETE ON pa_target + FOR EACH ROW EXECUTE PROCEDURE trig_fn(); + +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +CREATE FUNCTION trig_fn() RETURNS trigger LANGUAGE plpgsql AS + $$ BEGIN RETURN NULL; END; $$; + +CREATE TRIGGER ins_trig BEFORE INSERT ON pa_target + FOR EACH ROW EXECUTE PROCEDURE trig_fn(); + +DO $$ +DECLARE + result integer; +BEGIN +MERGE INTO pa_target t + USING pa_source s + ON t.tid = s.sid + WHEN MATCHED THEN + UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' + WHEN NOT MATCHED THEN + INSERT VALUES (sid, delta, 'inserted by merge') + WHEN NOT MATCHED BY SOURCE THEN + UPDATE SET val = val || ' not matched by source'; +GET DIAGNOSTICS result := ROW_COUNT; +RAISE NOTICE 'ROW_COUNT = %', result; +END; +$$; + +SELECT * FROM pa_target ORDER BY tid, val; + +ROLLBACK; + +BEGIN; + +ALTER TABLE pa_target ENABLE ROW LEVEL SECURITY; + +ALTER TABLE pa_target FORCE ROW LEVEL SECURITY; + +CREATE POLICY pa_target_pol ON pa_target USING (tid != 0); + +ROLLBACK; + +DROP TABLE pa_source; + +DROP TABLE pa_target CASCADE; + +CREATE TABLE pa_target (logts timestamp, tid integer, balance float, val text) + PARTITION BY RANGE (logts); + +CREATE TABLE part_m01 PARTITION OF pa_target + FOR VALUES FROM ('2017-01-01') TO ('2017-02-01') + PARTITION BY LIST (tid); + +CREATE TABLE part_m01_odd PARTITION OF part_m01 + FOR VALUES IN (1,3,5,7,9) WITH (autovacuum_enabled=off); + +CREATE TABLE part_m01_even PARTITION OF part_m01 + FOR VALUES IN (2,4,6,8) WITH (autovacuum_enabled=off); + +CREATE TABLE part_m02 PARTITION OF pa_target + FOR VALUES FROM ('2017-02-01') TO ('2017-03-01') + PARTITION BY LIST (tid); + +CREATE TABLE part_m02_odd PARTITION OF part_m02 + FOR VALUES IN (1,3,5,7,9) WITH (autovacuum_enabled=off); + +CREATE TABLE part_m02_even PARTITION OF part_m02 + FOR VALUES IN (2,4,6,8) WITH (autovacuum_enabled=off); + +CREATE TABLE pa_source (sid integer, delta float) + WITH (autovacuum_enabled=off); + +INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id; + +INSERT INTO pa_target SELECT '2017-01-31', id, id * 100, 'initial' FROM generate_series(1,9,3) AS id; + +INSERT INTO pa_target SELECT '2017-02-28', id, id * 100, 'initial' FROM generate_series(2,9,3) AS id; + +BEGIN; + +SELECT * FROM pa_target ORDER BY tid; + +ROLLBACK; + +DROP TABLE pa_source; + +DROP TABLE pa_target CASCADE; + +CREATE TABLE pa_target (tid integer PRIMARY KEY) PARTITION BY LIST (tid); + +CREATE TABLE pa_targetp PARTITION OF pa_target DEFAULT; + +CREATE TABLE pa_source (sid integer); + +INSERT INTO pa_source VALUES (1), (2); + +TABLE pa_target; + +DROP TABLE pa_targetp; + +DROP TABLE pa_source; + +DROP TABLE pa_target CASCADE; + +CREATE TABLE cj_target (tid integer, balance float, val text) + WITH (autovacuum_enabled=off); + +CREATE TABLE cj_source1 (sid1 integer, scat integer, delta integer) + WITH (autovacuum_enabled=off); + +CREATE TABLE cj_source2 (sid2 integer, sval text) + WITH (autovacuum_enabled=off); + +INSERT INTO cj_source1 VALUES (1, 10, 100); + +INSERT INTO cj_source1 VALUES (1, 20, 200); + +INSERT INTO cj_source1 VALUES (2, 20, 300); + +INSERT INTO cj_source1 VALUES (3, 10, 400); + +INSERT INTO cj_source2 VALUES (1, 'initial source2'); + +INSERT INTO cj_source2 VALUES (2, 'initial source2'); + +INSERT INTO cj_source2 VALUES (3, 'initial source2'); + +SELECT * FROM cj_target; + +SELECT * FROM cj_target; + +ALTER TABLE cj_source1 RENAME COLUMN sid1 TO sid; + +ALTER TABLE cj_source2 RENAME COLUMN sid2 TO sid; + +TRUNCATE cj_target; + +DROP TABLE cj_source2, cj_source1, cj_target; + +CREATE TABLE fs_target (a int, b int, c text) + WITH (autovacuum_enabled=off); + +SELECT count(*) FROM fs_target; + +DROP TABLE fs_target; + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +) WITH (autovacuum_enabled=off); + +CREATE TABLE measurement_y2006m02 ( + CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' ) +) INHERITS (measurement) WITH (autovacuum_enabled=off); + +CREATE TABLE measurement_y2006m03 ( + CHECK ( logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' ) +) INHERITS (measurement) WITH (autovacuum_enabled=off); + +CREATE TABLE measurement_y2007m01 ( + filler text, + peaktemp int, + logdate date not null, + city_id int not null, + unitsales int + CHECK ( logdate >= DATE '2007-01-01' AND logdate < DATE '2007-02-01') +) WITH (autovacuum_enabled=off); + +ALTER TABLE measurement_y2007m01 DROP COLUMN filler; + +ALTER TABLE measurement_y2007m01 INHERIT measurement; + +INSERT INTO measurement VALUES (0, '2005-07-21', 5, 15); + +CREATE OR REPLACE FUNCTION measurement_insert_trigger() +RETURNS TRIGGER AS $$ +BEGIN + IF ( NEW.logdate >= DATE '2006-02-01' AND + NEW.logdate < DATE '2006-03-01' ) THEN + INSERT INTO measurement_y2006m02 VALUES (NEW.*); + ELSIF ( NEW.logdate >= DATE '2006-03-01' AND + NEW.logdate < DATE '2006-04-01' ) THEN + INSERT INTO measurement_y2006m03 VALUES (NEW.*); + ELSIF ( NEW.logdate >= DATE '2007-01-01' AND + NEW.logdate < DATE '2007-02-01' ) THEN + INSERT INTO measurement_y2007m01 (city_id, logdate, peaktemp, unitsales) + VALUES (NEW.*); + ELSE + RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!'; + END IF; + RETURN NULL; +END; +$$ LANGUAGE plpgsql ; + +CREATE TRIGGER insert_measurement_trigger + BEFORE INSERT ON measurement + FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger(); + +INSERT INTO measurement VALUES (1, '2006-02-10', 35, 10); + +INSERT INTO measurement VALUES (1, '2006-02-16', 45, 20); + +INSERT INTO measurement VALUES (1, '2006-03-17', 25, 10); + +INSERT INTO measurement VALUES (1, '2006-03-27', 15, 40); + +INSERT INTO measurement VALUES (1, '2007-01-15', 10, 10); + +INSERT INTO measurement VALUES (1, '2007-01-17', 10, 10); + +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate; + +CREATE TABLE new_measurement (LIKE measurement) WITH (autovacuum_enabled=off); + +INSERT INTO new_measurement VALUES (0, '2005-07-21', 25, 20); + +INSERT INTO new_measurement VALUES (1, '2006-03-01', 20, 10); + +INSERT INTO new_measurement VALUES (1, '2006-02-16', 50, 10); + +INSERT INTO new_measurement VALUES (2, '2006-02-10', 20, 20); + +INSERT INTO new_measurement VALUES (1, '2006-03-27', NULL, NULL); + +INSERT INTO new_measurement VALUES (1, '2007-01-17', NULL, NULL); + +INSERT INTO new_measurement VALUES (1, '2007-01-15', 5, NULL); + +INSERT INTO new_measurement VALUES (1, '2007-01-16', 10, 10); + +BEGIN; + +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate, peaktemp; + +ROLLBACK; + +SELECT tableoid::regclass, * FROM measurement ORDER BY city_id, logdate; + +BEGIN; + +SELECT * FROM new_measurement ORDER BY city_id, logdate; + +ROLLBACK; + +SELECT * FROM new_measurement ORDER BY city_id, logdate; + +DROP TRIGGER insert_measurement_trigger ON measurement; + +ALTER TABLE measurement ADD CONSTRAINT mcheck CHECK (city_id = 0) NO INHERIT; + +BEGIN; + +SELECT * FROM ONLY measurement ORDER BY city_id, logdate; + +ROLLBACK; + +ALTER TABLE measurement ENABLE ROW LEVEL SECURITY; + +ALTER TABLE measurement FORCE ROW LEVEL SECURITY; + +CREATE POLICY measurement_p ON measurement USING (peaktemp IS NOT NULL); + +SELECT * FROM ONLY measurement ORDER BY city_id, logdate; + +DROP TABLE measurement, new_measurement CASCADE; + +DROP FUNCTION measurement_insert_trigger(); + +CREATE TABLE src (a int, b text); + +INSERT INTO src VALUES (1, 'src row'); + +CREATE TABLE tgt (a int, b text); + +INSERT INTO tgt VALUES (NULL, 'tgt row'); + +SELECT * FROM tgt; + +DROP TABLE src, tgt; + +CREATE TABLE bug18634t (a int, b int, c text); + +INSERT INTO bug18634t VALUES(1, 10, 'tgt1'), (2, 20, 'tgt2'); + +CREATE VIEW bug18634v AS + SELECT * FROM bug18634t WHERE EXISTS (SELECT 1 FROM bug18634t); + +CREATE TABLE bug18634s (a int, b int, c text); + +INSERT INTO bug18634s VALUES (1, 2, 'src1'); + +SELECT * FROM bug18634t; + +DROP TABLE bug18634t CASCADE; + +DROP TABLE bug18634s; + +RESET SESSION AUTHORIZATION; + +CREATE VIEW classv AS SELECT * FROM pg_class; + +DROP TABLE target, target2; + +DROP TABLE source, source2; + +DROP FUNCTION merge_trigfunc(); + +DROP USER regress_merge_privs; + +DROP USER regress_merge_no_privs; + +DROP USER regress_merge_none; diff --git a/crates/pgt_pretty_print/tests/data/multi/misc_60.sql b/crates/pgt_pretty_print/tests/data/multi/misc_60.sql new file mode 100644 index 000000000..dece1a4e5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/misc_60.sql @@ -0,0 +1,185 @@ +CREATE FUNCTION overpaid(emp) + RETURNS bool + AS 'regresslib' + LANGUAGE C STRICT; + +CREATE FUNCTION reverse_name(name) + RETURNS name + AS 'regresslib' + LANGUAGE C STRICT; + +UPDATE onek + SET unique1 = onek.unique1 + 1; + +UPDATE onek + SET unique1 = onek.unique1 - 1; + +SELECT two, stringu1, ten, string4 + INTO TABLE tmp + FROM onek; + +UPDATE tmp + SET stringu1 = reverse_name(onek.stringu1) + FROM onek + WHERE onek.stringu1 = 'JBAAAA' and + onek.stringu1 = tmp.stringu1; + +UPDATE tmp + SET stringu1 = reverse_name(onek2.stringu1) + FROM onek2 + WHERE onek2.stringu1 = 'JCAAAA' and + onek2.stringu1 = tmp.stringu1; + +DROP TABLE tmp; + +COPY onek TO 'filename'; + +CREATE TEMP TABLE onek_copy (LIKE onek); + +COPY onek_copy FROM 'filename'; + +SELECT * FROM onek EXCEPT ALL SELECT * FROM onek_copy; + +SELECT * FROM onek_copy EXCEPT ALL SELECT * FROM onek; + +COPY BINARY stud_emp TO 'filename'; + +CREATE TEMP TABLE stud_emp_copy (LIKE stud_emp); + +COPY BINARY stud_emp_copy FROM 'filename'; + +SELECT * FROM stud_emp_copy; + +CREATE TABLE hobbies_r ( + name text, + person text +); + +CREATE TABLE equipment_r ( + name text, + hobby text +); + +INSERT INTO hobbies_r (name, person) + SELECT 'posthacking', p.name + FROM person* p + WHERE p.name = 'mike' or p.name = 'jeff'; + +INSERT INTO hobbies_r (name, person) + SELECT 'basketball', p.name + FROM person p + WHERE p.name = 'joe' or p.name = 'sally'; + +INSERT INTO hobbies_r (name) VALUES ('skywalking'); + +INSERT INTO equipment_r (name, hobby) VALUES ('advil', 'posthacking'); + +INSERT INTO equipment_r (name, hobby) VALUES ('peet''s coffee', 'posthacking'); + +INSERT INTO equipment_r (name, hobby) VALUES ('hightops', 'basketball'); + +INSERT INTO equipment_r (name, hobby) VALUES ('guts', 'skywalking'); + +CREATE FUNCTION hobbies(person) + RETURNS setof hobbies_r + AS 'select * from hobbies_r where person = $1.name' + LANGUAGE SQL; + +CREATE FUNCTION hobby_construct(text, text) + RETURNS hobbies_r + AS 'select $1 as name, $2 as hobby' + LANGUAGE SQL; + +CREATE FUNCTION hobby_construct_named(name text, hobby text) + RETURNS hobbies_r + AS 'select name, hobby' + LANGUAGE SQL; + +CREATE FUNCTION hobbies_by_name(hobbies_r.name%TYPE) + RETURNS hobbies_r.person%TYPE + AS 'select person from hobbies_r where name = $1' + LANGUAGE SQL; + +CREATE FUNCTION equipment(hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = $1.name' + LANGUAGE SQL; + +CREATE FUNCTION equipment_named(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = equipment_named.hobby.name' + LANGUAGE SQL; + +CREATE FUNCTION equipment_named_ambiguous_1a(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = equipment_named_ambiguous_1a.hobby.name' + LANGUAGE SQL; + +CREATE FUNCTION equipment_named_ambiguous_1b(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = hobby.name' + LANGUAGE SQL; + +CREATE FUNCTION equipment_named_ambiguous_1c(hobby hobbies_r) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = hobby.name' + LANGUAGE SQL; + +CREATE FUNCTION equipment_named_ambiguous_2a(hobby text) + RETURNS setof equipment_r + AS 'select * from equipment_r where hobby = equipment_named_ambiguous_2a.hobby' + LANGUAGE SQL; + +CREATE FUNCTION equipment_named_ambiguous_2b(hobby text) + RETURNS setof equipment_r + AS 'select * from equipment_r where equipment_r.hobby = hobby' + LANGUAGE SQL; + +SELECT p.name, name(p.hobbies) FROM ONLY person p; + +SELECT p.name, name(p.hobbies) FROM person* p; + +SELECT DISTINCT hobbies_r.name, name(hobbies_r.equipment) FROM hobbies_r + ORDER BY 1,2; + +SELECT hobbies_r.name, (hobbies_r.equipment).name FROM hobbies_r; + +SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p; + +SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p; + +SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p; + +SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p; + +SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p; + +SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p; + +SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))); + +SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer'))); + +SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer'))); + +SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer'))); + +SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer'))); + +SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer'))); + +SELECT name(equipment_named_ambiguous_2a(text 'skywalking')); + +SELECT name(equipment_named_ambiguous_2b(text 'skywalking')); + +SELECT hobbies_by_name('basketball'); + +SELECT name, overpaid(emp.*) FROM emp; + +SELECT * FROM equipment(ROW('skywalking', 'mer')); + +SELECT name(equipment(ROW('skywalking', 'mer'))); + +SELECT *, name(equipment(h.*)) FROM hobbies_r h; + +SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h; diff --git a/crates/pgt_pretty_print/tests/data/multi/misc_functions_60.sql b/crates/pgt_pretty_print/tests/data/multi/misc_functions_60.sql new file mode 100644 index 000000000..013b87221 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/misc_functions_60.sql @@ -0,0 +1,400 @@ +CREATE FUNCTION explain_mask_costs(query text, do_analyze bool, + hide_costs bool, hide_row_est bool, hide_width bool) RETURNS setof text +LANGUAGE plpgsql AS +$$ +DECLARE + ln text; + analyze_str text; +BEGIN + IF do_analyze = true THEN + analyze_str := 'on'; + ELSE + analyze_str := 'off'; + END IF; + + -- avoid jit related output by disabling it + SET LOCAL jit = 0; + + FOR ln IN + EXECUTE format('explain (analyze %s, costs on, summary off, timing off, buffers off) %s', + analyze_str, query) + LOOP + IF hide_costs = true THEN + ln := regexp_replace(ln, 'cost=\d+\.\d\d\.\.\d+\.\d\d', 'cost=N..N'); + END IF; + + IF hide_row_est = true THEN + -- don't use 'g' so that we leave the actual rows intact + ln := regexp_replace(ln, 'rows=\d+', 'rows=N'); + END IF; + + IF hide_width = true THEN + ln := regexp_replace(ln, 'width=\d+', 'width=N'); + END IF; + + RETURN NEXT ln; + END LOOP; +END; +$$; + +SELECT num_nonnulls(NULL); + +SELECT num_nonnulls('1'); + +SELECT num_nonnulls(NULL::text); + +SELECT num_nonnulls(NULL::text, NULL::int); + +SELECT num_nonnulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL); + +SELECT num_nonnulls(VARIADIC '{1,2,NULL,3}'::int[]); + +SELECT num_nonnulls(VARIADIC '{"1","2","3","4"}'::text[]); + +SELECT num_nonnulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i)); + +SELECT num_nulls(NULL); + +SELECT num_nulls('1'); + +SELECT num_nulls(NULL::text); + +SELECT num_nulls(NULL::text, NULL::int); + +SELECT num_nulls(1, 2, NULL::text, NULL::point, '', int8 '9', 1.0 / NULL); + +SELECT num_nulls(VARIADIC '{1,2,NULL,3}'::int[]); + +SELECT num_nulls(VARIADIC '{"1","2","3","4"}'::text[]); + +SELECT num_nulls(VARIADIC ARRAY(SELECT CASE WHEN i <> 40 THEN i END FROM generate_series(1, 100) i)); + +SELECT num_nonnulls(VARIADIC NULL::text[]); + +SELECT num_nonnulls(VARIADIC '{}'::int[]); + +SELECT num_nulls(VARIADIC NULL::text[]); + +SELECT num_nulls(VARIADIC '{}'::int[]); + +SELECT num_nonnulls(); + +SELECT num_nulls(); + +CREATE FUNCTION test_canonicalize_path(text) + RETURNS text + AS 'regresslib' + LANGUAGE C STRICT IMMUTABLE; + +SELECT test_canonicalize_path('/'); + +SELECT test_canonicalize_path('/./abc/def/'); + +SELECT test_canonicalize_path('/./../abc/def'); + +SELECT test_canonicalize_path('/./../../abc/def/'); + +SELECT test_canonicalize_path('/abc/.././def/ghi'); + +SELECT test_canonicalize_path('/abc/./../def/ghi//'); + +SELECT test_canonicalize_path('/abc/def/../..'); + +SELECT test_canonicalize_path('/abc/def/../../..'); + +SELECT test_canonicalize_path('/abc/def/../../../../ghi/jkl'); + +SELECT test_canonicalize_path('.'); + +SELECT test_canonicalize_path('./'); + +SELECT test_canonicalize_path('./abc/..'); + +SELECT test_canonicalize_path('abc/../'); + +SELECT test_canonicalize_path('abc/../def'); + +SELECT test_canonicalize_path('..'); + +SELECT test_canonicalize_path('../abc/def'); + +SELECT test_canonicalize_path('../abc/..'); + +SELECT test_canonicalize_path('../abc/../def'); + +SELECT test_canonicalize_path('../abc/../../def/ghi'); + +SELECT test_canonicalize_path('./abc/./def/.'); + +SELECT test_canonicalize_path('./abc/././def/.'); + +SELECT test_canonicalize_path('./abc/./def/.././ghi/../../../jkl/mno'); + +SELECT pg_log_backend_memory_contexts(pg_backend_pid()); + +SELECT pg_log_backend_memory_contexts(pid) FROM pg_stat_activity + WHERE backend_type = 'checkpointer'; + +CREATE ROLE regress_log_memory; + +SELECT has_function_privilege('regress_log_memory', + 'pg_log_backend_memory_contexts(integer)', 'EXECUTE'); + +GRANT EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) + TO regress_log_memory; + +SELECT has_function_privilege('regress_log_memory', + 'pg_log_backend_memory_contexts(integer)', 'EXECUTE'); + +SET ROLE regress_log_memory; + +SELECT pg_log_backend_memory_contexts(pg_backend_pid()); + +RESET ROLE; + +REVOKE EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) + FROM regress_log_memory; + +DROP ROLE regress_log_memory; + +select setting as segsize +from pg_settings where name = 'wal_segment_size' + +select count(*) > 0 as ok from pg_ls_waldir(); + +select count(*) > 0 as ok from (select pg_ls_waldir()) ss; + +select * from pg_ls_waldir() limit 0; + +select count(*) > 0 as ok from (select * from pg_ls_waldir() limit 1) ss; + +select (w).size = 'segsize' as ok +from (select pg_ls_waldir() w) ss where length((w).name) = 24 limit 1; + +select count(*) >= 0 as ok from pg_ls_archive_statusdir(); + +select count(*) >= 0 as ok from pg_ls_summariesdir(); + +select length(pg_read_file('postmaster.pid')) > 20; + +select length(pg_read_file('postmaster.pid', 1, 20)); + +select pg_read_file('does not exist'); + +select pg_read_file('does not exist', true) IS NULL; + +select pg_read_file('does not exist', 0, -1); + +select pg_read_file('does not exist', 0, -1, true); + +select length(pg_read_binary_file('postmaster.pid')) > 20; + +select length(pg_read_binary_file('postmaster.pid', 1, 20)); + +select pg_read_binary_file('does not exist'); + +select pg_read_binary_file('does not exist', true) IS NULL; + +select pg_read_binary_file('does not exist', 0, -1); + +select pg_read_binary_file('does not exist', 0, -1, true); + +select size > 20, isdir from pg_stat_file('postmaster.pid'); + +select * from (select pg_ls_dir('.') a) a where a = 'base' limit 1; + +select pg_ls_dir('does not exist', false, false); + +select pg_ls_dir('does not exist', true, false); + +select count(*) = 1 as dot_found + from pg_ls_dir('.', false, true) as ls where ls = '.'; + +select count(*) = 1 as dot_found + from pg_ls_dir('.', false, false) as ls where ls = '.'; + +select * from (select (pg_timezone_names()).name) ptn where name='UTC' limit 1; + +select count(*) > 0 from + (select pg_tablespace_databases(oid) as pts from pg_tablespace + where spcname = 'pg_default') pts + join pg_database db on pts.pts = db.oid; + +CREATE ROLE regress_slot_dir_funcs; + +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalsnapdir()', 'EXECUTE'); + +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalmapdir()', 'EXECUTE'); + +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_replslotdir(text)', 'EXECUTE'); + +GRANT pg_monitor TO regress_slot_dir_funcs; + +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalsnapdir()', 'EXECUTE'); + +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_logicalmapdir()', 'EXECUTE'); + +SELECT has_function_privilege('regress_slot_dir_funcs', + 'pg_ls_replslotdir(text)', 'EXECUTE'); + +DROP ROLE regress_slot_dir_funcs; + +CREATE FUNCTION my_int_eq(int, int) RETURNS bool + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$int4eq$$; + +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42); + +CREATE FUNCTION test_support_func(internal) + RETURNS internal + AS 'regresslib', 'test_support_func' + LANGUAGE C STRICT; + +ALTER FUNCTION my_int_eq(int, int) SUPPORT test_support_func; + +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42); + +CREATE FUNCTION my_gen_series(int, int) RETURNS SETOF integer + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$generate_series_int4$$ + SUPPORT test_support_func; + +SELECT * FROM tenk1 a JOIN my_gen_series(1,1000) g ON a.unique1 = g; + +SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g; + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(TIMESTAMPTZ '2024-02-01', TIMESTAMPTZ '2024-03-01', INTERVAL '1 day') g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(TIMESTAMP '2024-02-01', TIMESTAMP '2024-03-01', INTERVAL '1 day') g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(TIMESTAMPTZ '2024-02-01', TIMESTAMPTZ '2024-03-01', INTERVAL '1 day', 'UTC') g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(TIMESTAMPTZ '2024-02-01', TIMESTAMPTZ '2024-03-01', INTERVAL '7 day') g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(TIMESTAMPTZ '2024-03-01', TIMESTAMPTZ '2024-02-01', INTERVAL '-1 day') g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(TIMESTAMPTZ '2024-03-01', TIMESTAMPTZ '2024-02-01', INTERVAL '1 day') g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(TIMESTAMPTZ '-infinity', TIMESTAMPTZ 'infinity', INTERVAL '1 day') g(s);$$, +false, true, false, true); + +SELECT * FROM generate_series(TIMESTAMPTZ '2024-02-01', TIMESTAMPTZ '2024-03-01', INTERVAL '0 day') g(s); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(1.0, 25.0) g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(1.0, 25.0, 2.0) g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(25.0, 1.0, -1.0) g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(25.0, 1.0, 1.0) g(s);$$, +true, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series('-infinity'::NUMERIC, 'infinity'::NUMERIC, 1.0) g(s);$$, +false, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(1.0, 25.0, 'NaN'::NUMERIC) g(s);$$, +false, true, false, true); + +SELECT explain_mask_costs($$ +SELECT * FROM generate_series(25.0, 2.0, 0.0) g(s);$$, +false, true, false, true); + +SELECT count(*) > 0 AS ok FROM pg_control_checkpoint(); + +SELECT count(*) > 0 AS ok FROM pg_control_init(); + +SELECT count(*) > 0 AS ok FROM pg_control_recovery(); + +SELECT count(*) > 0 AS ok FROM pg_control_system(); + +SELECT * FROM pg_split_walfile_name(NULL); + +SELECT * FROM pg_split_walfile_name('invalid'); + +SELECT segment_number > 0 AS ok_segment_number, timeline_id + FROM pg_split_walfile_name('000000010000000100000000'); + +SELECT segment_number > 0 AS ok_segment_number, timeline_id + FROM pg_split_walfile_name('ffffffFF00000001000000af'); + +SELECT setting::int8 AS segment_size +FROM pg_settings +WHERE name = 'wal_segment_size' + +SELECT segment_number, file_offset +FROM pg_walfile_name_offset('0/0'::pg_lsn + 'segment_size'), + pg_split_walfile_name(file_name); + +SELECT segment_number, file_offset +FROM pg_walfile_name_offset('0/0'::pg_lsn + 'segment_size' + 1), + pg_split_walfile_name(file_name); + +SELECT segment_number, file_offset = 'segment_size' - 1 +FROM pg_walfile_name_offset('0/0'::pg_lsn + 'segment_size' - 1), + pg_split_walfile_name(file_name); + +CREATE ROLE regress_current_logfile; + +SELECT has_function_privilege('regress_current_logfile', + 'pg_current_logfile()', 'EXECUTE'); + +GRANT pg_monitor TO regress_current_logfile; + +SELECT has_function_privilege('regress_current_logfile', + 'pg_current_logfile()', 'EXECUTE'); + +DROP ROLE regress_current_logfile; + +CREATE TABLE test_chunk_id (a TEXT, b TEXT STORAGE EXTERNAL); + +INSERT INTO test_chunk_id VALUES ('x', repeat('x', 8192)); + +SELECT t.relname AS toastrel FROM pg_class c + LEFT JOIN pg_class t ON c.reltoastrelid = t.oid + WHERE c.relname = 'test_chunk_id' + +DROP TABLE test_chunk_id; + +DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool); + +SELECT gist_translate_cmptype_common(7); + +SELECT gist_translate_cmptype_common(3); + +CREATE FUNCTION test_relpath() + RETURNS void + AS 'regresslib' + LANGUAGE C; + +SELECT test_relpath(); + +SELECT pg_replication_origin_create('regress_' || repeat('a', 505)); diff --git a/crates/pgt_pretty_print/tests/data/multi/misc_sanity_60.sql b/crates/pgt_pretty_print/tests/data/multi/misc_sanity_60.sql new file mode 100644 index 000000000..d83a71218 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/misc_sanity_60.sql @@ -0,0 +1,32 @@ +SELECT * +FROM pg_depend as d1 +WHERE refclassid = 0 OR refobjid = 0 OR + classid = 0 OR objid = 0 OR + deptype NOT IN ('a', 'e', 'i', 'n', 'x', 'P', 'S'); + +SELECT * +FROM pg_shdepend as d1 +WHERE refclassid = 0 OR refobjid = 0 OR + classid = 0 OR objid = 0 OR + deptype NOT IN ('a', 'i', 'o', 'r', 't'); + +SELECT relname, attname, atttypid::regtype +FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid +WHERE c.oid < 16384 AND + reltoastrelid = 0 AND + relkind = 'r' AND + attstorage != 'p' +ORDER BY 1, 2; + +SELECT relname +FROM pg_class +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'r' + AND pg_class.oid NOT IN (SELECT indrelid FROM pg_index WHERE indisprimary) +ORDER BY 1; + +SELECT relname +FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid +WHERE relnamespace = 'pg_catalog'::regnamespace AND relkind = 'i' + AND i.indisunique + AND c.oid NOT IN (SELECT conindid FROM pg_constraint) +ORDER BY 1; diff --git a/crates/pgt_pretty_print/tests/data/multi/money_60.sql b/crates/pgt_pretty_print/tests/data/multi/money_60.sql new file mode 100644 index 000000000..ea886430b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/money_60.sql @@ -0,0 +1,217 @@ +CREATE TABLE money_data (m money); + +INSERT INTO money_data VALUES ('123'); + +SELECT * FROM money_data; + +SELECT m + '123' FROM money_data; + +SELECT m + '123.45' FROM money_data; + +SELECT m - '123.45' FROM money_data; + +SELECT m / '2'::money FROM money_data; + +SELECT m * 2 FROM money_data; + +SELECT 2 * m FROM money_data; + +SELECT m / 2 FROM money_data; + +SELECT m * 2::int2 FROM money_data; + +SELECT 2::int2 * m FROM money_data; + +SELECT m / 2::int2 FROM money_data; + +SELECT m * 2::int8 FROM money_data; + +SELECT 2::int8 * m FROM money_data; + +SELECT m / 2::int8 FROM money_data; + +SELECT m * 2::float8 FROM money_data; + +SELECT 2::float8 * m FROM money_data; + +SELECT m / 2::float8 FROM money_data; + +SELECT m * 2::float4 FROM money_data; + +SELECT 2::float4 * m FROM money_data; + +SELECT m / 2::float4 FROM money_data; + +SELECT m = '$123.00' FROM money_data; + +SELECT m != '$124.00' FROM money_data; + +SELECT m <= '$123.00' FROM money_data; + +SELECT m >= '$123.00' FROM money_data; + +SELECT m < '$124.00' FROM money_data; + +SELECT m > '$122.00' FROM money_data; + +SELECT m = '$123.01' FROM money_data; + +SELECT m != '$123.00' FROM money_data; + +SELECT m <= '$122.99' FROM money_data; + +SELECT m >= '$123.01' FROM money_data; + +SELECT m > '$124.00' FROM money_data; + +SELECT m < '$122.00' FROM money_data; + +SELECT cashlarger(m, '$124.00') FROM money_data; + +SELECT cashsmaller(m, '$124.00') FROM money_data; + +SELECT cash_words(m) FROM money_data; + +SELECT cash_words(m + '1.23') FROM money_data; + +DELETE FROM money_data; + +INSERT INTO money_data VALUES ('$123.45'); + +SELECT * FROM money_data; + +DELETE FROM money_data; + +INSERT INTO money_data VALUES ('$123.451'); + +SELECT * FROM money_data; + +DELETE FROM money_data; + +INSERT INTO money_data VALUES ('$123.454'); + +SELECT * FROM money_data; + +DELETE FROM money_data; + +INSERT INTO money_data VALUES ('$123.455'); + +SELECT * FROM money_data; + +DELETE FROM money_data; + +INSERT INTO money_data VALUES ('$123.456'); + +SELECT * FROM money_data; + +DELETE FROM money_data; + +INSERT INTO money_data VALUES ('$123.459'); + +SELECT * FROM money_data; + +SELECT '1234567890'::money; + +SELECT '12345678901234567'::money; + +SELECT '123456789012345678'::money; + +SELECT '9223372036854775807'::money; + +SELECT '-12345'::money; + +SELECT '-1234567890'::money; + +SELECT '-12345678901234567'::money; + +SELECT '-123456789012345678'::money; + +SELECT '-9223372036854775808'::money; + +SELECT '(1)'::money; + +SELECT '($123,456.78)'::money; + +SELECT pg_input_is_valid('\x0001', 'money'); + +SELECT * FROM pg_input_error_info('\x0001', 'money'); + +SELECT pg_input_is_valid('192233720368547758.07', 'money'); + +SELECT * FROM pg_input_error_info('192233720368547758.07', 'money'); + +SELECT '-92233720368547758.08'::money; + +SELECT '92233720368547758.07'::money; + +SELECT '-92233720368547758.09'::money; + +SELECT '92233720368547758.08'::money; + +SELECT '-92233720368547758.085'::money; + +SELECT '92233720368547758.075'::money; + +SELECT '878.08'::money / 11::float8; + +SELECT '878.08'::money / 11::float4; + +SELECT '878.08'::money / 11::bigint; + +SELECT '878.08'::money / 11::int; + +SELECT '878.08'::money / 11::smallint; + +SELECT '90000000000000099.00'::money / 10::bigint; + +SELECT '90000000000000099.00'::money / 10::int; + +SELECT '90000000000000099.00'::money / 10::smallint; + +SELECT 1234567890::money; + +SELECT 12345678901234567::money; + +SELECT (-12345)::money; + +SELECT (-1234567890)::money; + +SELECT (-12345678901234567)::money; + +SELECT 1234567890::int4::money; + +SELECT 12345678901234567::int8::money; + +SELECT 12345678901234567::numeric::money; + +SELECT (-1234567890)::int4::money; + +SELECT (-12345678901234567)::int8::money; + +SELECT (-12345678901234567)::numeric::money; + +SELECT '12345678901234567'::money::numeric; + +SELECT '-12345678901234567'::money::numeric; + +SELECT '92233720368547758.07'::money::numeric; + +SELECT '-92233720368547758.08'::money::numeric; + +SELECT '92233720368547758.07'::money + '0.01'::money; + +SELECT '-92233720368547758.08'::money - '0.01'::money; + +SELECT '92233720368547758.07'::money * 2::float8; + +SELECT '-1'::money / 1.175494e-38::float4; + +SELECT '92233720368547758.07'::money * 2::int4; + +SELECT '1'::money / 0::int2; + +SELECT '42'::money * 'inf'::float8; + +SELECT '42'::money * '-inf'::float8; + +SELECT '42'::money * 'nan'::float4; diff --git a/crates/pgt_pretty_print/tests/data/multi/multirangetypes_60.sql b/crates/pgt_pretty_print/tests/data/multi/multirangetypes_60.sql new file mode 100644 index 000000000..f44604dad --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/multirangetypes_60.sql @@ -0,0 +1,1263 @@ +select ''::textmultirange; + +select '{,}'::textmultirange; + +select '{(,)}.'::textmultirange; + +select '{[a,c),}'::textmultirange; + +select '{,[a,c)}'::textmultirange; + +select '{-[a,z)}'::textmultirange; + +select '{[a,z) - }'::textmultirange; + +select '{(",a)}'::textmultirange; + +select '{(,,a)}'::textmultirange; + +select '{(),a)}'::textmultirange; + +select '{(a,))}'::textmultirange; + +select '{(],a)}'::textmultirange; + +select '{(a,])}'::textmultirange; + +select '{[z,a]}'::textmultirange; + +select '{}'::textmultirange; + +select ' {} '::textmultirange; + +select ' { empty, empty } '::textmultirange; + +select ' {( " a " " a ", " z " " z " ) }'::textmultirange; + +select textrange('\\\\', repeat('a', 200))::textmultirange; + +select '{(,z)}'::textmultirange; + +select '{(a,)}'::textmultirange; + +select '{[,z]}'::textmultirange; + +select '{[a,]}'::textmultirange; + +select '{(,)}'::textmultirange; + +select '{[ , ]}'::textmultirange; + +select '{["",""]}'::textmultirange; + +select '{[",",","]}'::textmultirange; + +select '{["\\","\\"]}'::textmultirange; + +select '{["""","\""]}'::textmultirange; + +select '{(\\,a)}'::textmultirange; + +select '{((,z)}'::textmultirange; + +select '{([,z)}'::textmultirange; + +select '{(!,()}'::textmultirange; + +select '{(!,[)}'::textmultirange; + +select '{[a,a]}'::textmultirange; + +select '{[a,a],[a,b]}'::textmultirange; + +select '{[a,b), [b,e]}'::textmultirange; + +select '{[a,d), [b,f]}'::textmultirange; + +select '{[a,a],[b,b]}'::textmultirange; + +select '{[a,a], [b,b]}'::textmultirange; + +select '{[1,2], [3,4]}'::int4multirange; + +select '{[a,a], [b,b], [c,c]}'::textmultirange; + +select '{[a,d], [b,e]}'::textmultirange; + +select '{[a,d), [d,e)}'::textmultirange; + +select '{[a,a)}'::textmultirange; + +select '{(a,a]}'::textmultirange; + +select '{(a,a)}'::textmultirange; + +select pg_input_is_valid('{[1,2], [4,5]}', 'int4multirange'); + +select pg_input_is_valid('{[1,2], [4,5]', 'int4multirange'); + +select * from pg_input_error_info('{[1,2], [4,5]', 'int4multirange'); + +select pg_input_is_valid('{[1,2], [4,zed]}', 'int4multirange'); + +select * from pg_input_error_info('{[1,2], [4,zed]}', 'int4multirange'); + +select textmultirange(); + +select textmultirange(textrange('a', 'c')); + +select textmultirange(textrange('a', 'c'), textrange('f', 'g')); + +select textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd')); + +select 'empty'::int4range::int4multirange; + +select int4range(1, 3)::int4multirange; + +select int4range(1, null)::int4multirange; + +select int4range(null, null)::int4multirange; + +select 'empty'::textrange::textmultirange; + +select textrange('a', 'c')::textmultirange; + +select textrange('a', null)::textmultirange; + +select textrange(null, null)::textmultirange; + +select unnest(int4multirange(int4range('5', '6'), int4range('1', '2'))); + +select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e'))); + +select unnest(textmultirange(textrange('\\\\', repeat('a', 200)), textrange('c', 'd'))); + +CREATE TABLE nummultirange_test (nmr NUMMULTIRANGE); + +CREATE INDEX nummultirange_test_btree ON nummultirange_test(nmr); + +INSERT INTO nummultirange_test VALUES('{}'); + +INSERT INTO nummultirange_test VALUES('{[,)}'); + +INSERT INTO nummultirange_test VALUES('{[3,]}'); + +INSERT INTO nummultirange_test VALUES('{[,), [3,]}'); + +INSERT INTO nummultirange_test VALUES('{[, 5)}'); + +INSERT INTO nummultirange_test VALUES(nummultirange()); + +INSERT INTO nummultirange_test VALUES(nummultirange(variadic '{}'::numrange[])); + +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.1, 2.2))); + +INSERT INTO nummultirange_test VALUES('{empty}'); + +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9))); + +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1))); + +SELECT nmr, isempty(nmr), lower(nmr), upper(nmr) FROM nummultirange_test ORDER BY nmr; + +SELECT nmr, lower_inc(nmr), lower_inf(nmr), upper_inc(nmr), upper_inf(nmr) FROM nummultirange_test ORDER BY nmr; + +SELECT * FROM nummultirange_test WHERE nmr = '{}'; + +SELECT * FROM nummultirange_test WHERE nmr = '{(,5)}'; + +SELECT * FROM nummultirange_test WHERE nmr = '{[3,)}'; + +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7]}'; + +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7],[1.9,2.1)}'; + +SELECT * FROM nummultirange_test WHERE nmr < '{}'; + +SELECT * FROM nummultirange_test WHERE nmr < '{[-1000.0, -1000.0]}'; + +SELECT * FROM nummultirange_test WHERE nmr < '{[0.0, 1.0]}'; + +SELECT * FROM nummultirange_test WHERE nmr < '{[1000.0, 1001.0]}'; + +SELECT * FROM nummultirange_test WHERE nmr <= '{}'; + +SELECT * FROM nummultirange_test WHERE nmr <= '{[3,)}'; + +SELECT * FROM nummultirange_test WHERE nmr >= '{}'; + +SELECT * FROM nummultirange_test WHERE nmr >= '{[3,)}'; + +SELECT * FROM nummultirange_test WHERE nmr > '{}'; + +SELECT * FROM nummultirange_test WHERE nmr > '{[-1000.0, -1000.0]}'; + +SELECT * FROM nummultirange_test WHERE nmr > '{[0.0, 1.0]}'; + +SELECT * FROM nummultirange_test WHERE nmr > '{[1000.0, 1001.0]}'; + +SELECT * FROM nummultirange_test WHERE nmr <> '{}'; + +SELECT * FROM nummultirange_test WHERE nmr <> '{(,5)}'; + +select nummultirange(numrange(2.0, 1.0)); + +select nummultirange(numrange(5.0, 6.0), numrange(1.0, 2.0)); + +analyze nummultirange_test; + +SELECT * FROM nummultirange_test WHERE range_overlaps_multirange(numrange(4.0, 4.2), nmr); + +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) && nmr; + +SELECT * FROM nummultirange_test WHERE multirange_overlaps_range(nmr, numrange(4.0, 4.2)); + +SELECT * FROM nummultirange_test WHERE nmr && numrange(4.0, 4.2); + +SELECT * FROM nummultirange_test WHERE multirange_overlaps_multirange(nmr, nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0))); + +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0)); + +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0)); + +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0), numrange(8.0, 9.0)); + +SELECT * FROM nummultirange_test WHERE multirange_contains_elem(nmr, 4.0); + +SELECT * FROM nummultirange_test WHERE nmr @> 4.0; + +SELECT * FROM nummultirange_test WHERE multirange_contains_range(nmr, numrange(4.0, 4.2)); + +SELECT * FROM nummultirange_test WHERE nmr @> numrange(4.0, 4.2); + +SELECT * FROM nummultirange_test WHERE multirange_contains_multirange(nmr, '{[4.0,4.2), [6.0, 8.0)}'); + +SELECT * FROM nummultirange_test WHERE nmr @> '{[4.0,4.2), [6.0, 8.0)}'::nummultirange; + +SELECT * FROM nummultirange_test WHERE elem_contained_by_multirange(4.0, nmr); + +SELECT * FROM nummultirange_test WHERE 4.0 <@ nmr; + +SELECT * FROM nummultirange_test WHERE range_contained_by_multirange(numrange(4.0, 4.2), nmr); + +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) <@ nmr; + +SELECT * FROM nummultirange_test WHERE multirange_contained_by_multirange('{[4.0,4.2), [6.0, 8.0)}', nmr); + +SELECT * FROM nummultirange_test WHERE '{[4.0,4.2), [6.0, 8.0)}'::nummultirange <@ nmr; + +SELECT 'empty'::numrange && nummultirange(); + +SELECT 'empty'::numrange && nummultirange(numrange(1,2)); + +SELECT nummultirange() && 'empty'::numrange; + +SELECT nummultirange(numrange(1,2)) && 'empty'::numrange; + +SELECT nummultirange() && nummultirange(); + +SELECT nummultirange() && nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,2)) && nummultirange(); + +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(7,8)); + +SELECT nummultirange(numrange(1,2), numrange(7,8)) && nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(3.5,8)); + +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && numrange(3,4); + +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && nummultirange(numrange(3,4)); + +select '{(10,20),(30,40),(50,60)}'::nummultirange && '(42,92)'::numrange; + +SELECT nummultirange() @> nummultirange(); + +SELECT nummultirange() @> 'empty'::numrange; + +SELECT nummultirange(numrange(null,null)) @> numrange(1,2); + +SELECT nummultirange(numrange(null,null)) @> numrange(null,2); + +SELECT nummultirange(numrange(null,null)) @> numrange(2,null); + +SELECT nummultirange(numrange(null,5)) @> numrange(null,3); + +SELECT nummultirange(numrange(null,5)) @> numrange(null,8); + +SELECT nummultirange(numrange(5,null)) @> numrange(8,null); + +SELECT nummultirange(numrange(5,null)) @> numrange(3,null); + +SELECT nummultirange(numrange(1,5)) @> numrange(8,9); + +SELECT nummultirange(numrange(1,5)) @> numrange(3,9); + +SELECT nummultirange(numrange(1,5)) @> numrange(1,4); + +SELECT nummultirange(numrange(1,5)) @> numrange(1,5); + +SELECT nummultirange(numrange(-4,-2), numrange(1,5)) @> numrange(1,5); + +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(1,5); + +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(6,7); + +SELECT nummultirange(numrange(1,5), numrange(6,9)) @> numrange(6,7); + +SELECT '{[1,5)}'::nummultirange @> '{[1,5)}'; + +SELECT '{[-4,-2), [1,5)}'::nummultirange @> '{[1,5)}'; + +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[1,5)}'; + +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[6,7)}'; + +SELECT '{[1,5), [6,9)}'::nummultirange @> '{[6,7)}'; + +select '{(10,20),(30,40),(50,60)}'::nummultirange @> '(52,56)'::numrange; + +SELECT numrange(null,null) @> nummultirange(numrange(1,2)); + +SELECT numrange(null,null) @> nummultirange(numrange(null,2)); + +SELECT numrange(null,null) @> nummultirange(numrange(2,null)); + +SELECT numrange(null,5) @> nummultirange(numrange(null,3)); + +SELECT numrange(null,5) @> nummultirange(numrange(null,8)); + +SELECT numrange(5,null) @> nummultirange(numrange(8,null)); + +SELECT numrange(5,null) @> nummultirange(numrange(3,null)); + +SELECT numrange(1,5) @> nummultirange(numrange(8,9)); + +SELECT numrange(1,5) @> nummultirange(numrange(3,9)); + +SELECT numrange(1,5) @> nummultirange(numrange(1,4)); + +SELECT numrange(1,5) @> nummultirange(numrange(1,5)); + +SELECT numrange(1,9) @> nummultirange(numrange(-4,-2), numrange(1,5)); + +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(8,9)); + +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,9)); + +SELECT numrange(1,9) @> nummultirange(numrange(1,5), numrange(6,10)); + +SELECT '{[1,9)}' @> '{[1,5)}'::nummultirange; + +SELECT '{[1,9)}' @> '{[-4,-2), [1,5)}'::nummultirange; + +SELECT '{[1,9)}' @> '{[1,5), [8,9)}'::nummultirange; + +SELECT '{[1,9)}' @> '{[1,5), [6,9)}'::nummultirange; + +SELECT '{[1,9)}' @> '{[1,5), [6,10)}'::nummultirange; + +SELECT nummultirange() <@ nummultirange(); + +SELECT 'empty'::numrange <@ nummultirange(); + +SELECT numrange(1,2) <@ nummultirange(numrange(null,null)); + +SELECT numrange(null,2) <@ nummultirange(numrange(null,null)); + +SELECT numrange(2,null) <@ nummultirange(numrange(null,null)); + +SELECT numrange(null,3) <@ nummultirange(numrange(null,5)); + +SELECT numrange(null,8) <@ nummultirange(numrange(null,5)); + +SELECT numrange(8,null) <@ nummultirange(numrange(5,null)); + +SELECT numrange(3,null) <@ nummultirange(numrange(5,null)); + +SELECT numrange(8,9) <@ nummultirange(numrange(1,5)); + +SELECT numrange(3,9) <@ nummultirange(numrange(1,5)); + +SELECT numrange(1,4) <@ nummultirange(numrange(1,5)); + +SELECT numrange(1,5) <@ nummultirange(numrange(1,5)); + +SELECT numrange(1,5) <@ nummultirange(numrange(-4,-2), numrange(1,5)); + +SELECT numrange(1,5) <@ nummultirange(numrange(1,5), numrange(8,9)); + +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(8,9)); + +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(6,9)); + +SELECT '{[1,5)}' <@ '{[1,5)}'::nummultirange; + +SELECT '{[1,5)}' <@ '{[-4,-2), [1,5)}'::nummultirange; + +SELECT '{[1,5)}' <@ '{[1,5), [8,9)}'::nummultirange; + +SELECT '{[6,7)}' <@ '{[1,5), [8,9)}'::nummultirange; + +SELECT '{[6,7)}' <@ '{[1,5), [6,9)}'::nummultirange; + +SELECT nummultirange(numrange(1,2)) <@ numrange(null,null); + +SELECT nummultirange(numrange(null,2)) <@ numrange(null,null); + +SELECT nummultirange(numrange(2,null)) <@ numrange(null,null); + +SELECT nummultirange(numrange(null,3)) <@ numrange(null,5); + +SELECT nummultirange(numrange(null,8)) <@ numrange(null,5); + +SELECT nummultirange(numrange(8,null)) <@ numrange(5,null); + +SELECT nummultirange(numrange(3,null)) <@ numrange(5,null); + +SELECT nummultirange(numrange(8,9)) <@ numrange(1,5); + +SELECT nummultirange(numrange(3,9)) <@ numrange(1,5); + +SELECT nummultirange(numrange(1,4)) <@ numrange(1,5); + +SELECT nummultirange(numrange(1,5)) <@ numrange(1,5); + +SELECT nummultirange(numrange(-4,-2), numrange(1,5)) <@ numrange(1,9); + +SELECT nummultirange(numrange(1,5), numrange(8,9)) <@ numrange(1,9); + +SELECT nummultirange(numrange(1,5), numrange(6,9)) <@ numrange(1,9); + +SELECT nummultirange(numrange(1,5), numrange(6,10)) <@ numrange(1,9); + +SELECT '{[1,5)}'::nummultirange <@ '{[1,9)}'; + +SELECT '{[-4,-2), [1,5)}'::nummultirange <@ '{[1,9)}'; + +SELECT '{[1,5), [8,9)}'::nummultirange <@ '{[1,9)}'; + +SELECT '{[1,5), [6,9)}'::nummultirange <@ '{[1,9)}'; + +SELECT '{[1,5), [6,10)}'::nummultirange <@ '{[1,9)}'; + +SELECT 'empty'::numrange &< nummultirange(); + +SELECT 'empty'::numrange &< nummultirange(numrange(1,2)); + +SELECT nummultirange() &< 'empty'::numrange; + +SELECT nummultirange(numrange(1,2)) &< 'empty'::numrange; + +SELECT nummultirange() &< nummultirange(); + +SELECT nummultirange(numrange(1,2)) &< nummultirange(); + +SELECT nummultirange() &< nummultirange(numrange(1,2)); + +SELECT numrange(6,7) &< nummultirange(numrange(3,4)); + +SELECT numrange(1,2) &< nummultirange(numrange(3,4)); + +SELECT numrange(1,4) &< nummultirange(numrange(3,4)); + +SELECT numrange(1,6) &< nummultirange(numrange(3,4)); + +SELECT numrange(3.5,6) &< nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(6,7)) &< numrange(3,4); + +SELECT nummultirange(numrange(1,2)) &< numrange(3,4); + +SELECT nummultirange(numrange(1,4)) &< numrange(3,4); + +SELECT nummultirange(numrange(1,6)) &< numrange(3,4); + +SELECT nummultirange(numrange(3.5,6)) &< numrange(3,4); + +SELECT nummultirange(numrange(6,7)) &< nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,2)) &< nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,4)) &< nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,6)) &< nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(3.5,6)) &< nummultirange(numrange(3,4)); + +SELECT nummultirange() &> 'empty'::numrange; + +SELECT nummultirange(numrange(1,2)) &> 'empty'::numrange; + +SELECT 'empty'::numrange &> nummultirange(); + +SELECT 'empty'::numrange &> nummultirange(numrange(1,2)); + +SELECT nummultirange() &> nummultirange(); + +SELECT nummultirange() &> nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,2)) &> nummultirange(); + +SELECT nummultirange(numrange(3,4)) &> numrange(6,7); + +SELECT nummultirange(numrange(3,4)) &> numrange(1,2); + +SELECT nummultirange(numrange(3,4)) &> numrange(1,4); + +SELECT nummultirange(numrange(3,4)) &> numrange(1,6); + +SELECT nummultirange(numrange(3,4)) &> numrange(3.5,6); + +SELECT numrange(3,4) &> nummultirange(numrange(6,7)); + +SELECT numrange(3,4) &> nummultirange(numrange(1,2)); + +SELECT numrange(3,4) &> nummultirange(numrange(1,4)); + +SELECT numrange(3,4) &> nummultirange(numrange(1,6)); + +SELECT numrange(3,4) &> nummultirange(numrange(3.5,6)); + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(6,7)); + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,4)); + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,6)); + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(3.5,6)); + +SELECT 'empty'::numrange -|- nummultirange(); + +SELECT 'empty'::numrange -|- nummultirange(numrange(1,2)); + +SELECT nummultirange() -|- 'empty'::numrange; + +SELECT nummultirange(numrange(1,2)) -|- 'empty'::numrange; + +SELECT nummultirange() -|- nummultirange(); + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(); + +SELECT nummultirange() -|- nummultirange(numrange(1,2)); + +SELECT numrange(1,2) -|- nummultirange(numrange(2,4)); + +SELECT numrange(1,2) -|- nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,2)) -|- numrange(2,4); + +SELECT nummultirange(numrange(1,2)) -|- numrange(3,4); + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4)); + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(6,7)); + +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(8,9)); + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4), numrange(6,7)); + +select 'empty'::numrange << nummultirange(); + +select numrange(1,2) << nummultirange(); + +select numrange(1,2) << nummultirange(numrange(3,4)); + +select numrange(1,2) << nummultirange(numrange(0,4)); + +select numrange(1,2) << nummultirange(numrange(0,4), numrange(7,8)); + +select nummultirange() << 'empty'::numrange; + +select nummultirange() << numrange(1,2); + +select nummultirange(numrange(3,4)) << numrange(3,6); + +select nummultirange(numrange(0,2)) << numrange(3,6); + +select nummultirange(numrange(0,2), numrange(7,8)) << numrange(3,6); + +select nummultirange(numrange(-4,-2), numrange(0,2)) << numrange(3,6); + +select nummultirange() << nummultirange(); + +select nummultirange() << nummultirange(numrange(1,2)); + +select nummultirange(numrange(1,2)) << nummultirange(); + +select nummultirange(numrange(1,2)) << nummultirange(numrange(1,2)); + +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4)); + +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4), numrange(7,8)); + +select nummultirange(numrange(1,2), numrange(4,5)) << nummultirange(numrange(3,4), numrange(7,8)); + +select nummultirange() >> 'empty'::numrange; + +select nummultirange() >> numrange(1,2); + +select nummultirange(numrange(3,4)) >> numrange(1,2); + +select nummultirange(numrange(0,4)) >> numrange(1,2); + +select nummultirange(numrange(0,4), numrange(7,8)) >> numrange(1,2); + +select 'empty'::numrange >> nummultirange(); + +select numrange(1,2) >> nummultirange(); + +select numrange(3,6) >> nummultirange(numrange(3,4)); + +select numrange(3,6) >> nummultirange(numrange(0,2)); + +select numrange(3,6) >> nummultirange(numrange(0,2), numrange(7,8)); + +select numrange(3,6) >> nummultirange(numrange(-4,-2), numrange(0,2)); + +select nummultirange() >> nummultirange(); + +select nummultirange(numrange(1,2)) >> nummultirange(); + +select nummultirange() >> nummultirange(numrange(1,2)); + +select nummultirange(numrange(1,2)) >> nummultirange(numrange(1,2)); + +select nummultirange(numrange(3,4)) >> nummultirange(numrange(1,2)); + +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2)); + +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2), numrange(4,5)); + +SELECT nummultirange() + nummultirange(); + +SELECT nummultirange() + nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,2)) + nummultirange(); + +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(2,4)); + +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(2,4)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(0,9)); + +SELECT range_merge(nummultirange()); + +SELECT range_merge(nummultirange(numrange(1,2))); + +SELECT range_merge(nummultirange(numrange(1,2), numrange(7,8))); + +SELECT nummultirange() - nummultirange(); + +SELECT nummultirange() - nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,2)) - nummultirange(); + +SELECT nummultirange(numrange(1,2), numrange(3,4)) - nummultirange(); + +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(2,4)); + +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(3,4)); + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(2,3)); + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,8)); + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,2)); + +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(0,2), numrange(3,4)); + +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(2,3), numrange(5,null)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(2,4)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(3,5)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(0,9)); + +SELECT nummultirange(numrange(1,3), numrange(4,5)) - nummultirange(numrange(2,9)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(8,9)); + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0), numrange(8,9)); + +SELECT nummultirange() * nummultirange(); + +SELECT nummultirange() * nummultirange(numrange(1,2)); + +SELECT nummultirange(numrange(1,2)) * nummultirange(); + +SELECT '{[1,3)}'::nummultirange * '{[1,5)}'::nummultirange; + +SELECT '{[1,3)}'::nummultirange * '{[0,5)}'::nummultirange; + +SELECT '{[1,3)}'::nummultirange * '{[0,2)}'::nummultirange; + +SELECT '{[1,3)}'::nummultirange * '{[2,5)}'::nummultirange; + +SELECT '{[1,4)}'::nummultirange * '{[2,3)}'::nummultirange; + +SELECT '{[1,4)}'::nummultirange * '{[0,2), [3,5)}'::nummultirange; + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,8), [9,12)}'::nummultirange; + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[9,12)}'::nummultirange; + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[-5,-4), [5,6), [9,12)}'::nummultirange; + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange; + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange; + +create table test_multirange_gist(mr int4multirange); + +insert into test_multirange_gist select int4multirange(int4range(g, g+10),int4range(g+20, g+30),int4range(g+40, g+50)) from generate_series(1,2000) g; + +insert into test_multirange_gist select '{}'::int4multirange from generate_series(1,500) g; + +insert into test_multirange_gist select int4multirange(int4range(g, g+10000)) from generate_series(1,1000) g; + +insert into test_multirange_gist select int4multirange(int4range(NULL, g*10, '(]'), int4range(g*10, g*20, '(]')) from generate_series(1,100) g; + +insert into test_multirange_gist select int4multirange(int4range(g*10, g*20, '(]'), int4range(g*20, NULL, '(]')) from generate_series(1,100) g; + +create index test_mulrirange_gist_idx on test_multirange_gist using gist (mr); + +analyze test_multirange_gist; + +SET enable_seqscan = t; + +SET enable_indexscan = f; + +SET enable_bitmapscan = f; + +select count(*) from test_multirange_gist where mr = '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr @> 'empty'::int4range; + +select count(*) from test_multirange_gist where mr && 'empty'::int4range; + +select count(*) from test_multirange_gist where mr <@ 'empty'::int4range; + +select count(*) from test_multirange_gist where mr << 'empty'::int4range; + +select count(*) from test_multirange_gist where mr >> 'empty'::int4range; + +select count(*) from test_multirange_gist where mr &< 'empty'::int4range; + +select count(*) from test_multirange_gist where mr &> 'empty'::int4range; + +select count(*) from test_multirange_gist where mr -|- 'empty'::int4range; + +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr && '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr << '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr >> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr &< '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr &> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)); + +select count(*) from test_multirange_gist where mr @> 10; + +select count(*) from test_multirange_gist where mr @> int4range(10,20); + +select count(*) from test_multirange_gist where mr && int4range(10,20); + +select count(*) from test_multirange_gist where mr <@ int4range(10,50); + +select count(*) from test_multirange_gist where mr << int4range(100,500); + +select count(*) from test_multirange_gist where mr >> int4range(100,500); + +select count(*) from test_multirange_gist where mr &< int4range(100,500); + +select count(*) from test_multirange_gist where mr &> int4range(100,500); + +select count(*) from test_multirange_gist where mr -|- int4range(100,500); + +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)); + +select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange; + +select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange; + +select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)); + +SET enable_seqscan = f; + +SET enable_indexscan = t; + +SET enable_bitmapscan = f; + +select count(*) from test_multirange_gist where mr = '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr @> 'empty'::int4range; + +select count(*) from test_multirange_gist where mr && 'empty'::int4range; + +select count(*) from test_multirange_gist where mr <@ 'empty'::int4range; + +select count(*) from test_multirange_gist where mr << 'empty'::int4range; + +select count(*) from test_multirange_gist where mr >> 'empty'::int4range; + +select count(*) from test_multirange_gist where mr &< 'empty'::int4range; + +select count(*) from test_multirange_gist where mr &> 'empty'::int4range; + +select count(*) from test_multirange_gist where mr -|- 'empty'::int4range; + +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr && '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr << '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr >> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr &< '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr &> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr @> 'empty'::int4range; + +select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60)); + +select count(*) from test_multirange_gist where mr @> 10; + +select count(*) from test_multirange_gist where mr @> int4range(10,20); + +select count(*) from test_multirange_gist where mr && int4range(10,20); + +select count(*) from test_multirange_gist where mr <@ int4range(10,50); + +select count(*) from test_multirange_gist where mr << int4range(100,500); + +select count(*) from test_multirange_gist where mr >> int4range(100,500); + +select count(*) from test_multirange_gist where mr &< int4range(100,500); + +select count(*) from test_multirange_gist where mr &> int4range(100,500); + +select count(*) from test_multirange_gist where mr -|- int4range(100,500); + +select count(*) from test_multirange_gist where mr @> '{}'::int4multirange; + +select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40)); + +select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange; + +select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange; + +select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500)); + +drop table test_multirange_gist; + +create table reservations ( room_id integer not null, booked_during daterange ); + +insert into reservations values +-- 1: has a meets and a gap +(1, daterange('2018-07-01', '2018-07-07')), +(1, daterange('2018-07-07', '2018-07-14')), +(1, daterange('2018-07-20', '2018-07-22')), +-- 2: just a single row +(2, daterange('2018-07-01', '2018-07-03')), +-- 3: one null range +(3, NULL), +-- 4: two null ranges +(4, NULL), +(4, NULL), +-- 5: a null range and a non-null range +(5, NULL), +(5, daterange('2018-07-01', '2018-07-03')), +-- 6: has overlap +(6, daterange('2018-07-01', '2018-07-07')), +(6, daterange('2018-07-05', '2018-07-10')), +-- 7: two ranges that meet: no gap or overlap +(7, daterange('2018-07-01', '2018-07-07')), +(7, daterange('2018-07-07', '2018-07-14')), +-- 8: an empty range +(8, 'empty'::daterange) +; + +SELECT room_id, range_agg(booked_during) +FROM reservations +GROUP BY room_id +ORDER BY room_id; + +SELECT range_agg(r) +FROM (VALUES + ('[a,c]'::textrange), + ('[b,b]'::textrange), + ('[c,f]'::textrange), + ('[g,h)'::textrange), + ('[h,j)'::textrange) + ) t(r); + +select range_agg(nmr) from nummultirange_test; + +select range_agg(nmr) from nummultirange_test where false; + +select range_agg(null::nummultirange) from nummultirange_test; + +select range_agg(nmr) from (values ('{}'::nummultirange)) t(nmr); + +select range_agg(nmr) from (values ('{}'::nummultirange), ('{}'::nummultirange)) t(nmr); + +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr); + +select range_agg(nmr) from (values ('{[1,2], [5,6]}'::nummultirange)) t(nmr); + +select range_agg(nmr) from (values ('{[1,2], [2,3]}'::nummultirange)) t(nmr); + +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[5,6]}'::nummultirange)) t(nmr); + +select range_agg(nmr) from (values ('{[1,2]}'::nummultirange), ('{[2,3]}'::nummultirange)) t(nmr); + +select range_intersect_agg(nmr) from nummultirange_test; + +select range_intersect_agg(nmr) from nummultirange_test where false; + +select range_intersect_agg(null::nummultirange) from nummultirange_test; + +select range_intersect_agg(nmr) from (values ('{[1,3]}'::nummultirange), ('{[6,12]}'::nummultirange)) t(nmr); + +select range_intersect_agg(nmr) from (values ('{[1,6]}'::nummultirange), ('{[3,12]}'::nummultirange)) t(nmr); + +select range_intersect_agg(nmr) from (values ('{[1,6], [10,12]}'::nummultirange), ('{[4,14]}'::nummultirange)) t(nmr); + +select range_intersect_agg(nmr) from (values ('{}'::nummultirange)) t(nmr); + +select range_intersect_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr); + +select range_intersect_agg(nmr) from (values ('{[1,6], [10,12]}'::nummultirange)) t(nmr); + +select range_intersect_agg(nmr) from nummultirange_test where nmr @> 4.0; + +create table nummultirange_test2(nmr nummultirange); + +create index nummultirange_test2_hash_idx on nummultirange_test2 using hash (nmr); + +INSERT INTO nummultirange_test2 VALUES('{[, 5)}'); + +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); + +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); + +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2,'()'))); + +INSERT INTO nummultirange_test2 VALUES('{}'); + +select * from nummultirange_test2 where nmr = '{}'; + +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.2)); + +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.3)); + +set enable_nestloop=t; + +set enable_hashjoin=f; + +set enable_mergejoin=f; + +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + +set enable_nestloop=f; + +set enable_hashjoin=t; + +set enable_mergejoin=f; + +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + +set enable_nestloop=f; + +set enable_hashjoin=f; + +set enable_mergejoin=t; + +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + +set enable_nestloop to default; + +set enable_hashjoin to default; + +set enable_mergejoin to default; + +DROP TABLE nummultirange_test2; + +select '{[123.001, 5.e9)}'::float8multirange @> 888.882::float8; + +create table float8multirange_test(f8mr float8multirange, i int); + +insert into float8multirange_test values(float8multirange(float8range(-100.00007, '1.111113e9')), 42); + +select * from float8multirange_test; + +drop table float8multirange_test; + +create domain mydomain as int4; + +create type mydomainrange as range(subtype=mydomain); + +select '{[4,50)}'::mydomainmultirange @> 7::mydomain; + +drop domain mydomain cascade; + +create domain restrictedmultirange as int4multirange check (upper(value) < 10); + +select '{[4,5)}'::restrictedmultirange @> 7; + +select '{[4,50)}'::restrictedmultirange @> 7; + +drop domain restrictedmultirange; + +create type intr as range(subtype=int); + +select intr_multirange(intr(1,10)); + +drop type intr; + +create type intmultirange as (x int, y int); + +create type intrange as range(subtype=int); + +drop type intmultirange; + +create type intr_multirange as (x int, y int); + +create type intr as range(subtype=int); + +drop type intr_multirange; + +create type textrange1 as range(subtype=text, multirange_type_name=int, collation="C"); + +create type textrange1 as range(subtype=text, multirange_type_name=multirange_of_text, collation="C"); + +create type textrange2 as range(subtype=text, multirange_type_name=_textrange1, collation="C"); + +select multirange_of_text(textrange2('a','Z')); + +select multirange_of_text(textrange1('a','Z')) @> 'b'::text; + +select unnest(multirange_of_text(textrange1('a','b'), textrange1('d','e'))); + +select _textrange1(textrange2('a','z')) @> 'b'::text; + +drop type textrange1; + +drop type textrange2; + +create type textrange1 as range(subtype=text, multirange_type_name=multitextrange1, collation="C"); + +create role regress_multirange_owner; + +alter type multitextrange1 owner to regress_multirange_owner; + +alter type textrange1 owner to regress_multirange_owner; + +set role regress_multirange_owner; + +revoke usage on type multitextrange1 from public; + +revoke usage on type textrange1 from public; + +create temp table test1(f1 multitextrange1[]); + +revoke usage on type textrange1 from regress_multirange_owner; + +create temp table test2(f1 multitextrange1[]); + +drop table test1; + +drop type textrange1; + +reset role; + +drop role regress_multirange_owner; + +create function anyarray_anymultirange_func(a anyarray, r anymultirange) + returns anyelement as 'select $1[1] + lower($2);' language sql; + +select anyarray_anymultirange_func(ARRAY[1,2], int4multirange(int4range(10,20))); + +select anyarray_anymultirange_func(ARRAY[1,2], nummultirange(numrange(10,20))); + +drop function anyarray_anymultirange_func(anyarray, anymultirange); + +create function bogus_func(anyelement) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql; + +create function bogus_func(int) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql; + +create function range_add_bounds(anymultirange) + returns anyelement as 'select lower($1) + upper($1)' language sql; + +select range_add_bounds(int4multirange(int4range(1, 17))); + +select range_add_bounds(nummultirange(numrange(1.0001, 123.123))); + +create function multirangetypes_sql(q anymultirange, b anyarray, out c anyelement) + as $$ select upper($1) + $2[1] $$ + language sql; + +select multirangetypes_sql(int4multirange(int4range(1,10)), ARRAY[2,20]); + +select multirangetypes_sql(nummultirange(numrange(1,10)), ARRAY[2,20]); + +create function anycompatiblearray_anycompatiblemultirange_func(a anycompatiblearray, mr anycompatiblemultirange) + returns anycompatible as 'select $1[1] + lower($2);' language sql; + +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(int4range(10,20))); + +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(numrange(10,20))); + +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1.1,2], multirange(int4range(10,20))); + +drop function anycompatiblearray_anycompatiblemultirange_func(anycompatiblearray, anycompatiblemultirange); + +create function anycompatiblerange_anycompatiblemultirange_func(r anycompatiblerange, mr anycompatiblemultirange) + returns anycompatible as 'select lower($1) + lower($2);' language sql; + +select anycompatiblerange_anycompatiblemultirange_func(int4range(1,2), multirange(int4range(10,20))); + +select anycompatiblerange_anycompatiblemultirange_func(numrange(1,2), multirange(int4range(10,20))); + +drop function anycompatiblerange_anycompatiblemultirange_func(anycompatiblerange, anycompatiblemultirange); + +create function bogus_func(anycompatible) + returns anycompatiblerange as 'select int4range(1,10)' language sql; + +select ARRAY[nummultirange(numrange(1.1, 1.2)), nummultirange(numrange(12.3, 155.5))]; + +create table i8mr_array (f1 int, f2 int8multirange[]); + +insert into i8mr_array values (42, array[int8multirange(int8range(1,10)), int8multirange(int8range(2,20))]); + +select * from i8mr_array; + +drop table i8mr_array; + +select arraymultirange(arrayrange(ARRAY[1,2], ARRAY[2,1])); + +select arraymultirange(arrayrange(ARRAY[2,1], ARRAY[1,2])); + +select array[1,1] <@ arraymultirange(arrayrange(array[1,2], array[2,1])); + +select array[1,3] <@ arraymultirange(arrayrange(array[1,2], array[2,1])); + +create type two_ints as (a int, b int); + +create type two_ints_range as range (subtype = two_ints); + +select *, row_to_json(upper(t)) as u from + (values (two_ints_multirange(two_ints_range(row(1,2), row(3,4)))), + (two_ints_multirange(two_ints_range(row(5,6), row(7,8))))) v(t); + +drop type two_ints cascade; + +set enable_sort = off; + +select '{(01,10)}'::varbitmultirange except select '{(10,11)}'::varbitmultirange; + +reset enable_sort; + +create function mr_outparam_succeed(i anymultirange, out r anymultirange, out t text) + as $$ select $1, 'foo'::text $$ language sql; + +select * from mr_outparam_succeed(int4multirange(int4range(1,2))); + +create function mr_outparam_succeed2(i anymultirange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql; + +select * from mr_outparam_succeed2(int4multirange(int4range(1,2))); + +create function mr_outparam_succeed3(i anymultirange, out r anyrange, out t text) + as $$ select range_merge($1), 'foo'::text $$ language sql; + +select * from mr_outparam_succeed3(int4multirange(int4range(1,2))); + +create function mr_outparam_succeed4(i anyrange, out r anymultirange, out t text) + as $$ select multirange($1), 'foo'::text $$ language sql; + +select * from mr_outparam_succeed4(int4range(1,2)); + +create function mr_inoutparam_succeed(out i anyelement, inout r anymultirange) + as $$ select upper($1), $1 $$ language sql; + +select * from mr_inoutparam_succeed(int4multirange(int4range(1,2))); + +create function mr_table_succeed(i anyelement, r anymultirange) returns table(i anyelement, r anymultirange) + as $$ select $1, $2 $$ language sql; + +select * from mr_table_succeed(123, int4multirange(int4range(1,11))); + +create function mr_polymorphic(i anyrange) returns anymultirange + as $$ begin return multirange($1); end; $$ language plpgsql; + +select mr_polymorphic(int4range(1, 4)); + +create function mr_outparam_fail(i anyelement, out r anymultirange, out t text) + as $$ select '[1,10]', 'foo' $$ language sql; + +create function mr_inoutparam_fail(inout i anyelement, out r anymultirange) + as $$ select $1, '[1,10]' $$ language sql; + +create function mr_table_fail(i anyelement) returns table(i anyelement, r anymultirange) + as $$ select $1, '[1,10]' $$ language sql; diff --git a/crates/pgt_pretty_print/tests/data/multi/mvcc_60.sql b/crates/pgt_pretty_print/tests/data/multi/mvcc_60.sql new file mode 100644 index 000000000..32670129b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/mvcc_60.sql @@ -0,0 +1,36 @@ +BEGIN; + +SET LOCAL enable_seqscan = false; + +SET LOCAL enable_indexonlyscan = false; + +SET LOCAL enable_bitmapscan = false; + +CREATE TABLE clean_aborted_self(key int, data text); + +CREATE INDEX clean_aborted_self_key ON clean_aborted_self(key); + +INSERT INTO clean_aborted_self (key, data) VALUES (-1, 'just to allocate metapage'); + +SELECT pg_relation_size('clean_aborted_self_key') AS clean_aborted_self_key_before ; + +DO $$ +BEGIN + -- iterate often enough to see index growth even on larger-than-default page sizes + FOR i IN 1..100 LOOP + BEGIN + -- perform index scan over all the inserted keys to get them to be seen as dead + IF EXISTS(SELECT * FROM clean_aborted_self WHERE key > 0 AND key < 100) THEN + RAISE data_corrupted USING MESSAGE = 'these rows should not exist'; + END IF; + INSERT INTO clean_aborted_self SELECT g.i, 'rolling back in a sec' FROM generate_series(1, 100) g(i); + -- just some error that's not normally thrown + RAISE reading_sql_data_not_permitted USING MESSAGE = 'round and round again'; + EXCEPTION WHEN reading_sql_data_not_permitted THEN END; + END LOOP; +END;$$; + +SELECT 'clean_aborted_self_key_before' AS size_before, pg_relation_size('clean_aborted_self_key') size_after +WHERE 'clean_aborted_self_key_before' != pg_relation_size('clean_aborted_self_key'); + +ROLLBACK; diff --git a/crates/pgt_pretty_print/tests/data/multi/name_60.sql b/crates/pgt_pretty_print/tests/data/multi/name_60.sql new file mode 100644 index 000000000..acbf53f12 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/name_60.sql @@ -0,0 +1,87 @@ +SELECT name 'name string' = name 'name string' AS "True"; + +SELECT name 'name string' = name 'name string ' AS "False"; + +CREATE TABLE NAME_TBL(f1 name); + +INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'); + +INSERT INTO NAME_TBL(f1) VALUES ('1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr'); + +INSERT INTO NAME_TBL(f1) VALUES ('asdfghjkl;'); + +INSERT INTO NAME_TBL(f1) VALUES ('343f%2a'); + +INSERT INTO NAME_TBL(f1) VALUES ('d34aaasdf'); + +INSERT INTO NAME_TBL(f1) VALUES (''); + +INSERT INTO NAME_TBL(f1) VALUES ('1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + +SELECT * FROM NAME_TBL; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 <> '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 < '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 <= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 > '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 >= '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 !~ '.*'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '[0-9]'; + +SELECT c.f1 FROM NAME_TBL c WHERE c.f1 ~ '.*asdf.*'; + +DROP TABLE NAME_TBL; + +DO $$ +DECLARE r text[]; +BEGIN + r := parse_ident('Schemax.Tabley'); + RAISE NOTICE '%', format('%I.%I', r[1], r[2]); + r := parse_ident('"SchemaX"."TableY"'); + RAISE NOTICE '%', format('%I.%I', r[1], r[2]); +END; +$$; + +SELECT parse_ident('foo.boo'); + +SELECT parse_ident('foo.boo[]'); + +SELECT parse_ident('foo.boo[]', strict => false); + +SELECT parse_ident(' '); + +SELECT parse_ident(' .aaa'); + +SELECT parse_ident(' aaa . '); + +SELECT parse_ident('aaa.a%b'); + +SELECT parse_ident(E'X\rXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); + +SELECT length(a[1]), length(a[2]) from parse_ident('"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy') as a ; + +SELECT parse_ident(' first . " second " ." third ". " ' || repeat('x',66) || '"'); + +SELECT parse_ident(' first . " second " ." third ". " ' || repeat('x',66) || '"')::name[]; + +SELECT parse_ident(E'"c".X XXXX\002XXXXXX'); + +SELECT parse_ident('1020'); + +SELECT parse_ident('10.20'); + +SELECT parse_ident('.'); + +SELECT parse_ident('.1020'); + +SELECT parse_ident('xxx.1020'); diff --git a/crates/pgt_pretty_print/tests/data/multi/namespace_60.sql b/crates/pgt_pretty_print/tests/data/multi/namespace_60.sql new file mode 100644 index 000000000..ece9aeb00 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/namespace_60.sql @@ -0,0 +1,110 @@ +SELECT pg_catalog.set_config('search_path', ' ', false); + +CREATE SCHEMA test_ns_schema_1 + +CREATE UNIQUE INDEX abc_a_idx ON abc (a) + +CREATE VIEW abc_view AS + SELECT a+1 AS a, b+1 AS b FROM abc + +CREATE TABLE abc ( + a serial, + b int UNIQUE + ); + +SET search_path to public; + +BEGIN; + +SET search_path to public, test_ns_schema_1; + +CREATE SCHEMA test_ns_schema_2 + +CREATE VIEW abc_view AS SELECT c FROM abc; + +COMMIT; + +SHOW search_path; + +BEGIN; + +SET search_path to public, test_ns_schema_1; + +CREATE SCHEMA test_ns_schema_2 + +CREATE VIEW abc_view AS SELECT a FROM abc; + +SHOW search_path; + +COMMIT; + +SHOW search_path; + +DROP SCHEMA test_ns_schema_2 CASCADE; + +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1'); + +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES; + +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES; + +INSERT INTO test_ns_schema_1.abc DEFAULT VALUES; + +SELECT * FROM test_ns_schema_1.abc; + +SELECT * FROM test_ns_schema_1.abc_view; + +ALTER SCHEMA test_ns_schema_1 RENAME TO test_ns_schema_renamed; + +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_1'); + +CREATE SCHEMA test_ns_schema_renamed; + +CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed; + +CREATE SCHEMA IF NOT EXISTS test_ns_schema_renamed + +CREATE TABLE abc ( + a serial, + b int UNIQUE + ); + +DROP SCHEMA test_ns_schema_renamed CASCADE; + +SELECT COUNT(*) FROM pg_class WHERE relnamespace = + (SELECT oid FROM pg_namespace WHERE nspname = 'test_ns_schema_renamed'); + +CREATE SCHEMA test_maint_search_path; + +SET search_path = test_maint_search_path; + +CREATE FUNCTION fn(INT) RETURNS INT IMMUTABLE LANGUAGE plpgsql AS $$ + BEGIN + RAISE NOTICE 'current search_path: %', current_setting('search_path'); + RETURN $1; + END; +$$; + +CREATE TABLE test_maint(i INT); + +INSERT INTO test_maint VALUES (1), (2); + +CREATE MATERIALIZED VIEW test_maint_mv AS SELECT fn(i) FROM test_maint; + +CREATE INDEX test_maint_idx ON test_maint_search_path.test_maint (fn(i)); + +REINDEX TABLE test_maint_search_path.test_maint; + +ANALYZE test_maint_search_path.test_maint; + +VACUUM FULL test_maint_search_path.test_maint; + +CLUSTER test_maint_search_path.test_maint USING test_maint_idx; + +REFRESH MATERIALIZED VIEW test_maint_search_path.test_maint_mv; + +RESET search_path; + +DROP SCHEMA test_maint_search_path CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/numa_60.sql b/crates/pgt_pretty_print/tests/data/multi/numa_60.sql new file mode 100644 index 000000000..88b81b4f4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/numa_60.sql @@ -0,0 +1,5 @@ +SELECT NOT(pg_numa_available()) AS skip_test ; + +SELECT COUNT(*) = 0 AS ok FROM pg_shmem_allocations_numa; + +SELECT COUNT(*) >= 0 AS ok FROM pg_shmem_allocations_numa; diff --git a/crates/pgt_pretty_print/tests/data/multi/numeric_60.sql b/crates/pgt_pretty_print/tests/data/multi/numeric_60.sql new file mode 100644 index 000000000..37f71093b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/numeric_60.sql @@ -0,0 +1,1690 @@ +CREATE TABLE num_data (id int4, val numeric(210,10)); + +CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(210,10)); + +CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(210,10)); + +CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(210,10)); + +CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(210,10)); + +CREATE TABLE num_exp_sqrt (id int4, expected numeric(210,10)); + +CREATE TABLE num_exp_ln (id int4, expected numeric(210,10)); + +CREATE TABLE num_exp_log10 (id int4, expected numeric(210,10)); + +CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(210,10)); + +CREATE TABLE num_result (id1 int4, id2 int4, result numeric(210,10)); + +BEGIN TRANSACTION; + +INSERT INTO num_exp_add VALUES (0,0,'0'); + +INSERT INTO num_exp_sub VALUES (0,0,'0'); + +INSERT INTO num_exp_mul VALUES (0,0,'0'); + +INSERT INTO num_exp_div VALUES (0,0,'NaN'); + +INSERT INTO num_exp_add VALUES (0,1,'0'); + +INSERT INTO num_exp_sub VALUES (0,1,'0'); + +INSERT INTO num_exp_mul VALUES (0,1,'0'); + +INSERT INTO num_exp_div VALUES (0,1,'NaN'); + +INSERT INTO num_exp_add VALUES (0,2,'-34338492.215397047'); + +INSERT INTO num_exp_sub VALUES (0,2,'34338492.215397047'); + +INSERT INTO num_exp_mul VALUES (0,2,'0'); + +INSERT INTO num_exp_div VALUES (0,2,'0'); + +INSERT INTO num_exp_add VALUES (0,3,'4.31'); + +INSERT INTO num_exp_sub VALUES (0,3,'-4.31'); + +INSERT INTO num_exp_mul VALUES (0,3,'0'); + +INSERT INTO num_exp_div VALUES (0,3,'0'); + +INSERT INTO num_exp_add VALUES (0,4,'7799461.4119'); + +INSERT INTO num_exp_sub VALUES (0,4,'-7799461.4119'); + +INSERT INTO num_exp_mul VALUES (0,4,'0'); + +INSERT INTO num_exp_div VALUES (0,4,'0'); + +INSERT INTO num_exp_add VALUES (0,5,'16397.038491'); + +INSERT INTO num_exp_sub VALUES (0,5,'-16397.038491'); + +INSERT INTO num_exp_mul VALUES (0,5,'0'); + +INSERT INTO num_exp_div VALUES (0,5,'0'); + +INSERT INTO num_exp_add VALUES (0,6,'93901.57763026'); + +INSERT INTO num_exp_sub VALUES (0,6,'-93901.57763026'); + +INSERT INTO num_exp_mul VALUES (0,6,'0'); + +INSERT INTO num_exp_div VALUES (0,6,'0'); + +INSERT INTO num_exp_add VALUES (0,7,'-83028485'); + +INSERT INTO num_exp_sub VALUES (0,7,'83028485'); + +INSERT INTO num_exp_mul VALUES (0,7,'0'); + +INSERT INTO num_exp_div VALUES (0,7,'0'); + +INSERT INTO num_exp_add VALUES (0,8,'74881'); + +INSERT INTO num_exp_sub VALUES (0,8,'-74881'); + +INSERT INTO num_exp_mul VALUES (0,8,'0'); + +INSERT INTO num_exp_div VALUES (0,8,'0'); + +INSERT INTO num_exp_add VALUES (0,9,'-24926804.045047420'); + +INSERT INTO num_exp_sub VALUES (0,9,'24926804.045047420'); + +INSERT INTO num_exp_mul VALUES (0,9,'0'); + +INSERT INTO num_exp_div VALUES (0,9,'0'); + +INSERT INTO num_exp_add VALUES (1,0,'0'); + +INSERT INTO num_exp_sub VALUES (1,0,'0'); + +INSERT INTO num_exp_mul VALUES (1,0,'0'); + +INSERT INTO num_exp_div VALUES (1,0,'NaN'); + +INSERT INTO num_exp_add VALUES (1,1,'0'); + +INSERT INTO num_exp_sub VALUES (1,1,'0'); + +INSERT INTO num_exp_mul VALUES (1,1,'0'); + +INSERT INTO num_exp_div VALUES (1,1,'NaN'); + +INSERT INTO num_exp_add VALUES (1,2,'-34338492.215397047'); + +INSERT INTO num_exp_sub VALUES (1,2,'34338492.215397047'); + +INSERT INTO num_exp_mul VALUES (1,2,'0'); + +INSERT INTO num_exp_div VALUES (1,2,'0'); + +INSERT INTO num_exp_add VALUES (1,3,'4.31'); + +INSERT INTO num_exp_sub VALUES (1,3,'-4.31'); + +INSERT INTO num_exp_mul VALUES (1,3,'0'); + +INSERT INTO num_exp_div VALUES (1,3,'0'); + +INSERT INTO num_exp_add VALUES (1,4,'7799461.4119'); + +INSERT INTO num_exp_sub VALUES (1,4,'-7799461.4119'); + +INSERT INTO num_exp_mul VALUES (1,4,'0'); + +INSERT INTO num_exp_div VALUES (1,4,'0'); + +INSERT INTO num_exp_add VALUES (1,5,'16397.038491'); + +INSERT INTO num_exp_sub VALUES (1,5,'-16397.038491'); + +INSERT INTO num_exp_mul VALUES (1,5,'0'); + +INSERT INTO num_exp_div VALUES (1,5,'0'); + +INSERT INTO num_exp_add VALUES (1,6,'93901.57763026'); + +INSERT INTO num_exp_sub VALUES (1,6,'-93901.57763026'); + +INSERT INTO num_exp_mul VALUES (1,6,'0'); + +INSERT INTO num_exp_div VALUES (1,6,'0'); + +INSERT INTO num_exp_add VALUES (1,7,'-83028485'); + +INSERT INTO num_exp_sub VALUES (1,7,'83028485'); + +INSERT INTO num_exp_mul VALUES (1,7,'0'); + +INSERT INTO num_exp_div VALUES (1,7,'0'); + +INSERT INTO num_exp_add VALUES (1,8,'74881'); + +INSERT INTO num_exp_sub VALUES (1,8,'-74881'); + +INSERT INTO num_exp_mul VALUES (1,8,'0'); + +INSERT INTO num_exp_div VALUES (1,8,'0'); + +INSERT INTO num_exp_add VALUES (1,9,'-24926804.045047420'); + +INSERT INTO num_exp_sub VALUES (1,9,'24926804.045047420'); + +INSERT INTO num_exp_mul VALUES (1,9,'0'); + +INSERT INTO num_exp_div VALUES (1,9,'0'); + +INSERT INTO num_exp_add VALUES (2,0,'-34338492.215397047'); + +INSERT INTO num_exp_sub VALUES (2,0,'-34338492.215397047'); + +INSERT INTO num_exp_mul VALUES (2,0,'0'); + +INSERT INTO num_exp_div VALUES (2,0,'NaN'); + +INSERT INTO num_exp_add VALUES (2,1,'-34338492.215397047'); + +INSERT INTO num_exp_sub VALUES (2,1,'-34338492.215397047'); + +INSERT INTO num_exp_mul VALUES (2,1,'0'); + +INSERT INTO num_exp_div VALUES (2,1,'NaN'); + +INSERT INTO num_exp_add VALUES (2,2,'-68676984.430794094'); + +INSERT INTO num_exp_sub VALUES (2,2,'0'); + +INSERT INTO num_exp_mul VALUES (2,2,'1179132047626883.596862135856320209'); + +INSERT INTO num_exp_div VALUES (2,2,'1.00000000000000000000'); + +INSERT INTO num_exp_add VALUES (2,3,'-34338487.905397047'); + +INSERT INTO num_exp_sub VALUES (2,3,'-34338496.525397047'); + +INSERT INTO num_exp_mul VALUES (2,3,'-147998901.44836127257'); + +INSERT INTO num_exp_div VALUES (2,3,'-7967167.56737750510440835266'); + +INSERT INTO num_exp_add VALUES (2,4,'-26539030.803497047'); + +INSERT INTO num_exp_sub VALUES (2,4,'-42137953.627297047'); + +INSERT INTO num_exp_mul VALUES (2,4,'-267821744976817.8111137106593'); + +INSERT INTO num_exp_div VALUES (2,4,'-4.40267480046830116685'); + +INSERT INTO num_exp_add VALUES (2,5,'-34322095.176906047'); + +INSERT INTO num_exp_sub VALUES (2,5,'-34354889.253888047'); + +INSERT INTO num_exp_mul VALUES (2,5,'-563049578578.769242506736077'); + +INSERT INTO num_exp_div VALUES (2,5,'-2094.18866914563535496429'); + +INSERT INTO num_exp_add VALUES (2,6,'-34244590.637766787'); + +INSERT INTO num_exp_sub VALUES (2,6,'-34432393.793027307'); + +INSERT INTO num_exp_mul VALUES (2,6,'-3224438592470.18449811926184222'); + +INSERT INTO num_exp_div VALUES (2,6,'-365.68599891479766440940'); + +INSERT INTO num_exp_add VALUES (2,7,'-117366977.215397047'); + +INSERT INTO num_exp_sub VALUES (2,7,'48689992.784602953'); + +INSERT INTO num_exp_mul VALUES (2,7,'2851072985828710.485883795'); + +INSERT INTO num_exp_div VALUES (2,7,'.41357483778485235518'); + +INSERT INTO num_exp_add VALUES (2,8,'-34263611.215397047'); + +INSERT INTO num_exp_sub VALUES (2,8,'-34413373.215397047'); + +INSERT INTO num_exp_mul VALUES (2,8,'-2571300635581.146276407'); + +INSERT INTO num_exp_div VALUES (2,8,'-458.57416721727870888476'); + +INSERT INTO num_exp_add VALUES (2,9,'-59265296.260444467'); + +INSERT INTO num_exp_sub VALUES (2,9,'-9411688.170349627'); + +INSERT INTO num_exp_mul VALUES (2,9,'855948866655588.453741509242968740'); + +INSERT INTO num_exp_div VALUES (2,9,'1.37757299946438931811'); + +INSERT INTO num_exp_add VALUES (3,0,'4.31'); + +INSERT INTO num_exp_sub VALUES (3,0,'4.31'); + +INSERT INTO num_exp_mul VALUES (3,0,'0'); + +INSERT INTO num_exp_div VALUES (3,0,'NaN'); + +INSERT INTO num_exp_add VALUES (3,1,'4.31'); + +INSERT INTO num_exp_sub VALUES (3,1,'4.31'); + +INSERT INTO num_exp_mul VALUES (3,1,'0'); + +INSERT INTO num_exp_div VALUES (3,1,'NaN'); + +INSERT INTO num_exp_add VALUES (3,2,'-34338487.905397047'); + +INSERT INTO num_exp_sub VALUES (3,2,'34338496.525397047'); + +INSERT INTO num_exp_mul VALUES (3,2,'-147998901.44836127257'); + +INSERT INTO num_exp_div VALUES (3,2,'-.00000012551512084352'); + +INSERT INTO num_exp_add VALUES (3,3,'8.62'); + +INSERT INTO num_exp_sub VALUES (3,3,'0'); + +INSERT INTO num_exp_mul VALUES (3,3,'18.5761'); + +INSERT INTO num_exp_div VALUES (3,3,'1.00000000000000000000'); + +INSERT INTO num_exp_add VALUES (3,4,'7799465.7219'); + +INSERT INTO num_exp_sub VALUES (3,4,'-7799457.1019'); + +INSERT INTO num_exp_mul VALUES (3,4,'33615678.685289'); + +INSERT INTO num_exp_div VALUES (3,4,'.00000055260225961552'); + +INSERT INTO num_exp_add VALUES (3,5,'16401.348491'); + +INSERT INTO num_exp_sub VALUES (3,5,'-16392.728491'); + +INSERT INTO num_exp_mul VALUES (3,5,'70671.23589621'); + +INSERT INTO num_exp_div VALUES (3,5,'.00026285234387695504'); + +INSERT INTO num_exp_add VALUES (3,6,'93905.88763026'); + +INSERT INTO num_exp_sub VALUES (3,6,'-93897.26763026'); + +INSERT INTO num_exp_mul VALUES (3,6,'404715.7995864206'); + +INSERT INTO num_exp_div VALUES (3,6,'.00004589912234457595'); + +INSERT INTO num_exp_add VALUES (3,7,'-83028480.69'); + +INSERT INTO num_exp_sub VALUES (3,7,'83028489.31'); + +INSERT INTO num_exp_mul VALUES (3,7,'-357852770.35'); + +INSERT INTO num_exp_div VALUES (3,7,'-.00000005190989574240'); + +INSERT INTO num_exp_add VALUES (3,8,'74885.31'); + +INSERT INTO num_exp_sub VALUES (3,8,'-74876.69'); + +INSERT INTO num_exp_mul VALUES (3,8,'322737.11'); + +INSERT INTO num_exp_div VALUES (3,8,'.00005755799201399553'); + +INSERT INTO num_exp_add VALUES (3,9,'-24926799.735047420'); + +INSERT INTO num_exp_sub VALUES (3,9,'24926808.355047420'); + +INSERT INTO num_exp_mul VALUES (3,9,'-107434525.43415438020'); + +INSERT INTO num_exp_div VALUES (3,9,'-.00000017290624149854'); + +INSERT INTO num_exp_add VALUES (4,0,'7799461.4119'); + +INSERT INTO num_exp_sub VALUES (4,0,'7799461.4119'); + +INSERT INTO num_exp_mul VALUES (4,0,'0'); + +INSERT INTO num_exp_div VALUES (4,0,'NaN'); + +INSERT INTO num_exp_add VALUES (4,1,'7799461.4119'); + +INSERT INTO num_exp_sub VALUES (4,1,'7799461.4119'); + +INSERT INTO num_exp_mul VALUES (4,1,'0'); + +INSERT INTO num_exp_div VALUES (4,1,'NaN'); + +INSERT INTO num_exp_add VALUES (4,2,'-26539030.803497047'); + +INSERT INTO num_exp_sub VALUES (4,2,'42137953.627297047'); + +INSERT INTO num_exp_mul VALUES (4,2,'-267821744976817.8111137106593'); + +INSERT INTO num_exp_div VALUES (4,2,'-.22713465002993920385'); + +INSERT INTO num_exp_add VALUES (4,3,'7799465.7219'); + +INSERT INTO num_exp_sub VALUES (4,3,'7799457.1019'); + +INSERT INTO num_exp_mul VALUES (4,3,'33615678.685289'); + +INSERT INTO num_exp_div VALUES (4,3,'1809619.81714617169373549883'); + +INSERT INTO num_exp_add VALUES (4,4,'15598922.8238'); + +INSERT INTO num_exp_sub VALUES (4,4,'0'); + +INSERT INTO num_exp_mul VALUES (4,4,'60831598315717.14146161'); + +INSERT INTO num_exp_div VALUES (4,4,'1.00000000000000000000'); + +INSERT INTO num_exp_add VALUES (4,5,'7815858.450391'); + +INSERT INTO num_exp_sub VALUES (4,5,'7783064.373409'); + +INSERT INTO num_exp_mul VALUES (4,5,'127888068979.9935054429'); + +INSERT INTO num_exp_div VALUES (4,5,'475.66281046305802686061'); + +INSERT INTO num_exp_add VALUES (4,6,'7893362.98953026'); + +INSERT INTO num_exp_sub VALUES (4,6,'7705559.83426974'); + +INSERT INTO num_exp_mul VALUES (4,6,'732381731243.745115764094'); + +INSERT INTO num_exp_div VALUES (4,6,'83.05996138436129499606'); + +INSERT INTO num_exp_add VALUES (4,7,'-75229023.5881'); + +INSERT INTO num_exp_sub VALUES (4,7,'90827946.4119'); + +INSERT INTO num_exp_mul VALUES (4,7,'-647577464846017.9715'); + +INSERT INTO num_exp_div VALUES (4,7,'-.09393717604145131637'); + +INSERT INTO num_exp_add VALUES (4,8,'7874342.4119'); + +INSERT INTO num_exp_sub VALUES (4,8,'7724580.4119'); + +INSERT INTO num_exp_mul VALUES (4,8,'584031469984.4839'); + +INSERT INTO num_exp_div VALUES (4,8,'104.15808298366741897143'); + +INSERT INTO num_exp_add VALUES (4,9,'-17127342.633147420'); + +INSERT INTO num_exp_sub VALUES (4,9,'32726265.456947420'); + +INSERT INTO num_exp_mul VALUES (4,9,'-194415646271340.1815956522980'); + +INSERT INTO num_exp_div VALUES (4,9,'-.31289456112403769409'); + +INSERT INTO num_exp_add VALUES (5,0,'16397.038491'); + +INSERT INTO num_exp_sub VALUES (5,0,'16397.038491'); + +INSERT INTO num_exp_mul VALUES (5,0,'0'); + +INSERT INTO num_exp_div VALUES (5,0,'NaN'); + +INSERT INTO num_exp_add VALUES (5,1,'16397.038491'); + +INSERT INTO num_exp_sub VALUES (5,1,'16397.038491'); + +INSERT INTO num_exp_mul VALUES (5,1,'0'); + +INSERT INTO num_exp_div VALUES (5,1,'NaN'); + +INSERT INTO num_exp_add VALUES (5,2,'-34322095.176906047'); + +INSERT INTO num_exp_sub VALUES (5,2,'34354889.253888047'); + +INSERT INTO num_exp_mul VALUES (5,2,'-563049578578.769242506736077'); + +INSERT INTO num_exp_div VALUES (5,2,'-.00047751189505192446'); + +INSERT INTO num_exp_add VALUES (5,3,'16401.348491'); + +INSERT INTO num_exp_sub VALUES (5,3,'16392.728491'); + +INSERT INTO num_exp_mul VALUES (5,3,'70671.23589621'); + +INSERT INTO num_exp_div VALUES (5,3,'3804.41728329466357308584'); + +INSERT INTO num_exp_add VALUES (5,4,'7815858.450391'); + +INSERT INTO num_exp_sub VALUES (5,4,'-7783064.373409'); + +INSERT INTO num_exp_mul VALUES (5,4,'127888068979.9935054429'); + +INSERT INTO num_exp_div VALUES (5,4,'.00210232958726897192'); + +INSERT INTO num_exp_add VALUES (5,5,'32794.076982'); + +INSERT INTO num_exp_sub VALUES (5,5,'0'); + +INSERT INTO num_exp_mul VALUES (5,5,'268862871.275335557081'); + +INSERT INTO num_exp_div VALUES (5,5,'1.00000000000000000000'); + +INSERT INTO num_exp_add VALUES (5,6,'110298.61612126'); + +INSERT INTO num_exp_sub VALUES (5,6,'-77504.53913926'); + +INSERT INTO num_exp_mul VALUES (5,6,'1539707782.76899778633766'); + +INSERT INTO num_exp_div VALUES (5,6,'.17461941433576102689'); + +INSERT INTO num_exp_add VALUES (5,7,'-83012087.961509'); + +INSERT INTO num_exp_sub VALUES (5,7,'83044882.038491'); + +INSERT INTO num_exp_mul VALUES (5,7,'-1361421264394.416135'); + +INSERT INTO num_exp_div VALUES (5,7,'-.00019748690453643710'); + +INSERT INTO num_exp_add VALUES (5,8,'91278.038491'); + +INSERT INTO num_exp_sub VALUES (5,8,'-58483.961509'); + +INSERT INTO num_exp_mul VALUES (5,8,'1227826639.244571'); + +INSERT INTO num_exp_div VALUES (5,8,'.21897461960978085228'); + +INSERT INTO num_exp_add VALUES (5,9,'-24910407.006556420'); + +INSERT INTO num_exp_sub VALUES (5,9,'24943201.083538420'); + +INSERT INTO num_exp_mul VALUES (5,9,'-408725765384.257043660243220'); + +INSERT INTO num_exp_div VALUES (5,9,'-.00065780749354660427'); + +INSERT INTO num_exp_add VALUES (6,0,'93901.57763026'); + +INSERT INTO num_exp_sub VALUES (6,0,'93901.57763026'); + +INSERT INTO num_exp_mul VALUES (6,0,'0'); + +INSERT INTO num_exp_div VALUES (6,0,'NaN'); + +INSERT INTO num_exp_add VALUES (6,1,'93901.57763026'); + +INSERT INTO num_exp_sub VALUES (6,1,'93901.57763026'); + +INSERT INTO num_exp_mul VALUES (6,1,'0'); + +INSERT INTO num_exp_div VALUES (6,1,'NaN'); + +INSERT INTO num_exp_add VALUES (6,2,'-34244590.637766787'); + +INSERT INTO num_exp_sub VALUES (6,2,'34432393.793027307'); + +INSERT INTO num_exp_mul VALUES (6,2,'-3224438592470.18449811926184222'); + +INSERT INTO num_exp_div VALUES (6,2,'-.00273458651128995823'); + +INSERT INTO num_exp_add VALUES (6,3,'93905.88763026'); + +INSERT INTO num_exp_sub VALUES (6,3,'93897.26763026'); + +INSERT INTO num_exp_mul VALUES (6,3,'404715.7995864206'); + +INSERT INTO num_exp_div VALUES (6,3,'21786.90896293735498839907'); + +INSERT INTO num_exp_add VALUES (6,4,'7893362.98953026'); + +INSERT INTO num_exp_sub VALUES (6,4,'-7705559.83426974'); + +INSERT INTO num_exp_mul VALUES (6,4,'732381731243.745115764094'); + +INSERT INTO num_exp_div VALUES (6,4,'.01203949512295682469'); + +INSERT INTO num_exp_add VALUES (6,5,'110298.61612126'); + +INSERT INTO num_exp_sub VALUES (6,5,'77504.53913926'); + +INSERT INTO num_exp_mul VALUES (6,5,'1539707782.76899778633766'); + +INSERT INTO num_exp_div VALUES (6,5,'5.72674008674192359679'); + +INSERT INTO num_exp_add VALUES (6,6,'187803.15526052'); + +INSERT INTO num_exp_sub VALUES (6,6,'0'); + +INSERT INTO num_exp_mul VALUES (6,6,'8817506281.4517452372676676'); + +INSERT INTO num_exp_div VALUES (6,6,'1.00000000000000000000'); + +INSERT INTO num_exp_add VALUES (6,7,'-82934583.42236974'); + +INSERT INTO num_exp_sub VALUES (6,7,'83122386.57763026'); + +INSERT INTO num_exp_mul VALUES (6,7,'-7796505729750.37795610'); + +INSERT INTO num_exp_div VALUES (6,7,'-.00113095617281538980'); + +INSERT INTO num_exp_add VALUES (6,8,'168782.57763026'); + +INSERT INTO num_exp_sub VALUES (6,8,'19020.57763026'); + +INSERT INTO num_exp_mul VALUES (6,8,'7031444034.53149906'); + +INSERT INTO num_exp_div VALUES (6,8,'1.25401073209839612184'); + +INSERT INTO num_exp_add VALUES (6,9,'-24832902.467417160'); + +INSERT INTO num_exp_sub VALUES (6,9,'25020705.622677680'); + +INSERT INTO num_exp_mul VALUES (6,9,'-2340666225110.29929521292692920'); + +INSERT INTO num_exp_div VALUES (6,9,'-.00376709254265256789'); + +INSERT INTO num_exp_add VALUES (7,0,'-83028485'); + +INSERT INTO num_exp_sub VALUES (7,0,'-83028485'); + +INSERT INTO num_exp_mul VALUES (7,0,'0'); + +INSERT INTO num_exp_div VALUES (7,0,'NaN'); + +INSERT INTO num_exp_add VALUES (7,1,'-83028485'); + +INSERT INTO num_exp_sub VALUES (7,1,'-83028485'); + +INSERT INTO num_exp_mul VALUES (7,1,'0'); + +INSERT INTO num_exp_div VALUES (7,1,'NaN'); + +INSERT INTO num_exp_add VALUES (7,2,'-117366977.215397047'); + +INSERT INTO num_exp_sub VALUES (7,2,'-48689992.784602953'); + +INSERT INTO num_exp_mul VALUES (7,2,'2851072985828710.485883795'); + +INSERT INTO num_exp_div VALUES (7,2,'2.41794207151503385700'); + +INSERT INTO num_exp_add VALUES (7,3,'-83028480.69'); + +INSERT INTO num_exp_sub VALUES (7,3,'-83028489.31'); + +INSERT INTO num_exp_mul VALUES (7,3,'-357852770.35'); + +INSERT INTO num_exp_div VALUES (7,3,'-19264149.65197215777262180974'); + +INSERT INTO num_exp_add VALUES (7,4,'-75229023.5881'); + +INSERT INTO num_exp_sub VALUES (7,4,'-90827946.4119'); + +INSERT INTO num_exp_mul VALUES (7,4,'-647577464846017.9715'); + +INSERT INTO num_exp_div VALUES (7,4,'-10.64541262725136247686'); + +INSERT INTO num_exp_add VALUES (7,5,'-83012087.961509'); + +INSERT INTO num_exp_sub VALUES (7,5,'-83044882.038491'); + +INSERT INTO num_exp_mul VALUES (7,5,'-1361421264394.416135'); + +INSERT INTO num_exp_div VALUES (7,5,'-5063.62688881730941836574'); + +INSERT INTO num_exp_add VALUES (7,6,'-82934583.42236974'); + +INSERT INTO num_exp_sub VALUES (7,6,'-83122386.57763026'); + +INSERT INTO num_exp_mul VALUES (7,6,'-7796505729750.37795610'); + +INSERT INTO num_exp_div VALUES (7,6,'-884.20756174009028770294'); + +INSERT INTO num_exp_add VALUES (7,7,'-166056970'); + +INSERT INTO num_exp_sub VALUES (7,7,'0'); + +INSERT INTO num_exp_mul VALUES (7,7,'6893729321395225'); + +INSERT INTO num_exp_div VALUES (7,7,'1.00000000000000000000'); + +INSERT INTO num_exp_add VALUES (7,8,'-82953604'); + +INSERT INTO num_exp_sub VALUES (7,8,'-83103366'); + +INSERT INTO num_exp_mul VALUES (7,8,'-6217255985285'); + +INSERT INTO num_exp_div VALUES (7,8,'-1108.80577182462841041118'); + +INSERT INTO num_exp_add VALUES (7,9,'-107955289.045047420'); + +INSERT INTO num_exp_sub VALUES (7,9,'-58101680.954952580'); + +INSERT INTO num_exp_mul VALUES (7,9,'2069634775752159.035758700'); + +INSERT INTO num_exp_div VALUES (7,9,'3.33089171198810413382'); + +INSERT INTO num_exp_add VALUES (8,0,'74881'); + +INSERT INTO num_exp_sub VALUES (8,0,'74881'); + +INSERT INTO num_exp_mul VALUES (8,0,'0'); + +INSERT INTO num_exp_div VALUES (8,0,'NaN'); + +INSERT INTO num_exp_add VALUES (8,1,'74881'); + +INSERT INTO num_exp_sub VALUES (8,1,'74881'); + +INSERT INTO num_exp_mul VALUES (8,1,'0'); + +INSERT INTO num_exp_div VALUES (8,1,'NaN'); + +INSERT INTO num_exp_add VALUES (8,2,'-34263611.215397047'); + +INSERT INTO num_exp_sub VALUES (8,2,'34413373.215397047'); + +INSERT INTO num_exp_mul VALUES (8,2,'-2571300635581.146276407'); + +INSERT INTO num_exp_div VALUES (8,2,'-.00218067233500788615'); + +INSERT INTO num_exp_add VALUES (8,3,'74885.31'); + +INSERT INTO num_exp_sub VALUES (8,3,'74876.69'); + +INSERT INTO num_exp_mul VALUES (8,3,'322737.11'); + +INSERT INTO num_exp_div VALUES (8,3,'17373.78190255220417633410'); + +INSERT INTO num_exp_add VALUES (8,4,'7874342.4119'); + +INSERT INTO num_exp_sub VALUES (8,4,'-7724580.4119'); + +INSERT INTO num_exp_mul VALUES (8,4,'584031469984.4839'); + +INSERT INTO num_exp_div VALUES (8,4,'.00960079113741758956'); + +INSERT INTO num_exp_add VALUES (8,5,'91278.038491'); + +INSERT INTO num_exp_sub VALUES (8,5,'58483.961509'); + +INSERT INTO num_exp_mul VALUES (8,5,'1227826639.244571'); + +INSERT INTO num_exp_div VALUES (8,5,'4.56673929509287019456'); + +INSERT INTO num_exp_add VALUES (8,6,'168782.57763026'); + +INSERT INTO num_exp_sub VALUES (8,6,'-19020.57763026'); + +INSERT INTO num_exp_mul VALUES (8,6,'7031444034.53149906'); + +INSERT INTO num_exp_div VALUES (8,6,'.79744134113322314424'); + +INSERT INTO num_exp_add VALUES (8,7,'-82953604'); + +INSERT INTO num_exp_sub VALUES (8,7,'83103366'); + +INSERT INTO num_exp_mul VALUES (8,7,'-6217255985285'); + +INSERT INTO num_exp_div VALUES (8,7,'-.00090187120721280172'); + +INSERT INTO num_exp_add VALUES (8,8,'149762'); + +INSERT INTO num_exp_sub VALUES (8,8,'0'); + +INSERT INTO num_exp_mul VALUES (8,8,'5607164161'); + +INSERT INTO num_exp_div VALUES (8,8,'1.00000000000000000000'); + +INSERT INTO num_exp_add VALUES (8,9,'-24851923.045047420'); + +INSERT INTO num_exp_sub VALUES (8,9,'25001685.045047420'); + +INSERT INTO num_exp_mul VALUES (8,9,'-1866544013697.195857020'); + +INSERT INTO num_exp_div VALUES (8,9,'-.00300403532938582735'); + +INSERT INTO num_exp_add VALUES (9,0,'-24926804.045047420'); + +INSERT INTO num_exp_sub VALUES (9,0,'-24926804.045047420'); + +INSERT INTO num_exp_mul VALUES (9,0,'0'); + +INSERT INTO num_exp_div VALUES (9,0,'NaN'); + +INSERT INTO num_exp_add VALUES (9,1,'-24926804.045047420'); + +INSERT INTO num_exp_sub VALUES (9,1,'-24926804.045047420'); + +INSERT INTO num_exp_mul VALUES (9,1,'0'); + +INSERT INTO num_exp_div VALUES (9,1,'NaN'); + +INSERT INTO num_exp_add VALUES (9,2,'-59265296.260444467'); + +INSERT INTO num_exp_sub VALUES (9,2,'9411688.170349627'); + +INSERT INTO num_exp_mul VALUES (9,2,'855948866655588.453741509242968740'); + +INSERT INTO num_exp_div VALUES (9,2,'.72591434384152961526'); + +INSERT INTO num_exp_add VALUES (9,3,'-24926799.735047420'); + +INSERT INTO num_exp_sub VALUES (9,3,'-24926808.355047420'); + +INSERT INTO num_exp_mul VALUES (9,3,'-107434525.43415438020'); + +INSERT INTO num_exp_div VALUES (9,3,'-5783481.21694835730858468677'); + +INSERT INTO num_exp_add VALUES (9,4,'-17127342.633147420'); + +INSERT INTO num_exp_sub VALUES (9,4,'-32726265.456947420'); + +INSERT INTO num_exp_mul VALUES (9,4,'-194415646271340.1815956522980'); + +INSERT INTO num_exp_div VALUES (9,4,'-3.19596478892958416484'); + +INSERT INTO num_exp_add VALUES (9,5,'-24910407.006556420'); + +INSERT INTO num_exp_sub VALUES (9,5,'-24943201.083538420'); + +INSERT INTO num_exp_mul VALUES (9,5,'-408725765384.257043660243220'); + +INSERT INTO num_exp_div VALUES (9,5,'-1520.20159364322004505807'); + +INSERT INTO num_exp_add VALUES (9,6,'-24832902.467417160'); + +INSERT INTO num_exp_sub VALUES (9,6,'-25020705.622677680'); + +INSERT INTO num_exp_mul VALUES (9,6,'-2340666225110.29929521292692920'); + +INSERT INTO num_exp_div VALUES (9,6,'-265.45671195426965751280'); + +INSERT INTO num_exp_add VALUES (9,7,'-107955289.045047420'); + +INSERT INTO num_exp_sub VALUES (9,7,'58101680.954952580'); + +INSERT INTO num_exp_mul VALUES (9,7,'2069634775752159.035758700'); + +INSERT INTO num_exp_div VALUES (9,7,'.30021990699995814689'); + +INSERT INTO num_exp_add VALUES (9,8,'-24851923.045047420'); + +INSERT INTO num_exp_sub VALUES (9,8,'-25001685.045047420'); + +INSERT INTO num_exp_mul VALUES (9,8,'-1866544013697.195857020'); + +INSERT INTO num_exp_div VALUES (9,8,'-332.88556569820675471748'); + +INSERT INTO num_exp_add VALUES (9,9,'-49853608.090094840'); + +INSERT INTO num_exp_sub VALUES (9,9,'0'); + +INSERT INTO num_exp_mul VALUES (9,9,'621345559900192.420120630048656400'); + +INSERT INTO num_exp_div VALUES (9,9,'1.00000000000000000000'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_sqrt VALUES (0,'0'); + +INSERT INTO num_exp_sqrt VALUES (1,'0'); + +INSERT INTO num_exp_sqrt VALUES (2,'5859.90547836712524903505'); + +INSERT INTO num_exp_sqrt VALUES (3,'2.07605394920266944396'); + +INSERT INTO num_exp_sqrt VALUES (4,'2792.75158435189147418923'); + +INSERT INTO num_exp_sqrt VALUES (5,'128.05092147657509145473'); + +INSERT INTO num_exp_sqrt VALUES (6,'306.43364311096782703406'); + +INSERT INTO num_exp_sqrt VALUES (7,'9111.99676251039939975230'); + +INSERT INTO num_exp_sqrt VALUES (8,'273.64392922189960397542'); + +INSERT INTO num_exp_sqrt VALUES (9,'4992.67503899937593364766'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_ln VALUES (0,'NaN'); + +INSERT INTO num_exp_ln VALUES (1,'NaN'); + +INSERT INTO num_exp_ln VALUES (2,'17.35177750493897715514'); + +INSERT INTO num_exp_ln VALUES (3,'1.46093790411565641971'); + +INSERT INTO num_exp_ln VALUES (4,'15.86956523951936572464'); + +INSERT INTO num_exp_ln VALUES (5,'9.70485601768871834038'); + +INSERT INTO num_exp_ln VALUES (6,'11.45000246622944403127'); + +INSERT INTO num_exp_ln VALUES (7,'18.23469429965478772991'); + +INSERT INTO num_exp_ln VALUES (8,'11.22365546576315513668'); + +INSERT INTO num_exp_ln VALUES (9,'17.03145425013166006962'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_log10 VALUES (0,'NaN'); + +INSERT INTO num_exp_log10 VALUES (1,'NaN'); + +INSERT INTO num_exp_log10 VALUES (2,'7.53578122160797276459'); + +INSERT INTO num_exp_log10 VALUES (3,'.63447727016073160075'); + +INSERT INTO num_exp_log10 VALUES (4,'6.89206461372691743345'); + +INSERT INTO num_exp_log10 VALUES (5,'4.21476541614777768626'); + +INSERT INTO num_exp_log10 VALUES (6,'4.97267288886207207671'); + +INSERT INTO num_exp_log10 VALUES (7,'7.91922711353275546914'); + +INSERT INTO num_exp_log10 VALUES (8,'4.87437163556421004138'); + +INSERT INTO num_exp_log10 VALUES (9,'7.39666659961986567059'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_power_10_ln VALUES (0,'NaN'); + +INSERT INTO num_exp_power_10_ln VALUES (1,'NaN'); + +INSERT INTO num_exp_power_10_ln VALUES (2,'224790267919917955.13261618583642653184'); + +INSERT INTO num_exp_power_10_ln VALUES (3,'28.90266599445155957393'); + +INSERT INTO num_exp_power_10_ln VALUES (4,'7405685069594999.07733999469386277636'); + +INSERT INTO num_exp_power_10_ln VALUES (5,'5068226527.32127265408584640098'); + +INSERT INTO num_exp_power_10_ln VALUES (6,'281839893606.99372343357047819067'); + +INSERT INTO num_exp_power_10_ln VALUES (7,'1716699575118597095.42330819910640247627'); + +INSERT INTO num_exp_power_10_ln VALUES (8,'167361463828.07491320069016125952'); + +INSERT INTO num_exp_power_10_ln VALUES (9,'107511333880052007.04141124673540337457'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_data VALUES (0, '0'); + +INSERT INTO num_data VALUES (1, '0'); + +INSERT INTO num_data VALUES (2, '-34338492.215397047'); + +INSERT INTO num_data VALUES (3, '4.31'); + +INSERT INTO num_data VALUES (4, '7799461.4119'); + +INSERT INTO num_data VALUES (5, '16397.038491'); + +INSERT INTO num_data VALUES (6, '93901.57763026'); + +INSERT INTO num_data VALUES (7, '-83028485'); + +INSERT INTO num_data VALUES (8, '74881'); + +INSERT INTO num_data VALUES (9, '-24926804.045047420'); + +COMMIT TRANSACTION; + +CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add (id1, id2); + +CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub (id1, id2); + +CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div (id1, id2); + +CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul (id1, id2); + +CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt (id); + +CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln (id); + +CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 (id); + +CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln (id); + +VACUUM ANALYZE num_exp_add; + +VACUUM ANALYZE num_exp_sub; + +VACUUM ANALYZE num_exp_div; + +VACUUM ANALYZE num_exp_mul; + +VACUUM ANALYZE num_exp_sqrt; + +VACUUM ANALYZE num_exp_ln; + +VACUUM ANALYZE num_exp_log10; + +VACUUM ANALYZE num_exp_power_10_ln; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 10) as expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 10); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 40) + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 40); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 30) as expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 30); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val / t2.val + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0'; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val / t2.val, 80) + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0'; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 80) as expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 80); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, SQRT(ABS(val)) + FROM num_data; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_sqrt t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, LN(ABS(val)) + FROM num_data + WHERE val != '0.0'; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, LOG(numeric '10', ABS(val)) + FROM num_data + WHERE val != '0.0'; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_log10 t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, POWER(numeric '10', LN(ABS(round(val,200)))) + FROM num_data + WHERE val != '0.0'; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_power_10_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('inf'),('-inf'),('nan')) +SELECT x1, x2, + x1 + x2 AS sum, + x1 - x2 AS diff, + x1 * x2 AS prod +FROM v AS v1(x1), v AS v2(x2); + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('inf'),('-inf'),('nan')) +SELECT x1, x2, + x1 / x2 AS quot, + x1 % x2 AS mod, + div(x1, x2) AS div +FROM v AS v1(x1), v AS v2(x2) WHERE x2 != 0; + +SELECT 'inf'::numeric / '0'; + +SELECT '-inf'::numeric / '0'; + +SELECT 'nan'::numeric / '0'; + +SELECT '0'::numeric / '0'; + +SELECT 'inf'::numeric % '0'; + +SELECT '-inf'::numeric % '0'; + +SELECT 'nan'::numeric % '0'; + +SELECT '0'::numeric % '0'; + +SELECT div('inf'::numeric, '0'); + +SELECT div('-inf'::numeric, '0'); + +SELECT div('nan'::numeric, '0'); + +SELECT div('0'::numeric, '0'); + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('inf'),('-inf'),('nan')) +SELECT x, -x as minusx, abs(x), floor(x), ceil(x), sign(x), numeric_inc(x) as inc +FROM v; + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('inf'),('-inf'),('nan')) +SELECT x, round(x), round(x,1) as round1, trunc(x), trunc(x,1) as trunc1 +FROM v; + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('-1'),('4.2'),('-7.777'),('1e340'),('-1e340'), + ('inf'),('-inf'),('nan'), + ('inf'),('-inf'),('nan')) +SELECT substring(x::text, 1, 32) +FROM v ORDER BY x; + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('4.2'),('inf'),('nan')) +SELECT x, sqrt(x) +FROM v; + +SELECT sqrt('-1'::numeric); + +SELECT sqrt('-inf'::numeric); + +WITH v(x) AS + (VALUES('1'::numeric),('4.2'),('inf'),('nan')) +SELECT x, + log(x), + log10(x), + ln(x) +FROM v; + +SELECT ln('0'::numeric); + +SELECT ln('-1'::numeric); + +SELECT ln('-inf'::numeric); + +WITH v(x) AS + (VALUES('2'::numeric),('4.2'),('inf'),('nan')) +SELECT x1, x2, + log(x1, x2) +FROM v AS v1(x1), v AS v2(x2); + +SELECT log('0'::numeric, '10'); + +SELECT log('10'::numeric, '0'); + +SELECT log('-inf'::numeric, '10'); + +SELECT log('10'::numeric, '-inf'); + +SELECT log('inf'::numeric, '0'); + +SELECT log('inf'::numeric, '-inf'); + +SELECT log('-inf'::numeric, 'inf'); + +WITH v(x) AS + (VALUES('0'::numeric),('1'),('2'),('4.2'),('inf'),('nan')) +SELECT x1, x2, + power(x1, x2) +FROM v AS v1(x1), v AS v2(x2) WHERE x1 != 0 OR x2 >= 0; + +SELECT power('0'::numeric, '-1'); + +SELECT power('0'::numeric, '-inf'); + +SELECT power('-1'::numeric, 'inf'); + +SELECT power('-2'::numeric, '3'); + +SELECT power('-2'::numeric, '3.3'); + +SELECT power('-2'::numeric, '-1'); + +SELECT power('-2'::numeric, '-1.5'); + +SELECT power('-2'::numeric, 'inf'); + +SELECT power('-2'::numeric, '-inf'); + +SELECT power('inf'::numeric, '-2'); + +SELECT power('inf'::numeric, '-inf'); + +SELECT power('-inf'::numeric, '2'); + +SELECT power('-inf'::numeric, '3'); + +SELECT power('-inf'::numeric, '4.5'); + +SELECT power('-inf'::numeric, '-2'); + +SELECT power('-inf'::numeric, '-3'); + +SELECT power('-inf'::numeric, '0'); + +SELECT power('-inf'::numeric, 'inf'); + +SELECT power('-inf'::numeric, '-inf'); + +SELECT AVG(val) FROM num_data; + +SELECT MAX(val) FROM num_data; + +SELECT MIN(val) FROM num_data; + +SELECT STDDEV(val) FROM num_data; + +SELECT VARIANCE(val) FROM num_data; + +CREATE TABLE fract_only (id int, val numeric(4,4)); + +INSERT INTO fract_only VALUES (1, '0.0'); + +INSERT INTO fract_only VALUES (2, '0.1'); + +INSERT INTO fract_only VALUES (3, '1.0'); + +INSERT INTO fract_only VALUES (4, '-0.9999'); + +INSERT INTO fract_only VALUES (5, '0.99994'); + +INSERT INTO fract_only VALUES (6, '0.99995'); + +INSERT INTO fract_only VALUES (7, '0.00001'); + +INSERT INTO fract_only VALUES (8, '0.00017'); + +INSERT INTO fract_only VALUES (9, 'NaN'); + +INSERT INTO fract_only VALUES (10, 'Inf'); + +INSERT INTO fract_only VALUES (11, '-Inf'); + +SELECT * FROM fract_only; + +DROP TABLE fract_only; + +SELECT (-9223372036854775808.5)::int8; + +SELECT (-9223372036854775808.4)::int8; + +SELECT 9223372036854775807.4::int8; + +SELECT 9223372036854775807.5::int8; + +SELECT (-2147483648.5)::int4; + +SELECT (-2147483648.4)::int4; + +SELECT 2147483647.4::int4; + +SELECT 2147483647.5::int4; + +SELECT (-32768.5)::int2; + +SELECT (-32768.4)::int2; + +SELECT 32767.4::int2; + +SELECT 32767.5::int2; + +SELECT 'NaN'::float8::numeric; + +SELECT 'Infinity'::float8::numeric; + +SELECT '-Infinity'::float8::numeric; + +SELECT 'NaN'::numeric::float8; + +SELECT 'Infinity'::numeric::float8; + +SELECT '-Infinity'::numeric::float8; + +SELECT 'NaN'::float4::numeric; + +SELECT 'Infinity'::float4::numeric; + +SELECT '-Infinity'::float4::numeric; + +SELECT 'NaN'::numeric::float4; + +SELECT 'Infinity'::numeric::float4; + +SELECT '-Infinity'::numeric::float4; + +SELECT '42'::int2::numeric; + +SELECT 'NaN'::numeric::int2; + +SELECT 'Infinity'::numeric::int2; + +SELECT '-Infinity'::numeric::int2; + +SELECT 'NaN'::numeric::int4; + +SELECT 'Infinity'::numeric::int4; + +SELECT '-Infinity'::numeric::int4; + +SELECT 'NaN'::numeric::int8; + +SELECT 'Infinity'::numeric::int8; + +SELECT '-Infinity'::numeric::int8; + +CREATE TABLE ceil_floor_round (a numeric); + +INSERT INTO ceil_floor_round VALUES ('-5.5'); + +INSERT INTO ceil_floor_round VALUES ('-5.499999'); + +INSERT INTO ceil_floor_round VALUES ('9.5'); + +INSERT INTO ceil_floor_round VALUES ('9.4999999'); + +INSERT INTO ceil_floor_round VALUES ('0.0'); + +INSERT INTO ceil_floor_round VALUES ('0.0000001'); + +INSERT INTO ceil_floor_round VALUES ('-0.000001'); + +SELECT a, ceil(a), ceiling(a), floor(a), round(a) FROM ceil_floor_round; + +DROP TABLE ceil_floor_round; + +SELECT i as pow, + round((-2.5 * 10 ^ i)::numeric, -i), + round((-1.5 * 10 ^ i)::numeric, -i), + round((-0.5 * 10 ^ i)::numeric, -i), + round((0.5 * 10 ^ i)::numeric, -i), + round((1.5 * 10 ^ i)::numeric, -i), + round((2.5 * 10 ^ i)::numeric, -i) +FROM generate_series(-5,5) AS t(i); + +SELECT round(4.4e131071, -131071) = 4e131071; + +SELECT round(4.5e131071, -131071) = 5e131071; + +SELECT round(4.5e131071, -131072); + +SELECT round(5.5e131071, -131072); + +SELECT round(5.5e131071, -131073); + +SELECT round(5.5e131071, -1000000); + +SELECT round(5e-16383, 1000000) = 5e-16383; + +SELECT round(5e-16383, 16383) = 5e-16383; + +SELECT round(5e-16383, 16382) = 1e-16382; + +SELECT round(5e-16383, 16381) = 0; + +SELECT trunc(9.9e131071, -131071) = 9e131071; + +SELECT trunc(9.9e131071, -131072); + +SELECT trunc(9.9e131071, -131073); + +SELECT trunc(9.9e131071, -1000000); + +SELECT trunc(5e-16383, 1000000) = 5e-16383; + +SELECT trunc(5e-16383, 16383) = 5e-16383; + +SELECT trunc(5e-16383, 16382) = 0; + +SELECT width_bucket(5.0, 3.0, 4.0, 0); + +SELECT width_bucket(5.0, 3.0, 4.0, -5); + +SELECT width_bucket(3.5, 3.0, 3.0, 888); + +SELECT width_bucket(5.0::float8, 3.0::float8, 4.0::float8, 0); + +SELECT width_bucket(5.0::float8, 3.0::float8, 4.0::float8, -5); + +SELECT width_bucket(3.5::float8, 3.0::float8, 3.0::float8, 888); + +SELECT width_bucket('NaN', 3.0, 4.0, 888); + +SELECT width_bucket('NaN'::float8, 3.0::float8, 4.0::float8, 888); + +SELECT width_bucket(0, 'NaN', 4.0, 888); + +SELECT width_bucket(0::float8, 'NaN', 4.0::float8, 888); + +SELECT width_bucket(2.0, 3.0, '-inf', 888); + +SELECT width_bucket(0::float8, '-inf', 4.0::float8, 888); + +CREATE TABLE width_bucket_test (operand_num numeric, operand_f8 float8); + +UPDATE width_bucket_test SET operand_f8 = operand_num::float8; + +SELECT + operand_num, + width_bucket(operand_num, 0, 10, 5) AS wb_1, + width_bucket(operand_f8, 0, 10, 5) AS wb_1f, + width_bucket(operand_num, 10, 0, 5) AS wb_2, + width_bucket(operand_f8, 10, 0, 5) AS wb_2f, + width_bucket(operand_num, 2, 8, 4) AS wb_3, + width_bucket(operand_f8, 2, 8, 4) AS wb_3f, + width_bucket(operand_num, 5.0, 5.5, 20) AS wb_4, + width_bucket(operand_f8, 5.0, 5.5, 20) AS wb_4f, + width_bucket(operand_num, -25, 25, 10) AS wb_5, + width_bucket(operand_f8, -25, 25, 10) AS wb_5f + FROM width_bucket_test; + +SELECT width_bucket(0.0::numeric, 'Infinity'::numeric, 5, 10); + +SELECT width_bucket(0.0::numeric, 5, '-Infinity'::numeric, 20); + +SELECT width_bucket('Infinity'::numeric, 1, 10, 10), + width_bucket('-Infinity'::numeric, 1, 10, 10); + +SELECT width_bucket(0.0::float8, 'Infinity'::float8, 5, 10); + +SELECT width_bucket(0.0::float8, 5, '-Infinity'::float8, 20); + +SELECT width_bucket('Infinity'::float8, 1, 10, 10), + width_bucket('-Infinity'::float8, 1, 10, 10); + +DROP TABLE width_bucket_test; + +SELECT x, width_bucket(x::float8, 10, 100, 9) as flt, + width_bucket(x::numeric, 10, 100, 9) as num +FROM generate_series(0, 110, 10) x; + +SELECT x, width_bucket(x::float8, 100, 10, 9) as flt, + width_bucket(x::numeric, 100, 10, 9) as num +FROM generate_series(0, 110, 10) x; + +SELECT width_bucket(0, -1e100::numeric, 1, 10); + +SELECT width_bucket(0, -1e100::float8, 1, 10); + +SELECT width_bucket(1, 1e100::numeric, 0, 10); + +SELECT width_bucket(1, 1e100::float8, 0, 10); + +SELECT oper, low, high, cnt, width_bucket(oper, low, high, cnt) +FROM + (SELECT 1.797e+308::float8 AS big, 5e-324::float8 AS tiny) as v, + LATERAL (VALUES + (10.5::float8, -big, big, 1), + (10.5::float8, -big, big, 2), + (10.5::float8, -big, big, 3), + (big / 4, -big / 2, big / 2, 10), + (10.5::float8, big, -big, 1), + (10.5::float8, big, -big, 2), + (10.5::float8, big, -big, 3), + (big / 4, big / 2, -big / 2, 10), + (0, 0, tiny, 4), + (tiny, 0, tiny, 4), + (0, 0, 1, 2147483647), + (1, 1, 0, 2147483647) + ) as sample(oper, low, high, cnt); + +SELECT width_bucket(1::float8, 0, 1, 2147483647); + +SELECT width_bucket(0::float8, 1, 0, 2147483647); + +SELECT to_char(val, '9G999G999G999G999G999') + FROM num_data; + +SELECT to_char(val, '9G999G999G999G999G999D999G999G999G999G999') + FROM num_data; + +SELECT to_char(val, '9999999999999999.999999999999999PR') + FROM num_data; + +SELECT to_char(val, '9999999999999999.999999999999999S') + FROM num_data; + +SELECT to_char(val, 'MI9999999999999999.999999999999999') FROM num_data; + +SELECT to_char(val, 'FMS9999999999999999.999999999999999') FROM num_data; + +SELECT to_char(val, 'FM9999999999999999.999999999999999THPR') FROM num_data; + +SELECT to_char(val, 'SG9999999999999999.999999999999999th') FROM num_data; + +SELECT to_char(val, '0999999999999999.999999999999999') FROM num_data; + +SELECT to_char(val, 'S0999999999999999.999999999999999') FROM num_data; + +SELECT to_char(val, 'FM0999999999999999.999999999999999') FROM num_data; + +SELECT to_char(val, 'FM9999999999999999.099999999999999') FROM num_data; + +SELECT to_char(val, 'FM9999999999990999.990999999999999') FROM num_data; + +SELECT to_char(val, 'FM0999999999999999.999909999999999') FROM num_data; + +SELECT to_char(val, 'FM9999999990999999.099999999999999') FROM num_data; + +SELECT to_char(val, 'L9999999999999999.099999999999999') FROM num_data; + +SELECT to_char(val, 'FM9999999999999999.99999999999999') FROM num_data; + +SELECT to_char(val, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data; + +SELECT to_char(val, 'FMS 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9') FROM num_data; + +SELECT to_char(val, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM num_data; + +SELECT to_char(val, '999999SG9999999999') FROM num_data; + +SELECT to_char(val, 'FM9999999999999999.999999999999999') FROM num_data; + +SELECT to_char(val, '9.999EEEE') FROM num_data; + +SELECT to_char(val, 'FMRN') FROM num_data; + +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, '9.999EEEE') as numeric, + to_char(val::float8, '9.999EEEE') as float8, + to_char(val::float4, '9.999EEEE') as float4 +FROM v; + +WITH v(exp) AS + (VALUES(-16379),(-16378),(-1234),(-789),(-45),(-5),(-4),(-3),(-2),(-1),(0), + (1),(2),(3),(4),(5),(38),(275),(2345),(45678),(131070),(131071)) +SELECT exp, + to_char(('1.2345e'||exp)::numeric, '9.999EEEE') as numeric +FROM v; + +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, 'MI9999999999.99') as numeric, + to_char(val::float8, 'MI9999999999.99') as float8, + to_char(val::float4, 'MI9999999999.99') as float4 +FROM v; + +WITH v(val) AS + (VALUES('0'::numeric),('-4.2'),('4.2e9'),('1.2e-5'),('inf'),('-inf'),('nan')) +SELECT val, + to_char(val, 'MI99.99') as numeric, + to_char(val::float8, 'MI99.99') as float8, + to_char(val::float4, 'MI99.99') as float4 +FROM v; + +SELECT to_char('100'::numeric, 'FM999.9'); + +SELECT to_char('100'::numeric, 'FM999.'); + +SELECT to_char('100'::numeric, 'FM999'); + +SELECT to_char('12345678901'::float8, 'FM9999999999D9999900000000000000000'); + +SELECT to_char('100'::numeric, 'rn'); + +SELECT to_char('1234'::numeric, 'rn'); + +SELECT to_char('1235'::float4, 'rn'); + +SELECT to_char('1236'::float8, 'rn'); + +SELECT to_char('1237'::float8, 'fmrn'); + +SELECT to_char('100e9'::numeric, 'RN'); + +SELECT to_char('100e9'::float4, 'RN'); + +SELECT to_char('100e9'::float8, 'RN'); + +SELECT to_char(1234.56::numeric, '99999V99'); + +SELECT to_char(1234.56::float4, '99999V99'); + +SELECT to_char(1234.56::float8, '99999V99'); + +SELECT to_char('100'::numeric, 'foo999'); + +SELECT to_char('100'::numeric, 'f\oo999'); + +SELECT to_char('100'::numeric, 'f\\oo999'); + +SELECT to_char('100'::numeric, 'f\"oo999'); + +SELECT to_char('100'::numeric, 'f\\"oo999'); + +SELECT to_char('100'::numeric, 'f"ool"999'); + +SELECT to_char('100'::numeric, 'f"\ool"999'); + +SELECT to_char('100'::numeric, 'f"\\ool"999'); + +SELECT to_char('100'::numeric, 'f"ool\"999'); + +SELECT to_char('100'::numeric, 'f"ool\\"999'); + +SET lc_numeric = 'C'; + +SELECT to_number('-34,338,492', '99G999G999'); + +SELECT to_number('-34,338,492.654,878', '99G999G999D999G999'); + +SELECT to_number('<564646.654564>', '999999.999999PR'); + +SELECT to_number('0.00001-', '9.999999S'); + +SELECT to_number('5.01-', 'FM9.999999S'); + +SELECT to_number('5.01-', 'FM9.999999MI'); + +SELECT to_number('5 4 4 4 4 8 . 7 8', '9 9 9 9 9 9 . 9 9'); + +SELECT to_number('.01', 'FM9.99'); + +SELECT to_number('.0', '99999999.99999999'); + +SELECT to_number('0', '99.99'); + +SELECT to_number('.-01', 'S99.99'); + +SELECT to_number('.01-', '99.99S'); + +SELECT to_number(' . 0 1-', ' 9 9 . 9 9 S'); + +SELECT to_number('34,50','999,99'); + +SELECT to_number('123,000','999G'); + +SELECT to_number('123456','999G999'); + +SELECT to_number('$1234.56','L9,999.99'); + +SELECT to_number('$1234.56','L99,999.99'); + +SELECT to_number('$1,234.56','L99,999.99'); + +SELECT to_number('1234.56','L99,999.99'); + +SELECT to_number('1,234.56','L99,999.99'); + +SELECT to_number('42nd', '99th'); + +SELECT to_number('123456', '99999V99'); diff --git a/crates/pgt_pretty_print/tests/data/multi/numeric_big_60.sql b/crates/pgt_pretty_print/tests/data/multi/numeric_big_60.sql new file mode 100644 index 000000000..49aa879aa --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/numeric_big_60.sql @@ -0,0 +1,1635 @@ +DROP TABLE num_data; + +DROP TABLE num_exp_add; + +DROP TABLE num_exp_sub; + +DROP TABLE num_exp_div; + +DROP TABLE num_exp_mul; + +DROP TABLE num_exp_sqrt; + +DROP TABLE num_exp_ln; + +DROP TABLE num_exp_log10; + +DROP TABLE num_exp_power_10_ln; + +DROP TABLE num_result; + +CREATE TABLE num_data (id int4, val numeric(1000,800)); + +CREATE TABLE num_exp_add (id1 int4, id2 int4, expected numeric(1000,800)); + +CREATE TABLE num_exp_sub (id1 int4, id2 int4, expected numeric(1000,800)); + +CREATE TABLE num_exp_div (id1 int4, id2 int4, expected numeric(1000,800)); + +CREATE TABLE num_exp_mul (id1 int4, id2 int4, expected numeric(1000,800)); + +CREATE TABLE num_exp_sqrt (id int4, expected numeric(1000,800)); + +CREATE TABLE num_exp_ln (id int4, expected numeric(1000,800)); + +CREATE TABLE num_exp_log10 (id int4, expected numeric(1000,800)); + +CREATE TABLE num_exp_power_10_ln (id int4, expected numeric(1000,800)); + +CREATE TABLE num_result (id1 int4, id2 int4, result numeric(1000,800)); + +BEGIN TRANSACTION; + +INSERT INTO num_exp_add VALUES (0,0,'0'); + +INSERT INTO num_exp_sub VALUES (0,0,'0'); + +INSERT INTO num_exp_mul VALUES (0,0,'0'); + +INSERT INTO num_exp_div VALUES (0,0,'NaN'); + +INSERT INTO num_exp_add VALUES (0,1,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (0,1,'-85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (0,1,'0'); + +INSERT INTO num_exp_div VALUES (0,1,'0'); + +INSERT INTO num_exp_add VALUES (0,2,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (0,2,'994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (0,2,'0'); + +INSERT INTO num_exp_div VALUES (0,2,'0'); + +INSERT INTO num_exp_add VALUES (0,3,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (0,3,'60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (0,3,'0'); + +INSERT INTO num_exp_div VALUES (0,3,'0'); + +INSERT INTO num_exp_add VALUES (0,4,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (0,4,'-5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (0,4,'0'); + +INSERT INTO num_exp_div VALUES (0,4,'0'); + +INSERT INTO num_exp_add VALUES (0,5,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (0,5,'652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (0,5,'0'); + +INSERT INTO num_exp_div VALUES (0,5,'0'); + +INSERT INTO num_exp_add VALUES (0,6,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364'); + +INSERT INTO num_exp_sub VALUES (0,6,'-.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364'); + +INSERT INTO num_exp_mul VALUES (0,6,'0'); + +INSERT INTO num_exp_div VALUES (0,6,'0'); + +INSERT INTO num_exp_add VALUES (0,7,'-818934540071845742'); + +INSERT INTO num_exp_sub VALUES (0,7,'818934540071845742'); + +INSERT INTO num_exp_mul VALUES (0,7,'0'); + +INSERT INTO num_exp_div VALUES (0,7,'0'); + +INSERT INTO num_exp_add VALUES (0,8,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800'); + +INSERT INTO num_exp_sub VALUES (0,8,'-8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800'); + +INSERT INTO num_exp_mul VALUES (0,8,'0'); + +INSERT INTO num_exp_div VALUES (0,8,'0'); + +INSERT INTO num_exp_add VALUES (0,9,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_sub VALUES (0,9,'-54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (0,9,'0'); + +INSERT INTO num_exp_div VALUES (0,9,'0'); + +INSERT INTO num_exp_add VALUES (1,0,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (1,0,'85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (1,0,'0'); + +INSERT INTO num_exp_div VALUES (1,0,'NaN'); + +INSERT INTO num_exp_add VALUES (1,1,'170486.79080049955252152479695727201571965474311716541919780029226071455736587237347615553466832461907447637054203186991790701615551214692555785671028648640897898741246882118067609728317430043806625387779037980513762118868084887015059202190301421555269486602797852927777567694581746398790609996101506730430853942556475840126871131898407356048450541232591147357021858041662012293323494543567675306406079659294204054863522259037763051870433216859794083051717080761509518250300466106939998045710070'); + +INSERT INTO num_exp_sub VALUES (1,1,'0'); + +INSERT INTO num_exp_mul VALUES (1,1,'7266436459.363324713115467666113895787027372854351303425444968800459979742082292257107107767894843498525848597439323325297125474674300428669958003640228730876886174255457103020291514229439701871032118057857763809224712818579091741996335014138185389554630910658876423205103697147288306070059640369158894028731728589073730895396494400175420670713113234800826523252075036892246807434088405522834549449664122407363485486902219500109237667016524913027290777216477989904700729228025571098410870506256758678625928245828210775042611512394316804583459576285681159178280400209217948833631961377519855502763611693070238579591463373484424582723121059964236704135695706864890193388054537703767833595331866551990460050750959493829603581882430597105627056085260296454181999581594565113210481151487049158699087454047624433576922179904629'); + +INSERT INTO num_exp_div VALUES (1,1,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (1,2,'-994877526002806872754342148663997.64812998474240514147207095573950146764154822009863493316394610578375247334825932838513167168342610420582834742950389452212867974756590355021495169819086060202117180229196935525386766373096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_sub VALUES (1,2,'994877526002806872754342148834484.43893048429492666626902822775522112238466538551783273345620682034111834572173548391979999630250058057637037929942180153828419189449146140692523818459983958943364062347264545253704196416903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (1,2,'-84806738323879544552397401815149740513.8505875535743013876823142649666132764556588225959336097903898464616542203793600590311980154402068027051522932586050753865288419084437796768749509032177577451738712965496693249429231838833655025794915864261585848007162358912070811805298210095333433397862313304655108809804359760907473898420016370058274978588765092161529583480924554820756527238472641797198545539410039895140087686344382628317530286295498797849942258314364503000942821309916954725689781458590617068629906894951122301020797266469357701283289275708774593896770378558232444454118891917258610753077932026885574920166837998049508644891327208474213193224700658584824407382455480657734911543930195324144216374573825'); + +INSERT INTO num_exp_div VALUES (1,2,'-.000000000000000000000000000085682300757901809257711279577127388124986344391495296640171942990079130291883279872719240502687189411421655284515420074848478500192127657883342858267913417679786356766341637336955924836847768457039175660279784295612167899455618405343686908907695358239088351870495830739180518509859269437015797489301844593920484927630172344269378248455657186218762679357609204333669024237648538465053048724383898528808961206696787294681884412485427843796696788390072124570957047672341581447744981862017791206857428430183366004980966398716823512288330174863890117558744630102020144500158878244146399686532935435591262767487823942606452349972401012308378888947381934278131785907155692007064636085000405504866631011593239041758448995933095907216863744502344014999804306234830774259496097549717476344048'); + +INSERT INTO num_exp_add VALUES (1,3,'-60302029489319384367663884408085672236.83687099063256754698860828386302509843815398979402006244388708674093244201278399438376682321121138429850885935540924586964982855913223221441591310211730902799041126800414795030815514254713522692405212716783388698431088814919226444677188004928663343696636297536500970117716818423689175692808344185016908913828066250587407384563498516598672584120143890364303296142744031320345312431817858545326010704685255237541162931904446804064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_sub VALUES (1,3,'60302029489319384367663884408085842723.62767149018508907178556555587874475318127115521321786273614780129829831438626014991843514783028586066905089122532715288580534070605779007112619958852628801540288008918482404759132944298520148080184250697297150817299173701934285646867489426483932830299434150464278537812298564822479785688909850915447762856384542090714278516461905872647123125352735037721325154184406043613668806975385533851732090363979459292404685190942209855935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (1,3,'-5140349743195574373979577554212527512597024.162480344833040409158673429491690439298506850052285119390701002577176786023622062742050099464897084793357329597395417632908812044304066963549928478520702505283307379218587635434673128958824348493758429380623577527186462464399974242800361134191519694694139153279582776168995426125926314513926640766117733774558011741611075336271613675760116784769700605008122422944290652448956922432960815546502965310676913079866511016221573557684245901002643719965652152439520727383305120298495304784052489867651462175349450610643411043707261107569691076730261762793560088893354750383257372118118753366377402045596735023445172252225346164608897913115394905485106225627590643805003075069931177395059698550161546962768768895596088478488887530518018212441345360153523733317120037436403475909117998647781920105313938836144009539683'); + +INSERT INTO num_exp_div VALUES (1,3,'-.000000000000000000000000000000001413607404628860353773457807436398753936801768769045711604884548436548520368932184112069166807060840219636509423284498981041814526856251281381511288768719259120481595036745286884246627534964287523188738499223075292690431699417313258943941279343383979626641848305343592679057491670166887054819766294147341982669243114259272404203080347707713358471397866402657818267495050115642987782080912962056565478445923456884713049272637646637760989004917643369240372476411912794578381690666695711891846833983534126217706309741885844723208036219144146342212915129560758201609824034610223907791643110990898577049488934294259106725414517181607988173722432655731491050637087261030314548853334338835938120502930424813699221083197863303458179445322810087784892821862085562891180364134284641396475'); + +INSERT INTO num_exp_add VALUES (1,4,'5329378275943663322300488.64471790965256505869684245785528331091076155554650629138833809683459634328609777839510066435612911583108717191216693735823717997111970662575497378762952496582183738308720094529950793570383580785385569873278068217936841324404119828637880370718028782103860007754579779716996004352284614661690063919125301052941328989181561787543541920734755989452320799185700078241880935083616978140555713297241612718277766918005268951861880490889884082730841740604517529391011862694381726143520658746305661338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (1,4,'-5329378275943663322130001.85391741010004353389988518583956365616764439012730849109607738227723047091262162286043233973705463946054514004224903034208166782419414876904468730122054597840936856190652484801633363526576955397606531892764306099068756437389060626447578949162759295501062154826802212022414257953494004665588557188694447110384853149054690655645134564686305448219729651828678220200218922790293483596988037990835533058983562863141746692824117439019450865871047657552800448629502344444081260036580660700595591338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (1,4,'454294299613767152878025320780.534199313974295807138790763501115780294529340799108297697573066187975311338382917022391830256203305238757334106943821060545424417350991354829668286194840925251162479496893943917530660694097932059166013476064988623431110002057735318529554555260199417935495388243829261809007709919225000608711536928171687251088217591210419208480251102484043683131687013687838713055660405381318396419588727500715930145098362997142075433472039319292466570912777345841400769387321465602989947078951135489852486382469990409873227894248208197179481868230244584527040573428134962626267135732247029762468417273891700661832893497067151409134724061246612631376075173287264787886064622106855886785805818642123776489793586531950438285720668411465570116161790343538663297713926678759640594912243360541590368666922379919514826022141331900181'); + +INSERT INTO num_exp_div VALUES (1,4,'.000000000000000000015994998100440878014888861029956505927201309704413242103407885948184870841766875212766910686894450511886242468216220470061916924303252919423028993720180330014505454865704155281502763018913215741264982350384245753394656021401865680441649920273268554396350483440173848850052788410943178207336328451359951614056237100465802151856198860908371340425459435127133071447273887829397881221098443685586506647314622864702873235212396755866459409263439958011711379929751157260020133239574261188528305921244365838405372320186907437842180388704854605498842516581811515413843298370501194935797268161171428747542997504369133579105180311662221854071962295818264211400101689450830279979372422749150894553349570063000769685274875561760334738424509532610467832951796852051505383374693614022043010735004494395190'); + +INSERT INTO num_exp_add VALUES (1,5,'-652670387.03916046850422757312745971450663862747133703839829692066597367760104802542475264601221776157515632293978442027199108085723617181683235487266149426304575903892721468296143475297345699313102262188759506518376019936160961709578829069446312051432780603656651983414612264636232727512091101057374054475214114364113300402823059519499217878746766275164739724770556122895799337810694888119810524986616938847385753562624139431982468828696587199570410008890188532132652095915565323400735066310142303225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (1,5,'652840873.82996096805674909792441698652235828221445420381749472095823439215841389779822880154688608619423079931032645214190898787339168396375791272937178074945473802633968350414211085025663129356908887576538544498889782055029046596593888271636613472988050090259449836342389832330814473910881711053475561205644968306669776242949930651397625234795216816397330872127577980937461350104018382663378200293023018506679957617487661691020231880567020416430204091941905612894161614165865789507675064355852373225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (1,5,'-55643106304872.575994253221940844841058071061962511162776681458310912066379595519265546225338405882027547140476045378015935579066580347282075024392379464189067155567624835346798806677988850250198082355055954078446421075165109896091047534711081616362392995575466807084807876544560268050611445006601394735810211678919646667455478469014906335433468365011768049600750224822391684377238242162320161552720449713229523135506671063115436813348612986916614320012995541575293478341408982118538094438068036422562665160411591652618670802973618768526197813319204816293073794413317669922144705633308090832805914096147659820167569140291210526520361556881576175809360614782817717579318298657744021133210954279487777567785280633309576696708168342539425395482429923273623865667723482418178781573723597156804085501875735112311466228778929147929'); + +INSERT INTO num_exp_div VALUES (1,5,'-.000130590057635351941758745900947472461593749814351229292370661147301124533787181489468804246182606762727711479707901680546780430454163647774077629503207962424213266902732555945190365467801995495570282501722505521485829885605904543846887348545254658726343578684749830307120625129857380290225370772763609458975555029415082569247186899112975387051141777417911244576134390940441209829852154391377911942082738699481875795620569383196133124499983396562167632007454221121465745085962247988140942672429187053671899537331280701003778040796615094903602095098880716919238394057384949891444700347825726273725378453454782330181608182747900774711384845635284701538541452235224216112380245660177463043471814071809869894647262285332580556739424040615194137651616350340752691170045698234853734471923738591898290468792787543896'); + +INSERT INTO num_exp_add VALUES (1,6,'85243.44233732197133191329295927531563604777955507322414928382967007765263923984471408038635831036097817458527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (1,6,'85243.34846317758118961150399799670008360696356209219504851646259063690472663252876207514831001425809630178527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (1,6,'4001.075404054519813215296429095020391062109905613738157927030437221793757373268325953178030040276107574363822832168160758728653712686313134828282109532831190239521843808940611025488601517574653932032236616573457735900045655665690517797280666732780030171712864961531623060353548802466577910774711998056232872212688464691036260746751992072745518373073825852119460094113694393273456369345499434994672730920070410547163082189385645712866100999708173472360864669110044660667614583576570496399103026286828660558854973376227247132815728164629722965145778698957093136175449225024685874279280018547740'); + +INSERT INTO num_exp_div VALUES (1,6,'1816120.848909727306817960620941575637231136442992819290405125420545200026620306446043740992108329883383706060582482495616151605111275635501481354526017831484915013545483361715432312183101964395505340188909970344423950565285639911521082834494088840596716495422427543520536844348040681236845850482165744696068209384509064196671206362539077218412355776790921130042376467606683622970728503408501481791356294886150690067651815776445750760428874351556866105285911902433352126498951242195408782804314174041618879250740246352525074791310920062276490422853700893340860452528740673590486626464460321410814395342850270921486724297414692313177440726749004398703147904603937755702369682956482832074779404350351752662820773690162594400557957241676636030332988289683112176900913522668426137377289536793838959751008646843014106876005'); + +INSERT INTO num_exp_add VALUES (1,7,'-818934540071760498.60459975022373923760152136399214017262844141729040109985386964272131706381326192223266583769046276181472898406504104649192224392653722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_sub VALUES (1,7,'818934540071930985.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (1,7,'-69808760806266041400340.70700818693892852138813934414383886494691670042143650609934777814995087699409404201920249076407981012095999320858479644760715204999741683528746097757549835956359129287002171391961763797857794730120426599135099619822532290339000466211195776337667123320942107370731349851576864242697412616810236323676004067839744992733887503405311090677026008324895177587064547630828026123718296429295638934384446325302964896473296829265805737112709269803814942537657996725913938408781715328945194948010970'); + +INSERT INTO num_exp_div VALUES (1,7,'-.000000000000104090609479936344103210175655521317012597986331111866307697262848964666360492361638117930801818899121383806224630563676018240181412174154250663423230239912527388431901852952893943812666142740182651125508583527237123596541789628675379232473721293630968882045044077795828674268595016625198802475186587918019739056755398151182369187670251750080227679555002307777300392769289647975058449905106584837938556260801229545589323224752038795423164214112897202147313792076165011373139219134850954217300915326944185918762838321705825423789073869940092569940135329697980600082436317664012683589681419530904283106912171330819469065141821685734295058255484933744156717782754922568796985634397878149984177882018261742637463462647452140104146195353696596211873925359508622779658904411330975862442989437933211964821'); + +INSERT INTO num_exp_add VALUES (1,8,'8497071467.03603749330791582407836434318377133169438097066269854720538319012928851657498035372443556191720308219530866834905045144302106406146277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (1,8,'-8496900980.24523699375539429928140707116805167695126380524350074691312247557192264420150419818976723729812860582476663647913254442686555191453722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_mul VALUES (1,8,'724311956372274.0135050255361637906710330203036651743488213007179039756514944640108625580172737414192938789413338554327986697518463087452612658955180411327002900979574347739956600177846996063741787205122007268468674386396156638261992679442768654367111433834151087792255469957061758837789341439211010331332174981459471333376067541234901538285101103690622656631026001337239036711179989456674399137008584021283568040818388709554256523118702728176420022080138548890713013682480239784198421500241995499841675772793497485550923152267616622892846304530712344886979674416990935007952941652591352603797627920865960622077762568060903908151958000'); + +INSERT INTO num_exp_div VALUES (1,8,'.000010032191786198542900505683562217892317481076466949299850809276743457759270150820565375820388277409258249926696079166209409657808406245382887790534127749833677458375931047385994887406206232330491317602830654688957983804698568410728278089250379255157030886262396950539100566975000094268415749476738358914633948867977798590927055566888255636132486899287919515638902721543629183577900872078173883974905921239149419877613723476347774771230668479296621531969573505480695490386225866950545725121902534610730154727385072738079149623798073810167706094070842646222833137345669922898403368997676634709281456818189049718956207208697021706186341405575300648248555331280690778367620868775005181264547924615247991795542738868003191757946979714250339430363902549866892041102771965653407197094250270379367437342632741280710'); + +INSERT INTO num_exp_add VALUES (1,9,'54948723.74225051983134098996071145685528795757427462111901537365053896571438476055974853245403475510333627298551845046116291696445177112567064282766115207407461565363967417615506303416694032848457927390574251904212425813072768882213388082765916956736282110801611726537663292922699021333445658549608928179155685881583228490235606377831724593358583903616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (1,9,'-54778236.95145002027881946516375418483956830283115745569981757335827825115701888818627237691936643048426179661497641859124500994829625897874508497095086558766563666622720535497438693688376602804651302002795213923698663694204683995198328880575615535181012624198813873609885725228117274934655048553507421448724831939026752650108735245933317237310133362383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_mul VALUES (1,9,'4676749348240.390309875431213992853550297086049749814750492488995108783145961719774217441193547534210468967573344456866203963659951312519988497979489304488948342258375915152429008993288817366720647491166024151209542534474867042837694499222928509320280684557676243780452100132238968233413333851595648146954975713386711764268506890884764704949969602122157394714663532141060559896359465918874990769222345665160127552795532197771168442486088776803398878354288847069602460071745966589164282641033852314335279121191855487126430176047553895892632834940595958394834437871886013513058514896870683979585091413977173250824451205330441299000850618134248917380244749589254309567551846327349592529960432446947239714236828401206843011440433362544797025114476612133622499094287321570559088587999417440664282418005102546343020409520421747216'); + +INSERT INTO num_exp_div VALUES (1,9,'.001553736563217204408368240901181555234014339476186598647410198373122572205209277343865051610898136462487966496673511261433286284257044548634547569923035899634327495195510767312478861719221916387940027268721306540663743713345337497285507595251328382906111997524508729275471287648008479480805967901972481289402930660848950039779707354469389216931774094174326513465502460315792834278614886136688161679443873815113442220055827192996984074129528034845339130162104547166079591654852164993577408422015514100323825529286511720963047269483211930770803479398243069649400360625259869765138545866815758888670363356947311319523139395191102286838888146829667276592755438606664644975648828848738708349790766370694194763606850690923803984129157519048493985198591771429264967247245289970213262206709011468289046840862597010969'); + +INSERT INTO num_exp_add VALUES (2,0,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (2,0,'-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (2,0,'0'); + +INSERT INTO num_exp_div VALUES (2,0,'NaN'); + +INSERT INTO num_exp_add VALUES (2,1,'-994877526002806872754342148663997.64812998474240514147207095573950146764154822009863493316394610578375247334825932838513167168342610420582834742950389452212867974756590355021495169819086060202117180229196935525386766373096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_sub VALUES (2,1,'-994877526002806872754342148834484.43893048429492666626902822775522112238466538551783273345620682034111834572173548391979999630250058057637037929942180153828419189449146140692523818459983958943364062347264545253704196416903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (2,1,'-84806738323879544552397401815149740513.8505875535743013876823142649666132764556588225959336097903898464616542203793600590311980154402068027051522932586050753865288419084437796768749509032177577451738712965496693249429231838833655025794915864261585848007162358912070811805298210095333433397862313304655108809804359760907473898420016370058274978588765092161529583480924554820756527238472641797198545539410039895140087686344382628317530286295498797849942258314364503000942821309916954725689781458590617068629906894951122301020797266469357701283289275708774593896770378558232444454118891917258610753077932026885574920166837998049508644891327208474213193224700658584824407382455480657734911543930195324144216374573825'); + +INSERT INTO num_exp_div VALUES (2,1,'-11671021799770914903865020509.301561107153561058074179843542446420696517132461554451075945807420674211966679216615407057626541711186781735967334896541890595771915856783008831770988426637435694856170266346306640678577376310547806764332837625966429200996250687908930748245035578756314083608655163891041399241377675534416837659335561005203219889972336214863417948542956735403991871098341470996860469878038840964359144637726669728240650066795729910649523281308716277906908340457162235831526838308777581569974551673352306004330423694524256415657620427590352277556907586751621496248973165690360552007637570957980230685679819820147036159174977086193494572117089582758015847544798464543446227632367713941117001423437766840744488426025388612316819120660814681298624293065972395923651314350558006567251033289878238407790871784676348196394482477767774'); + +INSERT INTO num_exp_add VALUES (2,2,'-1989755052005613745508684297498482.08706046903733180774109918349472259002621360561646766662015292612487081906999481230493166798592668478219872672892569606041287164205736495714018988279070019145481242576461480779090962790'); + +INSERT INTO num_exp_sub VALUES (2,2,'0'); + +INSERT INTO num_exp_mul VALUES (2,2,'989781291745465665243281323944996915810556285052564220274237162526.1617859904902612197894543199389468971679632139059029459520163585971122643624316475417489000981872666677202334180945949860058384424993911721081868337499377890298636260338063268639283065887210924895929155083478140340889209440025415565915964293989840603863813531303253038823629712989041722072693449251635519992922148998556112923060331794396659338057474019846675262291146025'); + +INSERT INTO num_exp_div VALUES (2,2,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (2,3,'-60303024366845387174536638750234506721.2758014749274942132576365116182462208228193753118527959000939070820507877345194783035668195137119648748792386548310474079340204536236936213411512867171486174240518914767934028451971067161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (2,3,'60301034611793381560791130065937008239.1887410058901624055165373281235236307966057696953851292799409809571799686645246659986351515277852800926805119259053513475211488115663286642009614039264484259692394657121785950542874788161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (2,3,'59993133911282372667149627097418449223835595194300848703012380022306762.154418449236691515146061305380465061074531890529497774836941002526095632166401249277270674802626154774328055399254982998368191676630276960361274433270795772477146870294928855773172789856196219950097157391050424577381777627004101100872747943673762087675405200265837631665464736842180920496158545887039337399558993437594084473932658319914390365451919627956823980800124880375978662052111797881386060353490432427832058851094210488804887183034572364751639107535041308434932952695103493677600969712634416241541391613699710826602011076372592299807609658979777598672141389319098817824624950794758296679318319299142035'); + +INSERT INTO num_exp_div VALUES (2,3,'.000016498242835741013709859217005931279826178662180173096568520102488480129191427472581644597420895622947234184547373944996197105916093347103336318249582032230903680989710242610024298937774441533502282949127537125997753002819456724709929935850697744632904111143787011103837624936502324835260843148595669524694347566421203164808527739207590986975750648112133699756328511947175496694080071202064255118777680958612315513441989609682655431197367166056616661045712867189326408877133865572680407329449150282415810958772293869902662884761202424695742898573841869524376684740249281181605067345203479719345061595919652192297531638467223956758315591610733251562492794891852151639643060692698365496208796638230566761231611376199140556503620471090364900792180618741355091923808605890415081571900697282725022629812561702118'); + +INSERT INTO num_exp_add VALUES (2,4,'-994877520673428596810678826533995.79421257464236160757218576989993781147390382997132644206786872350652200243563770552469933194637146474528320738725486418004701192337175478117026439697031462361180324038544450723753402846519731908503949116978812841497201119103409772457270340059605961197538918709309004130294868847110690336360689446090125918336908930881873778405661757289469281163974774492810850778950071063044769131228124355961427111369335109426492177657001035045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643'); + +INSERT INTO num_exp_sub VALUES (2,4,'-994877531332185148698005470964486.29284789439497020016891341359478477855230977564514122455228420261834881663435710678023233603955522003691551934167083188036585971868561017596992548582038556784300918537917030055337559943480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (2,4,'-5302078674303935968062773235453828254014583744527466365136.236414807326868572353809920518232561005161225922028750078608989965741402418802255050636954800114792425419735155504035469350521800895164087027043476055514245942961100610551646034472084954313670284875310691807937254054948742125729353864014122131419164449567115006621212424805182687707372956385102095255735458593389920872596796806885847543910224476727171570873698525606016990229936284811067826588349092841322512643043008589065847223683467371925773023109720951609815041012521485326120380123169545818055967455575736140138663815073081494226676896278654189873597341203197903408668523514375373841493189836809506003729379742035629498519683885268256481104619815130659628225053833297766479068686119691010593208135616363994230674606991733148502293102108193522604968743948323130517040609601859735899914987426089053869350663'); + +INSERT INTO num_exp_div VALUES (2,4,'-186677971.517539861245390308778107722315862721823627804195528485535806132067679059453022306691281662574091826898288146790399178357754908901382135796783067563944022498807930452234032896817601590728156392188660701355670595952594500812333935362955625137944589981298793332621503315902294100258945995827423279442031218510259915311555745581797315793010762585658196457363672908315687720174516274528662385172326028870945153551774300419158584379602045442200523311437013776079979639415633358878239012925000523542907592866797199229858272764668664323316251874027468128770456766875866492004650352654523634716923150212263912760225390093339729495231675627059805624175587380165509763048913150826017167286786277908970769297060278191518730887417202276531151575412404467497036737825989088867451153485938272367300939127313445244028528055624'); + +INSERT INTO num_exp_add VALUES (2,5,'-994877526002806872754342801504871.47809095279915423939648794226185974985600242391612965412218049794216637114648812993201775787765690351615479957141288239552036371132381627958673244764559862836085530643408020551049895730005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (2,5,'-994877526002806872754341495993610.60896951623817756834461124123286284017021118170033801249797242818270444792350668237291391010826978126604392715751281366489250793073354867755345743514510156309395711933053460228041067059994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_mul VALUES (2,5,'649411906691138274293985410502516861224852.2323455192714410716272307781034189160865613770320102043319541634113746032638191509585045862973333645830298922352816245477556264222094036953195419857712804755170632292914187367964994214922001758104594052499795564860466055599417895782179851297585155129541589802249540436678824225950907268084876110445460948679383611117263673106597132046331719468816839434908155684738864149955129235751738204036443603521478609787295079710078973503970964790273461142497259987849074597264522099648376356902360358310245001183020992360260836105404118742418040965190000718736837422434593694808973939805954329718232693154128543253581495885789333274488461716809104532693754070810202831113003978085636579574171344721710232931261731022478029314435363413498991740750878099825781577297965642009156858479681236085226911858782115'); + +INSERT INTO num_exp_div VALUES (2,5,'1524119409495532727030986.638577103454261465522025182901477334004986357902177024959076085490119358611626688213654669281670407680244740174673394111775678935383154847014211641601227316639834450258566053805263858706381900273201146454036688771735398324537667996974210741719621449948660517037619359095556637235980122706739013220201060795557114248610410815988952748489854367480813823114296393315170621979351958306734282429929421779129764262568942699813166237466796852578307944635545174715298176546980314973426586923195248536376403319094417073026382024413817222396402299695717290716014320518777088811749776114378145110676170242861393274018655137797545194817703831240390631723050378397773341835222892981773205967439339460305257986693600088957772328044922955990976285151896366292514128607363007421484320868718566256882080399264346243272770200676'); + +INSERT INTO num_exp_add VALUES (2,6,'-994877526002806872754342148749240.99659316232359475297606895243958507460511031229368344962653674268847910587702140353344168594152240599109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (2,6,'-994877526002806872754342148749241.09046730671373705476503023105513751542110329332278421699361618343639171319297340877148998204440427879109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (2,6,'-46696638263247522384986521136500.479312417066793299922708112595886608370451213741279484136907754744903470430131032928908162742687359367826808123516519335458861613010646992354378739165872253762686683966945711430182491860196341344982195078000259063231136011430995647812149294224699587849791008794261026932467933475782780'); + +INSERT INTO num_exp_div VALUES (2,6,'-21195986018643887410662481595901800.342199657994285865579781485758715114242459388977583220756870314514884887803267837816669111279417861218648323488364513921592045485003563036021370174294475403630933854767386355037781881144701319212711655881277140183173924089814927297045029394618083349813549439341772734606115369911736164723942330187830605893993276674913563980890459604886172701331890746621222114280438198802989678877404376001410627722336243835841751052795437979198996482216031399073597399901975686733315751292369326904428230195579137225651689857057115970784985439417129044974524632220457594191305254649113470116960582543784928547885740020507755033347968928034294570497118410435615856155184563329718831512839630769097935523279881940380220955993456451396417879773380305142918906742431812580562496634831735169817705720949712410595406012323294829461'); + +INSERT INTO num_exp_add VALUES (2,7,'-994877526002807691688882220594983.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (2,7,'-994877526002806053819802076903499.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (2,7,'814739569184924399102711674444306584731316176345067.39834031417849342571224916231092924046722938910652929295271097903377854123984307101079073134405782275535446337229706620713104545454319555885847481531722101704765783025789147453570970090'); + +INSERT INTO num_exp_div VALUES (2,7,'1214843772391778.127361407585140553741220126410637250571020684739034685508176000812180032686291124045768750332493129822580347351032145964983629059968936201592138368806173099130176852606440296388856520582890650384142745607345709716826703676313341953999327129144154152914234659001555055379537780751567782847296067128932113870102563522810980359433259696591977617184951677390423898232135100000764121508662830515405980450892222598485287609657612482190264517684867291774820716746063133066053446257163185646067618679478975882247893469409405379034723543061767846895135644429012095930584952053545016706315299076691015196261253199176743281648949731423486208098120903720124071047872917636988241710583721537777321338769039241700203546247947405745989053846970910400831817998342969657501678430211657755864160072525313889413731419647001970593'); + +INSERT INTO num_exp_add VALUES (2,8,'-994877526002806872754333651763017.40289299098701084219066388457144979069028441485513418625082363021182982914675513019536443438529749838106171095037135009526312783302868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (2,8,'-994877526002806872754350645735464.68416747805032096555043529892327279933592919076133348036932929591304098992323968210956723360062918640113701577855434596514974380902868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (2,8,'-8453460632655529853033389979024265783461224.3195241893307807116624750282852146303290708492834695194274289713076935297734670940696121761483641291930931061232942894577813178566088927221374036301485916497770984757492912292002695944367308880163698595015497307574177176409203214324418237020500352652934909632442547242092296504047310806151851207329042221920888326000'); + +INSERT INTO num_exp_div VALUES (2,8,'-117085929036205907700251.219065234073336548829793284434494573185718678644093751558890746941383215425734761534822966779511801033216479269605150574332107020180872343673157350081102818832254463561564431056604957702984438484261858890324442581609284935850435611342611117035589511568432559140282381526487115307554496353616929034919886387903446436924514812698404129456069856633480965357915969548215985452939172313964007318881987188665231550330515412104367728617802960792164260429920719961650164518261501571220901151359208484337831586551714193024143212288426326740373893030225940355268499071669300664200888186064836443459131985786957267268845966279576380786883200277187591448294590370986026461176853573555996139940001165172158855197070946665074838360933025833716166930231164328918316437195201546383664484983447934244744303265471044295601062898'); + +INSERT INTO num_exp_add VALUES (2,9,'-994877526002806872754342093885760.69667996446358567630831677089993316481039076439881735980566785462673358516198695146576524119916430759085192883825888457383242076882081857926408611052522393579396644731758241837010163568445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367'); + +INSERT INTO num_exp_sub VALUES (2,9,'-994877526002806872754342203612721.39038050457374613143278241259478942521582284121765030681448507149813723390800786083916642678676237719134679789066681148658045087323654637787610377226547625566084597844703238942080799221554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (2,9,'-54582443595378013373024060492546032003692.4875677735896411267274323339692558458420972958075073392126734000341372096298914875892612108329218081214550050039133117695428196702128258481789017059073444323729583900855712795086447886053552786449313809589992185978097430132940882612817775035217244553616977182049775786664446683332098226841743818600819221587510039430478859412452506872131851471967577741190323481953867845129745440745526578327709351120432530702446916035797432129052518980799424635406993848916727957825620638983706180841278402925286540375225365057191075559133035'); + +INSERT INTO num_exp_div VALUES (2,9,'-18133693300409132895168796.074616314168631402221003009151140409826855230810646429042722071403306917323628118792142878282108022292754325022530103525285999179488507720688317761243448898240836430183645778132937666952111134601563043980164547020295727057908447220163534134835130866457657964382363853570827467081988390359191484798677813656413640874450449802233520570178139244957518604566383671867773821069602665918688868868894979351219381089954104823746091972754649316823714354000113723793845707472924569647945844436702275724514171940901057842455729977729388911537391920702753167125695758365521631000334183494148229356487592577177344247694925635113222720411958290166668659311154664393442690740373285505786584987609789805525300762074682544164213490532272590665630428583216403362629445153016404037983825555019274338559686335405719430737559715778'); + +INSERT INTO num_exp_add VALUES (3,0,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (3,0,'-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (3,0,'0'); + +INSERT INTO num_exp_div VALUES (3,0,'NaN'); + +INSERT INTO num_exp_add VALUES (3,1,'-60302029489319384367663884408085672236.83687099063256754698860828386302509843815398979402006244388708674093244201278399438376682321121138429850885935540924586964982855913223221441591310211730902799041126800414795030815514254713522692405212716783388698431088814919226444677188004928663343696636297536500970117716818423689175692808344185016908913828066250587407384563498516598672584120143890364303296142744031320345312431817858545326010704685255237541162931904446804064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_sub VALUES (3,1,'-60302029489319384367663884408085842723.62767149018508907178556555587874475318127115521321786273614780129829831438626014991843514783028586066905089122532715288580534070605779007112619958852628801540288008918482404759132944298520148080184250697297150817299173701934285646867489426483932830299434150464278537812298564822479785688909850915447762856384542090714278516461905872647123125352735037721325154184406043613668806975385533851732090363979459292404685190942209855935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (3,1,'-5140349743195574373979577554212527512597024.162480344833040409158673429491690439298506850052285119390701002577176786023622062742050099464897084793357329597395417632908812044304066963549928478520702505283307379218587635434673128958824348493758429380623577527186462464399974242800361134191519694694139153279582776168995426125926314513926640766117733774558011741611075336271613675760116784769700605008122422944290652448956922432960815546502965310676913079866511016221573557684245901002643719965652152439520727383305120298495304784052489867651462175349450610643411043707261107569691076730261762793560088893354750383257372118118753366377402045596735023445172252225346164608897913115394905485106225627590643805003075069931177395059698550161546962768768895596088478488887530518018212441345360153523733317120037436403475909117998647781920105313938836144009539683'); + +INSERT INTO num_exp_div VALUES (3,1,'-707409990019504668223608170643582.082425157530076679823177950190511141917761066423266390864536360056345386873500583953954967225431526056199231768143978526582904071798714789552447782850723926323452633811653766838064983821149041415149067433978085927687765773012158659685363079191901396502099956189371719135315616249471739677995520904113581848295732911534266040260836644379296158092198514963023001686666281725991605685524015227112003429486755206848316731257322742428352116058878710728614841247581716185886403744830796740424927494009978599974431617064012221450054532987372285996679180090592706458366967534834069977644215413076082570497451654516268857039718730203921980307096740864747006176117071983875364434497517026142488015705391255750729200497229031250705777282987863242056223584453312226818451807347197583925624299372040413470456696588043062815'); + +INSERT INTO num_exp_add VALUES (3,2,'-60303024366845387174536638750234506721.2758014749274942132576365116182462208228193753118527959000939070820507877345194783035668195137119648748792386548310474079340204536236936213411512867171486174240518914767934028451971067161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (3,2,'-60301034611793381560791130065937008239.1887410058901624055165373281235236307966057696953851292799409809571799686645246659986351515277852800926805119259053513475211488115663286642009614039264484259692394657121785950542874788161683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (3,2,'59993133911282372667149627097418449223835595194300848703012380022306762.154418449236691515146061305380465061074531890529497774836941002526095632166401249277270674802626154774328055399254982998368191676630276960361274433270795772477146870294928855773172789856196219950097157391050424577381777627004101100872747943673762087675405200265837631665464736842180920496158545887039337399558993437594084473932658319914390365451919627956823980800124880375978662052111797881386060353490432427832058851094210488804887183034572364751639107535041308434932952695103493677600969712634416241541391613699710826602011076372592299807609658979777598672141389319098817824624950794758296679318319299142035'); + +INSERT INTO num_exp_div VALUES (3,2,'60612.515523995516156897729403721504966784736064970538891936016753206905080265887046037910122269129293912171105589512464185386239562077778499936203155976336284324712221812806801062157592930664021782540155687632208890794166119782594464410498356083266087045927038416810562596141871858142749062925965665039981381277808608946877852933015970874447235220989360704166270479475802673572039541121473138382812420076284458769543418652217394352637294823914346726065145538710933281768776286965107974980550163605068693568717671571780028113969794125200592691656568731359981803586296135840575095063824258761205175762907549288801963550628589530419118771779395037240198270853609924445368393952404606326559485235840170339343865253618184271158932135392539396160392488927771488269959497352568205940636180870805982484030168838833607478593'); + +INSERT INTO num_exp_add VALUES (3,3,'-120604058978638768735327768816171514960.4645424808176566187741738397417698516194251450072379251800348880392307563990441443022019710414972449675597505807363987554551692651900222855421126906435970433932913571889719978994845855323367077258946341408053951573026251685351209154467743141259617399607044800077950793001538324616896138171819510046467177021260834130168590102540438924579570947287892808562845032715007493401411940720339239705810106866471452994584812284665666'); + +INSERT INTO num_exp_sub VALUES (3,3,'0'); + +INSERT INTO num_exp_mul VALUES (3,3,'3636334760530744652235488357607657374520053530993537920755375319352615385278.023608692512217812784472508939511216316773023870624171279878340621219698109986095090336065266376220109007718694455520948311677863167090936408887147442375455695868593092154861636486745490748828207939155392396090682312136290864359484540126174821846208064763823279315343506148025281475729723686566174395516982893064510403581479746673749128344955124070957545815390178764940816628194640888255387443237798761377617383817511745005525149990207764725040109364671749403389999498572538135588695345112358160274671918953118753964073105250116426665508214894805722798842017943220605600452911496071424281587802689830031742105619630787641205011894680546049982654601956546154572720177337696285354350903475239411654436042931409507429892682706228354459580412759920815932840348933425754970917910500027837428631661182510071352138858'); + +INSERT INTO num_exp_div VALUES (3,3,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (3,4,'-60302029489314054989387940744763542234.98295358053252401308872309802346144227050959966671157134780970446370197110016237152333448347415674483796371931316021552756816073493808344537122580089676304958104270609762310229182150728136567294798680824019082599362332377530165818229609055765904048195574142709698758095302560470195171027219786996322461803443213101532716728918363951912367135900414238535625075942525108530051828834829820554490477645701692374399416239080329365045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643'); + +INSERT INTO num_exp_sub VALUES (3,4,'-60302029489324713745939828071407972725.48158890028513260568545074171830840934891554534052635383222518357552878529888177277886748756734050012959603126757618322788700853025193884017088688974683399381224865109134889560766307825097103477790782590061456916367930139323346273315068375646692125800496305291080749834712822775973790354498408104142209966769395239768969172107040437333428573572464689550003374384624966403962290572373571842567623422963022155546431883766327294954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (3,4,'-321372325955692885069615337209737469749246561535004445508427591.072860243358366933071485495726715620133686420023451450292996945184959542770492705998350644739298629407567812798540119555932604687814429669592481327761428042980782672136901602006622227365754036664912989085940235439697789102358431343119457114603363936544931303133371137532006899162833369543279729021228901466728220729625107362063321334489394782322741444425117731922691457341543446841167138481424319752111748042440994701571955325673470021626946676976482516292402239416632497972073915818846704053624707839813514171497746804751780741682011937606462260710753056669269928580460921188286249923152921382198282201761171043384698319895970192114563900025573490442674225227682235790590616707857188385274186584856872573669591460447105688151281208238908470285147895678001948902280493477604361481216667716971590499226735103039'); + +INSERT INTO num_exp_div VALUES (3,4,'-11315021446594.877643290091276308982961654569173523687151347727612592478433578066762912541361898899908505997444632820107356713116459078630334224890355872486337973552333755378190316811715776951317058334754704988120078733912131691682869448731717816749620336196719541702138949084375907248656748314375183301372633028246109596775255074617515860012417935744433243071057057560464360663978361945666099558526069794464437818864063206829678640156992474597480916575712563493776637239091589972373682399519931569163592317107392231951775499293572134702843085474656152913351183535194499521618027894129537558509428098859715020703897463518891082573242502356303078754574312965093639182648263511466558336912294702019648266054331227425119096294871153811412169351624751542166779635702042223762951850816568617453355571302500885410532963789364822647'); + +INSERT INTO num_exp_add VALUES (3,5,'-60302029489319384367663884408738513110.66683195868931664491302527038538338065260819361151478340212147889934633981101279593065290940544218360883531149731823374304151252289014494378769385157204705433009477214625880056478643611622410268943757215673170753460135411513114716313801477916713433956086133878890802448531292334570886746283905390661877220497842493537338035961123751393889400517474762491881277080205381424363695095196058838349029211365212855028824622924678684631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (3,5,'-60302029489319384367663884407433001849.79771052212833997386114856935638647096681695139572314177791340913988441658803134837154906163605506135872443908341816501241365674229987734175441883907154998906319658504271319733469814941611260503645706198407368762270127105340397375230875953495882740039984314121888705481484090911598074635434289709802794549714765847764347865064280637851906308955404165593747173246944693509650424312007333558709071857299501674917023499921977975368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_mul VALUES (3,5,'39362489275784146262776411377472433635883331946.794473520543457442955620133347015506556162839462623905489255080102447195050109095701660164272430316804466254467810714209179752718730906325952685817112992943656292503112803950215110778476301809440329937774061163668461957943313261962261081942055908935814323069621279128270849852239727888939033546870208376394878842958202403235309372240005941467570230067124830916866857395233038346727879951123599893174252558078732888910139309038957525961212820831321973219557165558911222848692996406741318948607549825343491479728117062814094258484536263158005174429922237853707635743736923521032098496725445243775790161216159399180889906705265012270270348146530113428221072591696851818281866095288773371414866822270689959827332258348570976075184933893434327278299820594014788148344260948638847457822697682605612771344335201258128'); + +INSERT INTO num_exp_div VALUES (3,5,'92380711368470856513514428781.033155715252174277753317877861994356621252232374386687048394529670637693505779282500567256835271428113529026462111032257747830329068594622091282098767000694818101994264352932243278144124687156236926607422077479412495979777588932692081795130282128890441931602671468684153168580234070246201722180460130467506344034452687371838907269162119534950946217165384250603250357360223255177692065141037447374172264943732616165429783010079281851748804739433821308362193703012671569249508710820679009084891198169587484117171861141580870066764275087111843275285564262902405980617569581840831518012986031156042600391943605532635833608358301306456966765206853910579231447150839538731157206153540873916893579943906851149770881336811951119112558311734171557608362620988555075663589827484854016702489324791126228380209309587206299'); + +INSERT INTO num_exp_add VALUES (3,6,'-60302029489319384367663884408085757480.1853341682137571584926062805631087054017160819890685789064777236456590745415460695320768374693076860837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (3,6,'-60302029489319384367663884408085757480.2792083126038994602815675591786611462177090630181693462735571643935716818574980747701251335721895588837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (3,6,'-2830400711649493468815157129316992649.40542786074520931471973065281957756940496588853021620372179463538053123396140685749478530925306163968207226329985017644835203709485594362663495728106061878665324856417118064730721101615473194292620972173690618491026470353143141125614124440035267592258385099934706896692953497971326605145704135723011753705907329979207428661473172503098296622281647255008204864404416199384701720347319806375450632245634238172654086373193251877533131784268854289406126119630708578053354762596511353053106459297339360827562281168219966099848212'); + +INSERT INTO num_exp_div VALUES (3,6,'-1284742031601444539630782308463065726620.121021225455596762466053504195700643301310745151565435123335541550963124666304408503436412726848834604336377169205828654564329888653766451656774534718709065521243637375270687684572524302099749018591530352756390467862377335526634920857924031482455373589053524922608255779040656019538392173139295812160325688504210040741075388404155144782519528791757450256668977268409265390016721724966592135644698341754332845002439113523127047593325646484654291494607100188094186116001064043796216982681807318598789324900462932294782971663150070521334398542559480877366424630693734132836518604260869235580641521264976411493166969530737254118968281271908306432918913600567757535151861421384835424322504855607676315840963696944683182767935565256136130185809101891760917733694553800748568697830680328155128016670099315391685422333'); + +INSERT INTO num_exp_add VALUES (3,7,'-60302029489319384368482818948157603222.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (3,7,'-60302029489319384366844949868013911738.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (3,7,'49383414785234649002982046297226894664526726187218771083.0993243619030008310875293647868815940421844461627295157812843657782639833900543200310573708100000958929315945039020410482966753145208427035917753919085618457760620513481628641658765820294863970581642745379331727722585319163262763708386199720411053619449096019862596221607526610103408936214184850115071874430846697061554769773328338028749631552202705583855831155461651414320570061181212214810086436100771547030013079997847086'); + +INSERT INTO num_exp_div VALUES (3,7,'73634737013325927185.787791148221519354461791539553527545166847382784629235192342551464898036004011575416717008403527685470842765455409054592207142526523023201841973047779202013398235864494503216973882479116841765663948294836180515686647139678530220909072497288527276378202532400736141014848907023234659020093073127450778982904578906877634654521825977382116752537063128793631412296206704078569268566614023846282524151679028060869175439188773864994186109445961525301841201265289707928211114515861536069733921800160245586536759625418951427346236213019358749196674633237197452976517130405065120577692737021174118093373953642724512531935525024447977867020930500433287279183436509990047372809400167546185096048971157700858970777301410692908939206693154161335335755844997198191427289546263182822280127912118140820265025555165337881999926'); + +INSERT INTO num_exp_add VALUES (3,8,'-60302029489319384367663884399588771256.5916339968771732477072012126949734214868901845505193155307646111690097978112797961939995859130827784737422228762767014427842766445950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (3,8,'-60302029489319384367663884416582743703.8729084839404833710669726270467964301325349604567186096492702768702209585877643481082023851284144664938175277044596973126708926205950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (3,8,'-512385513828318260570283740065493064477880918352.732624553690077857674083796435724202494963885926573907185100543184828131859183999195040110586155435203949963570735841632689374488877298209082579317039061893012560130258753218955057387206477423088065663401594359617882154814262843273526859406265633827109554791772242178864873774889091687515990672487380368975556580539271333144212685871370972163560839446696514092637412587953506052848750866803569213269271165856310101244342151576488190595936869490659700946174362872797854591188391982770203203644172999264143929484089237665313698600170041324566984832357000400'); + +INSERT INTO num_exp_div VALUES (3,8,'-7096872691348467943606706217.907270287823269424282176534343841939501231816905820949045946136373255017076943323578903040918266385724756894003692978391468202345397178445216069294845721607024056189567609414049207292919519881725733381453217071918292453682942046440563446278374996563501512335133749731529362537349288419883140401056747081065947774593869673146309163791076953204291951821124894409171722911526435445719071769008713367057971351892550570642991097981458696464929009464411568672010548002196406312721789582428747564855324072212842315229302959908665089850886951261233852165624100634055045684536311382452553544676139507899503993644452161529145849579200003677255968757773363970434791501820320494192909660871475590637419913907191608957830524390049664686282439567943053924245852983990958276537000732363895444894582579142752920882750130052682'); + +INSERT INTO num_exp_add VALUES (3,9,'-60302029489319384367663884408030893999.8854209703537480818248540990234567956069965340942024890856088355839135538265116174644003927269495876835324407641642359213535695803871472434650475144516723617632059130297610134243891145006222068960999879308472500422640481972089756410157246974765071949782242392661524488959954348903412713930092273629207697480131360047867213863018127928853922173643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (3,9,'-60302029489319384367663884408140620960.5791215104639085369493197407183130560124286109130354360944260524553172025725325268378015783145476572840273098165721628341015996848028750420770651761919246816300854441592109844750954710317145008297946462099581451150385769713261452744310496166494545449824802407416426304041583975713483424241727236417259479541129474082301376239522310995725648773643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (3,9,'-3308379209762459471107480259839508279070920437.883503980178028214343751083865562028455061662673132221930429904398963590401793045470444301883103141901787466923883803951815572606105617157736442670792467625964359169270739534412932791178258858918086886061702512427989129732248215348301444245772127142869263635282888226326427510486246184233225114523636171202034558843515894542952126988613018789833835507734620046994907453602573865012044120483116345444810078666601100257620969379968264504287700045822481492526688635364586344704730579892342786173395802035361824932075736340405960099542224953439044947229246847140957298841482874444906129049023002897135347878048572628834749795298712449864571996898774444932083319581439741625832405434317985988163261591679157437224404970927012111196724239860528859217322132733404472897289'); + +INSERT INTO num_exp_div VALUES (3,9,'-1099128766678422054524173986658.839339966689456265703816212189145237878729886466041806078542573981227645802109969871638687985985845489422516004202630099080709709893022100481258818112345013009059633421290241583864468453396484606925071369550998772875840640325758308835852391176503689677263605949075815552026731067384737231681068134099746550363063940273625924224721503126912810251607546172009765059506591787282558727077669973711491157840340631805422942099954647016059576777054339588421998882440726473698513560202030309804089250300097589174314677765341104767702983421063649104691583044460507666600260994707192787133590502137391691330098102374713996115782701417107878938473243874299874872852713499024851414757892169376458916467621226859152075901273014182163212783658933754507272478777304254191033562324994395916168496097385872331012258027431094381'); + +INSERT INTO num_exp_add VALUES (4,0,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (4,0,'5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,0,'0'); + +INSERT INTO num_exp_div VALUES (4,0,'NaN'); + +INSERT INTO num_exp_add VALUES (4,1,'5329378275943663322300488.64471790965256505869684245785528331091076155554650629138833809683459634328609777839510066435612911583108717191216693735823717997111970662575497378762952496582183738308720094529950793570383580785385569873278068217936841324404119828637880370718028782103860007754579779716996004352284614661690063919125301052941328989181561787543541920734755989452320799185700078241880935083616978140555713297241612718277766918005268951861880490889884082730841740604517529391011862694381726143520658746305661338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (4,1,'5329378275943663322130001.85391741010004353389988518583956365616764439012730849109607738227723047091262162286043233973705463946054514004224903034208166782419414876904468730122054597840936856190652484801633363526576955397606531892764306099068756437389060626447578949162759295501062154826802212022414257953494004665588557188694447110384853149054690655645134564686305448219729651828678220200218922790293483596988037990835533058983562863141746692824117439019450865871047657552800448629502344444081260036580660700595591338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,1,'454294299613767152878025320780.534199313974295807138790763501115780294529340799108297697573066187975311338382917022391830256203305238757334106943821060545424417350991354829668286194840925251162479496893943917530660694097932059166013476064988623431110002057735318529554555260199417935495388243829261809007709919225000608711536928171687251088217591210419208480251102484043683131687013687838713055660405381318396419588727500715930145098362997142075433472039319292466570912777345841400769387321465602989947078951135489852486382469990409873227894248208197179481868230244584527040573428134962626267135732247029762468417273891700661832893497067151409134724061246612631376075173287264787886064622106855886785805818642123776489793586531950438285720668411465570116161790343538663297713926678759640594912243360541590368666922379919514826022141331900181'); + +INSERT INTO num_exp_div VALUES (4,1,'62519544780217042176.800424689664850775296526267109332647921183817056683200043718160298562843864918741523494444361916531159341418970534833628106062976341639276761669219281771109561175175033739624472497927501467465456946098280878993371659461957361369508794842102784763955539708800574418468150309301129490186416766691183270872711413796386178009615777589066235359283212636467980113350635181915492452697347977967985810294150853782607014649150457138118264698071689065469752702524632313088938504181640435324554007553994564705401249228914199354821595855823113730697333390936834057091883654016371107974899726642500486005445063301647520527084320363513388355471718583708935211830796440056542408492723718088396437530207347815505844074508948817594746824098278470533148171941442049323578854023683167934569551595335539887777638716651319134577441'); + +INSERT INTO num_exp_add VALUES (4,2,'-994877520673428596810678826533995.79421257464236160757218576989993781147390382997132644206786872350652200243563770552469933194637146474528320738725486418004701192337175478117026439697031462361180324038544450723753402846519731908503949116978812841497201119103409772457270340059605961197538918709309004130294868847110690336360689446090125918336908930881873778405661757289469281163974774492810850778950071063044769131228124355961427111369335109426492177657001035045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643'); + +INSERT INTO num_exp_sub VALUES (4,2,'994877531332185148698005470964486.29284789439497020016891341359478477855230977564514122455228420261834881663435710678023233603955522003691551934167083188036585971868561017596992548582038556784300918537917030055337559943480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,2,'-5302078674303935968062773235453828254014583744527466365136.236414807326868572353809920518232561005161225922028750078608989965741402418802255050636954800114792425419735155504035469350521800895164087027043476055514245942961100610551646034472084954313670284875310691807937254054948742125729353864014122131419164449567115006621212424805182687707372956385102095255735458593389920872596796806885847543910224476727171570873698525606016990229936284811067826588349092841322512643043008589065847223683467371925773023109720951609815041012521485326120380123169545818055967455575736140138663815073081494226676896278654189873597341203197903408668523514375373841493189836809506003729379742035629498519683885268256481104619815130659628225053833297766479068686119691010593208135616363994230674606991733148502293102108193522604968743948323130517040609601859735899914987426089053869350663'); + +INSERT INTO num_exp_div VALUES (4,2,'-.000000005356818439105666775800262590702859770599410113087721172791624002387236505438218124867814437523686300450045582100868990117124343222534568799037421944272316277130975314766456260710406160143182498931595199129228915695802952695510723443157825968340043198200740606202264287904755124946591110599335909404657109057432686191440989434662797205973563889238804413861126260401987949920244286377128599413927273444061572120561496904543200956508673923547626768641271397088562966176629018606103663605145666976048261236691866387601532424530473754175270500777679603569715192364542901360534980926452487443629100484491344001509360344122933911316486556042277769848194790964257060927912344609376571637126617813506411190014141992988288983968823792971270853369317867326071952900448455162898476163801382836761898292684175721846'); + +INSERT INTO num_exp_add VALUES (4,3,'-60302029489314054989387940744763542234.98295358053252401308872309802346144227050959966671157134780970446370197110016237152333448347415674483796371931316021552756816073493808344537122580089676304958104270609762310229182150728136567294798680824019082599362332377530165818229609055765904048195574142709698758095302560470195171027219786996322461803443213101532716728918363951912367135900414238535625075942525108530051828834829820554490477645701692374399416239080329365045332525699055300921341010989742896430768506909949340276549373661076950964959025967328861569387160956730002517417236732463510495205173523163676450203614971844583064927040066684531931069310935516821795449174271052747559395296525950219449541557191520903507653089998307641491381797101485104546410643'); + +INSERT INTO num_exp_sub VALUES (4,3,'60302029489324713745939828071407972725.48158890028513260568545074171830840934891554534052635383222518357552878529888177277886748756734050012959603126757618322788700853025193884017088688974683399381224865109134889560766307825097103477790782590061456916367930139323346273315068375646692125800496305291080749834712822775973790354498408104142209966769395239768969172107040437333428573572464689550003374384624966403962290572373571842567623422963022155546431883766327294954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,3,'-321372325955692885069615337209737469749246561535004445508427591.072860243358366933071485495726715620133686420023451450292996945184959542770492705998350644739298629407567812798540119555932604687814429669592481327761428042980782672136901602006622227365754036664912989085940235439697789102358431343119457114603363936544931303133371137532006899162833369543279729021228901466728220729625107362063321334489394782322741444425117731922691457341543446841167138481424319752111748042440994701571955325673470021626946676976482516292402239416632497972073915818846704053624707839813514171497746804751780741682011937606462260710753056669269928580460921188286249923152921382198282201761171043384698319895970192114563900025573490442674225227682235790590616707857188385274186584856872573669591460447105688151281208238908470285147895678001948902280493477604361481216667716971590499226735103039'); + +INSERT INTO num_exp_div VALUES (4,3,'-.000000000000088378091435340426596348183959201660680284222502095357746364378698792730669202270228092348823133529449019715406417264278615046537007844589547485282959556860316942508808911542109265489435572674031608663747132688980867386885961271358592278360097086532747883342438036287136994589308551796702164612609710942175900921197001888540314760352113821737014875886635147123114456910985089625906448913621495025509697742196814421833448856595853403450682101743559369637786458968714240975228615283970739279506239628546165569688434254286341567486905374255702980370754235630955328837646999003123103831262789115646588779721625156078607919060762857866951417867378220773543985422722165221371084387943737083254760594128718841665355053236168688218864433967871311858292181233490194833547273501436630325295640020916257836404'); + +INSERT INTO num_exp_add VALUES (4,4,'10658756551887326644430490.49863531975260859259672764369484696707840594567381478248441547911182681419871940125553300409318375529163231195441596770031884779531385539479966108885007094423120594499372579331584157096960536182992101766042374317005597761793180455085459319880788077604922162581381991739410262305778619327278621107819748163326182138236252443188676485421061437672050451014378298442099857873910461737543751288077145777261329781147015644685997929909334948601889398157317978020514207138462986180101319446901252677846098070081948065342276861225678086539994965165526535072979009589652953672647099592770056310833870145919866630936137861378128966356409101651457894504881209406948099561100916885616958192984693820003384717017236405797029790907178714'); + +INSERT INTO num_exp_sub VALUES (4,4,'0'); + +INSERT INTO num_exp_mul VALUES (4,4,'28402272808100253242547006276715304015308580784958.804614276533085644370816876160290159450291717634111299841065255625515058118012211808741402904995080624675460593676923639082981788732031193774047612589113654423166826140872334380708795266307037944059108148612979119729408762532396036043629484049508789880964586236575769826806092391573178899640321403656891487586452524427223891405519836671312830183895761747460911777623703557946796784873885800089025388390522992806365773290733075927321101736155663727528284512100509273076328103465333687228713897893434161293693971954442699482857938492961830350598789444266860160794913830991304996676299650460125000959751177037694425217989910261807246272771711816326991282202653917488360776928533800529297474279497910326579608191975246060946079639658615178160271122713225105861574160788280907842327681375920919676063500116492292319'); + +INSERT INTO num_exp_div VALUES (4,4,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (4,5,'5329378275943662669459614.81475694159581596077242547133292502869630735172901157043010370467618244548786897684821457816189831652076071977025794948484549600736179389638319303817478693948215387894509009504287664213474693208847025374388286162907794727810231557001266897729978691844410171412189947386181530441402903608214502713480332746271552746231631136145916685939539173054989927058122097304419584979598595477177513004218594211597809300517607260841648610322863666300637648662611916496850248528515936635845594390453288113296413254893687029540384176335735114863908372780241463999450547422213639667099644505472777149095004849805371205203850993689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (4,5,'5329378275943663974970875.68387837815679263182430217236192193838209859394480321205431177443564436871085042440731842593128543877087159218415801821547335178795206149841646805067528400474905206604863569827296492883485842974145076391654088154097803033982948898084192422150809385760511991169192044353228731864375715719064118394339415417054629392004621307042759799481522264617060523956256201137680272894311866260366238283858551565663520480629408383844349319586471282301251749494706061523663958609947049544255725056447964564549684815188261035801892684889942971676086592385285071073528462167439314005547455087297279161738865296114495425732286867689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,5,'-3478781676337858247983014311182511.567538638808357215203593479841446379226774481291286361639429856698999485760647422501864626078375852610019829111004807806660731243672830787729048847342063218718651165150612717759770504648306347926061960607388621011846314969634048226452709389995594961695723139571002939804473057725442880410434039783304583526414509590532906062732322732569475349107437896717416548237633532805602064623969799081086996320156575550896200848758685986331692388099427314008504506503745527468550106879602399030419569897808150076298414568875477195447656904373310322813412927463518325927626891046356679526447117311923853482118502868148386882363449163182892615259995945992014431502761210899772725227648729095696228388558331052524469604046072203605897109629560683446827492904111565278516043939137760721315953500281379039771826554155511347152'); + +INSERT INTO num_exp_div VALUES (4,5,'-8164430956184510.184223536017248184022252663660196916321116266103608317725855237211273642694947892658721606226082017525816544904635887836163201565923338826779819876742736219975639586566502584026349778499211535661173597356253186281116862244165796632756909578140184577853088376334255860281874385669242675881761388233070861374295536603371778669602656670852115614651462552069294889723058758969660566508798011830996965570446030123780674316363670374970480994905368006454513642480180066435609577311074332150098288374616437489163254821095377348025470309665651059603665062887597814064136313866690824972464351274062540825405003954064175728198182815347642172934453828192850870808373638597839434504241236228591053696481146252072190903430582534862988719805163692697482513169856291048966811374872266165034373412719593685881972700171726777938'); + +INSERT INTO num_exp_add VALUES (4,6,'5329378275943663322215245.29625473207137544719284446115519970394719946335145777492574745992986971075733570324679065009803281404581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (4,6,'5329378275943663322215245.20238058768123314540388318253964726313120648232235700755866801918195710344138369800874235399515094124581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,6,'250145412892811547138949.592621291590152419206270097656346630226508074074623894951308487425470437268130465956063593951784820669318897182831355375451719125809800516979013437732298382708070979871283132689492336823087794373113039154669229889503700598930220858275174342776478898670277868700384853696009897221747924643343353942154528501454689084608965009561564638167714973711022212547096732831847202912862290958304510651828842182545311077713664465815992616213663619529378061133917572474298028065850515876361609671565914027186063801852554353160801534696062207299890867876199323530337336273950892723090754719547285920090419070001019943385293110663922226230169381423410428577990604776655422105400452217085311617728003688836185608912367677734364834577573255789160419371322775733777518997638403409000055707558465286469808848200141192627396502735'); + +INSERT INTO num_exp_div VALUES (4,6,'113543048739697485358574290.758354267447744932153707340542459183720907885610125346262898114677742971240785031722334497858930434531517077525413654346644836353208132641713415396062580605566225794048569430676355036264762949452090151450855446984773994337170590068740235544320694721909983307239491151139099779296496785240814600627140543144068640768857707110930453204162312973998304574796413938461971472337040811785231390930046688391955000749644938061585377150632133417156866197053052425576957646564943278156977176976876921235395711611898108821587442609611001702344783440618040704066809035404237786023075676374788819144406909313755996914145273176359246052899650387182222905558751208368173052381982668563471143298720677965028880626152749773712037769548408324298835212547215352657271696665387200792785056233953536347605130973626194099064678842085'); + +INSERT INTO num_exp_add VALUES (4,7,'5329377457009123250369503.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (4,7,'5329379094878203394060987.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,7,'-4364411947278810125327066890819882483326918.05664098958260550284395870948992407314161088028674246708928421994893923699743452802989464864039994566042797942433140378990308345483670828497915478397481687305406460330009319949623844175096007381662809083363069100235985794575399268709260901964834244796150883807308976949196661411035264619638771824190014274817662519438658481432363824187693821267613212631153175155634316128036152465184903927860719447693468054624663668062006049759837326188252927823612718163916100588143128358998656306593393889422386501730237442526450419990376323903182669190482615734972147533221144682538647497701130447816148459762464395194383090936159579764712919396391813914821973715879062992249315474841639591907249142779103650773383644785606333916967894'); + +INSERT INTO num_exp_div VALUES (4,7,'-6507697.520580964829176145824902679560705744817573189143227837387224410616222039115571544850095278317993922427931439719549137387753697989249394347047436951117850128104928719365703899136632100669607126357491484781141296021264049762417528697619931558728863308905257358126654378784709213859234056696519305650316810797382293500878834933984458810656133463638442959750083607649924453935287420620424368291770694630751828333903156364366745210911640207075765008558904788350844410055253643515389003711759818446776538393914018427075074171758415188027562645239606914126802490579848138218395145734902830046359100742374008993296019987093605275289913663224324033923096998194326249508491872193747944673057257521552387923218450155737056841633810711295424578984452176016198348344913655301417872189073133147510027427530833694019910340299'); + +INSERT INTO num_exp_add VALUES (4,8,'5329378275943671819201468.88995490340795935797824952902333498786202536079000703830146057240651898748760197658486790165425772165585380839129948178510273188565692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (4,8,'5329378275943654825229021.60868041634464923461847811467151197921638058488380774418295490670530782671111742467066510243892603363577850356311648591521611590965692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,8,'45283653791262997781451381354094822.762732909505051438036873220502792213670540454778361182993875916509061144859281577740137081988678361247725064336120451090222456518107029158304937620179032477664627949959143233370320432203497828243297406462513350790251761540074946469824444452248386782451723637769289822576372357189700319768797708375563651655860093365309717823602754924352327588945034832436331911584742966378275504545736896430718939807674966738116698454215555860047859161126694019895490767779791933882712567492115664113775047192011252893773389940988533801360010782816196288710063568554147458866942816721046004257953642508395867837127678980002737669139369781058046396738606563716339660654364541530532834806205571191828994250708412638796240377704994928921528330863683630622922959130920715261879547446054261914770022377059156125037157979236658010950'); + +INSERT INTO num_exp_div VALUES (4,8,'627208063620965.397582272040628872773601055303353339700043792111288801181637510303989399395425313995651311362368773096988861977687484912995632130587762386590996099363383976320342247076516604162469063709298438133327434461462906199160715395064249299615054970359309619951777972710299484596875999967582794277241285253106817446259313281064844416249524876385699646393555435017820686376877981018047574348711991428666249794623006175739581915209218834701034964043360823844816042368184094857692062884223864639972005010863342567608351008172649209459933114800143792514183138995700133608613158857147417653998048890116531052767737435620558349226865105888201598712435680481803901906613772821370519525404423549161696526405320391828194356063547089626322474164332505209233143121068245585662919687001395119229263995765376465304715643388771609446'); + +INSERT INTO num_exp_add VALUES (4,9,'5329378275943663377078725.59616792993138452386059664269485161374191901124632386474661634799161523147237015531446709484039091244606359050341194730653343894986479159670583937529516163204904273806158788218327396375034882788180783796976731912141525319602448709213495905899041406302673881364465504945113279286939663215197485367850132991968081639290297033476859158044889351836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (4,9,'5329378275943663267351764.90246738982122406873613100099999535333648693442749091773779913112021158272634924594106590925279284284556872145100402039378540884544906379809382171355490931218216320693213791113256760721925653394811317969065642404864072442190731745871963413981746671302248281216916486794296983018838956112081135739969615171358100498945955409711817327376172085836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (4,9,'292388240303165948041827159734686.255558469787242316676287235194652580157149226950109397295920730296960145548003120827363226435916209781396711693581454960342091452830648929118261388933297036933167543189308061917640517578583521401267417187854611829815212778183983326568586118831109538377828156118900313778053576483381085207892754728937946691892849474364477434665960112125254104966566712906532318984871145605839506991591027939136026602051635433295687547552796828217859648186757719639965988287173297286034098497871707197092627676226053609131138590878743560287292934815277894463305001278326023708395571840850120055316276256138004565442099731931051413153564744766098053176049414330146267604802971221161572130161432525297614616942172815141372973870720928125699420370428856022295499447755488148545048400795053604349570217878099721865670458104653570360'); + +INSERT INTO num_exp_div VALUES (4,9,'97138902640718538.241246716463110895614166618530828908023040947887095196830690221211560526562522274118188963051412359798837957512805692731972838989047910709158995922699598619854907969493232150042212406549916252602794415099066259707018021422154933830674786488990033885447289593742424717170197810316367637885248684134204152352748803532396210051700193575105804898183523770153431536054848843504020390623875664696278263569145547515663340450903772852615789980257449146000410036925975898331113013857953289990299253584950458042598491897496393582249411290555264437893099880371008957017323366523688894303458743415715114628052487518110654201696604914159777300997374156315186315524817636714210119873791848535246674326877611945112249137224923201544452904111118569299934059002046318394345055859769572070097973298522564724884895879226870720839'); + +INSERT INTO num_exp_add VALUES (5,0,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (5,0,'-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (5,0,'0'); + +INSERT INTO num_exp_div VALUES (5,0,'NaN'); + +INSERT INTO num_exp_add VALUES (5,1,'-652670387.03916046850422757312745971450663862747133703839829692066597367760104802542475264601221776157515632293978442027199108085723617181683235487266149426304575903892721468296143475297345699313102262188759506518376019936160961709578829069446312051432780603656651983414612264636232727512091101057374054475214114364113300402823059519499217878746766275164739724770556122895799337810694888119810524986616938847385753562624139431982468828696587199570410008890188532132652095915565323400735066310142303225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (5,1,'-652840873.82996096805674909792441698652235828221445420381749472095823439215841389779822880154688608619423079931032645214190898787339168396375791272937178074945473802633968350414211085025663129356908887576538544498889782055029046596593888271636613472988050090259449836342389832330814473910881711053475561205644968306669776242949930651397625234795216816397330872127577980937461350104018382663378200293023018506679957617487661691020231880567020416430204091941905612894161614165865789507675064355852373225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (5,1,'-55643106304872.575994253221940844841058071061962511162776681458310912066379595519265546225338405882027547140476045378015935579066580347282075024392379464189067155567624835346798806677988850250198082355055954078446421075165109896091047534711081616362392995575466807084807876544560268050611445006601394735810211678919646667455478469014906335433468365011768049600750224822391684377238242162320161552720449713229523135506671063115436813348612986916614320012995541575293478341408982118538094438068036422562665160411591652618670802973618768526197813319204816293073794413317669922144705633308090832805914096147659820167569140291210526520361556881576175809360614782817717579318298657744021133210954279487777567785280633309576696708168342539425395482429923273623865667723482418178781573723597156804085501875735112311466228778929147929'); + +INSERT INTO num_exp_div VALUES (5,1,'-7657.550797567691019915353529993301413746369700087741672762343206271266232635965032053368224472333368713006346867984576168784127503674579531243603836945595880917241997606783133673324236134063757452734295148763280059050480246827193380861494669624151921824660313516974440913733511526807313019192263170823268678149435664224184903925632177789052038092611394447709922076676981043877747276056677801802695466205531230350209787298926245402046182150996849906836743231861317120171583577624262765589605263477198809166390259128339127005924586833372241946051704497188891325715185091060185547236923494393813210904033520844572880475265306843414506359253445517738473745552980984097762509546161690823646176501838559393690565709795724159196133663168004773260451322595899506776323262195323943138344537866088159583331807728944620284996'); + +INSERT INTO num_exp_add VALUES (5,2,'-994877526002806872754342801504871.47809095279915423939648794226185974985600242391612965412218049794216637114648812993201775787765690351615479957141288239552036371132381627958673244764559862836085530643408020551049895730005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (5,2,'994877526002806872754341495993610.60896951623817756834461124123286284017021118170033801249797242818270444792350668237291391010826978126604392715751281366489250793073354867755345743514510156309395711933053460228041067059994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_mul VALUES (5,2,'649411906691138274293985410502516861224852.2323455192714410716272307781034189160865613770320102043319541634113746032638191509585045862973333645830298922352816245477556264222094036953195419857712804755170632292914187367964994214922001758104594052499795564860466055599417895782179851297585155129541589802249540436678824225950907268084876110445460948679383611117263673106597132046331719468816839434908155684738864149955129235751738204036443603521478609787295079710078973503970964790273461142497259987849074597264522099648376356902360358310245001183020992360260836105404118742418040965190000718736837422434593694808973939805954329718232693154128543253581495885789333274488461716809104532693754070810202831113003978085636579574171344721710232931261731022478029314435363413498991740750878099825781577297965642009156858479681236085226911858782115'); + +INSERT INTO num_exp_div VALUES (5,2,'.000000000000000000000000656116570506105776235076334177868550033347254561166417969910286926369599900073757929714260350320362090452092025380232792749476245042480546813848702351830607516880397305138543526307608094143028291193163613755680419049060162928958489964834941920423432354996040147818253087783193280640282263490705632002572757216731766513434035163528102590524432221718194164133959630768718395847710529339782880381264265894322494716854757290930538739000043383104085867828258790010654331660516512156519838978751447311068903958136482041673109857552178367614498426226323001399275980281507353231821022591045797658991388304873240910526149138339658220844723880158150606035181559877351791752701872877147074033569061408920725522180134133183999181370354585872214368766629114773129541658653693832843354053701079334077'); + +INSERT INTO num_exp_add VALUES (5,3,'-60302029489319384367663884408738513110.66683195868931664491302527038538338065260819361151478340212147889934633981101279593065290940544218360883531149731823374304151252289014494378769385157204705433009477214625880056478643611622410268943757215673170753460135411513114716313801477916713433956086133878890802448531292334570886746283905390661877220497842493537338035961123751393889400517474762491881277080205381424363695095196058838349029211365212855028824622924678684631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (5,3,'60302029489319384367663884407433001849.79771052212833997386114856935638647096681695139572314177791340913988441658803134837154906163605506135872443908341816501241365674229987734175441883907154998906319658504271319733469814941611260503645706198407368762270127105340397375230875953495882740039984314121888705481484090911598074635434289709802794549714765847764347865064280637851906308955404165593747173246944693509650424312007333558709071857299501674917023499921977975368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_mul VALUES (5,3,'39362489275784146262776411377472433635883331946.794473520543457442955620133347015506556162839462623905489255080102447195050109095701660164272430316804466254467810714209179752718730906325952685817112992943656292503112803950215110778476301809440329937774061163668461957943313261962261081942055908935814323069621279128270849852239727888939033546870208376394878842958202403235309372240005941467570230067124830916866857395233038346727879951123599893174252558078732888910139309038957525961212820831321973219557165558911222848692996406741318948607549825343491479728117062814094258484536263158005174429922237853707635743736923521032098496725445243775790161216159399180889906705265012270270348146530113428221072591696851818281866095288773371414866822270689959827332258348570976075184933893434327278299820594014788148344260948638847457822697682605612771344335201258128'); + +INSERT INTO num_exp_div VALUES (5,3,'.000000000000000000000000000010824770508763323320533297369674519056450544793568147911931789010432012750062661590994728968589403602468229106206242395792957238667714358401601098858606386995096923432407249369639633268143022787987190106724545750803196130511146323174462918572423414631798141263222875752767731279138952850500369328934959764805948568471324562210715908420467881411844098258193571194910997918428786213948547748701831331312040839544355427357749520227124858111324859160114175254197992204974033767300989488517391063188153561391320190653403747521648794370679322504188364455328709488846777004202196382575648619395139553279192346251133156445942281048959845827006761160755031086836046398020850814350246219929303018051720203943879538087954853996826539712240458022307680912400297508925714946398031304516583939283'); + +INSERT INTO num_exp_add VALUES (5,4,'5329378275943662669459614.81475694159581596077242547133292502869630735172901157043010370467618244548786897684821457816189831652076071977025794948484549600736179389638319303817478693948215387894509009504287664213474693208847025374388286162907794727810231557001266897729978691844410171412189947386181530441402903608214502713480332746271552746231631136145916685939539173054989927058122097304419584979598595477177513004218594211597809300517607260841648610322863666300637648662611916496850248528515936635845594390453288113296413254893687029540384176335735114863908372780241463999450547422213639667099644505472777149095004849805371205203850993689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (5,4,'-5329378275943663974970875.68387837815679263182430217236192193838209859394480321205431177443564436871085042440731842593128543877087159218415801821547335178795206149841646805067528400474905206604863569827296492883485842974145076391654088154097803033982948898084192422150809385760511991169192044353228731864375715719064118394339415417054629392004621307042759799481522264617060523956256201137680272894311866260366238283858551565663520480629408383844349319586471282301251749494706061523663958609947049544255725056447964564549684815188261035801892684889942971676086592385285071073528462167439314005547455087297279161738865296114495425732286867689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (5,4,'-3478781676337858247983014311182511.567538638808357215203593479841446379226774481291286361639429856698999485760647422501864626078375852610019829111004807806660731243672830787729048847342063218718651165150612717759770504648306347926061960607388621011846314969634048226452709389995594961695723139571002939804473057725442880410434039783304583526414509590532906062732322732569475349107437896717416548237633532805602064623969799081086996320156575550896200848758685986331692388099427314008504506503745527468550106879602399030419569897808150076298414568875477195447656904373310322813412927463518325927626891046356679526447117311923853482118502868148386882363449163182892615259995945992014431502761210899772725227648729095696228388558331052524469604046072203605897109629560683446827492904111565278516043939137760721315953500281379039771826554155511347152'); + +INSERT INTO num_exp_div VALUES (5,4,'-.000000000000000122482510461124748279475400009367345900846466958806966807399903713411658400733717078392550780910604704603123670767210550800752620037863340961255721285160854785449315208955654408132775022766783343331151895973970395232686910362226184006990485313002943710214511418310741271074710741339586430026286272098156531835438969774325517509155992092194349661122678547097423264670055720422496527272118788005921590521726691666219504214087867030003203385360001614199656989667055583749577099440092378355805901262289841168751608673297446473709956390142112843400255748161809121986096092991616144443486023218404881798896685413932215981950393130292001833627899480153863300557853617312991880655905907971211246077450786084079040513198340644157868678782195341316027563717617074364438885981635394382733697473265872796207'); + +INSERT INTO num_exp_add VALUES (5,5,'-1305511260.86912143656097667105187670102899690968579124221579164162420806975946192322298144755910384776938712225011087241390006873062785578059026760203327501250049706526689818710354560323008828670011149765298051017265801991190008306172717341082925524420830693916101819757002096967047201422972812110849615680859082670783076645772990170896843113541983091562070596898134103833260687914713270783188725279639957354065711180111801123002700709263607616000614100832094145026813710081431112908410130665994676451253271560294574006261508508554207856812178219605043607074077914745225674338447810581824502012643860446309124220528435874'); + +INSERT INTO num_exp_sub VALUES (5,5,'0'); + +INSERT INTO num_exp_mul VALUES (5,5,'426089913064020811.057708378200224487694731586862745370027417544052374884336177893807736467646454486029424673621605232432043672119510371547153895504456723242262639262542904151307250842477327375961936454637964429999741717244285121019840463692418987118402683746281993192269229200465080358289645050337976214115902915692028162689089167194843185708212911364017271332623359100711545479273675423617018342297822477514128997410642005300368966199980354369928371655155437291469427189561877718971914040675572136507472590254222870537216617260612835805368361975725573009455402822669103118872235140158440342063571894152305875004532651814592458133460160514384171804043127771746596286988679698684698755896736275307574630777027620558428909546664763675431701332632828281070572045822129984625797185173815273651376003614106277727279230096226977335510'); + +INSERT INTO num_exp_div VALUES (5,5,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (5,6,'-652755630.38762364608541718463145771120672223443489913059334543712856431450577465795351472116052777583325262472505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (5,6,'-652755630.48149779047555948642041898982227467525089211162244620449564375525368726526946672639857607193613449752505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (5,6,'-30638438.151446159804025029882398388155309149089870990062944469684482366692824338098201222171115395923414887930224163525189097571163687285244255335505387733673499447610577050114902372990462064696637481657064525319516004273769831260452832960893174173254560250804003884280384718123289136453955482855362019158401218620018346500189769819687260476334734259702665316562988639223597110627626759216850014150105605927773639897638043177685498804811787888811168524202700283461266793154726325540776914500415140842975457394524215869103737379109516024460317825645645301237375972914247141703084877141866316168268901439172491577729880760950895760711857112463508064820414904611059588717092145484656103798852859978690742216940980929562068'); + +INSERT INTO num_exp_div VALUES (5,6,'-13907037655.047994416383638650569341223199042786813441967582376077478024677494832069402897226848055043557486983268019376307288565911231748501636517992289743940159005664424461285010295150828744259113760652210086696250085454819340987566229400805422509198052317518991183515696724846560872057916862620762789778660622787735923967096950195583369113574365386627110408307941105082873469072519133330718161987781080307947247163619814890462416622144825161521790673339279047700672881113718394727610096366361422482794458375587355933614201638489194194834709433413694420512869179976485096875057742460003147602405353823942488343056906912173170809084207937229591627643451380735179767199816663168139837088183577975769442341678933576388936845704303859241320794255052627716474860113993958556604381707826493168941926878481079724185426298004604'); + +INSERT INTO num_exp_add VALUES (5,7,'-818934540724601372.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (5,7,'818934539419090111.56543928171951166447406164948550154515710437889210417918789596512026903838850927622044807611530643887494456379304996563468607210970486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_mul VALUES (5,7,'534564131989234694540350103.27821462973515555648644772098605028371173048154132108733819196629002548296868548691993248746628993380136454426833349407578676005545111508293942736555269938962058196496152360848131645787941032968937794930046928523006455386861100809286408671908320322523368135203881520526880998279355848280412933152306299256343179622513731096363088094541514890135766460631462465021694553063366717467560655272004461368865264059368514271105464855575429914212085797297268595943955105608543373940035636033207568676745293499106348500559628723682588033431457023964317090780615020801564861497990103549650624438425421690193862533733474254'); + +INSERT INTO num_exp_div VALUES (5,7,'.000000000797079129642393611556079160915147221153735075943759104977169600937534508973732991117540626046659124172765761873705978811124901421049332579161931652390647472911517923131800238903184679028518657818755558526885018755394697157094867449047655737107085020874974955627907737126958129710597811740696534189608639914753884882702680512272194316887744972931453458445314561564591875764930680945589486999586667912816485821717403892703364322658245615895415781719033810595358092343690359557942948213374234065052300866661453767599465059289920067095083062096458980564265691295895672503728815182981118876144075942348853666085714846210822847053889733510154276933759200630639642310562242207518883342516103725757482864105340008709446643820864294556778969997115586027866760708448174502158738150605938364482719960251612464993'); + +INSERT INTO num_exp_add VALUES (5,8,'7844230593.20607652525116672615394735666141304947992676684520382624714879797087461877675155217754947572297228288498221620714146356962938009770486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_sub VALUES (5,8,'-9149741854.07519796181214339720582405769040995916571800906099546787135686773033654199973299973665332349235940513509308862104153230025723587829513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (5,8,'-5546455599206321494.0676583421119904300307105296377723816472192007866147764761501865875232824814135783697976183493106885436876081315217834621720906478074798596116645640251460842350553806256223963023430631066024389364515688765194373161385579258482225808660340732705687558150699172147896486727530192499184101617379930846663835628510376484675411350654979679181852179924386290069790336316958202582966248703889464308649631486542724072047294216362186036638115240070658004553260251510288423749333873893917690832829128021808383128393431810674177390352413548658782609064839524756041501835115152819802758773711821322162752064589750295542985780512921839490040396053737870038534216948323935020460307350020911362024271167085905714873548388570602799432705061561572854498075600'); + +INSERT INTO num_exp_div VALUES (5,8,'-.076822018213756690975099471985461347542955923191183223634407380481978143225129486622351714276452369661632980197282261508936298649901018470846144321441236073683990324039849865750139470288565622579952182053792815638469841531577235191276257498209844422440366423136595067535337374223115507557306455001792362506235886189722508617024948653046102060677266555476719102193278190540414934812073355995577639986512222998268934000209944414236509139290657402937840986061987219441410741189615344050459067454369371094189930607834375561948483494321255500497786795636801854613881105643003358210407867114145806225724880370339074242480071595684502491827709175732777776915682786771730423733673667248186336046898260378049328204094804755195626798951644386924178161926128482002518979482630732440619051262620098544265763306253807191182'); + +INSERT INTO num_exp_add VALUES (5,9,'-597892150.08771044822540810796370552966707032464017958269847934730769542644402913723848026909285133109089452632480800168074607090893991283808726990171062867538012237270000932798704781608969096508450960185964292594677356241956277714380500188870696516251767979457838109804726539408115452577436052503866633026489282425086547752714324273565900641436632912781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (5,9,'-707619110.78141098833556856308817117136192658504561165951731229431651264331543278598450117846625251667849259592530287073315399782168794294250299770032264633712037469256688885911649778714039732161560189579333758422588445749233730591792217152212229008169062714458263709952275557558931748845536759606982982654369800245696528893058665897330942472105350178781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (5,9,'-35812445701642379.972368737320206275515144213236752803936806738624588812089615098329765811617509505790110909629109400553415312470540217508070421816878544125783329593128638405659896184248784794258084116406472768709113030915308410565617764394827427154923321461158387012978726512246146545834669665093228316853342805604075936530371665576147966721599968786161939347726656168798065647411457701453987215491345496003650288850096338695703984042549594979897253521041581573388369367579323607093487743440894765114619634001789457486407909224339065748496715380572175183589195611952939575073075140094901024063428239223964510824958346570603142906309198033196987949067156046076497974760641964978711558209708743776024313916111738542765749928287600981397080809041007714387564206594515733287925008053261840295560398311905155157989225181164097547541'); + +INSERT INTO num_exp_div VALUES (5,9,'-11.897816658873986795664687519069203701902563457968097729876034796143085813450454323128600602495745166997629078984618283588337379184733369491549230343315369634754204412939757136108898254582353378508832611703989221079986765793923635928759179573599208612516427628403686659479459867527627014558600521732194240404211484706621458983727740143568799713006127585168144158660566534382037451913967363675002134687952374080694449905223371627606557311710348820900963340884001770733452314715448053233208783321215998063958966729954113843581448912079950334969908657535514847005768455377990262943747367245613296497099716892292154137652893990339292671106003657659470243633112063075297194691349631518467702876183897580432003030164590920118726657290102377710611324297862045849839571689192181090062958059281673245670440852080202548743'); + +INSERT INTO num_exp_add VALUES (6,0,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364'); + +INSERT INTO num_exp_sub VALUES (6,0,'.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364'); + +INSERT INTO num_exp_mul VALUES (6,0,'0'); + +INSERT INTO num_exp_div VALUES (6,0,'NaN'); + +INSERT INTO num_exp_add VALUES (6,1,'85243.44233732197133191329295927531563604777955507322414928382967007765263923984471408038635831036097817458527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (6,1,'-85243.34846317758118961150399799670008360696356209219504851646259063690472663252876207514831001425809630178527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (6,1,'4001.075404054519813215296429095020391062109905613738157927030437221793757373268325953178030040276107574363822832168160758728653712686313134828282109532831190239521843808940611025488601517574653932032236616573457735900045655665690517797280666732780030171712864961531623060353548802466577910774711998056232872212688464691036260746751992072745518373073825852119460094113694393273456369345499434994672730920070410547163082189385645712866100999708173472360864669110044660667614583576570496399103026286828660558854973376227247132815728164629722965145778698957093136175449225024685874279280018547740'); + +INSERT INTO num_exp_div VALUES (6,1,'.000000550624150700285432940805295709861455424264970126953321538967550091614148982212874391026630805836518138806917934859138493583812313778188030836027246840794439412443826640206464415527687555214009725107630387889854278497875708390050387195108441635824296563108288712340902423706104029452615686971019125750530034798026103476074158922893374911891438688457439945897348811702908216883650280617098402133628688982793791562476980709924382381505517834196446365877784931355599480881104446907801805570471686295270927836995181422963320376948188855989986414581755633425437161760674162177776773597848142496583128607548351599750592863590334617838124741567654525843413232313914310487355539260264225486180000012813397807525203822863232682089295055713257835007742845010741137213301116647610033909062369843750685396196342928455'); + +INSERT INTO num_exp_add VALUES (6,2,'-994877526002806872754342148749240.99659316232359475297606895243958507460511031229368344962653674268847910587702140353344168594152240599109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (6,2,'994877526002806872754342148749241.09046730671373705476503023105513751542110329332278421699361618343639171319297340877148998204440427879109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (6,2,'-46696638263247522384986521136500.479312417066793299922708112595886608370451213741279484136907754744903470430131032928908162742687359367826808123516519335458861613010646992354378739165872253762686683966945711430182491860196341344982195078000259063231136011430995647812149294224699587849791008794261026932467933475782780'); + +INSERT INTO num_exp_div VALUES (6,2,'-.000000000000000000000000000000000047178744084866106587600962473825168237820701199970144691815329658682341685812472535816245052671243808078367856957579485152424914481414614360809698177236664771558713606961423658442962083541733004775309314926918118528217478256885324362912426275407382550929085958089798861918760121727491366034496581249711153289495601712583077918760003840368008056353090552282274780428335438032908213783490070198414584291402513547386013689752310173492320159738977752795528725029134841933604057954874523842273790958618375118974623107241366036640538085329921129023905888674299774726871808862832797230915933851225308164365269753526489223540580759951230801125605963901491073619448437890841032149898629231552019804656219062534881074125995130202820302133432951999011667568746004715268323913437054078537'); + +INSERT INTO num_exp_add VALUES (6,3,'-60302029489319384367663884408085757480.1853341682137571584926062805631087054017160819890685789064777236456590745415460695320768374693076860837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (6,3,'60302029489319384367663884408085757480.2792083126038994602815675591786611462177090630181693462735571643935716818574980747701251335721895588837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (6,3,'-2830400711649493468815157129316992649.40542786074520931471973065281957756940496588853021620372179463538053123396140685749478530925306163968207226329985017644835203709485594362663495728106061878665324856417118064730721101615473194292620972173690618491026470353143141125614124440035267592258385099934706896692953497971326605145704135723011753705907329979207428661473172503098296622281647255008204864404416199384701720347319806375450632245634238172654086373193251877533131784268854289406126119630708578053354762596511353053106459297339360827562281168219966099848212'); + +INSERT INTO num_exp_div VALUES (6,3,'-.000000000000000000000000000000000000000778366376597400971124059102619954214055884926284646546105035591052258074563706355894551049631537984053410850060739107742208523938741961208742831871056600773325053133977559789796700130019975964192371715826863472981072974742704091801166438465082519558956925444635729210849210496466189037623555622901738570979273502405907969114110345815802999687171113749364073269902319653450479463404003706147915064100959774312307195946966281098140229199529866429134937742584938255441169541436021827079647129394362379406256722903991353136733939395366152312959281905058592776286736536360235356737359904478313225848562436632109470589310799000750518904145312512621838935796912993778920622238202744037977772169066929474233952081158212174549695244127987299282384885288897893503991509410567351494'); + +INSERT INTO num_exp_add VALUES (6,4,'5329378275943663322215245.29625473207137544719284446115519970394719946335145777492574745992986971075733570324679065009803281404581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (6,4,'-5329378275943663322215245.20238058768123314540388318253964726313120648232235700755866801918195710344138369800874235399515094124581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (6,4,'250145412892811547138949.592621291590152419206270097656346630226508074074623894951308487425470437268130465956063593951784820669318897182831355375451719125809800516979013437732298382708070979871283132689492336823087794373113039154669229889503700598930220858275174342776478898670277868700384853696009897221747924643343353942154528501454689084608965009561564638167714973711022212547096732831847202912862290958304510651828842182545311077713664465815992616213663619529378061133917572474298028065850515876361609671565914027186063801852554353160801534696062207299890867876199323530337336273950892723090754719547285920090419070001019943385293110663922226230169381423410428577990604776655422105400452217085311617728003688836185608912367677734364834577573255789160419371322775733777518997638403409000055707558465286469808848200141192627396502735'); + +INSERT INTO num_exp_div VALUES (6,4,'.000000000000000000000000008807232244507937251856465017967626593430084223212999583902527587737263981869382895220711835510154989851222501080395520249593128253795609198666884523792646863341248402687314509176781281863891589925961900674092953408613128961234166906173266411035009516545964362406728942021813644419154548354247112601793685146960840364604115937119024575638240439041250900118977183124605578660115160551830946251713350556181960983267689939549506518185340972020820080460565392359379680036788592213479105831301723237102710863182596413567756605711230290883888612188805367801369264231165178487334557824054205160222371548005742602736713668548450400926514169967213301919971189065307721110805424950794015852531342286935114651278691214233054575660712537044810163930633456573860895791198853393107188289695511873068'); + +INSERT INTO num_exp_add VALUES (6,5,'-652755630.38762364608541718463145771120672223443489913059334543712856431450577465795351472116052777583325262472505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (6,5,'652755630.48149779047555948642041898982227467525089211162244620449564375525368726526946672639857607193613449752505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (6,5,'-30638438.151446159804025029882398388155309149089870990062944469684482366692824338098201222171115395923414887930224163525189097571163687285244255335505387733673499447610577050114902372990462064696637481657064525319516004273769831260452832960893174173254560250804003884280384718123289136453955482855362019158401218620018346500189769819687260476334734259702665316562988639223597110627626759216850014150105605927773639897638043177685498804811787888811168524202700283461266793154726325540776914500415140842975457394524215869103737379109516024460317825645645301237375972914247141703084877141866316168268901439172491577729880760950895760711857112463508064820414904611059588717092145484656103798852859978690742216940980929562068'); + +INSERT INTO num_exp_div VALUES (6,5,'-.000000000071906039575366987930696117572143566208825430801491864851999044659045681114433294052065377679745375399878664822361548237094424148992770296383642432040129230180142339557437679166815114510467763288057917694948929009212876391059413439647163295629904270262780935228234994930653489111444964446097124407804311494588517082748514970905563707392765567625639455978464081409330528324962333492925267647686759704415549221137291475247571296491073010175087298752769122449499990102435819414671847617062560524758344361194566796343756743243766853291113852464023843527189221162680613675369708907935197867458588904367993736363321133720345058432019986643353417257503619558797249295232894674255060861358071309619524800424087896023710729815248847792174290644245138831518072176198607255346603270853333176255533974364728342822'); + +INSERT INTO num_exp_add VALUES (6,6,'.0938741443901423017889612786155524408159929810291007673670794407479126073159520052380482961028818728'); + +INSERT INTO num_exp_sub VALUES (6,6,'0'); + +INSERT INTO num_exp_mul VALUES (6,6,'.00220308874624532134736695825088747995945783791378828770826401323533973395137378460250799184832278118133622563295093909508983301127615815865216895482784469538070133388154961402881325731054433770884496'); + +INSERT INTO num_exp_div VALUES (6,6,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (6,7,'-818934540071845741.9530629278049288491055193606922237795920035094854496163164602796260436963420239973809758519485590636'); + +INSERT INTO num_exp_sub VALUES (6,7,'818934540071845742.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364'); + +INSERT INTO num_exp_mul VALUES (6,7,'-38438389630389612.0042045464692275627184627672063157323631169405883031379129843031477339360597564128205768842448328088'); + +INSERT INTO num_exp_div VALUES (6,7,'-.000000000000000000057314803440765029050667129936880528769333499793237773980613524885506515999851858649385968476426313207429914995755091541422893944525222307473169425244462149015717526718376299808423552027796204632286454853167559026787019718806449038446612978917236245943248168920696452018925986743620392955122431521581268518101342690974749463089739042586011924590503136498488946387508310209984849243014542648765897536338824721211252335866349509669538308454367849024503312249951727948786393404944555844863805495937835281927012430439403132382055464307180153473189842433614777883826783689904293115204700185380661601223693428304020047393499702811581067120117405280772944184877279069842269329959037186324135435468322336398566440055479142909170224780318371473684868152271947368867666706912563225912012901437076773416'); + +INSERT INTO num_exp_add VALUES (6,8,'8496986223.68757431572672621257436634648368772473081887846765003074279255322456188404621827857612554765910678041003765241409149793494330798800'); + +INSERT INTO num_exp_sub VALUES (6,8,'-8496986223.59370017133658391078540506786813528391482589743854926337571311247664927673026627333807725155622490761003765241409149793494330798800'); + +INSERT INTO num_exp_mul VALUES (6,8,'398823655.819545574205652791249227663407026876411660299394659390409794761643751582473390322547798567169668246138880832642141417531427935520467563318363116897177899262525720710134129529640376020947774470933902793259531840625444267816319963200'); + +INSERT INTO num_exp_div VALUES (6,8,'.000000000005523967081937952184172713994498918048454262874017009201501812494019618863622631634736130436187167745347383745890248619882896153083428308074678908731005176810208100004498415662458272149380846809398637385270265351808328466537502823071145089961996689711299405627596294988646826454676198092260759424935699382655736524042353938814268760468122584678267125994645166955751211397353140569987758938572953312303398024147927938612934833827734142292697389251052485981023756760420972614486278837214553818521196182883489483756785207650821722660455451660719560529693418375773124813290305501923899840247103166971466167032437598057958226806335324315214908788839919408525748236713611579486768218564733151121028172253396652755590051310396973181595992981076269789287489208817712754098019817792758730835341151711523474207'); + +INSERT INTO num_exp_add VALUES (6,9,'54863480.39378734225015137845671346015520435061071252892396685718794832880965812803098645730572474084523997120024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_sub VALUES (6,9,'-54863480.29991319786000907666775218153965190979471954789486608982086888806174552071503445206767644474235809840024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (6,9,'2575131.137912978352131546639620215541477987701194164886305951830806120142596646541302305984776928560906754259789485960991272272782091464270104432109904222200473616116525297615725803495463468272171161659654385929185160689572943852767523792651123455283534072794326647404332228203001469884016996499768656263775233430922446983838511590562929268821678518640501686017030536100955531423152839988008496919169395159653034847677470665418765966542111749439412'); + +INSERT INTO num_exp_div VALUES (6,9,'.000000000855524875533453524582534418967571681572635027972658867593464437484123442242521660317156546196609749230372398872487667521984251509483676665788527375343148382604836976332389890799079878151841905152004537926201190193814594954194044560537664560344224646197027029681984683465852110060077865421064400958821808374370779297676624123638191407441015008434084079839721156870032377372497814037418047056438760664237367081226979226606227037631073946209105678283624370820396871058367779887709720661001099338250009251834581804647326512873792849059661525874160414378459696930831877643599421297749483849526695657467708603491876916749718079725746259119898269814551222336219537198318796277931946529242436502235147453584237994498566122973953203597470078105606906752099294162422474758048436539653041606499637623370030079916'); + +INSERT INTO num_exp_add VALUES (7,0,'-818934540071845742'); + +INSERT INTO num_exp_sub VALUES (7,0,'-818934540071845742'); + +INSERT INTO num_exp_mul VALUES (7,0,'0'); + +INSERT INTO num_exp_div VALUES (7,0,'NaN'); + +INSERT INTO num_exp_add VALUES (7,1,'-818934540071760498.60459975022373923760152136399214017262844141729040109985386964272131706381326192223266583769046276181472898406504104649192224392653722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_sub VALUES (7,1,'-818934540071930985.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_mul VALUES (7,1,'-69808760806266041400340.70700818693892852138813934414383886494691670042143650609934777814995087699409404201920249076407981012095999320858479644760715204999741683528746097757549835956359129287002171391961763797857794730120426599135099619822532290339000466211195776337667123320942107370731349851576864242697412616810236323676004067839744992733887503405311090677026008324895177587064547630828026123718296429295638934384446325302964896473296829265805737112709269803814942537657996725913938408781715328945194948010970'); + +INSERT INTO num_exp_div VALUES (7,1,'-9607014551997.140858001442365669993007297071681832468350855627077185145567261170534005832165603932891201648027598773639089125980996652005412450490063683624648655909636499261774535015914730479401090227915382926027949990128880284298688443593909017437720828163877690126019616194376778317148693270900349151496295698078575648169637635898560612738481294674167553369445426793073304518646116539082953755973571046622684332425840412198776081251646424875405772676893185726872613804612566569794177506268399878105117763696990094108960076591684779180089885283939385808214239337829666227427148603057941899878123459708920227867371285837642561064461118016739395972994827327543594846953341750907541716807985738518071480209106185726125017342997283356926976052909493074301401955202616191210810331245427141945840542129607439703255628683506772979'); + +INSERT INTO num_exp_add VALUES (7,2,'-994877526002807691688882220594983.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (7,2,'994877526002806053819802076903499.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (7,2,'814739569184924399102711674444306584731316176345067.39834031417849342571224916231092924046722938910652929295271097903377854123984307101079073134405782275535446337229706620713104545454319555885847481531722101704765783025789147453570970090'); + +INSERT INTO num_exp_div VALUES (7,2,'.000000000000000823151110229758332661330617426417726331211894330147399760458555778324097596176117291103184653828305857999638466183347321835058943563347767579219763002258622507889760416640758842509635599414768344140175277742935564567127659688612699366182158030839083982896107176174766408199870924563237827899202849733606842856491701660599599211106794572237923985121475458446997860253437578966578617985764298513928307852082168209458400544457824307270777530312648199364084272310536024283945598340590403612752287693234647719354745060851129534452514828239800716088248915975054881011343555492596002595181046121935660176097475159074973635534016835214952415720717896518544064238656360099884889450237541254761746029507300068198731306211736696956568648033834554273602524147075895460874922913883751452403825099444642503437'); + +INSERT INTO num_exp_add VALUES (7,3,'-60302029489319384368482818948157603222.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (7,3,'60302029489319384366844949868013911738.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (7,3,'49383414785234649002982046297226894664526726187218771083.0993243619030008310875293647868815940421844461627295157812843657782639833900543200310573708100000958929315945039020410482966753145208427035917753919085618457760620513481628641658765820294863970581642745379331727722585319163262763708386199720411053619449096019862596221607526610103408936214184850115071874430846697061554769773328338028749631552202705583855831155461651414320570061181212214810086436100771547030013079997847086'); + +INSERT INTO num_exp_div VALUES (7,3,'.000000000000000000013580546907080371873577430837141172674171921610919544849037647398734065712983603204704663262116138799357430947986241590690589753181299773842880079777640016786921825609617596862828930939366173224366864448436461306602680780407912534492687474933386043505172346330210659476505435994582446405414027199938970759003336829722057241708213838318628292667946636226143164221380503228191376939596663443230082698085439531600756771639601022064620204571458766303985028143400866776954225590745596639602613498355332049777798367675438365442468743270334407716567057368347458892075084694158566383133325959042076573734408841629149903649365079563374278550978052491499304166424686842598833319515705663176855033865872333988551611996194856472662292344160194821687681312501127516922809221030420253714666026321243515830'); + +INSERT INTO num_exp_add VALUES (7,4,'5329377457009123250369503.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (7,4,'-5329379094878203394060987.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (7,4,'-4364411947278810125327066890819882483326918.05664098958260550284395870948992407314161088028674246708928421994893923699743452802989464864039994566042797942433140378990308345483670828497915478397481687305406460330009319949623844175096007381662809083363069100235985794575399268709260901964834244796150883807308976949196661411035264619638771824190014274817662519438658481432363824187693821267613212631153175155634316128036152465184903927860719447693468054624663668062006049759837326188252927823612718163916100588143128358998656306593393889422386501730237442526450419990376323903182669190482615734972147533221144682538647497701130447816148459762464395194383090936159579764712919396391813914821973715879062992249315474841639591907249142779103650773383644785606333916967894'); + +INSERT INTO num_exp_div VALUES (7,4,'-.000000153664179510102140733858340480800294287837601105047285453457000254577644933901525444082336054243749405512900867540483190494113677173628646221933766421338612376123824684592850465460156248403574333545090544920568230979754949827013129083778435107488003838746926270955224758508832133483591156567868631938590248213604979638895901933775098150684618378235712437137852195098700137765601802898366867034641606131280434771339920637353140131159441790904703083143627590062236537714415872864218260252838432414759890832271190606933534662897006726154587341385852258168335058931957995901987808602365467861573344491265289043037273815504867254228957776127752540924854546837197432384563153608878864912196453587628891285275067452280357349897203095502806923463147414086919014592380804424300739713935051357374227246098303140106'); + +INSERT INTO num_exp_add VALUES (7,5,'-818934540724601372.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (7,5,'-818934539419090111.56543928171951166447406164948550154515710437889210417918789596512026903838850927622044807611530643887494456379304996563468607210970486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_mul VALUES (7,5,'534564131989234694540350103.27821462973515555648644772098605028371173048154132108733819196629002548296868548691993248746628993380136454426833349407578676005545111508293942736555269938962058196496152360848131645787941032968937794930046928523006455386861100809286408671908320322523368135203881520526880998279355848280412933152306299256343179622513731096363088094541514890135766460631462465021694553063366717467560655272004461368865264059368514271105464855575429914212085797297268595943955105608543373940035636033207568676745293499106348500559628723682588033431457023964317090780615020801564861497990103549650624438425421690193862533733474254'); + +INSERT INTO num_exp_div VALUES (7,5,'1254580584.048971438599349046867230181719371038956756285986415773300837165755558702217197735811549684202279755101552533605390208155708695952004683670878589028717509749282693444655857296902117478518511492735290086040573521482737598395369632843374456793385511847676556826348943588519880411018079886373631771830925920986588708409208527042927229627786932908015502292313887561198156623702404977221789649731458241770690830680067801377815840764873662400590343236662968218256211697981048576328148435241545372543075051594952109757428031762469834781538302930957095080167901199455226976113347018972534334210416375400979738414416582588689496706548495076287263281908191770792203069614447622517839588243746755480572371988630084226963919158931419126724681617069720048557166545204944250492282054791996953359013543036918134163144772567093'); + +INSERT INTO num_exp_add VALUES (7,6,'-818934540071845741.9530629278049288491055193606922237795920035094854496163164602796260436963420239973809758519485590636'); + +INSERT INTO num_exp_sub VALUES (7,6,'-818934540071845742.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364'); + +INSERT INTO num_exp_mul VALUES (7,6,'-38438389630389612.0042045464692275627184627672063157323631169405883031379129843031477339360597564128205768842448328088'); + +INSERT INTO num_exp_div VALUES (7,6,'-17447499423661151023.558342555162228919125358089491573318627107322332520978657843895009110781773496490472817700487707134216424855867015781267287628022535529641238372370292374146871103236048507252055787621394728096799222976387108688980537900309311204203302960751747509648304056939321473462375648710590981564101023812800603438271190184064874290215309040519813024962909469701968804925443161094255632624090623433640078421818321246597728308302979223833487133268472455479442002005374793705431817866798804822885690193667521606781156962792120052947767160957903073698536973292205899421787948529970837601521657406211962967291912148632072929662185840265855612193255596825032457033402506154930851214421895488796227471490998190312007513478459049382774782886773158311656817014322925167278223360446454868236479549745612973293185989975394307678926'); + +INSERT INTO num_exp_add VALUES (7,7,'-1637869080143691484'); + +INSERT INTO num_exp_sub VALUES (7,7,'0'); + +INSERT INTO num_exp_mul VALUES (7,7,'670653780922685519356619170643530564'); + +INSERT INTO num_exp_div VALUES (7,7,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (7,8,'-818934531574859518.35936275646834493832011429282408849567717761204690035294074716714939441961175772404289860039233415598996234758590850206505669201200'); + +INSERT INTO num_exp_sub VALUES (7,8,'-818934548568831965.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800'); + +INSERT INTO num_exp_mul VALUES (7,8,'-6958475505053954666339703437.48985528725312694198056665033448258303533387675711770743843194274181580881296671866212320171337132096489224277825857521033238709600'); + +INSERT INTO num_exp_div VALUES (7,8,'-96379412.478435590945480884955616049873645089637121682284625533034225619945532704111492738646389632607594293500930307222576571876059094206480673293295865214240456906965855425738072430281475736130342229749511650392658808510082775031098547507966544723255869156056349218776847523349173551313282283869146710349521487706884633419341568648959204688757523312579312713453540395840470692533267158388401676533369105590789036132185107859069994833345453200014884023709597817280132465224778002071890368479648934317322270613208789859930618055792958996389145963056607200020526949699302565905917600478429628844015684879886549766473809801710003649193772354147104446894109928903223843036925147624639466770660174828940577089095480826473544099693433597812637069287644606693066736302793687011165899362920686114156254982709172925265118077531'); + +INSERT INTO num_exp_add VALUES (7,9,'-818934540016982261.65314972994491977243776717915257186979728396159058352649559139156429817562698954531329940720620096519975256547379603654362598494779213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367'); + +INSERT INTO num_exp_sub VALUES (7,9,'-818934540126709222.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (7,9,'-44929599044588573810654775.83678007633232843418115790847152455559258007804727916986432256198687661496804050903769496933400455947645400628259699874770581538122521805603947464462448454681701547899144129061961394870320463199545502030106801911915987309444301341575451240764927967432593181449618816978119423290767783843864768557371257918447461479570164065303599994081990686'); + +INSERT INTO num_exp_div VALUES (7,9,'-14926769772.797708334489652004325241753714626257641081061212878627972973992233480868793527325656854681817156284203427388055525855608883067129036717726368707982450450575794623567027457808927082390474261155500697096284790656757163047499531247323702909360444831707029353441147768321257650234732286165724178549576948957405037843360446785505536809409054071975214796532504678683693402401018726571884721963641317944453797513145055081061680091585467186975354801535734149952115333241283186621720677488342266420359417174224757781125498130120775969091933838082305123652811689513300403051544682523761263183781206840940347226802620226164265210810994106136738030959199259066517106713585343004140573604437146025585149934286364795122716971496775012412420105368351774715982565252533025207453326002101655121126631180162560463548157187175671'); + +INSERT INTO num_exp_add VALUES (8,0,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800'); + +INSERT INTO num_exp_sub VALUES (8,0,'8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800'); + +INSERT INTO num_exp_mul VALUES (8,0,'0'); + +INSERT INTO num_exp_div VALUES (8,0,'NaN'); + +INSERT INTO num_exp_add VALUES (8,1,'8497071467.03603749330791582407836434318377133169438097066269854720538319012928851657498035372443556191720308219530866834905045144302106406146277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (8,1,'8496900980.24523699375539429928140707116805167695126380524350074691312247557192264420150419818976723729812860582476663647913254442686555191453722107164485675679551050629376558940966195135841284978096687306110481009743118940565957556492470398904849289222365256698601073536111216152709126800604695001949246634784573028721762079936564434050796321975774729383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_mul VALUES (8,1,'724311956372274.0135050255361637906710330203036651743488213007179039756514944640108625580172737414192938789413338554327986697518463087452612658955180411327002900979574347739956600177846996063741787205122007268468674386396156638261992679442768654367111433834151087792255469957061758837789341439211010331332174981459471333376067541234901538285101103690622656631026001337239036711179989456674399137008584021283568040818388709554256523118702728176420022080138548890713013682480239784198421500241995499841675772793497485550923152267616622892846304530712344886979674416990935007952941652591352603797627920865960622077762568060903908151958000'); + +INSERT INTO num_exp_div VALUES (8,1,'99679.115123747637190903598543851248555278745675862923884476564848911494649941770503156134872464666625927195645517181131678518619856156844072856993813601495176097972982587061507650426363887871820112714099226501603733968262566093655417466145183587899155614471697804006772915054739361437054029183182533671508695646413074668188590846200362324428338974890534273352188276373478524543505805545661569395314989170104140776362043880099775594658817242753124957385625811310332354760117110779649164022618274859298031549851269619167173746259018497289174255201452265070501056913033329291819570027877856677145579673495987354805150868813877928857472561883332547900866904764950837506993759536410161752469488392566682723027340638271076406246129989851281210810196699482980833204884400423019400653089825859983062096326294783573417554749'); + +INSERT INTO num_exp_add VALUES (8,2,'-994877526002806872754333651763017.40289299098701084219066388457144979069028441485513418625082363021182982914675513019536443438529749838106171095037135009526312783302868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_sub VALUES (8,2,'994877526002806872754350645735464.68416747805032096555043529892327279933592919076133348036932929591304098992323968210956723360062918640113701577855434596514974380902868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_exp_mul VALUES (8,2,'-8453460632655529853033389979024265783461224.3195241893307807116624750282852146303290708492834695194274289713076935297734670940696121761483641291930931061232942894577813178566088927221374036301485916497770984757492912292002695944367308880163698595015497307574177176409203214324418237020500352652934909632442547242092296504047310806151851207329042221920888326000'); + +INSERT INTO num_exp_div VALUES (8,2,'-.000000000000000000000008540735921314463871578184793632135730756619558669911183806487803411545406462244216408739432325839683804021466133071768612386706692296158696852363349481716813410857655324486448455846562309041306880675446880859847445987588059144788756984750993583865748280824370754934966494724951583311563735533173023858438364336214213295786266815116844775733072416507474834701984381586060478606371028156925222726225495235702395502085206072985373035972506738983640539009567237336002073370431753469632428303255926718930619221521257726366850472572830063284204851204189447233044832163423057501488364913539948261528280564870049935369825245920984413480757133585498984374354957754078525161296201228031555280486615145365039415418251448980923331334883673792135893857917681235883506783408111446970710546686739582471'); + +INSERT INTO num_exp_add VALUES (8,3,'-60302029489319384367663884399588771256.5916339968771732477072012126949734214868901845505193155307646111690097978112797961939995859130827784737422228762767014427842766445950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (8,3,'60302029489319384367663884416582743703.8729084839404833710669726270467964301325349604567186096492702768702209585877643481082023851284144664938175277044596973126708926205950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (8,3,'-512385513828318260570283740065493064477880918352.732624553690077857674083796435724202494963885926573907185100543184828131859183999195040110586155435203949963570735841632689374488877298209082579317039061893012560130258753218955057387206477423088065663401594359617882154814262843273526859406265633827109554791772242178864873774889091687515990672487380368975556580539271333144212685871370972163560839446696514092637412587953506052848750866803569213269271165856310101244342151576488190595936869490659700946174362872797854591188391982770203203644172999264143929484089237665313698600170041324566984832357000400'); + +INSERT INTO num_exp_div VALUES (8,3,'-.000000000000000000000000000140907135225782279761112255989433531718277338909398600029580768021365259747075253760824424092983497958717844671162530550507041138147836569244869107757945370200122955794509365120853536859837243314494576053441804831018954867623755033888264275704547752628348151132333655667171970175829826792355986148522268067032057293494927558322394395160508723637192234110428953945018965078022622950949911124494740703606109543716688008516750321047603009424529696862953094999450658951089435460411028678817795100630449046993274191915359520936265372754315076684798942557329584282177053819106884196674660057281227248874819417305259132106690385871316407455034281900110779740008476645291647094776093567400422266906817555937149628005629880142615126571231411138926043531449659320501743591992888328328980526602'); + +INSERT INTO num_exp_add VALUES (8,4,'5329378275943671819201468.88995490340795935797824952902333498786202536079000703830146057240651898748760197658486790165425772165585380839129948178510273188565692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (8,4,'-5329378275943654825229021.60868041634464923461847811467151197921638058488380774418295490670530782671111742467066510243892603363577850356311648591521611590965692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (8,4,'45283653791262997781451381354094822.762732909505051438036873220502792213670540454778361182993875916509061144859281577740137081988678361247725064336120451090222456518107029158304937620179032477664627949959143233370320432203497828243297406462513350790251761540074946469824444452248386782451723637769289822576372357189700319768797708375563651655860093365309717823602754924352327588945034832436331911584742966378275504545736896430718939807674966738116698454215555860047859161126694019895490767779791933882712567492115664113775047192011252893773389940988533801360010782816196288710063568554147458866942816721046004257953642508395867837127678980002737669139369781058046396738606563716339660654364541530532834806205571191828994250708412638796240377704994928921528330863683630622922959130920715261879547446054261914770022377059156125037157979236658010950'); + +INSERT INTO num_exp_div VALUES (8,4,'.000000000000001594367257057971052149628499448029056279649281098852958322409409919964709324200796473211884339143791758566019217634542932882694487712398244322522748736692741288668885362384266615527166964187404128216235057387796054457728789109537338988453837993084016408244895452291151218602815057669592284587317035387004942691671916981967449109983992675125005085762403043329820872839739877674121174083273716295673230993049263574856197011389828478636779342320299895806297835595427859271617831720398457416685435560152182883615601663820189195644140652141180949257192740185075408019971747810015931542757445763460947106918998459997631117642552273815713467150465548031203738878873114842844016176922502916339025283749846225376341878386377192605865913018132981323065698049618379727531925408677611856682983907951667054819'); + +INSERT INTO num_exp_add VALUES (8,5,'7844230593.20607652525116672615394735666141304947992676684520382624714879797087461877675155217754947572297228288498221620714146356962938009770486619898336249374975146736655090644822719838495585664994425117350974491367099004404995846913641329458537237789584653041949090121498951516476399288513593944575192159570458664608461677113504914551578443229008454218964701550932948083369656042643364608405637360180021322967144409944099438498649645368196191999692949583952927486593144959284443545794934667002661774373364219852712996869245745722896071593910890197478196462961042627387162830776094709087748993678069776845437889735782063'); + +INSERT INTO num_exp_sub VALUES (8,5,'9149741854.07519796181214339720582405769040995916571800906099546787135686773033654199973299973665332349235940513509308862104153230025723587829513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (8,5,'-5546455599206321494.0676583421119904300307105296377723816472192007866147764761501865875232824814135783697976183493106885436876081315217834621720906478074798596116645640251460842350553806256223963023430631066024389364515688765194373161385579258482225808660340732705687558150699172147896486727530192499184101617379930846663835628510376484675411350654979679181852179924386290069790336316958202582966248703889464308649631486542724072047294216362186036638115240070658004553260251510288423749333873893917690832829128021808383128393431810674177390352413548658782609064839524756041501835115152819802758773711821322162752064589750295542985780512921839490040396053737870038534216948323935020460307350020911362024271167085905714873548388570602799432705061561572854498075600'); + +INSERT INTO num_exp_div VALUES (8,5,'-13.017101389051085341042057308965769356145255575582875626848796382322826525772114256699384710400140437710569924703769685567402446691691210934185000959063158239023412379691360587119206695513775971704926722817528818197919265145207032750407924774510773427697188520818450702875142190949766251178733262143962213111236591970766836685919581025629742334704854852196126735685421250263035895756028805974153787560164935038227108975229771590754808331856162035119882347418116049174638416621093907738608991987582465865527947015457540650512339263071898410531735438556948115098562123055444965056347091625748703503220861221718449714020622377233272042277814766996198081939221253025243417993701684007826177845003391944496774674489538520354606358872276671998045196738090133576377830721671972381371985771591052597345572374064920279182'); + +INSERT INTO num_exp_add VALUES (8,6,'8496986223.68757431572672621257436634648368772473081887846765003074279255322456188404621827857612554765910678041003765241409149793494330798800'); + +INSERT INTO num_exp_sub VALUES (8,6,'8496986223.59370017133658391078540506786813528391482589743854926337571311247664927673026627333807725155622490761003765241409149793494330798800'); + +INSERT INTO num_exp_mul VALUES (8,6,'398823655.819545574205652791249227663407026876411660299394659390409794761643751582473390322547798567169668246138880832642141417531427935520467563318363116897177899262525720710134129529640376020947774470933902793259531840625444267816319963200'); + +INSERT INTO num_exp_div VALUES (8,6,'181029319177.110996740664566780784253502559986936959009611748146099327460471609593148344991059106574612143724330935988823134137686051475120980257829276671900076859337187540608483895641504622910361858962883971613675309676443079313179200981488761707281247447120551917205792352229666049191991270809865110506639390610910481490688182068719005593641339338678014189749279508731647492051879768743158839680867283217578754666643688259810863605002821607490100820241093473083445658378988069593782353275713240897038366242558466047071334385431080003439842348547427066389352198560236731403235927478177780757802759046212921140424771887928786549573201311120885052685761195784207710933764480136690216943336587118385525047554334029388869436622866247240903231799829259264158812528305210833683370536416861544931420820452512390255774498188962903'); + +INSERT INTO num_exp_add VALUES (8,7,'-818934531574859518.35936275646834493832011429282408849567717761204690035294074716714939441961175772404289860039233415598996234758590850206505669201200'); + +INSERT INTO num_exp_sub VALUES (8,7,'818934548568831965.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800'); + +INSERT INTO num_exp_mul VALUES (8,7,'-6958475505053954666339703437.48985528725312694198056665033448258303533387675711770743843194274181580881296671866212320171337132096489224277825857521033238709600'); + +INSERT INTO num_exp_div VALUES (8,7,'-.000000010375659845651632013446652385870617923988120764298690164486716047614260682259722116360931978511176121353975789418625836899338225571166376573732227571704071000348895791547943896682585450808398324252224265156214259224488248639550967292466343168350213394398101712526534464002532408445204630441167137710565437434313424987517531891145368203998329086865151248833625645567863740298397742783405267970015165358620026813812552194344790169289440822038223606218360105618852154152168496637886434061050281055613760360200323363465925493033734895631921307644481639236601187225135325401868178006133838932915485272554505684060229409404902185944047523033315868230944723282246159741659387362889777495094736963530708159604929268812778894177095572578862150793098548829744006499229853198046828954650334595737117597239208825268'); + +INSERT INTO num_exp_add VALUES (8,8,'16993972447.28127448706331012335977141435182300864564477590619929411850566570121116077648455191420279921533168802007530482818299586988661597600'); + +INSERT INTO num_exp_sub VALUES (8,8,'0'); + +INSERT INTO num_exp_mul VALUES (8,8,'72198774884738777393.8687539247642452953425155400068591498151280875559609979248583367700231031634872342122563819478919600402159024059794279536786611373504966204744811722007869415559012475160471227957857756325962941799428857291371597146319816910515366298862558849452235442246081440000'); + +INSERT INTO num_exp_div VALUES (8,8,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +INSERT INTO num_exp_add VALUES (8,9,'8551849703.98748751358673528924211852802333963452553842636251612056366144128630740476125273064380199240146487881028508694029546139131732304020786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_sub VALUES (8,9,'8442122743.29378697347657483411765288632848337412010634954368317355484422441490375601523182127040080681386680920979021788788753447856929293579213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367'); + +INSERT INTO num_exp_mul VALUES (8,9,'466174236688165594.9218054325256670866060556227711696100465581464881295978997280335378678072434776702952026828137140986670189756965420183565968027969700090735690246176791371115610886533930223141650377886909408268207750238603105232560663571044993507074695683027062426288270199495225881785499139012931143826099668999261931834700467395442768201666740663642498098541516326470052372008385656719236306238735524802875519713512894448940917708118676095378518264553310312628830009314653641136566040400'); + +INSERT INTO num_exp_div VALUES (8,9,'154.875085756903716715488911525453064308758123952566428258639786597308109810869086867746263482721081985848551254298524280231489145092826397833394044637104667137816928932471315095067524966582810436282901424423215992139000153713476369887383242289102867530775908269805285313842050961754114751975054515055089553180717444020378611767296609130477264722612784088270193199394531972594028420402254831778715196248487757266330454269044609134602570688339750190391651801546906342796660819535014295618246236706572780627362908121159003488810140236665846928586992082180006454824311789091323774002510945263351862712964422865623934112293184149374573706760114682326698881257123280119140924775171374360283137569618025005229268057970275164869735173660958715166148344076027212231446680947914004346760896298312286730627916684448923824769'); + +INSERT INTO num_exp_add VALUES (9,0,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_sub VALUES (9,0,'54863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (9,0,'0'); + +INSERT INTO num_exp_div VALUES (9,0,'NaN'); + +INSERT INTO num_exp_add VALUES (9,1,'54948723.74225051983134098996071145685528795757427462111901537365053896571438476055974853245403475510333627298551845046116291696445177112567064282766115207407461565363967417615506303416694032848457927390574251904212425813072768882213388082765916956736282110801611726537663292922699021333445658549608928179155685881583228490235606377831724593358583903616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_exp_sub VALUES (9,1,'54778236.95145002027881946516375418483956830283115745569981757335827825115701888818627237691936643048426179661497641859124500994829625897874508497095086558766563666622720535497438693688376602804651302002795213923698663694204683995198328880575615535181012624198813873609885725228117274934655048553507421448724831939026752650108735245933317237310133362383704426321489070979168993853338252728216162346796960170352897972568238870481118474064783391570102958474141459619245240874849766946530000977144965'); + +INSERT INTO num_exp_mul VALUES (9,1,'4676749348240.390309875431213992853550297086049749814750492488995108783145961719774217441193547534210468967573344456866203963659951312519988497979489304488948342258375915152429008993288817366720647491166024151209542534474867042837694499222928509320280684557676243780452100132238968233413333851595648146954975713386711764268506890884764704949969602122157394714663532141060559896359465918874990769222345665160127552795532197771168442486088776803398878354288847069602460071745966589164282641033852314335279121191855487126430176047553895892632834940595958394834437871886013513058514896870683979585091413977173250824451205330441299000850618134248917380244749589254309567551846327349592529960432446947239714236828401206843011440433362544797025114476612133622499094287321570559088587999417440664282418005102546343020409520421747216'); + +INSERT INTO num_exp_div VALUES (9,1,'643.609749344751131516972294140174556703217311736700045690413622699888869645595256683013323517984528456698303984909359393772036036540901870537096836621035845014213031549051156299974682317824766457362427063305495772666640279328909129870227828460705733995380145417663304348663705694070309475835826101153850359826502235923289787750107778906593010060115662191620280031872002110849782776325630424918493602259707267214006217268630948545349980430128422952869610116216278256812581821942763705098526140427280008360043829906543029486315209818099697988089748683904695870401517598840185535891464842870210715421728852789815860153472208176465166954851895457846723102438114697692610933532992841803219018495137378534010155991355251803548866919409031477821173935696065078362044927492034445482457329200246282082707380974745411383781'); + +INSERT INTO num_exp_add VALUES (9,2,'-994877526002806872754342093885760.69667996446358567630831677089993316481039076439881735980566785462673358516198695146576524119916430759085192883825888457383242076882081857926408611052522393579396644731758241837010163568445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367'); + +INSERT INTO num_exp_sub VALUES (9,2,'994877526002806872754342203612721.39038050457374613143278241259478942521582284121765030681448507149813723390800786083916642678676237719134679789066681148658045087323654637787610377226547625566084597844703238942080799221554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (9,2,'-54582443595378013373024060492546032003692.4875677735896411267274323339692558458420972958075073392126734000341372096298914875892612108329218081214550050039133117695428196702128258481789017059073444323729583900855712795086447886053552786449313809589992185978097430132940882612817775035217244553616977182049775786664446683332098226841743818600819221587510039430478859412452506872131851471967577741190323481953867845129745440745526578327709351120432530702446916035797432129052518980799424635406993848916727957825620638983706180841278402925286540375225365057191075559133035'); + +INSERT INTO num_exp_div VALUES (9,2,'-.000000000000000000000000055145964114074763360265614481666934002579974728749248345352023099030383962250681574081874554842623852433135871821620640200582985140388676650602814646133317791813938390695683843848260103199745295436998313216878337673674660966362155480524935736646623766057029148471463569162153009963312016563281545776175277904913263614668092319707343286073000287493274965714031678784835459999763925833141049057636632430975424499618419962303087175237320046300285962065818926167792812657620724550768858763098967149546312995222223400007044549870620849992226072041407997925405957501929449911416474388622107825120486594723448780503829317691081601820425151593487431389373265285594626753418140874747955925763163132984655078996173911578832035721963554569605730262976354029623260224710106409129114204296314733036'); + +INSERT INTO num_exp_add VALUES (9,3,'-60302029489319384367663884408030893999.8854209703537480818248540990234567956069965340942024890856088355839135538265116174644003927269495876835324407641642359213535695803871472434650475144516723617632059130297610134243891145006222068960999879308472500422640481972089756410157246974765071949782242392661524488959954348903412713930092273629207697480131360047867213863018127928853922173643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_sub VALUES (9,3,'60302029489319384367663884408140620960.5791215104639085369493197407183130560124286109130354360944260524553172025725325268378015783145476572840273098165721628341015996848028750420770651761919246816300854441592109844750954710317145008297946462099581451150385769713261452744310496166494545449824802407416426304041583975713483424241727236417259479541129474082301376239522310995725648773643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_exp_mul VALUES (9,3,'-3308379209762459471107480259839508279070920437.883503980178028214343751083865562028455061662673132221930429904398963590401793045470444301883103141901787466923883803951815572606105617157736442670792467625964359169270739534412932791178258858918086886061702512427989129732248215348301444245772127142869263635282888226326427510486246184233225114523636171202034558843515894542952126988613018789833835507734620046994907453602573865012044120483116345444810078666601100257620969379968264504287700045822481492526688635364586344704730579892342786173395802035361824932075736340405960099542224953439044947229246847140957298841482874444906129049023002897135347878048572628834749795298712449864571996898774444932083319581439741625832405434317985988163261591679157437224404970927012111196724239860528859217322132733404472897289'); + +INSERT INTO num_exp_div VALUES (9,3,'-.000000000000000000000000000000909811507365065002714756487495210579371808512079908127938523896001746219475805196061435010714649189975968123072269549018826343830061696154665503565341929634172463095299662727352635590451263034658630449260378893723785917860125051787451512267088404686342938118993621396641623525252649748977992770709930435013456855344203854749977414354164157192885125263071636468941596567220391082793700307461350484216679632552883058303710297475827456761138832914743429330069022439380297715971317819244718196187172770061156794130040674050533617155253444764036426045091327368023602807193742585178432544430741520636125146531502042579276206322507516332917325631822606079220413965396706334639331097621824106950192993127113903265025719013680733760540930122186345919977470628988674677630636632053583144327'); + +INSERT INTO num_exp_add VALUES (9,4,'5329378275943663377078725.59616792993138452386059664269485161374191901124632386474661634799161523147237015531446709484039091244606359050341194730653343894986479159670583937529516163204904273806158788218327396375034882788180783796976731912141525319602448709213495905899041406302673881364465504945113279286939663215197485367850132991968081639290297033476859158044889351836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_sub VALUES (9,4,'-5329378275943663267351764.90246738982122406873613100099999535333648693442749091773779913112021158272634924594106590925279284284556872145100402039378540884544906379809382171355490931218216320693213791113256760721925653394811317969065642404864072442190731745871963413981746671302248281216916486794296983018838956112081135739969615171358100498945955409711817327376172085836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_exp_mul VALUES (9,4,'292388240303165948041827159734686.255558469787242316676287235194652580157149226950109397295920730296960145548003120827363226435916209781396711693581454960342091452830648929118261388933297036933167543189308061917640517578583521401267417187854611829815212778183983326568586118831109538377828156118900313778053576483381085207892754728937946691892849474364477434665960112125254104966566712906532318984871145605839506991591027939136026602051635433295687547552796828217859648186757719639965988287173297286034098497871707197092627676226053609131138590878743560287292934815277894463305001278326023708395571840850120055316276256138004565442099731931051413153564744766098053176049414330146267604802971221161572130161432525297614616942172815141372973870720928125699420370428856022295499447755488148545048400795053604349570217878099721865670458104653570360'); + +INSERT INTO num_exp_div VALUES (9,4,'.000000000000000010294536718194523982241053267404812827031741197656209184880073175960433631103885281961037127283726462743623757855378209281373475473018922090781553213750339001555832360656399849031527008437303091226051008068950896796359518673740801770866360774945096397034708173365378527676779736929035450380795854046109380272505550244458858231227568118355064007614608452292270378691774826689216790090661497154742954386244856792006376222923780801296832612827123778915598893970651480451509706836620045721191411824060983487064555397842027454385628620582036592315345973096405447742002746762099231557054678593446667904250189208490698468539396733604833688133512716508825505666644390119877423938820483653319376926639295680552194966870285838815705038244628263602997511842285889300557188773128635554621378148419364876651'); + +INSERT INTO num_exp_add VALUES (9,5,'-597892150.08771044822540810796370552966707032464017958269847934730769542644402913723848026909285133109089452632480800168074607090893991283808726990171062867538012237270000932798704781608969096508450960185964292594677356241956277714380500188870696516251767979457838109804726539408115452577436052503866633026489282425086547752714324273565900641436632912781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_sub VALUES (9,5,'707619110.78141098833556856308817117136192658504561165951731229431651264331543278598450117846625251667849259592530287073315399782168794294250299770032264633712037469256688885911649778714039732161560189579333758422588445749233730591792217152212229008169062714458263709952275557558931748845536759606982982654369800245696528893058665897330942472105350178781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_exp_mul VALUES (9,5,'-35812445701642379.972368737320206275515144213236752803936806738624588812089615098329765811617509505790110909629109400553415312470540217508070421816878544125783329593128638405659896184248784794258084116406472768709113030915308410565617764394827427154923321461158387012978726512246146545834669665093228316853342805604075936530371665576147966721599968786161939347726656168798065647411457701453987215491345496003650288850096338695703984042549594979897253521041581573388369367579323607093487743440894765114619634001789457486407909224339065748496715380572175183589195611952939575073075140094901024063428239223964510824958346570603142906309198033196987949067156046076497974760641964978711558209708743776024313916111738542765749928287600981397080809041007714387564206594515733287925008053261840295560398311905155157989225181164097547541'); + +INSERT INTO num_exp_div VALUES (9,5,'-.084049034261605466896663277055600903951276881294745183935726262038673990196778002490449355450474227878560465916800470848046625257516764244432096856845087412397406701521972651300484716852035267197801389708234913163750232707469240634303111868882057393120649919262424619226282082184091177505826009374043368623853156698509808569378758387708910629731005691079770517679511879694426434724918004419953301426679939010592502325130576915399009756468717124460489039474155719834555522581553817856854607844133431854471292027873672356863673617090151801474016666978499651970627896504709551656249007718965259502928591648533670568214972768900993459927860068104745163979267716597907297073374689384723943955361288974065531322408839914599555769945298758102515352082822617428033648130099822033393662643586331479103933840387663729387'); + +INSERT INTO num_exp_add VALUES (9,6,'54863480.39378734225015137845671346015520435061071252892396685718794832880965812803098645730572474084523997120024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_sub VALUES (9,6,'54863480.29991319786000907666775218153965190979471954789486608982086888806174552071503445206767644474235809840024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (9,6,'2575131.137912978352131546639620215541477987701194164886305951830806120142596646541302305984776928560906754259789485960991272272782091464270104432109904222200473616116525297615725803495463468272171161659654385929185160689572943852767523792651123455283534072794326647404332228203001469884016996499768656263775233430922446983838511590562929268821678518640501686017030536100955531423152839988008496919169395159653034847677470665418765966542111749439412'); + +INSERT INTO num_exp_div VALUES (9,6,'1168873084.346566233232746391559830634361431940000227460271861554316197556566224118756340501278103405856646766537018954185964066240457859194626558143313125824412559635129130086906976028635444060218797992547370132082916380788496584864016645155338102476357490305222392452114945853620686975383081427840791892729407194179236897452655907829255937027286698570784397487382242990326347080472574546312522326038419753951437799831430690304084087684303035538181812523230890783372773953961677974396907303758903934808035747944477277528267001070234880092255363221274303820343225415479126819937070570562654065195009839593938440374000473302075568746771126391307584779249330981594640387657042725725493800876630516005713789705652827210295338592985225924959199657729900181287069808881130884115897407246324220524401243575641227725030779990490'); + +INSERT INTO num_exp_add VALUES (9,7,'-818934540016982261.65314972994491977243776717915257186979728396159058352649559139156429817562698954531329940720620096519975256547379603654362598494779213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367'); + +INSERT INTO num_exp_sub VALUES (9,7,'818934540126709222.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_mul VALUES (9,7,'-44929599044588573810654775.83678007633232843418115790847152455559258007804727916986432256198687661496804050903769496933400455947645400628259699874770581538122521805603947464462448454681701547899144129061961394870320463199545502030106801911915987309444301341575451240764927967432593181449618816978119423290767783843864768557371257918447461479570164065303599994081990686'); + +INSERT INTO num_exp_div VALUES (9,7,'-.000000000066993731076524206362744068866774567920404984046399050881532938231826344009126898802592302273719505485084766150904380671495128604515800845609713368334606489445184535043833069145643553083555507533900955661105251251918425885537513359541698046533092111969478225528665278023069818968531644884466229545497943710817187632203193468836772459599856856811131193744272314519908999458320275710240994009061040198159739169960258978462113813370513611735006229733329565083659159456172425715216475781507996483885669437855000029758892126410922067202159414570164537031153818197618428471046051340835826664787585016361564969663413176434498159140395476980277574789931364078570781760777773379636490084338326576889857824344578398580499610233575273027387501809967324874264742269453420400624883982643066864175851881870402856698'); + +INSERT INTO num_exp_add VALUES (9,8,'8551849703.98748751358673528924211852802333963452553842636251612056366144128630740476125273064380199240146487881028508694029546139131732304020786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +INSERT INTO num_exp_sub VALUES (9,8,'-8442122743.29378697347657483411765288632848337412010634954368317355484422441490375601523182127040080681386680920979021788788753447856929293579213610069399116912987384006656023443527501447464682173445385303315267086044455246361273561294141518329233754041352632499787199926225490924591851865949646448441825186059741089695009429827829188117479084665641367'); + +INSERT INTO num_exp_mul VALUES (9,8,'466174236688165594.9218054325256670866060556227711696100465581464881295978997280335378678072434776702952026828137140986670189756965420183565968027969700090735690246176791371115610886533930223141650377886909408268207750238603105232560663571044993507074695683027062426288270199495225881785499139012931143826099668999261931834700467395442768201666740663642498098541516326470052372008385656719236306238735524802875519713512894448940917708118676095378518264553310312628830009314653641136566040400'); + +INSERT INTO num_exp_div VALUES (9,8,'.006456816440893715330247418029019114736889626790871612141686117271826070935285769018710680035004320626745647926106882508048159628931624522666638442625219959259156539178378186912871506893482633695438850964052285542425753626455183282159259999492971992739484319464700978750304962671213318202670228197968646486740006148091321740497272644910882302412140576608739962605210964504469426861972705740810533465451230811358870068391007718532021526225893542801514255726272411690175555142385382688220121052891017808391607717500701760375927811435030512071347521837090721052128992926357375527600337655573639413811262412492632491693179011503973930804928749370652038245414768103001067902012962988384812280453070895781287237746786414435546976395632454474312533482077585837153357017362048554313154580576238549196250793055676215164'); + +INSERT INTO num_exp_add VALUES (9,9,'109726960.69370054011016045512446564169485626040543207681883294700881721687140364874602090937340118558759806960049486905240792691274803010441572779861201766174025231986687953112944997105070635653109229393369465827911089507277452877411716963341532491917294735000425600147549018150816296268100707103116349627880517820609981140344341623765041830668717266'); + +INSERT INTO num_exp_sub VALUES (9,9,'0'); + +INSERT INTO num_exp_mul VALUES (9,9,'3010001475769225.8286280957637941018500905354415197182850820227163907782811814730309044010416886791014702373809932926301368137684091094408663914110947072451332976891128659038142954192986392936981664792370678656287232795203974766040821110221158579481177539669363513848425151485663431478439528936592701070340012569297177488556353760756495238304538439278682066056721729656193616571456456325016960870401748115848423105783116854283646624807603476682295234280408938557209608025246638166902335016025467565869375885610813662767004038102486303756741615124814580306266901273803721191779461890468156043551004644728343579032524687612403663816107770451694666844862368101122025340182510019516924578414085461628689'); + +INSERT INTO num_exp_div VALUES (9,9,'1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_sqrt VALUES (0,'0'); + +INSERT INTO num_exp_sqrt VALUES (1,'291.964716019333021494947753821238960905461614737525349376826064492714634914263808902604580614735501799528494357560837535773816469841426747889103714048646989532842972129124080559131220979335403729022278994440514872845756198274805589586120535745968205107562348427941379641465378272611453955517402598409789621997041856848783989993820946766177453801729783316269310186191833995557234577548740940419224137195404391193633808203715191863638616433190672511651125299379882126530500870287424768024674231651229908224729856278167033444719242144302972892419034855417126978468296581589282861879645409909873113678361180607775255758820910366926076380306290306477790931129670172989289536405788838857428768869345763784112862591549008321546447442552533919976570125718481191724503352619626562352280522949665158335559389298720990302071'); + +INSERT INTO num_exp_sqrt VALUES (2,'31541679188064906.712574384704440356216787857626740375004266523720148374188511622980520374202725176835435173058936870163875556102907654264048353814040480579464700545975346621546520503928314632418705230212623378642743044255181848913683862360044189531298446109955034944189751302497670367665492719604026161836224535961347218522748523360100432275693829501972749859329753224444694962089604095212784768854310289429208671271394086829270986183171968944659703708706544668326267327938226750760690620258967209626420981505237183055363540806281098871221581265173394406715458619627534396065960117454160969749739483126059760636526242783235685190739315590041294766649891987044641492234243404608847939002062827210734973778130441825067858641461599799772535304379732674727995848518807202053316225824685704785148921785964036119338754973714515974054'); + +INSERT INTO num_exp_sqrt VALUES (3,'7765438138915239878.949520541017683429203286303188179443533225547096446554008374834292278237558244698868300666061834105683999048386497322007336816482648302911579331582895326423063492240235074387242190187374869842856897538718280497895072291181675294000739548676781615025944675912072664211455701112700937190832332966000160156597821149428032612782336278939437593991008833233156511435294360065004167893309428565243314846456225604669764879344135321428948841659419438769652686215993544390780212859309497190065178705035652106614050448518931820975038314187040226298661787490226917902356569717171481159691409131778764973037046501816919243659681416263730519167614043077472097520207347950292377914586524327206547377189493301153212000966249655331053184913579513686655963686155890934436604123384536027235444923674128269748280097789270784333442'); + +INSERT INTO num_exp_sqrt VALUES (4,'2308544622905.016172868282330339228589083058636874526727829838244942341440716909466939214393597311710652963849541394758298277969240038668406494621950956862959196896847352631445328917063551082418729435554972200530109505384839391233286173517804321019323644218483570886304028175359854335870835404627608254205407525763332087823548640923282031978903399118139052814618531713327991857575390136755426466065839913887477577516426991104516201265995293600539957187007068885368699949673989051443005684755994465547159213587471972139403333249259808344536605314911144950465968669770276463111776581675944967401948957460097365849699783091843609965345747287667911324039374314413430490112443463386381631812537639503425989372084906324702158112088898424705684574998783112519152403201231176840068666882123684602080460378627639651465436618032671756'); + +INSERT INTO num_exp_sqrt VALUES (5,'25549.082770905117529972076915050747181125832857399138345044265535151111965091602789684342996759657333588444489085160336703294705499665424408218434077722506748278242942379566431768762487954917389137120540138359870652558814224523699917122023018717544160579704907452934297025088008618627873220397030397424422097405152321366495319708580932627092620533785271831833326130796638935296720064431288560292191928489034307645738331451165431755179025359993690642194334018457793169983249853388987495489562746304107188105521296156525984787815685365255240654972150342496329030279439124533240114879332406941960563154881888172285475336782757262639979527682925214971861707635327995621436598536743180180978457735632181738067997521785965451385630326464388080990200265186437768409003553910194212076755448477164192901658547251079126833187'); + +INSERT INTO num_exp_sqrt VALUES (6,'.216649653115510782473161631235601739254284877523828136703593069337209747459679979369185882839688430004369697316986054374456779366220242645866798278985273820408495361607183119980716020227424205519727777568954933592987351750339481522149106749713967143685591960510946511796062486795368200503801097611436787402191532618456991115230272084771674098613479989808680789347124789253499967359190605681912854639520917409710307182238065185749856554472717209097115325999946728168357936779767099041518574001682560265549916593333117469681763348860131760281253987626822958726920016922608371657319505153308390495179319529587670415367205193280809809356733443291197315823747505896510820272670040485083775482983378341120809542502350385555577946098824446199419354197416933858522419312733314383889554606932774046771497129486979593226'); + +INSERT INTO num_exp_sqrt VALUES (7,'904950020.759072496304165474991957396337281699986101765045213964054286624338102141970514306010139529492299343393832200631760194440206005974547202512275476562767685193838576516154915404389465528270010938533075930081897392863141132529694804621418663424569202655893682412466871297412964570322984865326770090075582481194532433411398133265643849129084449161396724635797324126396071308557057830046688990212282866035593809633839882468628249964862932050189148498591642162462777480125024786829078066012617362076651920045684345679767223337287825546294839320770903419463644110383560050404456170063805115223954191445548226706113970164823214416171441655706141596091717118495955441099867737827763335880891937222647408575142200256804313345924443344596462585960919126827045197885802122062165934504665811115031150357820196176799560314653'); + +INSERT INTO num_exp_sqrt VALUES (8,'92179.098626752893864900181023972781406074846653380680747862421481598042923358730531575438403865501429843141967819802251116774924400485954931201776260931315313253827346015775662310076094882239170765060649024538403329505426563390044695320714825481746233901773893996663258170360232639353378395244461670781152793416950717050461856097473105730100523010642696332151571372764781034028324977128554099993021459338419164426784774496292405945103200724413639660488309795423335142455569853549710795692020963174011003447023610692365550245567840477105794884132665155376243735213346877116105595296043532605899184658904822980397411096930267453332143879534914237169761039374689145860503772331147367757318826885494994339695470190886515765452545019167989882527248872835783707554463866334705735781549392895480816605355996057201589681125'); + +INSERT INTO num_exp_sqrt VALUES (9,'7406.988615277484686670011157489572203134420118818648711986549881046321377798441006745317356200279801348355202517703531020643333388857073977704009782384103170022716610432579974132111487533733493986910583223121269323909760573942980360508642443245341392335557152177332615977623338526935953706604224108508582338123915133189529507760875123300397933931420500010248194253078118618381590347297853307090813639981736227771834732256867579490224181748450683295253634852775448770576585177080941820456051588076218688792321741398867304684922665590162004919486643750098085197190000638539994723704724550600891137853975703823903659121582583388450687255538838161486019214242094423895463814933532217776443473765708693285683261505695170847285063013324823850724236845500162436661946026097459146424122412596018946436589967013641971183281'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_ln VALUES (0,'NaN'); + +INSERT INTO num_exp_ln VALUES (1,'11.353265918833698201334218522735144514838241118349715803442713722607336732214173255618762341321138898556011520430414052782971985419141860417968593746833898952016980791997105866598425597066404919489902082738711038276194174786383758877067916049129476352925010880025206629976454341252818402788928939407784629386362069592202090897264194883276572978998896242281239126931595483958092059051047739223830394259082355969005503976135238921488192773135287876801394308064862257453262299764712613486466254696464150007113953810688169396432889052881763511661127351872408811370081346456019961324265446884877073712053408327408917588393884214304220369626106333713688792094943405258431214313197283237071070354654837081449831786573831004911008790533179001070424813584405346221388686999574752038655226138085374176702005198770598232862'); + +INSERT INTO num_exp_ln VALUES (2,'75.980172429959420723484178622920965327708652620924912610122049843800380131746381968266727388919414524075492921510147435877107720844487333947572033626887969846858337336557672107987074468763307953130616555202495401302128216460637786993535376622372745654109623249396257174895352222213037880060756992073605135503615371392439827458529942230210514752764526895030759481226199720092008002458654297737883219558685499445394647863430593136350562417924068100891680398878483362058595716232013516337079804607378041880078724811071904523716775991447489914128580100888252698281559809224785596795038122963619830942475652745611551345360922016753939774272970008770647516790944335173711498988149783075646985898883858697162003144539047532603946093022417842140993960433780913606807466518632121884254341907122163281927271483110212890483'); + +INSERT INTO num_exp_ln VALUES (3,'86.992429107491709045555322727377654177072455841678650084144967727028762699430180506209786297136121512625728883607972513154010138109866327600596617277403558404624813332464431424791338402731178416819791932126837396086742033973404980654712734845137075562739300866280737071167943367603243180515859476717635339619107593771719314284984269343476343816253634799874584843436046260962736006310389088154751401911743739429257286834178656182340416539923956100441369280015412718483971113838923221170027312390404790743389872757674342133486652087007983701950040432125562287337697971646750563062524010514537132255605131615248097901911480464339325353279118429890601202554448469387179349495284716473293965884844451619766312048304583068386805927433174443889441171878078987788018564357316138422561213329104267180509029624308926098065'); + +INSERT INTO num_exp_ln VALUES (4,'56.935276817066740776567329017240462885579486075188456418197311631774373422196025180114152248099799048545382060930401786002025479108787121595516444894009593031141335985913019897883627990503003577804436730367402618412514152465206336556967419434371593632864308139215157721913158949066717186782560422199668568894551013785702491365073449320535603830475158258853167712460432995074161536886421366716995573365924430692151761737886552457036412140640821310927642146210426044265504978418405684030862182425702683702307323138985481047994648222224089112998195621687911787785594701557252468626097576375468916953563766801336922479861708649876362257086586679701715813254414915314296890025577780265459584203893089574567331742100451277992780400302806430264717887468808962517029442262560742822875484362427192693300423729233467613910'); + +INSERT INTO num_exp_ln VALUES (5,'20.296713391219923821414834924710998522858242536565236229645868008008504475111229451635162536658197320282791428572861452713483981402773630985812066048575864982038046409484905688236579134672910905547858248343712686247795669280482288748331949478864729205285910525962001251260319741279139167559906461672936902355959755164523720443059989357054368460911050707727029320725144824995614445423492687177126412520389766864793826362309254124276325522276592246655562770110024099522184080118637524912964002223613671995639705240767929562023556724031894855094820328152633412077228479168557819219970917880393852962560319397442566813746504969336443969816954424715197797253670026862362130664772772977978222813915593329422557592316429203293264572088112274848838446633519530653849595288125585730314673691986554304725866754516304420665'); + +INSERT INTO num_exp_ln VALUES (6,'-3.058947463851998053084898503420969773173569760507671013593014983772013099601022840164736581595033399273677583253456908293015637115395777673836877852797643436458673662566205707359569792482081945396989472318998080581824382006377064185813936544714612287417301161454496258176319380348780934551188852900784476213986897306897793456700682073399936398243222895442594762628402487110466705108765286617060826203345783502301472192906817785365563881556293576463515218574477264521950513789471494214626744754200844840310516235570475410854073969787604451971790833680742315518808178608136598148628107328076871698598743664423452623124027059698038466681488746505289551548778131621576387262707147068500249466398507704796800459013580425992071957391417767257856002976954566094297724379688683375704613872658653366052459242767328235849'); + +INSERT INTO num_exp_ln VALUES (7,'41.246780548917246608934265057073076900048579756649769602488660179351587788197892095257027979113051775079905924990472069951828742350559917110289416201523653941731339141666097617614477426376799479821365070373247490598890520285155435501242427296281987676879064510605563522117334502131946383957407685328562874307957108543536378261847119286989184256009392692140821396916222386573424618796707564187152459973446833193743614720624765332006827171872712331032607870580880807058576154429597725560836582655488602546786785520452359711161305828045237044625934404295366273012300148250900116489718279757540843657039519736455668388572899273464839528462223812926410544976290646668870192676914370659142463304861500879195867873346447316374869974900582948166687948531910220128160490935170837209017355954301127162240133341813847180541'); + +INSERT INTO num_exp_ln VALUES (8,'22.862977375646110045361670561177818139082238721442691850491173190000619222046296383571431877856442345505931635735363450488731186880557789439424987680284612480261693386095598289519783790826332183796775862215503493910816035128476952347072320869461206895223935484838130924268616681347949695029657753251443811448783435000569829291535036468240771401957519222523032235686030017496209956550934543164421459898155836108824017735809352580723262896259290484291175350770265895317482371895188221452083719817251845416195168686335127805092334984596224320638378502008767433534450949989322562311171685891891122105437154553106840103473941148230953978989145470651955269817951560544095229079088083494695756914405635176899994279484466773598435268700064279990885608144109747858515514066444373797446449729058958270758597627587968112958'); + +INSERT INTO num_exp_ln VALUES (9,'17.820358481980064387183481028572263407130633079314879566896470101569251997264841660326428805413719418277889123643557369421967068805165885825106611310020187894256310674762734896979157570968168599492401269694048046876387337971177513661006711375440365724346137980004810780215236524986274043416621637509807126148966029923572853117418545426960105154053049098579812135003711132897895016476695223444397389521434633067499404903493027304737402519428197015899833229473322655155458942323004249812974150129789653469524573801259946118454333405580647485894435301530550214095993989552176497867244278699359917247910082169086524111229983698975613609318418313798992088206507831757327320958918656453341769110558376097374227592021075267882222057385413453949580066342977546145482215220982989992069525148522710254796105001938615214263'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_log10 VALUES (0,'NaN'); + +INSERT INTO num_exp_log10 VALUES (1,'4.930660740129727276654889314296515979425461685461970306647398411855044094312185293195497201658739777714943974003690119189101973212927970410047992001003936259467465542044528955416040460487922970233600641954269411521809500203864460110903973264337093883907933081597350982496469748131390809569321256206859934619579029279954574676601709408712255490686948453752571699579252140062805776361984468580258289509013081691778727372026090522694670379557247829136504595898935235926069699309392675806881162434168418505908116911054206058735257796918687777716036307205415038158583184624809880157060625643069601549803887864772092583549388533013233603450097615537162442973385137488450178790573546382354482351187412256794374383453695483855501587939419102008302408157959291557415763034668013452188944554607063362933134950906875499201'); + +INSERT INTO num_exp_log10 VALUES (2,'32.997769620388965086774969704518222090258389987679691893351902336370051104718852164011301929506188893338106627980171059175447833290713847317665944354651476245003161501753612545484635275306181777040447675475670149066399611203341262105766118892586541910243351018829302798733989560900125591073082441126709911019648451232244139674063434385451279378543163944005973452562993913383659295688375546058256196254319767218634546732685705517341998116744642480938405113447415486950667007645850519659606476727681944251201236366198374488204017630268083077471516734133869728427050843306716313813724061560369884508660845630727190444623729815564381063131729592825825486515070406390371638817503915214206586939112681762984038333298146999891250107667687034785493312416966635780188163871680959873288697497561452228182734430749066579749'); + +INSERT INTO num_exp_log10 VALUES (3,'37.780331928743475574895606142114739140772838801045013007323050327909196792739138159615327729728110344767302636436234256468332011934881494997184865617793179255006442447189720642997935223133982347184994174261506212652322213673745795726283311685835974151422721233207287206894148660531800622455957268888702309499182978182878524951883775154983702898237404558813230370364953160102391101897560104513279410610948028599674950811462114131673380477843456965645417025376374320207504913806546872166094337441573669261285052323206348035827948287081776955945081345131570610652073053464020209215624179904586956137079321655773178387441622685682721151900601340680061607114354850640946256225260430676099781727317540719923791064452012925902993317349390523278687089530234444415688602090547516647302454865526291471706301790881694022223'); + +INSERT INTO num_exp_log10 VALUES (4,'24.726676547286224970759328746582840552419566534667446425423046931401641497155587075591229106937829957279943690528061985864558314570189069764367933957499905044566413640017549478921384160584906257607957223101377816440084188042395098536074479064548620374152344954289432050971466476174493306432228880930006524504974367146536665170956555486181410864034862861231267121149652317599303804477688621597163730470970207231328339082779056152481480926452142005969020950341307977091850953883445808399574256295803245530993204179747743812544604144379381347499056545148243304041538981954204310612049423688645476667184129189153715486929216331980316967699254518020077226689317148303152585009031597809279387172427408557115400021035692880631275593381822805377317270568779655383061987766693697518921188619814204902583361096973421134004'); + +INSERT INTO num_exp_log10 VALUES (5,'8.814750626578650238811431417807018895270298639823442501111235973209197727215795256506525221092818797578008152140054383421240180435087611869193019443372556081555311825248667278358330916098378127100899126895012782320751838528480712942601038190627182482614147263228588284866661508052724762701223357327343090598060805245853527435948381893458352744679795853650453594546267600486696643924152372736774331080527157374379043696696647158270918245668579680394279565181670004245143555617589138267976417280970718829942998800499312890580011246294669585429723974582350357991472101919333996770115834067969654217063942059882195268353998096891812525364797586486311202350700339609637274043915687880562465121559531284337603363356183320193656553931871200575467929714875483123706358278876389849119105053294688326141759401230994901405'); + +INSERT INTO num_exp_log10 VALUES (6,'-1.328484003982869642690619298690906747763234110040562640557173509402512757735587333095924652711056556491908059708986413635120656426593745303715671199761364516107844087845783714418487426723538440387069985879601248897538855843115404484229652166941838283489828419407478748732927617251897244190697443966424660881366993754577233476597163021768156814527570512834684713730559883782625870597080940193303268818336816535968869931456641949301731046034660616615392129109391145214470757259042172416816936479713743188047425796931722546185493217275537303458837771965375448968719169174136287532752370175863826715450565025635651343928205805494319778539652563499901671319955144823432132740582617949774638538594081514904904341299199113721131520557004571803778698005652464301037962272085633628653321081368256925971558076970172779715'); + +INSERT INTO num_exp_log10 VALUES (7,'17.913249188669140643510654105014358282516966474257460687880559542190804665566625978925406311113121982595279826214959603627387555578965653325278444455875162277940655989601428868642914577248262147833499137348602966573601719040813549936948178463592211685237720748377879836890106515699728652218324794927458352954247096536337594789471529493944292143186953509162522579060020018226817623648563806559917579317916242706559131476179714031602207057714677845347616752450567251644277767418397621490301286115159509360375419599968738067461569666699939732107480135216621373057421990702923042287910730395998082514702629760389192370666675364405730936537832803383367187639209534697198515928978064543150195911463663617683085348965065679311986715357338675515370634753254774665197233934933271954463040729779956682570415317734489164385'); + +INSERT INTO num_exp_log10 VALUES (8,'9.929264914121995501917993119394933531225401243275938207624866270551448544301376913376130982251708700134720886862945040266148728213253651323129942781577143957084726727561987639140151337848818195806259935747329665025823709044567138449084349729747202164413995795609659711723455165142329822773177102845804114214340046404641970845707372809306219463962664551623665322610139794354769767829380018857313559373283673392337954610346290037758389035140213224696023751541663171574697035012610534455189013755134090933979479069288110010954211669067225249755249337768792642303351914884187159646984708862430789018895140670365476746734456807215043628059581947593694929159076346249490593187993386780521089745819640214783614157516171005086731241769146397577246387886107367648843380733370112546792442909347322732196805316614555689762'); + +INSERT INTO num_exp_log10 VALUES (9,'7.739283354261751283625223433456284905560931805428759681411970457812279544250432389511382263439324085689734710188041049046660480575958686859942980599595036769090747781359217248301544587434077376812293034848418204834388504169166350770257248896025815531248627658465029806509131631454856186387892627989218208026727504548130018922325585619738185507999433763118148418722504204066578294826264005398891049629199412773138457218976050467479292777172717500219850781664314597312411301296201533610562886229900497272268364496763758868455934979903774531992886483396489868888731578355541611359130188566524240259770918423445785338175040098706500034487703124623745259139247432324145633151895802637182446905097253961951018926565652497920605819785424451050191604602898777804133717341512568151920576684198443843944721398831404081859'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_exp_power_10_ln VALUES (0,'NaN'); + +INSERT INTO num_exp_power_10_ln VALUES (1,'225561990715.277245515991117670624124484084762557459065170589803293759247930753528436379932442146759103295277479258327642314622036941865221478746258727236601688778946696303277607709407496616423493315166963938393760548678730128692212077086588682984700837334554241405763691119669847463520746595280034536307041368063462023793177898200220207765205127584303464304601759554817607633012272490650155253979182893585119965271975927569080191838676053084168631217591768468344106219831174026139608715965691941366334940196517120885214887008671956523579678156919416435031020452971977153991139145404842034138317592877675821045409772456977018293365238179815614004574330200783530118851005077771478448804470170641452481992602803877112958872108069738434946694089025321283178188028224338756015337492913115267362635647236447601252924834642796058'); + +INSERT INTO num_exp_power_10_ln VALUES (2,'9553718264533556311125292459627965006385666643531070061102266984368939757379.536714147420215784125170401370065894858487440153494392538261078415409784085960333028254155527328359894197540839556987826344995348426293585457768226283066583722499658006242709930685932246087653832230889613022921575445199055131152661556678809191264086381976922223866204038615136758192929883317207903579770917317641181652055458721731297347443662717939116561947785705140374908203404860090658919334137955075887697259604047657534191202566335372150375993361370075961180728155127447781364264047857624746079509591666068708743260905728661917791822925979235918475633100283148558978385583805341715868143937062092264994833222352433299015979561976964779350640064096690062929265992966564232453102431600199173711947391200249130712039686700111791790265309426741120465259677894665532560198051256215915373145226284270408649736509'); + +INSERT INTO num_exp_power_10_ln VALUES (3,'982718444846268846508445482774217796844461660819285525931206164100817251856409365450682.362683768066405322653747385034480250394145008573806022660379219602846285813744865438912887625784087005970975437905783802114553690522787857272953842288090141945268495451006273685577260054069522075046955466204804067271437138871789034722069934693546671607506851844248427950939791205412350536883779850165603116191193657054604569586553874805856647223849267039531773072343908345333155562072887754900969504551717514980465801806565999410206735831440712124661645970935112535081991606671600328471264697018198676317466846450405861359235297846597981143547119390922405594115478086038680663368675222949247096131378724350715530605691796680604309063173515781378545860473572389718345696107553363715518601596249508215455106779522851210398208919496668879040223859884166805448827948087400426315425231119801173387715922086154065273'); + +INSERT INTO num_exp_power_10_ln VALUES (4,'861542720105376650266753999919217194383259935058507531116.774511336660822591851369622743235084609149542494189385785321912210129989390054947787009383210009523204976629456268332186620016067379702483800883493431423160815760933380418976582725913410929214462739708321325884209636272001805871036779154087677637129248122540412937033791526383240502286607736226090213753913654673523613612439527815137888202973659987501649474772884055648603290154867585312925699571949539600328906295652872654314913539778815035321695215634102441494403825526533235061083947035338872599854931230001361227174477274708230470794066733245241594719912710139298949856243576688344051439047966427547889756037265151798639614843866387316916203238068277912991427278268083231579195846744438643659745041780103653332041031419793815914447232121937821142169172566753399257291244398531365781832297786941359729799400'); + +INSERT INTO num_exp_power_10_ln VALUES (5,'198021976607570296508.271597639984889464620426933601643322058775615235389194561064983706229795978402690473201671702614911129095149240715527556855309177671128442458698638704394974473956869419481315262823632891676087912529523219333012290621046361106033860210270638559271706082115529424772192777643046125905852037759566224116373416253787241195450409652089019290072319861181399387753223422998872180810295299831487867222464355713552301775702554189470264147325049133532522718679336524769566984150923939420759804463781082299907043016120177416779442865059261387111806785876531152192378576258351599534512031062777609734092707165605364139201322351960602280089186180302246827234844736393745487324460438448807241887783263546165171099497316415863122023114646876909575845860402164818094500541234974716577550807551946414081410743197768993152975501'); + +INSERT INTO num_exp_power_10_ln VALUES (6,'.000873076977206566818052116526263730226812004454463281371489634779519089200224205946321120805055212090024554381349223642352209212670470260295303361873760972918129853308169576675500721645609379420329169271088810484607337679253503247351324049221970104335289487989027621978310506220905131150125321713385148268584530413680037620544212746920563790371941626294733473967065607791756894237438288480748407449237446113996117912144587258434808327522518688617394025018756570740098795745692805352377041347367240475846033282850136270250633825482156304826383360291164928049344226886150285595932088884965511963310715773499733217615863523253012606066583814112265708693122563204149232245895551314975524172504103194858904869273185785182598234060315036187756490539352752560361560286717869643902435677448962235275054804452967413005'); + +INSERT INTO num_exp_power_10_ln VALUES (7,'176514565873872717825163931126806100435750.096278384530154766967061948052237623936423931849868926020451465515367348890410352640552194499619062823622476972850692557798609619250753020363520533767813563613425606228355802781302735485038377521515850536680425059519814786118919994914180918228654298075183514200191737597656810036850772127169441661576862538643715648802139886576391427423689320082366572297580054381937437005879583216745596935643579262248665490169331304003204939561361718554509909313409421397022626924406091551900222555950699170864234411017062042057683304265485826061096835531732950909546314722726990314852356462874701181085379772134121978510387397276859318242238150439474660772561390798432890789762504242822787017140808209820627435991445529404692793744568204608385843245177656436105160780897472099970336514833257055017279707999437302548655364559'); + +INSERT INTO num_exp_power_10_ln VALUES (8,'72941951052009383458167.300747500436981484566111756088702608000390737594784514635592222758882092500858797317505303492923829092720870826490477962201959426813271424853341826896270963213736922458746003100613943600855942721319226948714369219316345322636075285343544788982588956431405042577296229122673590336976893594798942025893296105815818487227300314490440902574022885833779324177053242170024559675073866612316965636832258283516275906085642459351367507561963945012828379111856700009391438637054015804558386733558956649061672420804826896303889067785497738203077050774825608647969196321506624991188638449047860249367840775936911749905927108478444112230174584693363226143549933224252679398881354887872642908328737917862751077365602631600279486028043329404269490375935308156815477700961014566228692743960491745353377403533037122586797765130'); + +INSERT INTO num_exp_power_10_ln VALUES (9,'661239032819374816.097553651299556484820492272269662685578275493609248662925676004753503494252951243895572437264999063878330704584509915845096232798927524470286655554736724913758600775591269525423912692080421094644542553026831758426157681271572808657664918053119324646138457659418857926209701677786068580819823633713337632456905824562235373422309621872998037966404189020165296080436871220718574009921789858751384547836431858428729570977259373272041837411903005303672798845573379758630607982213326716018594073712340609488043353995410508475153538231445235003980586600882223782814368245305160648543466496726973755388826656879616734762068443462618454921858705377028522664844761719759342490380417060255776725333319537746890406213693117052223545525717132695297770810635066731941724108167146710297146989770382041617889670713111888375717'); + +COMMIT TRANSACTION; + +BEGIN TRANSACTION; + +INSERT INTO num_data VALUES (0, '0'); + +INSERT INTO num_data VALUES (1, '85243.39540024977626076239847863600785982737155858270959890014613035727868293618673807776733416230953723818527101593495895350807775607346277892835514324320448949370623441059033804864158715021903312693889518990256881059434042443507529601095150710777634743301398926463888783847290873199395304998050753365215426971278237920063435565949203678024225270616295573678510929020831006146661747271783837653203039829647102027431761129518881525935216608429897041525858540380754759125150233053469999022855035'); + +INSERT INTO num_data VALUES (2, '-994877526002806872754342148749241.04353023451866590387054959174736129501310680280823383331007646306243540953499740615246583399296334239109936336446284803020643582102868247857009494139535009572740621288230740389545481395'); + +INSERT INTO num_data VALUES (3, '-60302029489319384367663884408085757480.2322712404088283093870869198708849258097125725036189625900174440196153781995220721511009855207486224837798752903681993777275846325950111427710563453217985216966456785944859989497422927661683538629473170704026975786513125842675604577233871570629808699803522400038975396500769162308448069085909755023233588510630417065084295051270219462289785473643946404281422516357503746700705970360169619852905053433235726497292406142332833'); + +INSERT INTO num_data VALUES (4, '5329378275943663322215245.24931765987630429629836382184742348353920297283690739124220773955591340709935970062776650204659187764581615597720798385015942389765692769739983054442503547211560297249686289665792078548480268091496050883021187158502798880896590227542729659940394038802461081290690995869705131152889309663639310553909874081663091069118126221594338242710530718836025225507189149221049928936955230868771875644038572888630664890573507822342998964954667474300944699078658989010257103569231493090050659723450626338923049035040974032671138430612839043269997482582763267536489504794826476836323549796385028155416935072959933315468068930689064483178204550825728947252440604703474049780550458442808479096492346910001692358508618202898514895453589357'); + +INSERT INTO num_data VALUES (5, '-652755630.43456071828048833552593835051449845484289562110789582081210403487973096161149072377955192388469356112505543620695003436531392789029513380101663750625024853263344909355177280161504414335005574882649025508632900995595004153086358670541462762210415346958050909878501048483523600711486406055424807840429541335391538322886495085448421556770991545781035298449067051916630343957356635391594362639819978677032855590055900561501350354631803808000307050416047072513406855040715556454205065332997338225626635780147287003130754254277103928406089109802521803537038957372612837169223905290912251006321930223154562110264217937'); + +INSERT INTO num_data VALUES (6, '0.0469370721950711508944806393077762204079964905145503836835397203739563036579760026190241480514409364'); + +INSERT INTO num_data VALUES (7, '-818934540071845742'); + +INSERT INTO num_data VALUES (8, '8496986223.64063724353165506167988570717591150432282238795309964705925283285060558038824227595710139960766584401003765241409149793494330798800'); + +INSERT INTO num_data VALUES (9, '054863480.34685027005508022756223282084742813020271603840941647350440860843570182437301045468670059279379903480024743452620396345637401505220786389930600883087012615993343976556472498552535317826554614696684732913955544753638726438705858481670766245958647367500212800073774509075408148134050353551558174813940258910304990570172170811882520915334358633'); + +COMMIT TRANSACTION; + +CREATE UNIQUE INDEX num_exp_add_idx ON num_exp_add (id1, id2); + +CREATE UNIQUE INDEX num_exp_sub_idx ON num_exp_sub (id1, id2); + +CREATE UNIQUE INDEX num_exp_div_idx ON num_exp_div (id1, id2); + +CREATE UNIQUE INDEX num_exp_mul_idx ON num_exp_mul (id1, id2); + +CREATE UNIQUE INDEX num_exp_sqrt_idx ON num_exp_sqrt (id); + +CREATE UNIQUE INDEX num_exp_ln_idx ON num_exp_ln (id); + +CREATE UNIQUE INDEX num_exp_log10_idx ON num_exp_log10 (id); + +CREATE UNIQUE INDEX num_exp_power_10_ln_idx ON num_exp_power_10_ln (id); + +VACUUM ANALYZE num_exp_add; + +VACUUM ANALYZE num_exp_sub; + +VACUUM ANALYZE num_exp_div; + +VACUUM ANALYZE num_exp_mul; + +VACUUM ANALYZE num_exp_sqrt; + +VACUUM ANALYZE num_exp_ln; + +VACUUM ANALYZE num_exp_log10; + +VACUUM ANALYZE num_exp_power_10_ln; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val + t2.val + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val + t2.val, 10) + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 10) as expected + FROM num_result t1, num_exp_add t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 10); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val - t2.val + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val - t2.val, 40) + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 40) + FROM num_result t1, num_exp_sub t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 40); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val * t2.val + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val * t2.val, 30) + FROM num_data t1, num_data t2; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 30) as expected + FROM num_result t1, num_exp_mul t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 30); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, t1.val / t2.val + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0'; + +SELECT t1.id1, t1.id2, t1.result, t2.expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT t1.id, t2.id, round(t1.val / t2.val, 80) + FROM num_data t1, num_data t2 + WHERE t2.val != '0.0'; + +SELECT t1.id1, t1.id2, t1.result, round(t2.expected, 80) as expected + FROM num_result t1, num_exp_div t2 + WHERE t1.id1 = t2.id1 AND t1.id2 = t2.id2 + AND t1.result != round(t2.expected, 80); + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, SQRT(ABS(val)) + FROM num_data; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_sqrt t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, LN(ABS(val)) + FROM num_data + WHERE val != '0.0'; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, LOG('10'::numeric, ABS(val)) + FROM num_data + WHERE val != '0.0'; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_log10 t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +DELETE FROM num_result; + +INSERT INTO num_result SELECT id, 0, POW(numeric '10', LN(ABS(round(val,1000)))) + FROM num_data + WHERE val != '0.0'; + +SELECT t1.id1, t1.result, t2.expected + FROM num_result t1, num_exp_power_10_ln t2 + WHERE t1.id1 = t2.id + AND t1.result != t2.expected; + +WITH t(b, p, bc_result) AS (VALUES +(0.084738, -20, 2744326694304960114888.785913), +(0.084738, -19, 232548755422013710215.445941), +(0.084738, -18, 19705716436950597776.236458), +(0.084738, -17, 1669822999434319754.362725), +(0.084738, -16, 141497461326065387.345189), +(0.084738, -15, 11990211877848128.792857), +(0.084738, -14, 1016026574105094.737649), +(0.084738, -13, 86096059836517.517879), +(0.084738, -12, 7295607918426.821430), +(0.084738, -11, 618215223791.651994), +(0.084738, -10, 52386321633.657007), +(0.084738, -9, 4439112122.5928274), +(0.084738, -8, 376161483.04427101), +(0.084738, -7, 31875171.750205437), +(0.084738, -6, 2701038.3037689083), +(0.084738, -5, 228880.58378476975), +(0.084738, -4, 19394.882908753819), +(0.084738, -3, 1643.4835879219811), +(0.084738, -2, 139.26551227333284), +(0.084738, -1, 11.801080979017678), +(0.084738, 0, 1), +(0.084738, 1, .084738), +(0.084738, 2, .007180528644), +(0.084738, 3, .000608463636235272), +(0.084738, 4, .00005155999160730448), +(0.084738, 5, .000004369090568819767), +(0.084738, 6, .0000003702279966206494), +(0.084738, 7, .00000003137237997764059), +(0.084738, 8, .000000002658432734545308), +(0.084738, 9, .0000000002252702730599003), +(0.084738, 10, .00000000001908895239854983), +(0.084738, 11, .000000000001617559648348316), +(0.084738, 12, .0000000000001370687694817396), +(0.084738, 13, .00000000000001161493338834365), +(0.084738, 14, .0000000000000009842262254614642), +(0.084738, 15, .00000000000000008340136189315355), +(0.084738, 16, .000000000000000007067264604102046), +(0.084738, 17, .0000000000000000005988658680223991), +(0.084738, 18, .00000000000000000005074669592448206), +(0.084738, 19, .000000000000000000004300173519248761), +(0.084738, 20, .0000000000000000000003643881036741015)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t; + +WITH t(b, p, bc_result) AS (VALUES +(37.821637, -20, .00000000000000000000000000000002787363175065101), +(37.821637, -19, .000000000000000000000000000001054226381944797), +(37.821637, -18, .00000000000000000000000000003987256753373947), +(37.821637, -17, .000000000000000000000000001508045775519079), +(37.821637, -16, .00000000000000000000000005703675990106610), +(37.821637, -15, .000000000000000000000002157223628634278), +(37.821637, -14, .00000000000000000000008158972901002847), +(37.821637, -13, .000000000000000000003085857113545666), +(37.821637, -12, .0000000000000000001167121675823920), +(37.821637, -11, .000000000000000004414245235784397), +(37.821637, -10, .0000000000000001669539809368169), +(37.821637, -9, .000000000000006314472862697207), +(37.821637, -8, .0000000000002388237004592846), +(37.821637, -7, .000000000009032703305767796), +(37.821637, -6, .0000000003416316255594496), +(37.821637, -5, .00000001292106732962942), +(37.821637, -4, .0000004886959181938034), +(37.821637, -3, .00001848327962130773), +(37.821637, -2, .0006990678924065984), +(37.821637, -1, .02643989206495742), +(37.821637, 0, 1), +(37.821637, 1, 37.821637), +(37.821637, 2, 1430.476225359769), +(37.821637, 3, 54102.952532687378), +(37.821637, 4, 2046262.2313195326), +(37.821637, 5, 77392987.319777394), +(37.821637, 6, 2927129472.7542235), +(37.821637, 7, 110708828370.511632), +(37.821637, 8, 4187189119324.792454), +(37.821637, 9, 158366346921451.985294), +(37.821637, 10, 5989674486279224.500736), +(37.821637, 11, 226539294168214309.708325), +(37.821637, 12, 8568086950266418559.993831), +(37.821637, 13, 324059074417413536066.149409), +(37.821637, 14, 12256444679171401239980.310926), +(37.821637, 15, 463558801566202198479885.206986), +(37.821637, 16, 17532552720991931019508170.100286), +(37.821637, 17, 663109844696719094948877928.067252), +(37.821637, 18, 25079899837245684700124994552.671731), +(37.821637, 19, 948562867640665366544581398598.127577), +(37.821637, 20, 35876200451584291931921101974730.690104)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t; + +WITH t(b, p, bc_result) AS (VALUES +(0.06933247, -20.342987, 379149253615977128356318.39406340), +(0.06933247, -19.342987, 26287354251852125772450.59436685), +(0.06933247, -18.342987, 1822567200045909954554.65766042), +(0.06933247, -17.342987, 126363085720167050546.86216560), +(0.06933247, -16.342987, 8761064849800910427.02880469), +(0.06933247, -15.342987, 607426265866876128.15466179), +(0.06933247, -14.342987, 42114363355427213.14899924), +(0.06933247, -13.342987, 2919892833909256.59283660), +(0.06933247, -12.342987, 202443382310228.51544515), +(0.06933247, -11.342987, 14035899730722.44924025), +(0.06933247, -10.342987, 973143597003.32229028), +(0.06933247, -9.342987, 67470449244.92493259), +(0.06933247, -8.342987, 4677892898.16028054), +(0.06933247, -7.342987, 324329869.02491071), +(0.06933247, -6.342987, 22486590.914273551), +(0.06933247, -5.342987, 1559050.8899661435), +(0.06933247, -4.342987, 108092.84905705095), +(0.06933247, -3.342987, 7494.3442144625131), +(0.06933247, -2.342987, 519.60139541889576), +(0.06933247, -1.342987, 36.025248159838727), +(0.06933247, 0.342987, .40036522320023350), +(0.06933247, 1.342987, .02775830982657349), +(0.06933247, 2.342987, .001924552183301612), +(0.06933247, 3.342987, .0001334339565121935), +(0.06933247, 4.342987, .000009251305786862961), +(0.06933247, 5.342987, .0000006414158809285026), +(0.06933247, 6.342987, .00000004447094732199898), +(0.06933247, 7.342987, .000000003083280621074075), +(0.06933247, 8.342987, .0000000002137714611621997), +(0.06933247, 9.342987, .00000000001482130341788437), +(0.06933247, 10.342987, .000000000001027597574581366), +(0.06933247, 11.342987, .00000000000007124587801173530), +(0.06933247, 12.342987, .000000000000004939652699872298), +(0.06933247, 13.342987, .0000000000000003424783226243151), +(0.06933247, 14.342987, .00000000000000002374486802900065), +(0.06933247, 15.342987, .000000000000000001646290350274646), +(0.06933247, 16.342987, .0000000000000000001141413763217064), +(0.06933247, 17.342987, .000000000000000000007913703549583420), +(0.06933247, 18.342987, .0000000000000000000005486766139403860), +(0.06933247, 19.342987, .00000000000000000000003804110487572339), +(0.06933247, 20.342987, .000000000000000000000002637483762562946)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t; + +WITH t(b, p, bc_result) AS (VALUES +(27.234987, -20.230957, .000000000000000000000000000009247064512095633), +(27.234987, -19.230957, .0000000000000000000000000002518436817750859), +(27.234987, -18.230957, .000000000000000000000000006858959399176602), +(27.234987, -17.230957, .0000000000000000000000001868036700701026), +(27.234987, -16.230957, .000000000000000000000005087595525911532), +(27.234987, -15.230957, .0000000000000000000001385605980094587), +(27.234987, -14.230957, .000000000000000000003773696085499835), +(27.234987, -13.230957, .0000000000000000001027765638305389), +(27.234987, -12.230957, .000000000000000002799118379829397), +(27.234987, -11.230957, .00000000000000007623395268611469), +(27.234987, -10.230957, .000000000000002076230710364949), +(27.234987, -9.230957, .00000000000005654611640579014), +(27.234987, -8.230957, .000000000001540032745212181), +(27.234987, -7.230957, .00000000004194277179542807), +(27.234987, -6.230957, .000000001142310844592450), +(27.234987, -5.230957, .00000003111082100243440), +(27.234987, -4.230957, .0000008473028055606278), +(27.234987, -3.230957, .00002307628089450723), +(27.234987, -2.230957, .0006284822101702527), +(27.234987, -1.230957, .01711670482371810), +(27.234987, 0.230957, 2.1451253063142300), +(27.234987, 1.230957, 58.422459830839071), +(27.234987, 2.230957, 1591.1349340009243), +(27.234987, 3.230957, 43334.539242761031), +(27.234987, 4.230957, 1180215.6129275865), +(27.234987, 5.230957, 32143156.875279851), +(27.234987, 6.230957, 875418459.63720737), +(27.234987, 7.230957, 23842010367.779367), +(27.234987, 8.230957, 649336842420.336290), +(27.234987, 9.230957, 17684680461938.907402), +(27.234987, 10.230957, 481642042480060.137900), +(27.234987, 11.230957, 13117514765597885.614921), +(27.234987, 12.230957, 357255344113366461.949871), +(27.234987, 13.230957, 9729844652608062117.440722), +(27.234987, 14.230957, 264992192625800087863.690528), +(27.234987, 15.230957, 7217058921265161257566.469315), +(27.234987, 16.230957, 196556505898890690402726.443417), +(27.234987, 17.230957, 5353213882921711267539279.451015), +(27.234987, 18.230957, 145794710509592328389185797.837767), +(27.234987, 19.230957, 3970717045397510438979206144.696206), +(27.234987, 20.230957, 108142427112079606637962972621.121293)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t; + +WITH t(b, p, bc_result) AS (VALUES +(0.12, -2829.8369, 58463948950011752465280493160293790845494328939320966633018493248607815580903065923369555885857984675501574162389726507612128133630191173383130639968378879506624785786843501848666498440326970769604109017960864573408272864266102690849952650095786874354625921641729880352858506454246180842452983243549491658464046163869265572232996388827878976066830374513768599285647145439771472435206769249126377164951470622827631950210853282324510655982757098065657709137845327135766013147354253426364240746381620690117663724329288646510198895137275207992825719846135857839292915100523542874885080351683587865157015032404901182924720371819942957083390475846809517968191151435281268695782594904484795360890092607679215675240583291240729468370895035823777914792823688291214492607109455017754453939895630226174304357121900605689015734289765672740769194115142607443713769825894380064727556869268488695795705030158832909348803019429370973064732712469794182891757241046263341655894972953512257981661670321890336672832647028099324621932563236459127918144141230217523147304565594514812518826936144181257723061181656522095236928347413997136815409159361412494284201481609684892562646522086577634100783077813105675590737823924220663206479031113753135119759722725207724879578900186075841393115040465401462266086907464970054073340036852442184414587772177753008511913377364966775792477387717262694468450099866775550614257191941835797445874557362115814601886902749237439492398087966544817154173072811937702110580330775581851211123491341435883319798273456296794954514173820352334127081705706502510709179711510240917772628308487366740741280043704807717608366220401933596364641284631036907635403895053036499618723044314773148779735006542501244942039455169872946018271985844759209768927953340447524637670938413827595013338859796135512187473850161303598087634723542727044978083220970836296653305188470017342167913572166172051819741354902582606590658382067039498769674611071582171914886494269818475850690414812481252963932223686078322390396586222238852602472958831686564971334200490182175112490433364675164900946902818404704835106260174052265784055642968397240262737313737007322288203637798365320295080314524864099419556398713380156353062937736280885716820226469419928595465390700629307079710611273715705695938635644841913194091407807776191951797748706106000922803167645881087385311847268311361092838264814899353459146959869764278464187826798546290981492648723002412475976344071283321798061003719251864595518596639432393032991023409676558943539937377229130132816883146259468718344018277257037013406135980469482324577407154032999045733141275895.3432), +(1.2, 32908.8896, 58463467728170833376633133695001863276259293590926929026251227859007891876739460057725441400966420577009060860805883032969522911803372870882799865787473726926215148161529632590083389287080925059682489116446754279752928005457087175157581627230586554364417068189211136840990661174760199073702207450133797324318403866058202372178813998850887986769280847189341565507156189065295823921162851958925352114220880236114784962150135485415106748467247897246441194126125699204912883449386043559785865023459356275014504597646990160571664166410683323036984805434677654413174177920726210827006973855410386789516533036723888687725436216478665958434776205940192130053647653715221076841771578099896259902368829351569726536927952661429685419815305418450230567773264738536471211804481206474781470237730069753206249915908804615495060673071058534441654604668770343616386612119048579369195201590008082689834456232255266932976831478404670192731621439902738547169253818323045451045749609624500171633897705543164388470746657118050314064066768449450440405619135824055131398727045420324382226572368236570500391463795989258779677208133531636928003546809249007993065200108076924439703799231711400266122025052209803513232429907231051873161206025860851056337427740362763618748092029386371493898291580557004812947013231371383576580415676519066503391905962989205397824064923920045371823949776899815750413244195402085917098964452866825666226141169411712884994564949174271056284898570445214367063763956186792886147126466387576513166370247576466566827375268334148320298849218878848928271566491769458471357076035396330179659440244425914213309776100351793665960978678576150833311810944729586040624059867137538839913141142139636023129691775489034134511666020819676247950267220131499463010350308195762769192775344260909521732256844149916046793599150786757764962585268686580124987490115873389726527572428003433405659445349155536369077209682951123806333170190998931670309088422483075609203671527331975811507450670132060984691061148836994322505371265263690017938762760088575875666254883673433331627055180154954694693433502522592907190906966067656027637884202418119121728966267936832338377284832958974299187166554160783467156478554899314000348357280306042140481751668215838656488457943830180819301102535170705017482946779698265096226184239631924271857062033454725540956591929965181603262502135610768915716020374362368495244256420143645126927013882334008435586481691725030031204304273292938132599127402133470745819213047706793887965197191137237066440328777206799072470374264316425913530947082957300047105685634407092811630672103242089966046839626911122.7149)) +SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +(-20.29837, .000000001529431101152222), +(-19.29837, .000000004157424770142192), +(-18.29837, .00000001130105220586304), +(-17.29837, .00000003071944485366452), +(-16.29837, .00000008350410872606600), +(-15.29837, .0000002269877013517336), +(-14.29837, .0000006170165438681061), +(-13.29837, .000001677224859055276), +(-12.29837, .000004559169856609741), +(-11.29837, .00001239310857408049), +(-10.29837, .00003368796183504298), +(-9.29837, .00009157337449401917), +(-8.29837, .0002489222398577673), +(-7.29837, .0006766408013046928), +(-6.29837, .001839300394580514), +(-5.29837, .004999736839665763), +(-4.29837, .01359069379834070), +(-3.29837, .03694333598818056), +(-2.29837, .1004223988993283), +(-1.29837, .2729763820983097), +(0.29837, 1.3476603299656679), +(1.29837, 3.6633205858807959), +(2.29837, 9.9579377804197108), +(3.29837, 27.068481317440698), +(4.29837, 73.579760889182206), +(5.29837, 200.01052696742555), +(6.29837, 543.68498095607070), +(7.29837, 1477.8890041389891), +(8.29837, 4017.3188244304487), +(9.29837, 10920.204759575742), +(10.29837, 29684.194161006717), +(11.29837, 80690.005580314652), +(12.29837, 219338.17590722828), +(13.29837, 596222.97785597218), +(14.29837, 1620702.0864156289), +(15.29837, 4405525.0308492653), +(16.29837, 11975458.636179032), +(17.29837, 32552671.598188404), +(18.29837, 88487335.673150406), +(19.29837, 240533516.60908059), +(20.29837, 653837887.33381570)) +SELECT x, bc_result, exp(x), exp(x)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', -2.3025850929940457), +('1.0e-2', -4.6051701859880914), +('1.0e-3', -6.9077552789821371), +('1.0e-4', -9.2103403719761827), +('1.0e-5', -11.512925464970228), +('1.0e-6', -13.815510557964274), +('1.0e-7', -16.118095650958320), +('1.0e-8', -18.420680743952365), +('1.0e-9', -20.723265836946411), +('1.0e-10', -23.025850929940457), +('1.0e-11', -25.328436022934503), +('1.0e-12', -27.631021115928548), +('1.0e-13', -29.933606208922594), +('1.0e-14', -32.236191301916640), +('1.0e-15', -34.5387763949106853), +('1.0e-16', -36.84136148790473094), +('1.0e-17', -39.143946580898776628), +('1.0e-18', -41.4465316738928223123), +('1.0e-19', -43.74911676688686799634), +('1.0e-20', -46.051701859880913680360), +('1.0e-21', -48.3542869528749593643778), +('1.0e-22', -50.65687204586900504839581), +('1.0e-23', -52.959457138863050732413803), +('1.0e-24', -55.2620422318570964164317949), +('1.0e-25', -57.56462732485114210044978637), +('1.0e-26', -59.867212417845187784467777822), +('1.0e-27', -62.1697975108392334684857692765), +('1.0e-28', -64.47238260383327915250376073116), +('1.0e-29', -66.774967696827324836521752185847), +('1.0e-30', -69.0775527898213705205397436405309), +('1.0e-31', -71.38013788281541620455773509521529), +('1.0e-32', -73.682722975809461888575726549899655), +('1.0e-33', -75.9853080688035075725937180045840189), +('1.0e-34', -78.28789316179755325661170945926838306), +('1.0e-35', -80.590478254791598940629700913952747266), +('1.0e-36', -82.8930633477856446246476923686371114736), +('1.0e-37', -85.19564844077969030866568382332147568124), +('1.0e-38', -87.498233533773735992683675278005839888842), +('1.0e-39', -89.8008186267677816767016667326902040964430), +('1.0e-40', -92.10340371976182736071965818737456830404406)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', -.10536051565782630), +('1.0e-2', -.010050335853501441), +('1.0e-3', -.0010005003335835335), +('1.0e-4', -.00010000500033335834), +('1.0e-5', -.000010000050000333336), +('1.0e-6', -.0000010000005000003333), +('1.0e-7', -.00000010000000500000033), +('1.0e-8', -.000000010000000050000000), +('1.0e-9', -.0000000010000000005000000), +('1.0e-10', -.00000000010000000000500000), +('1.0e-11', -.000000000010000000000050000), +('1.0e-12', -.0000000000010000000000005000), +('1.0e-13', -.00000000000010000000000000500), +('1.0e-14', -.000000000000010000000000000050), +('1.0e-15', -.0000000000000010000000000000005), +('1.0e-16', -.00000000000000010000000000000001), +('1.0e-17', -.000000000000000010000000000000000), +('1.0e-18', -.0000000000000000010000000000000000), +('1.0e-19', -.00000000000000000010000000000000000), +('1.0e-20', -.000000000000000000010000000000000000), +('1.0e-21', -.0000000000000000000010000000000000000), +('1.0e-22', -.00000000000000000000010000000000000000), +('1.0e-23', -.000000000000000000000010000000000000000), +('1.0e-24', -.0000000000000000000000010000000000000000), +('1.0e-25', -.00000000000000000000000010000000000000000), +('1.0e-26', -.000000000000000000000000010000000000000000), +('1.0e-27', -.0000000000000000000000000010000000000000000), +('1.0e-28', -.00000000000000000000000000010000000000000000), +('1.0e-29', -.000000000000000000000000000010000000000000000), +('1.0e-30', -.0000000000000000000000000000010000000000000000), +('1.0e-31', -.00000000000000000000000000000010000000000000000), +('1.0e-32', -.000000000000000000000000000000010000000000000000), +('1.0e-33', -.0000000000000000000000000000000010000000000000000), +('1.0e-34', -.00000000000000000000000000000000010000000000000000), +('1.0e-35', -.000000000000000000000000000000000010000000000000000), +('1.0e-36', -.0000000000000000000000000000000000010000000000000000), +('1.0e-37', -.00000000000000000000000000000000000010000000000000000), +('1.0e-38', -.000000000000000000000000000000000000010000000000000000), +('1.0e-39', -.0000000000000000000000000000000000000010000000000000000), +('1.0e-40', -.00000000000000000000000000000000000000010000000000000000)) +SELECT '1-'||x, bc_result, ln(1.0-x::numeric), ln(1.0-x::numeric)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +('1.0e-1', .09531017980432486), +('1.0e-2', .009950330853168083), +('1.0e-3', .0009995003330835332), +('1.0e-4', .00009999500033330834), +('1.0e-5', .000009999950000333331), +('1.0e-6', .0000009999995000003333), +('1.0e-7', .00000009999999500000033), +('1.0e-8', .000000009999999950000000), +('1.0e-9', .0000000009999999995000000), +('1.0e-10', .00000000009999999999500000), +('1.0e-11', .000000000009999999999950000), +('1.0e-12', .0000000000009999999999995000), +('1.0e-13', .00000000000009999999999999500), +('1.0e-14', .000000000000009999999999999950), +('1.0e-15', .0000000000000009999999999999995), +('1.0e-16', .00000000000000010000000000000000), +('1.0e-17', .000000000000000010000000000000000), +('1.0e-18', .0000000000000000010000000000000000), +('1.0e-19', .00000000000000000010000000000000000), +('1.0e-20', .000000000000000000010000000000000000), +('1.0e-21', .0000000000000000000010000000000000000), +('1.0e-22', .00000000000000000000010000000000000000), +('1.0e-23', .000000000000000000000010000000000000000), +('1.0e-24', .0000000000000000000000010000000000000000), +('1.0e-25', .00000000000000000000000010000000000000000), +('1.0e-26', .000000000000000000000000010000000000000000), +('1.0e-27', .0000000000000000000000000010000000000000000), +('1.0e-28', .00000000000000000000000000010000000000000000), +('1.0e-29', .000000000000000000000000000010000000000000000), +('1.0e-30', .0000000000000000000000000000010000000000000000), +('1.0e-31', .00000000000000000000000000000010000000000000000), +('1.0e-32', .000000000000000000000000000000010000000000000000), +('1.0e-33', .0000000000000000000000000000000010000000000000000), +('1.0e-34', .00000000000000000000000000000000010000000000000000), +('1.0e-35', .000000000000000000000000000000000010000000000000000), +('1.0e-36', .0000000000000000000000000000000000010000000000000000), +('1.0e-37', .00000000000000000000000000000000000010000000000000000), +('1.0e-38', .000000000000000000000000000000000000010000000000000000), +('1.0e-39', .0000000000000000000000000000000000000010000000000000000), +('1.0e-40', .00000000000000000000000000000000000000010000000000000000)) +SELECT '1+'||x, bc_result, ln(1.0+x::numeric), ln(1.0+x::numeric)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +('1.0e1', 2.3025850929940457), +('1.0e2', 4.6051701859880914), +('1.0e3', 6.9077552789821371), +('1.0e4', 9.2103403719761827), +('1.0e5', 11.512925464970228), +('1.0e6', 13.815510557964274), +('1.0e7', 16.118095650958320), +('1.0e8', 18.420680743952365), +('1.0e9', 20.723265836946411), +('1.0e10', 23.025850929940457), +('1.0e11', 25.328436022934503), +('1.0e12', 27.631021115928548), +('1.0e13', 29.933606208922594), +('1.0e14', 32.236191301916640), +('1.0e15', 34.538776394910685), +('1.0e16', 36.841361487904731), +('1.0e17', 39.143946580898777), +('1.0e18', 41.446531673892822), +('1.0e19', 43.749116766886868), +('1.0e20', 46.051701859880914), +('1.0e21', 48.354286952874959), +('1.0e22', 50.656872045869005), +('1.0e23', 52.959457138863051), +('1.0e24', 55.262042231857096), +('1.0e25', 57.564627324851142), +('1.0e26', 59.867212417845188), +('1.0e27', 62.169797510839233), +('1.0e28', 64.472382603833279), +('1.0e29', 66.774967696827325), +('1.0e30', 69.077552789821371), +('1.0e31', 71.380137882815416), +('1.0e32', 73.682722975809462), +('1.0e33', 75.985308068803508), +('1.0e34', 78.287893161797553), +('1.0e35', 80.590478254791599), +('1.0e36', 82.893063347785645), +('1.0e37', 85.195648440779690), +('1.0e38', 87.498233533773736), +('1.0e39', 89.800818626767782), +('1.0e40', 92.103403719761827)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +('1.0e100', 230.25850929940457), +('1.0e200', 460.51701859880914), +('1.0e300', 690.77552789821371), +('1.0e400', 921.03403719761827), +('1.0e500', 1151.2925464970228), +('1.0e600', 1381.5510557964274), +('1.0e700', 1611.8095650958320), +('1.0e800', 1842.0680743952365), +('1.0e900', 2072.3265836946411), +('1.0e1000', 2302.5850929940457)) +SELECT x, bc_result, ln(x::numeric), ln(x::numeric)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +(484990182159328900690402236933516249572671683638747490717351807610531884491845416923860371219625151551889257298200816555016472471293780254009492949585031653913930735918829139712249577547959394351523545901788627247613322896296041868431769047433229466634098452564756860190085118463828382895145244362033728480588969626012192733802377468089120757046364393407262957242230928854711898925295251902007136232994524624903257456111389508582206404271734668422903183500589303866613158037169610592539145461637447957948521714058034772237111009429638870236361143304703683377693378577075353794118557951847394763531830696578809001981568860219578880229402696449243344235099860421846016326538272155937175661905904288335499593232232926636205909086901191153907183842087577811871344870731324067822883041265129394268082883745408414994.8967939438561591657171240282983703914075472645212002662497023142663831371447287624846942598424990784971781730103682951722370983277124599054059027055336437808366784501932987082321905202623642371063626378290734289114618092750984153422293450048717769065428713836637664433167768445609659527458911187829232316677137895259433038764404970599325009178297626038331436654541552998098529141205301472138026818453893127265938030066392881979113522757891639646670670272542401773230506961559808927249585675430838495658225557294666522469887436551840596777627408780618586500922973500018513068499587683746133637919751545157547095670767246977244726331271787622126889459658539988980096764323712767863722912919120929339399753431689512753214200090670880647731689804555417871258907716687575767185444541243606329768784843125926070743277339790277626515824924290352180761378846035233155198504033292692893297993698953705472933411199778880561376633444249703838589180474329586470353212010427945060694794274109764269805332803290229, + 1864.3702986939570026328504202935192533137907736189919154633800554877738455118081651650863235106905871352085850240570561347180517240105510505203972860921397909573687877993477806728098306202020229409548306695695574102950949468160529713610952021974630774784174851619325758380143625473386495586347322798415543385655090746985183329114860118551572428921774322172798724455202876781611633419444058398798142214904998877857425038669920064728855823072107227506485770367799671977282350083029452784747350395161797215115525867416898416360638482342253129160308632504217096916335590470843180746834864303790913372081974355613359678634194879425862536147988835528973291020680020540866655622823550861337486588647231688134992810403147262346312159819432914207194632564009749236609081399504118359354620598232725290537215007867979331582119891661859015726276335168158288396939655310210558566592649049602925182137256134162660116182293851038854455437841571331011002023088829768308520393956515509475418031437505751407687618234418262), +(87190145885430429849953615409019208993240447426362428988181639909267773304254748257120061524000254226856815085523676417146197197996896030672521334101413071112068202429835905642444187493717977611730127126387257253646790849384975208460867137315507010888782632024640844766297185244443116696943912406389670302370461137850160539373600494054874979342373255280815156048999900951842673141766630630919020492255966628630634124452614590400422133958133100159154995520080124736657520969784129924799670552560034302960877087853678350801769339861812435411200669026902417951572668727488315537985378304242438181615160041688723201917323705450185975141141262578884689500612295576288125956289035673242989906973367691922065122033180281670221390667818909912035903387888639331486823729897326624516015340.0330856710565117793999512551468220085711713631167607285185762046751452975325645379302403715842570486302993296501788672462090620871511446272026693318239212657949496275318383141403236705902077406660768573015707706831878445598837931116223956945944726162551477136715847593742032488181481888084716920605114101902724395659898621880016853548602514706686907951229872573180602614761229992106144727082722940736406782659562775289407005631298246624198606031298081220736931229256511054595028182057216042683060059115371651410352645266000330509331097811566633211452233019461903115970558624057877018778178814946285827512359903934291318219271464841957435711594154280905473802599888081783098187210283997106131616471807951265003903143099667366508222327805543948921694362089860577380749774036318574113007382111997454202845559941557812813566442364810680529092880773126707073967537693927177460459341763934709686530005721141046645111784404932103241501569571235364365556796422998363930810983452790309019295181282099408260156, + 1793.5767085750017553306932533574391150814202249805881581227430032600579405884415934520704053351781361105595296647510475380766428668443641914861849764330704062323054023252886955844207807229267936432730818329225450152491146839618683772020068682795388746108876393249306737841247788224204701299467519965182171772253974884845661168860422489046657965359832930382114760565628765599962013955588754803194908990025689040598990346417563277021386852342928910383706995866844541160576254266641602065102228267316550706943783591722246885978355472097314691737807509436806788803362444745551013400341861820755594413819894154786253014501454443272120342005711761286524843010157182464200556865694401941794983935172457481497909987740544409272349152397774548604845897687504977786762391359552407068124283290504752932824699865504970420939586707791994870941813718246825616335675307740641350673558328821461530563823677144691877374809441673507467507447891562257806191361453045937798278733402269265623588493124129181374135958668436774), +(93936642222690597390233191619858485419795942047468396309991947772747208870873993801669373075421461116465960407843923269693395211616591453397070258466704654943689268224479477016161636938138334729982904232438440955361656138189836032891825113139184685132178764873033678116450665758561650355252211196676137179184043639278410827092182700922151290703747496962700158844772453483316974221113826173404445159281421213715669245417896170368554410830320000019029956317336703559699859949692222685614036912057150632902650913831404804982509990655560731349634628713944739168096272097122388116038119844786988276635032016787352796502360718569977397214936366251320294621522016.6483354941025384161536675750898007896744690911429670830432784905421638721478353275821072200938900938046264210604940707974410950770029535636602548377806284157951164875821446035013896786653932045182167021839184824627082391478016195098055107001433336586881395912782883663046617432598969149948351689103230162742769845955320418573803127107923535948653168889411316007796459064267436246637115946581149511513369842911210359447262641996566147462977170742544980481275049898092152042927981394239266559286915303786701737610786594006685748456635797125029722684151298695274097006242412384086302106763844070230264910503179385988626477852818174114043927841085089058972074427820150462261941575665882880501074676800316585217150509780489224388148722603385921057007086785238310735038314861960410473809826927329368597558806004392175746233568789445929554890241140656324160187253042639339549705859147930476532359840809944163908006480881926041259363654863689570520534301207043189181147254153307163555433328278834311658232337, + 1510.4332713542154696529645934345554302578243896764921637693542962119938599884313210100957753316832762996428481801312323020427109678979117469716796746760060470871840325255146954580681101106876674367471955788143763250819168311353856748872452260808797135108102729064040463343792765872545182299889360257515315869180266759715933989413256377582681707188367254513700731642913479683031478361835565783219287780434673712341147656477670848734998849030451414278832848680301511646182446524915091598080243532068451726548537866633622180283865668708517173065893429240665300584705585310049892047293928733753369421499719516009692095913169665213597158441636480707309244604139865130782756488091268094213446272360006907802989573582755585110277620911226015342778471352130366770729972784317323917141031824334355639769512749560550167491709646539950725523461943580211843652293561678342656010571108219244870234329176123205423872844099992204896411752620881541000940129833754169391528449211839693800724450201835161044717173715867437)) +SELECT trim_scale(ln(x::numeric)-bc_result) AS diff FROM t; + +WITH t(x) AS (SELECT '1e-'||n FROM generate_series(1, 100) g(n)) +SELECT x, log(x::numeric) FROM t; + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', -.04575749056067513), +('6.0e-1', -.2218487496163564), +('3.0e-1', -.5228787452803376), +('9.0e-8', -7.045757490560675), +('6.0e-8', -7.221848749616356), +('3.0e-8', -7.522878745280338), +('9.0e-15', -14.0457574905606751), +('6.0e-15', -14.2218487496163564), +('3.0e-15', -14.5228787452803376), +('9.0e-22', -21.04575749056067512540994), +('6.0e-22', -21.22184874961635636749123), +('3.0e-22', -21.52287874528033756270497), +('9.0e-29', -28.045757490560675125409944193490), +('6.0e-29', -28.221848749616356367491233202020), +('3.0e-29', -28.522878745280337562704972096745), +('9.0e-36', -35.0457574905606751254099441934897693816), +('6.0e-36', -35.2218487496163563674912332020203916640), +('3.0e-36', -35.5228787452803375627049720967448846908), +('9.0e-43', -42.04575749056067512540994419348976938159974227), +('6.0e-43', -42.22184874961635636749123320202039166403168125), +('3.0e-43', -42.52287874528033756270497209674488469079987114), +('9.0e-50', -49.045757490560675125409944193489769381599742271618608), +('6.0e-50', -49.221848749616356367491233202020391664031681254347196), +('3.0e-50', -49.522878745280337562704972096744884690799871135809304)) +SELECT x, bc_result, log(x::numeric), log(x::numeric)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', -1.0000000000000000), +('6.0e-1', -.3979400086720376), +('3.0e-1', -.1549019599857432), +('9.0e-8', -.000000039086505130185422), +('6.0e-8', -.000000026057669695925208), +('3.0e-8', -.000000013028834652530076), +('9.0e-15', -.0000000000000039086503371292840), +('6.0e-15', -.0000000000000026057668914195188), +('3.0e-15', -.0000000000000013028834457097574), +('9.0e-22', -.00000000000000000000039086503371292664), +('6.0e-22', -.00000000000000000000026057668914195110), +('3.0e-22', -.00000000000000000000013028834457097555), +('9.0e-29', -.000000000000000000000000000039086503371292664), +('6.0e-29', -.000000000000000000000000000026057668914195110), +('3.0e-29', -.000000000000000000000000000013028834457097555), +('9.0e-36', -.0000000000000000000000000000000000039086503371292664), +('6.0e-36', -.0000000000000000000000000000000000026057668914195110), +('3.0e-36', -.0000000000000000000000000000000000013028834457097555)) +SELECT '1-'||x, bc_result, log(1.0-x::numeric), log(1.0-x::numeric)-bc_result AS diff FROM t; + +WITH t(x, bc_result) AS (VALUES +('9.0e-1', .2787536009528290), +('6.0e-1', .2041199826559248), +('3.0e-1', .1139433523068368), +('9.0e-8', .000000039086501612400118), +('6.0e-8', .000000026057668132465074), +('3.0e-8', .000000013028834261665042), +('9.0e-15', .0000000000000039086503371292489), +('6.0e-15', .0000000000000026057668914195031), +('3.0e-15', .0000000000000013028834457097535), +('9.0e-22', .00000000000000000000039086503371292664), +('6.0e-22', .00000000000000000000026057668914195110), +('3.0e-22', .00000000000000000000013028834457097555), +('9.0e-29', .000000000000000000000000000039086503371292664), +('6.0e-29', .000000000000000000000000000026057668914195110), +('3.0e-29', .000000000000000000000000000013028834457097555), +('9.0e-36', .0000000000000000000000000000000000039086503371292664), +('6.0e-36', .0000000000000000000000000000000000026057668914195110), +('3.0e-36', .0000000000000000000000000000000000013028834457097555)) +SELECT '1+'||x, bc_result, log(1.0+x::numeric), log(1.0+x::numeric)-bc_result AS diff FROM t; + +WITH t(x) AS (SELECT '1e'||n FROM generate_series(1, 100) g(n)) +SELECT x, log(x::numeric) FROM t; + +WITH t(x, bc_result) AS (VALUES +('2.0e10', 10.301029995663981), +('5.0e10', 10.698970004336019), +('8.0e10', 10.903089986991944), +('2.0e17', 17.301029995663981), +('5.0e17', 17.698970004336019), +('8.0e17', 17.903089986991944), +('2.0e24', 24.301029995663981), +('5.0e24', 24.698970004336019), +('8.0e24', 24.903089986991944), +('2.0e31', 31.301029995663981), +('5.0e31', 31.698970004336019), +('8.0e31', 31.903089986991944), +('2.0e38', 38.301029995663981), +('5.0e38', 38.698970004336019), +('8.0e38', 38.903089986991944), +('2.0e45', 45.30102999566398), +('5.0e45', 45.69897000433602), +('8.0e45', 45.90308998699194)) +SELECT x, bc_result, log(x::numeric), log(x::numeric)-bc_result AS diff FROM t; diff --git a/crates/pgt_pretty_print/tests/data/multi/numerology_60.sql b/crates/pgt_pretty_print/tests/data/multi/numerology_60.sql new file mode 100644 index 000000000..b091f9f78 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/numerology_60.sql @@ -0,0 +1,166 @@ +SELECT 0b100101; + +SELECT 0o273; + +SELECT 0x42F; + +SELECT 0b1111111111111111111111111111111; + +SELECT 0b10000000000000000000000000000000; + +SELECT 0o17777777777; + +SELECT 0o20000000000; + +SELECT 0x7FFFFFFF; + +SELECT 0x80000000; + +SELECT -0b10000000000000000000000000000000; + +SELECT -0b10000000000000000000000000000001; + +SELECT -0o20000000000; + +SELECT -0o20000000001; + +SELECT -0x80000000; + +SELECT -0x80000001; + +SELECT 0b111111111111111111111111111111111111111111111111111111111111111; + +SELECT 0b1000000000000000000000000000000000000000000000000000000000000000; + +SELECT 0o777777777777777777777; + +SELECT 0o1000000000000000000000; + +SELECT 0x7FFFFFFFFFFFFFFF; + +SELECT 0x8000000000000000; + +SELECT -0b1000000000000000000000000000000000000000000000000000000000000000; + +SELECT -0b1000000000000000000000000000000000000000000000000000000000000001; + +SELECT -0o1000000000000000000000; + +SELECT -0o1000000000000000000001; + +SELECT -0x8000000000000000; + +SELECT -0x8000000000000001; + +PREPARE p1 AS SELECT $1a; + +PREPARE p1 AS SELECT $2147483648; + +SELECT 1_000_000; + +SELECT 1_2_3; + +SELECT 0x1EEE_FFFF; + +SELECT 0o2_73; + +SELECT 0b_10_0101; + +SELECT 1_000.000_005; + +SELECT 1_000.; + +SELECT .000_005; + +SELECT 1_000.5e0_1; + +DO $$ +DECLARE + i int; +BEGIN + FOR i IN 1_001..1_003 LOOP + RAISE NOTICE 'i = %', i; + END LOOP; +END $$; + +SELECT _100; + +PREPARE p1 AS SELECT $0_1; + +CREATE TABLE TEMP_FLOAT (f1 FLOAT8); + +INSERT INTO TEMP_FLOAT (f1) + SELECT float8(f1) FROM INT4_TBL; + +INSERT INTO TEMP_FLOAT (f1) + SELECT float8(f1) FROM INT2_TBL; + +SELECT f1 FROM TEMP_FLOAT + ORDER BY f1; + +CREATE TABLE TEMP_INT4 (f1 INT4); + +INSERT INTO TEMP_INT4 (f1) + SELECT int4(f1) FROM FLOAT8_TBL + WHERE (f1 > -2147483647) AND (f1 < 2147483647); + +INSERT INTO TEMP_INT4 (f1) + SELECT int4(f1) FROM INT2_TBL; + +SELECT f1 FROM TEMP_INT4 + ORDER BY f1; + +CREATE TABLE TEMP_INT2 (f1 INT2); + +INSERT INTO TEMP_INT2 (f1) + SELECT int2(f1) FROM FLOAT8_TBL + WHERE (f1 >= -32767) AND (f1 <= 32767); + +INSERT INTO TEMP_INT2 (f1) + SELECT int2(f1) FROM INT4_TBL + WHERE (f1 >= -32767) AND (f1 <= 32767); + +SELECT f1 FROM TEMP_INT2 + ORDER BY f1; + +CREATE TABLE TEMP_GROUP (f1 INT4, f2 INT4, f3 FLOAT8); + +INSERT INTO TEMP_GROUP + SELECT 1, (- i.f1), (- f.f1) + FROM INT4_TBL i, FLOAT8_TBL f; + +INSERT INTO TEMP_GROUP + SELECT 2, i.f1, f.f1 + FROM INT4_TBL i, FLOAT8_TBL f; + +SELECT DISTINCT f1 AS two FROM TEMP_GROUP ORDER BY 1; + +SELECT f1 AS two, max(f3) AS max_float, min(f3) as min_float + FROM TEMP_GROUP + GROUP BY f1 + ORDER BY two, max_float, min_float; + +SELECT f1 AS two, max(f3) AS max_float, min(f3) AS min_float + FROM TEMP_GROUP + GROUP BY two + ORDER BY two, max_float, min_float; + +SELECT f1 AS two, (max(f3) + 1) AS max_plus_1, (min(f3) - 1) AS min_minus_1 + FROM TEMP_GROUP + GROUP BY f1 + ORDER BY two, min_minus_1; + +SELECT f1 AS two, + max(f2) + min(f2) AS max_plus_min, + min(f3) - 1 AS min_minus_1 + FROM TEMP_GROUP + GROUP BY f1 + ORDER BY two, min_minus_1; + +DROP TABLE TEMP_INT2; + +DROP TABLE TEMP_INT4; + +DROP TABLE TEMP_FLOAT; + +DROP TABLE TEMP_GROUP; diff --git a/crates/pgt_pretty_print/tests/data/multi/object_address_60.sql b/crates/pgt_pretty_print/tests/data/multi/object_address_60.sql new file mode 100644 index 000000000..26c13772c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/object_address_60.sql @@ -0,0 +1,332 @@ +SET client_min_messages TO 'warning'; + +DROP ROLE IF EXISTS regress_addr_user; + +RESET client_min_messages; + +CREATE USER regress_addr_user; + +CREATE SCHEMA addr_nsp; + +SET search_path TO 'addr_nsp'; + +CREATE FOREIGN DATA WRAPPER addr_fdw; + +CREATE SERVER addr_fserv FOREIGN DATA WRAPPER addr_fdw; + +CREATE TEXT SEARCH DICTIONARY addr_ts_dict (template=simple); + +CREATE TEXT SEARCH CONFIGURATION addr_ts_conf (copy=english); + +CREATE TEXT SEARCH TEMPLATE addr_ts_temp (lexize=dsimple_lexize); + +CREATE TEXT SEARCH PARSER addr_ts_prs + (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype); + +CREATE TABLE addr_nsp.gentable ( + a serial primary key CONSTRAINT a_chk CHECK (a > 0), + b text DEFAULT 'hello' +); + +CREATE TABLE addr_nsp.parttable ( + a int PRIMARY KEY +) PARTITION BY RANGE (a); + +CREATE VIEW addr_nsp.genview AS SELECT * from addr_nsp.gentable; + +CREATE MATERIALIZED VIEW addr_nsp.genmatview AS SELECT * FROM addr_nsp.gentable; + +CREATE TYPE addr_nsp.gencomptype AS (a int); + +CREATE TYPE addr_nsp.genenum AS ENUM ('one', 'two'); + +CREATE FOREIGN TABLE addr_nsp.genftable (a int) SERVER addr_fserv; + +CREATE AGGREGATE addr_nsp.genaggr(int4) (sfunc = int4pl, stype = int4); + +CREATE DOMAIN addr_nsp.gendomain AS int4 CONSTRAINT domconstr CHECK (value > 0); + +CREATE FUNCTION addr_nsp.trig() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN END; $$; + +CREATE TRIGGER t BEFORE INSERT ON addr_nsp.gentable FOR EACH ROW EXECUTE PROCEDURE addr_nsp.trig(); + +CREATE POLICY genpol ON addr_nsp.gentable; + +CREATE PROCEDURE addr_nsp.proc(int4) LANGUAGE SQL AS $$ $$; + +CREATE SERVER "integer" FOREIGN DATA WRAPPER addr_fdw; + +CREATE USER MAPPING FOR regress_addr_user SERVER "integer"; + +ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user IN SCHEMA public GRANT ALL ON TABLES TO regress_addr_user; + +ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE DELETE ON TABLES FROM regress_addr_user; + +CREATE TRANSFORM FOR int LANGUAGE SQL ( + FROM SQL WITH FUNCTION prsd_lextype(internal), + TO SQL WITH FUNCTION int4recv(internal)); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; + +CREATE PUBLICATION addr_pub_schema FOR TABLES IN SCHEMA addr_nsp; + +RESET client_min_messages; + +CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); + +CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable; + +SELECT pg_get_object_address('stone', '{}', '{}'); + +SELECT pg_get_object_address('table', '{}', '{}'); + +SELECT pg_get_object_address('table', '{NULL}', '{}'); + +DO $$ +DECLARE + objtype text; +BEGIN + FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'), + ('toast table column'), ('view column'), ('materialized view column') + LOOP + BEGIN + PERFORM pg_get_object_address(objtype, '{one}', '{}'); + EXCEPTION WHEN invalid_parameter_value THEN + RAISE WARNING 'error for %: %', objtype, sqlerrm; + END; + END LOOP; +END; +$$; + +select * from pg_get_object_address('operator of access method', '{btree,integer_ops,1}', '{int4,bool}'); + +select * from pg_get_object_address('operator of access method', '{btree,integer_ops,99}', '{int4,int4}'); + +select * from pg_get_object_address('function of access method', '{btree,integer_ops,1}', '{int4,bool}'); + +select * from pg_get_object_address('function of access method', '{btree,integer_ops,99}', '{int4,int4}'); + +DO $$ +DECLARE + objtype text; + names text[]; + args text[]; +BEGIN + FOR objtype IN VALUES + ('table'), ('index'), ('sequence'), ('view'), + ('materialized view'), ('foreign table'), + ('table column'), ('foreign table column'), + ('aggregate'), ('function'), ('procedure'), ('type'), ('cast'), + ('table constraint'), ('domain constraint'), ('conversion'), ('default value'), + ('operator'), ('operator class'), ('operator family'), ('rule'), ('trigger'), + ('text search parser'), ('text search dictionary'), + ('text search template'), ('text search configuration'), + ('policy'), ('user mapping'), ('default acl'), ('transform'), + ('operator of access method'), ('function of access method'), + ('publication namespace'), ('publication relation') + LOOP + FOR names IN VALUES ('{eins}'), ('{addr_nsp, zwei}'), ('{eins, zwei, drei}') + LOOP + FOR args IN VALUES ('{}'), ('{integer}') + LOOP + BEGIN + PERFORM pg_get_object_address(objtype, names, args); + EXCEPTION WHEN OTHERS THEN + RAISE WARNING 'error for %,%,%: %', objtype, names, args, sqlerrm; + END; + END LOOP; + END LOOP; + END LOOP; +END; +$$; + +SELECT pg_get_object_address('language', '{one}', '{}'); + +SELECT pg_get_object_address('language', '{one,two}', '{}'); + +SELECT pg_get_object_address('large object', '{123}', '{}'); + +SELECT pg_get_object_address('large object', '{123,456}', '{}'); + +SELECT pg_get_object_address('large object', '{blargh}', '{}'); + +SELECT pg_get_object_address('schema', '{one}', '{}'); + +SELECT pg_get_object_address('schema', '{one,two}', '{}'); + +SELECT pg_get_object_address('role', '{one}', '{}'); + +SELECT pg_get_object_address('role', '{one,two}', '{}'); + +SELECT pg_get_object_address('database', '{one}', '{}'); + +SELECT pg_get_object_address('database', '{one,two}', '{}'); + +SELECT pg_get_object_address('tablespace', '{one}', '{}'); + +SELECT pg_get_object_address('tablespace', '{one,two}', '{}'); + +SELECT pg_get_object_address('foreign-data wrapper', '{one}', '{}'); + +SELECT pg_get_object_address('foreign-data wrapper', '{one,two}', '{}'); + +SELECT pg_get_object_address('server', '{one}', '{}'); + +SELECT pg_get_object_address('server', '{one,two}', '{}'); + +SELECT pg_get_object_address('extension', '{one}', '{}'); + +SELECT pg_get_object_address('extension', '{one,two}', '{}'); + +SELECT pg_get_object_address('event trigger', '{one}', '{}'); + +SELECT pg_get_object_address('event trigger', '{one,two}', '{}'); + +SELECT pg_get_object_address('access method', '{one}', '{}'); + +SELECT pg_get_object_address('access method', '{one,two}', '{}'); + +SELECT pg_get_object_address('publication', '{one}', '{}'); + +SELECT pg_get_object_address('publication', '{one,two}', '{}'); + +SELECT pg_get_object_address('subscription', '{one}', '{}'); + +SELECT pg_get_object_address('subscription', '{one,two}', '{}'); + +WITH objects (type, name, args) AS (VALUES + ('table', '{addr_nsp, gentable}'::text[], '{}'::text[]), + ('table', '{addr_nsp, parttable}'::text[], '{}'::text[]), + ('index', '{addr_nsp, gentable_pkey}', '{}'), + ('index', '{addr_nsp, parttable_pkey}', '{}'), + ('sequence', '{addr_nsp, gentable_a_seq}', '{}'), + -- toast table + ('view', '{addr_nsp, genview}', '{}'), + ('materialized view', '{addr_nsp, genmatview}', '{}'), + ('foreign table', '{addr_nsp, genftable}', '{}'), + ('table column', '{addr_nsp, gentable, b}', '{}'), + ('foreign table column', '{addr_nsp, genftable, a}', '{}'), + ('aggregate', '{addr_nsp, genaggr}', '{int4}'), + ('function', '{pg_catalog, pg_identify_object}', '{pg_catalog.oid, pg_catalog.oid, int4}'), + ('procedure', '{addr_nsp, proc}', '{int4}'), + ('type', '{pg_catalog._int4}', '{}'), + ('type', '{addr_nsp.gendomain}', '{}'), + ('type', '{addr_nsp.gencomptype}', '{}'), + ('type', '{addr_nsp.genenum}', '{}'), + ('cast', '{int8}', '{int4}'), + ('collation', '{default}', '{}'), + ('table constraint', '{addr_nsp, gentable, a_chk}', '{}'), + ('domain constraint', '{addr_nsp.gendomain}', '{domconstr}'), + ('conversion', '{pg_catalog, koi8_r_to_mic}', '{}'), + ('default value', '{addr_nsp, gentable, b}', '{}'), + ('language', '{plpgsql}', '{}'), + -- large object + ('operator', '{+}', '{int4, int4}'), + ('operator class', '{btree, int4_ops}', '{}'), + ('operator family', '{btree, integer_ops}', '{}'), + ('operator of access method', '{btree,integer_ops,1}', '{integer,integer}'), + ('function of access method', '{btree,integer_ops,2}', '{integer,integer}'), + ('rule', '{addr_nsp, genview, _RETURN}', '{}'), + ('trigger', '{addr_nsp, gentable, t}', '{}'), + ('schema', '{addr_nsp}', '{}'), + ('text search parser', '{addr_ts_prs}', '{}'), + ('text search dictionary', '{addr_ts_dict}', '{}'), + ('text search template', '{addr_ts_temp}', '{}'), + ('text search configuration', '{addr_ts_conf}', '{}'), + ('role', '{regress_addr_user}', '{}'), + -- database + -- tablespace + ('foreign-data wrapper', '{addr_fdw}', '{}'), + ('server', '{addr_fserv}', '{}'), + ('user mapping', '{regress_addr_user}', '{integer}'), + ('default acl', '{regress_addr_user,public}', '{r}'), + ('default acl', '{regress_addr_user}', '{r}'), + -- extension + -- event trigger + ('policy', '{addr_nsp, gentable, genpol}', '{}'), + ('transform', '{int}', '{sql}'), + ('access method', '{btree}', '{}'), + ('publication', '{addr_pub}', '{}'), + ('publication namespace', '{addr_nsp}', '{addr_pub_schema}'), + ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), + ('subscription', '{regress_addr_sub}', '{}'), + ('statistics object', '{addr_nsp, gentable_stat}', '{}') + ) +SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, + -- test roundtrip through pg_identify_object_as_address + ROW(pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)) = + ROW(pg_identify_object(addr2.classid, addr2.objid, addr2.objsubid)) AS roundtrip +FROM objects, + pg_get_object_address(type, name, args) AS addr1, + pg_identify_object_as_address(classid, objid, objsubid) AS ioa (typ, nms, args), + pg_get_object_address(typ, nms, ioa.args) AS addr2 +ORDER BY addr1.classid, addr1.objid, addr1.objsubid; + +DROP FOREIGN DATA WRAPPER addr_fdw CASCADE; + +DROP PUBLICATION addr_pub; + +DROP PUBLICATION addr_pub_schema; + +DROP SUBSCRIPTION regress_addr_sub; + +DROP SCHEMA addr_nsp CASCADE; + +DROP OWNED BY regress_addr_user; + +DROP USER regress_addr_user; + +WITH objects (classid, objid, objsubid) AS (VALUES + ('pg_class'::regclass, 0, 0), -- no relation + ('pg_class'::regclass, 'pg_class'::regclass, 100), -- no column for relation + ('pg_proc'::regclass, 0, 0), -- no function + ('pg_type'::regclass, 0, 0), -- no type + ('pg_cast'::regclass, 0, 0), -- no cast + ('pg_collation'::regclass, 0, 0), -- no collation + ('pg_constraint'::regclass, 0, 0), -- no constraint + ('pg_conversion'::regclass, 0, 0), -- no conversion + ('pg_attrdef'::regclass, 0, 0), -- no default attribute + ('pg_language'::regclass, 0, 0), -- no language + ('pg_largeobject'::regclass, 0, 0), -- no large object, no error + ('pg_operator'::regclass, 0, 0), -- no operator + ('pg_opclass'::regclass, 0, 0), -- no opclass, no need to check for no access method + ('pg_opfamily'::regclass, 0, 0), -- no opfamily + ('pg_am'::regclass, 0, 0), -- no access method + ('pg_amop'::regclass, 0, 0), -- no AM operator + ('pg_amproc'::regclass, 0, 0), -- no AM proc + ('pg_rewrite'::regclass, 0, 0), -- no rewrite + ('pg_trigger'::regclass, 0, 0), -- no trigger + ('pg_namespace'::regclass, 0, 0), -- no schema + ('pg_statistic_ext'::regclass, 0, 0), -- no statistics + ('pg_ts_parser'::regclass, 0, 0), -- no TS parser + ('pg_ts_dict'::regclass, 0, 0), -- no TS dictionary + ('pg_ts_template'::regclass, 0, 0), -- no TS template + ('pg_ts_config'::regclass, 0, 0), -- no TS configuration + ('pg_authid'::regclass, 0, 0), -- no role + ('pg_auth_members'::regclass, 0, 0), -- no role membership + ('pg_database'::regclass, 0, 0), -- no database + ('pg_tablespace'::regclass, 0, 0), -- no tablespace + ('pg_foreign_data_wrapper'::regclass, 0, 0), -- no FDW + ('pg_foreign_server'::regclass, 0, 0), -- no server + ('pg_user_mapping'::regclass, 0, 0), -- no user mapping + ('pg_default_acl'::regclass, 0, 0), -- no default ACL + ('pg_extension'::regclass, 0, 0), -- no extension + ('pg_event_trigger'::regclass, 0, 0), -- no event trigger + ('pg_parameter_acl'::regclass, 0, 0), -- no parameter ACL + ('pg_policy'::regclass, 0, 0), -- no policy + ('pg_publication'::regclass, 0, 0), -- no publication + ('pg_publication_namespace'::regclass, 0, 0), -- no publication namespace + ('pg_publication_rel'::regclass, 0, 0), -- no publication relation + ('pg_subscription'::regclass, 0, 0), -- no subscription + ('pg_transform'::regclass, 0, 0) -- no transformation + ) +SELECT ROW(pg_identify_object(objects.classid, objects.objid, objects.objsubid)) + AS ident, + ROW(pg_identify_object_as_address(objects.classid, objects.objid, objects.objsubid)) + AS addr, + pg_describe_object(objects.classid, objects.objid, objects.objsubid) + AS descr +FROM objects +ORDER BY objects.classid, objects.objid, objects.objsubid; diff --git a/crates/pgt_pretty_print/tests/data/multi/oid_60.sql b/crates/pgt_pretty_print/tests/data/multi/oid_60.sql new file mode 100644 index 000000000..73e509f9a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/oid_60.sql @@ -0,0 +1,73 @@ +CREATE TABLE OID_TBL(f1 oid); + +INSERT INTO OID_TBL(f1) VALUES ('1234'); + +INSERT INTO OID_TBL(f1) VALUES ('1235'); + +INSERT INTO OID_TBL(f1) VALUES ('987'); + +INSERT INTO OID_TBL(f1) VALUES ('-1040'); + +INSERT INTO OID_TBL(f1) VALUES ('99999999'); + +INSERT INTO OID_TBL(f1) VALUES ('5 '); + +INSERT INTO OID_TBL(f1) VALUES (' 10 '); + +INSERT INTO OID_TBL(f1) VALUES (' 15 '); + +INSERT INTO OID_TBL(f1) VALUES (''); + +INSERT INTO OID_TBL(f1) VALUES (' '); + +INSERT INTO OID_TBL(f1) VALUES ('asdfasd'); + +INSERT INTO OID_TBL(f1) VALUES ('99asdfasd'); + +INSERT INTO OID_TBL(f1) VALUES ('5 d'); + +INSERT INTO OID_TBL(f1) VALUES (' 5d'); + +INSERT INTO OID_TBL(f1) VALUES ('5 5'); + +INSERT INTO OID_TBL(f1) VALUES (' - 500'); + +INSERT INTO OID_TBL(f1) VALUES ('32958209582039852935'); + +INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385'); + +SELECT * FROM OID_TBL; + +SELECT pg_input_is_valid('1234', 'oid'); + +SELECT pg_input_is_valid('01XYZ', 'oid'); + +SELECT * FROM pg_input_error_info('01XYZ', 'oid'); + +SELECT pg_input_is_valid('9999999999', 'oid'); + +SELECT * FROM pg_input_error_info('9999999999', 'oid'); + +SELECT pg_input_is_valid(' 1 2 4 ', 'oidvector'); + +SELECT pg_input_is_valid('01 01XYZ', 'oidvector'); + +SELECT * FROM pg_input_error_info('01 01XYZ', 'oidvector'); + +SELECT pg_input_is_valid('01 9999999999', 'oidvector'); + +SELECT * FROM pg_input_error_info('01 9999999999', 'oidvector'); + +SELECT o.* FROM OID_TBL o WHERE o.f1 = 1234; + +SELECT o.* FROM OID_TBL o WHERE o.f1 <> '1234'; + +SELECT o.* FROM OID_TBL o WHERE o.f1 <= '1234'; + +SELECT o.* FROM OID_TBL o WHERE o.f1 < '1234'; + +SELECT o.* FROM OID_TBL o WHERE o.f1 >= '1234'; + +SELECT o.* FROM OID_TBL o WHERE o.f1 > '1234'; + +DROP TABLE OID_TBL; diff --git a/crates/pgt_pretty_print/tests/data/multi/oidjoins_60.sql b/crates/pgt_pretty_print/tests/data/multi/oidjoins_60.sql new file mode 100644 index 000000000..1b32eb9b4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/oidjoins_60.sql @@ -0,0 +1,46 @@ +DO $doblock$ +declare + fk record; + nkeys integer; + cmd text; + err record; +begin + for fk in select * from pg_get_catalog_foreign_keys() + loop + raise notice 'checking % % => % %', + fk.fktable, fk.fkcols, fk.pktable, fk.pkcols; + nkeys := array_length(fk.fkcols, 1); + cmd := 'SELECT ctid'; + for i in 1 .. nkeys loop + cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); + end loop; + if fk.is_array then + cmd := cmd || ' FROM (SELECT ctid'; + for i in 1 .. nkeys-1 loop + cmd := cmd || ', ' || quote_ident(fk.fkcols[i]); + end loop; + cmd := cmd || ', unnest(' || quote_ident(fk.fkcols[nkeys]); + cmd := cmd || ') as ' || quote_ident(fk.fkcols[nkeys]); + cmd := cmd || ' FROM ' || fk.fktable::text || ') fk WHERE '; + else + cmd := cmd || ' FROM ' || fk.fktable::text || ' fk WHERE '; + end if; + if fk.is_opt then + for i in 1 .. nkeys loop + cmd := cmd || quote_ident(fk.fkcols[i]) || ' != 0 AND '; + end loop; + end if; + cmd := cmd || 'NOT EXISTS(SELECT 1 FROM ' || fk.pktable::text || ' pk WHERE '; + for i in 1 .. nkeys loop + if i > 1 then cmd := cmd || ' AND '; end if; + cmd := cmd || 'pk.' || quote_ident(fk.pkcols[i]); + cmd := cmd || ' = fk.' || quote_ident(fk.fkcols[i]); + end loop; + cmd := cmd || ')'; + -- raise notice 'cmd = %', cmd; + for err in execute cmd loop + raise warning 'FK VIOLATION IN %(%): %', fk.fktable, fk.fkcols, err; + end loop; + end loop; +end +$doblock$; diff --git a/crates/pgt_pretty_print/tests/data/multi/opr_sanity_60.sql b/crates/pgt_pretty_print/tests/data/multi/opr_sanity_60.sql new file mode 100644 index 000000000..1b6d45c68 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/opr_sanity_60.sql @@ -0,0 +1,999 @@ +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prolang = 0 OR p1.prorettype = 0 OR + p1.pronargs < 0 OR + p1.pronargdefaults < 0 OR + p1.pronargdefaults > p1.pronargs OR + array_lower(p1.proargtypes, 1) != 0 OR + array_upper(p1.proargtypes, 1) != p1.pronargs-1 OR + 0::oid = ANY (p1.proargtypes) OR + procost <= 0 OR + CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END OR + prokind NOT IN ('f', 'a', 'w', 'p') OR + provolatile NOT IN ('i', 's', 'v') OR + proparallel NOT IN ('s', 'r', 'u'); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prosrc IS NULL; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE (prosrc = '' OR prosrc = '-') AND prosqlbody IS NULL; + +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE proretset AND prokind != 'f'; + +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE prosecdef +ORDER BY 1; + +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE (pronargdefaults <> 0) != (proargdefaults IS NOT NULL); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prolang = 13 AND (probin IS NULL OR probin = '' OR probin = '-'); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE prolang != 13 AND probin IS NOT NULL; + +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.proname = p2.proname AND + p1.pronargs = p2.pronargs AND + p1.proargtypes = p2.proargtypes; + +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid < p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + (p1.prokind != 'a' OR p2.prokind != 'a') AND + (p1.prolang != p2.prolang OR + p1.prokind != p2.prokind OR + p1.prosecdef != p2.prosecdef OR + p1.proleakproof != p2.proleakproof OR + p1.proisstrict != p2.proisstrict OR + p1.proretset != p2.proretset OR + p1.provolatile != p2.provolatile OR + p1.pronargs != p2.pronargs); + +SELECT DISTINCT p1.prorettype::regtype, p2.prorettype::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.prorettype < p2.prorettype) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[0]::regtype, p2.proargtypes[0]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.proargtypes[0] < p2.proargtypes[0]) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[1]::regtype, p2.proargtypes[1]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + p1.prosrc NOT LIKE E'range\\_constructor_' AND + p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND + (p1.proargtypes[1] < p2.proargtypes[1]) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[2]::regtype, p2.proargtypes[2]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[2] < p2.proargtypes[2]) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[3]::regtype, p2.proargtypes[3]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[3] < p2.proargtypes[3]) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[4]::regtype, p2.proargtypes[4]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[4] < p2.proargtypes[4]) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[5]::regtype, p2.proargtypes[5]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[5] < p2.proargtypes[5]) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[6]::regtype, p2.proargtypes[6]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[6] < p2.proargtypes[6]) +ORDER BY 1, 2; + +SELECT DISTINCT p1.proargtypes[7]::regtype, p2.proargtypes[7]::regtype +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid != p2.oid AND + p1.prosrc = p2.prosrc AND + p1.prolang = 12 AND p2.prolang = 12 AND + p1.prokind != 'a' AND p2.prokind != 'a' AND + (p1.proargtypes[7] < p2.proargtypes[7]) +ORDER BY 1, 2; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'internal'::regtype AND NOT + 'internal'::regtype = ANY (p1.proargtypes); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN + ('anyelement'::regtype, 'anyarray'::regtype, 'anynonarray'::regtype, + 'anyenum'::regtype) + AND NOT + ('anyelement'::regtype = ANY (p1.proargtypes) OR + 'anyarray'::regtype = ANY (p1.proargtypes) OR + 'anynonarray'::regtype = ANY (p1.proargtypes) OR + 'anyenum'::regtype = ANY (p1.proargtypes) OR + 'anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN ('anyrange'::regtype, 'anymultirange'::regtype) + AND NOT + ('anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype IN + ('anycompatible'::regtype, 'anycompatiblearray'::regtype, + 'anycompatiblenonarray'::regtype) + AND NOT + ('anycompatible'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblearray'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblenonarray'::regtype = ANY (p1.proargtypes) OR + 'anycompatiblerange'::regtype = ANY (p1.proargtypes)) +ORDER BY 2; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'anycompatiblerange'::regtype + AND NOT + 'anycompatiblerange'::regtype = ANY (p1.proargtypes) +ORDER BY 2; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE 'cstring'::regtype = ANY (p1.proargtypes) + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid) + AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid) + AND p1.oid != 'shell_in(cstring)'::regprocedure +ORDER BY 1; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE p1.prorettype = 'cstring'::regtype + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid) + AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid) + AND p1.oid != 'shell_out(void)'::regprocedure +ORDER BY 1; + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND + array_length(proallargtypes,1) < array_length(proargtypes,1); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargmodes IS NOT NULL AND + array_length(proargmodes,1) < array_length(proargtypes,1); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargnames IS NOT NULL AND + array_length(proargnames,1) < array_length(proargtypes,1); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND proargmodes IS NOT NULL AND + array_length(proallargtypes,1) <> array_length(proargmodes,1); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND proargnames IS NOT NULL AND + array_length(proallargtypes,1) <> array_length(proargnames,1); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 +WHERE proargmodes IS NOT NULL AND proargnames IS NOT NULL AND + array_length(proargmodes,1) <> array_length(proargnames,1); + +SELECT p1.oid, p1.proname, p1.proargtypes, p1.proallargtypes, p1.proargmodes +FROM pg_proc as p1 +WHERE proallargtypes IS NOT NULL AND + ARRAY(SELECT unnest(proargtypes)) <> + ARRAY(SELECT proallargtypes[i] + FROM generate_series(1, array_length(proallargtypes, 1)) g(i) + WHERE proargmodes IS NULL OR proargmodes[i] IN ('i', 'b', 'v')); + +SELECT oid::regprocedure, provariadic::regtype, proargtypes::regtype[] +FROM pg_proc +WHERE provariadic != 0 +AND case proargtypes[array_length(proargtypes, 1)-1] + WHEN '"any"'::regtype THEN '"any"'::regtype + WHEN 'anyarray'::regtype THEN 'anyelement'::regtype + WHEN 'anycompatiblearray'::regtype THEN 'anycompatible'::regtype + ELSE (SELECT t.oid + FROM pg_type t + WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1]) + END != provariadic; + +SELECT oid::regprocedure, proargmodes, provariadic +FROM pg_proc +WHERE (proargmodes IS NOT NULL AND 'v' = any(proargmodes)) + IS DISTINCT FROM + (provariadic != 0); + +SELECT p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p2.oid = p1.prosupport AND + (p2.prorettype != 'internal'::regtype OR p2.proretset OR p2.pronargs != 1 + OR p2.proargtypes[0] != 'internal'::regtype); + +SELECT p1.oid, p1.proname +FROM pg_proc as p1 LEFT JOIN pg_description as d + ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0 +WHERE d.classoid IS NULL AND p1.oid <= 9999; + +SELECT p1.oid::regprocedure +FROM pg_proc p1 JOIN pg_namespace pn + ON pronamespace = pn.oid +WHERE nspname = 'pg_catalog' AND proleakproof +ORDER BY 1; + +SELECT p1.oid::regprocedure +FROM pg_proc p1 JOIN pg_namespace pn + ON pronamespace = pn.oid +WHERE nspname = 'pg_catalog' AND proleakproof AND pronargs = 0 +ORDER BY 1; + +select proname, oid from pg_catalog.pg_proc +where proname in ( + 'lo_open', + 'lo_close', + 'lo_creat', + 'lo_create', + 'lo_unlink', + 'lo_lseek', + 'lo_lseek64', + 'lo_tell', + 'lo_tell64', + 'lo_truncate', + 'lo_truncate64', + 'loread', + 'lowrite') +and pronamespace = (select oid from pg_catalog.pg_namespace + where nspname = 'pg_catalog') +order by 1; + +SELECT p1.oid, p1.proname +FROM pg_proc AS p1 +WHERE provolatile = 'i' AND proparallel = 'u'; + +SELECT * +FROM pg_cast c +WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i') + OR castmethod NOT IN ('f', 'b' ,'i'); + +SELECT * +FROM pg_cast c +WHERE (castmethod = 'f' AND castfunc = 0) + OR (castmethod IN ('b', 'i') AND castfunc <> 0); + +SELECT * +FROM pg_cast c +WHERE castsource = casttarget AND castfunc = 0; + +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget; + +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND + (p.pronargs < 1 OR p.pronargs > 3 + OR NOT (binary_coercible(c.castsource, p.proargtypes[0]) + OR (c.castsource = 'character'::regtype AND + p.proargtypes[0] = 'text'::regtype)) + OR NOT binary_coercible(p.prorettype, c.casttarget)); + +SELECT c.* +FROM pg_cast c, pg_proc p +WHERE c.castfunc = p.oid AND + ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR + (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype)); + +SELECT castsource::regtype, casttarget::regtype, castfunc, castcontext +FROM pg_cast c +WHERE c.castmethod = 'b' AND + NOT EXISTS (SELECT 1 FROM pg_cast k + WHERE k.castmethod = 'b' AND + k.castsource = c.casttarget AND + k.casttarget = c.castsource); + +SELECT c.oid, c.conname +FROM pg_conversion as c +WHERE c.conproc = 0 OR + pg_encoding_to_char(conforencoding) = '' OR + pg_encoding_to_char(contoencoding) = ''; + +SELECT p.oid, p.proname, c.oid, c.conname +FROM pg_proc p, pg_conversion c +WHERE p.oid = c.conproc AND + (p.prorettype != 'int4'::regtype OR p.proretset OR + p.pronargs != 6 OR + p.proargtypes[0] != 'int4'::regtype OR + p.proargtypes[1] != 'int4'::regtype OR + p.proargtypes[2] != 'cstring'::regtype OR + p.proargtypes[3] != 'internal'::regtype OR + p.proargtypes[4] != 'int4'::regtype OR + p.proargtypes[5] != 'bool'::regtype); + +SELECT c.oid, c.conname +FROM pg_conversion as c +WHERE condefault AND + convert('ABC'::bytea, pg_encoding_to_char(conforencoding), + pg_encoding_to_char(contoencoding)) != 'ABC'; + +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 +WHERE (o1.oprkind != 'b' AND o1.oprkind != 'l') OR + o1.oprresult = 0 OR o1.oprcode = 0; + +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 +WHERE (o1.oprleft = 0 and o1.oprkind != 'l') OR + (o1.oprleft != 0 and o1.oprkind = 'l') OR + o1.oprright = 0; + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oid != o2.oid AND + o1.oprname = o2.oprname AND + o1.oprkind = o2.oprkind AND + o1.oprleft = o2.oprleft AND + o1.oprright = o2.oprright; + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprcom = o2.oid AND + (o1.oprkind != 'b' OR + o1.oprleft != o2.oprright OR + o1.oprright != o2.oprleft OR + o1.oprresult != o2.oprresult OR + o1.oid != o2.oprcom); + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprnegate = o2.oid AND + (o1.oprkind != o2.oprkind OR + o1.oprleft != o2.oprleft OR + o1.oprright != o2.oprright OR + o1.oprresult != 'bool'::regtype OR + o2.oprresult != 'bool'::regtype OR + o1.oid != o2.oprnegate OR + o1.oid = o2.oid); + +SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2 +FROM pg_operator o1, pg_operator o2 +WHERE o1.oprcom = o2.oid AND o1.oprname <= o2.oprname +ORDER BY 1, 2; + +SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2 +FROM pg_operator o1, pg_operator o2 +WHERE o1.oprnegate = o2.oid AND o1.oprname <= o2.oprname +ORDER BY 1, 2; + +SELECT o1.oid, o1.oprname FROM pg_operator AS o1 +WHERE (o1.oprcanmerge OR o1.oprcanhash) AND NOT + (o1.oprkind = 'b' AND o1.oprresult = 'bool'::regtype AND o1.oprcom != 0); + +SELECT o1.oid, o1.oprname, o2.oid, o2.oprname +FROM pg_operator AS o1, pg_operator AS o2 +WHERE o1.oprcom = o2.oid AND + (o1.oprcanmerge != o2.oprcanmerge OR + o1.oprcanhash != o2.oprcanhash); + +SELECT o1.oid, o1.oprname +FROM pg_operator AS o1 +WHERE o1.oprcanmerge AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + amopopr = o1.oid AND amopstrategy = 3); + +SELECT o1.oid, o1.oprname, p.amopfamily +FROM pg_operator AS o1, pg_amop p +WHERE amopopr = o1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopstrategy = 3 + AND NOT o1.oprcanmerge; + +SELECT o1.oid, o1.oprname +FROM pg_operator AS o1 +WHERE o1.oprcanhash AND NOT EXISTS + (SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND + amopopr = o1.oid AND amopstrategy = 1); + +SELECT o1.oid, o1.oprname, p.amopfamily +FROM pg_operator AS o1, pg_amop p +WHERE amopopr = o1.oid + AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') + AND NOT o1.oprcanhash; + +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + o1.oprkind = 'b' AND + (p1.pronargs != 2 + OR NOT binary_coercible(p1.prorettype, o1.oprresult) + OR NOT binary_coercible(o1.oprleft, p1.proargtypes[0]) + OR NOT binary_coercible(o1.oprright, p1.proargtypes[1])); + +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + o1.oprkind = 'l' AND + (p1.pronargs != 1 + OR NOT binary_coercible(p1.prorettype, o1.oprresult) + OR NOT binary_coercible(o1.oprright, p1.proargtypes[0]) + OR o1.oprleft != 0); + +SELECT o1.oid, o1.oprname, p1.oid, p1.proname +FROM pg_operator AS o1, pg_proc AS p1 +WHERE o1.oprcode = p1.oid AND + (o1.oprcanmerge OR o1.oprcanhash) AND + p1.provolatile = 'v'; + +SELECT o1.oid, o1.oprname, p2.oid, p2.proname +FROM pg_operator AS o1, pg_proc AS p2 +WHERE o1.oprrest = p2.oid AND + (o1.oprresult != 'bool'::regtype OR + p2.prorettype != 'float8'::regtype OR p2.proretset OR + p2.pronargs != 4 OR + p2.proargtypes[0] != 'internal'::regtype OR + p2.proargtypes[1] != 'oid'::regtype OR + p2.proargtypes[2] != 'internal'::regtype OR + p2.proargtypes[3] != 'int4'::regtype); + +SELECT o1.oid, o1.oprname, p2.oid, p2.proname +FROM pg_operator AS o1, pg_proc AS p2 +WHERE o1.oprjoin = p2.oid AND + (o1.oprkind != 'b' OR o1.oprresult != 'bool'::regtype OR + p2.prorettype != 'float8'::regtype OR p2.proretset OR + p2.pronargs != 5 OR + p2.proargtypes[0] != 'internal'::regtype OR + p2.proargtypes[1] != 'oid'::regtype OR + p2.proargtypes[2] != 'internal'::regtype OR + p2.proargtypes[3] != 'int2'::regtype OR + p2.proargtypes[4] != 'internal'::regtype); + +SELECT o1.oid, o1.oprname +FROM pg_operator as o1 LEFT JOIN pg_description as d + ON o1.tableoid = d.classoid and o1.oid = d.objoid and d.objsubid = 0 +WHERE d.classoid IS NULL AND o1.oid <= 9999; + +WITH funcdescs AS ( + SELECT p.oid as p_oid, proname, o.oid as o_oid, + pd.description as prodesc, + 'implementation of ' || oprname || ' operator' as expecteddesc, + od.description as oprdesc + FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid + LEFT JOIN pg_description pd ON + (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0) + LEFT JOIN pg_description od ON + (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0) + WHERE o.oid <= 9999 +) +SELECT * FROM funcdescs + WHERE prodesc IS DISTINCT FROM expecteddesc + AND oprdesc NOT LIKE 'deprecated%' + AND prodesc IS DISTINCT FROM oprdesc; + +WITH funcdescs AS ( + SELECT p.oid as p_oid, proname, o.oid as o_oid, + pd.description as prodesc, + 'implementation of ' || oprname || ' operator' as expecteddesc, + od.description as oprdesc + FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid + LEFT JOIN pg_description pd ON + (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0) + LEFT JOIN pg_description od ON + (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0) + WHERE o.oid <= 9999 +) +SELECT p_oid, proname, prodesc FROM funcdescs + WHERE prodesc IS DISTINCT FROM expecteddesc + AND oprdesc NOT LIKE 'deprecated%' +ORDER BY 1; + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprcom = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof); + +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprnegate = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof); + +SELECT pp.oid::regprocedure as proc, pp.provolatile as vp, pp.proleakproof as lp, + po.oid::regprocedure as opr, po.provolatile as vo, po.proleakproof as lo +FROM pg_proc pp, pg_proc po, pg_operator o, pg_amproc ap, pg_amop ao +WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND + ao.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + ao.amopfamily = ap.amprocfamily AND + ao.amoplefttype = ap.amproclefttype AND + ao.amoprighttype = ap.amprocrighttype AND + ap.amprocnum = 1 AND + (pp.provolatile != po.provolatile OR + pp.proleakproof != po.proleakproof) +ORDER BY 1; + +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggfnoid = 0 OR aggtransfn = 0 OR + aggkind NOT IN ('n', 'o', 'h') OR + aggnumdirectargs < 0 OR + (aggkind = 'n' AND aggnumdirectargs > 0) OR + aggfinalmodify NOT IN ('r', 's', 'w') OR + aggmfinalmodify NOT IN ('r', 's', 'w') OR + aggtranstype = 0 OR aggtransspace < 0 OR aggmtransspace < 0; + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + (p.prokind != 'a' OR p.proretset OR p.pronargs < a.aggnumdirectargs); + +SELECT oid, proname +FROM pg_proc as p +WHERE p.prokind = 'a' AND + NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid); + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype; + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggtranstype) + OR NOT binary_coercible(a.aggtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + OR (p.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[3], ptr.proargtypes[4])) + -- we could carry the check further, but 4 args is enough for now + OR (p.pronargs > 4) + ); + +SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn +WHERE a.aggfnoid = p.oid AND + a.aggfinalfn = pfn.oid AND + (pfn.proretset OR + NOT binary_coercible(pfn.prorettype, p.prorettype) OR + NOT binary_coercible(a.aggtranstype, pfn.proargtypes[0]) OR + CASE WHEN a.aggfinalextra THEN pfn.pronargs != p.pronargs + 1 + ELSE pfn.pronargs != a.aggnumdirectargs + 1 END + OR (pfn.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1])) + OR (pfn.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) + OR (pfn.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) + ); + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggtransfn = ptr.oid AND ptr.proisstrict AND + a.agginitval IS NULL AND + NOT binary_coercible(p.proargtypes[0], a.aggtranstype); + +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggmtranstype != 0 AND + (aggmtransfn = 0 OR aggminvtransfn = 0); + +SELECT ctid, aggfnoid::oid +FROM pg_aggregate as a +WHERE aggmtranstype = 0 AND + (aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR + aggmtransspace != 0 OR aggminitval IS NOT NULL); + +SELECT a.aggfnoid::oid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn != 0 AND + a.aggmfinalfn = 0 AND p.prorettype != a.aggmtranstype; + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) + ); + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggminvtransfn = ptr.oid AND + (ptr.proretset + OR NOT (ptr.pronargs = + CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 + ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR (p.pronargs > 0 AND + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) + OR (p.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) + OR (p.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) + -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) + ); + +SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn +WHERE a.aggfnoid = p.oid AND + a.aggmfinalfn = pfn.oid AND + (pfn.proretset OR + NOT binary_coercible(pfn.prorettype, p.prorettype) OR + NOT binary_coercible(a.aggmtranstype, pfn.proargtypes[0]) OR + CASE WHEN a.aggmfinalextra THEN pfn.pronargs != p.pronargs + 1 + ELSE pfn.pronargs != a.aggnumdirectargs + 1 END + OR (pfn.pronargs > 1 AND + NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1])) + OR (pfn.pronargs > 2 AND + NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) + OR (pfn.pronargs > 3 AND + NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) + ); + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND ptr.proisstrict AND + a.aggminitval IS NULL AND + NOT binary_coercible(p.proargtypes[0], a.aggmtranstype); + +SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname, iptr.oid, iptr.proname +FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr, pg_proc AS iptr +WHERE a.aggfnoid = p.oid AND + a.aggmtransfn = ptr.oid AND + a.aggminvtransfn = iptr.oid AND + ptr.proisstrict != iptr.proisstrict; + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggcombinefn = p.oid AND + (p.pronargs != 2 OR + p.prorettype != p.proargtypes[0] OR + p.prorettype != p.proargtypes[1] OR + NOT binary_coercible(a.aggtranstype, p.proargtypes[0])); + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggcombinefn = p.oid AND + a.aggtranstype = 'internal'::regtype AND p.proisstrict; + +SELECT aggfnoid, aggtranstype, aggserialfn, aggdeserialfn +FROM pg_aggregate +WHERE (aggserialfn != 0 OR aggdeserialfn != 0) + AND (aggtranstype != 'internal'::regtype OR aggcombinefn = 0 OR + aggserialfn = 0 OR aggdeserialfn = 0); + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggserialfn = p.oid AND + (p.prorettype != 'bytea'::regtype OR p.pronargs != 1 OR + p.proargtypes[0] != 'internal'::regtype OR + NOT p.proisstrict); + +SELECT a.aggfnoid, p.proname +FROM pg_aggregate as a, pg_proc as p +WHERE a.aggdeserialfn = p.oid AND + (p.prorettype != 'internal'::regtype OR p.pronargs != 2 OR + p.proargtypes[0] != 'bytea'::regtype OR + p.proargtypes[1] != 'internal'::regtype OR + NOT p.proisstrict); + +SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn, + b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn +FROM + pg_aggregate a, pg_aggregate b +WHERE + a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND + (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn + OR a.aggdeserialfn != b.aggdeserialfn); + +SELECT DISTINCT proname, oprname +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid +ORDER BY 1, 2; + +SELECT a.aggfnoid::oid, o.oid +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + (oprkind != 'b' OR oprresult != 'boolean'::regtype + OR oprleft != p.proargtypes[0] OR oprright != p.proargtypes[0]); + +SELECT a.aggfnoid::oid, o.oid +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + NOT EXISTS(SELECT 1 FROM pg_amop + WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') + AND amopopr = o.oid + AND amoplefttype = o.oprleft + AND amoprighttype = o.oprright); + +SELECT DISTINCT proname, oprname, amopstrategy +FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p, + pg_amop as ao +WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND + amopopr = o.oid AND + amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') +ORDER BY 1, 2; + +SELECT p1.oid::regprocedure, p2.oid::regprocedure +FROM pg_proc AS p1, pg_proc AS p2 +WHERE p1.oid < p2.oid AND p1.proname = p2.proname AND + p1.prokind = 'a' AND p2.prokind = 'a' AND + array_dims(p1.proargtypes) != array_dims(p2.proargtypes) +ORDER BY 1; + +SELECT oid, proname +FROM pg_proc AS p +WHERE prokind = 'a' AND proargdefaults IS NOT NULL; + +SELECT p.oid, proname +FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid +WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n'; + +SELECT f.oid +FROM pg_opfamily as f +WHERE f.opfmethod = 0 OR f.opfnamespace = 0; + +SELECT oid, opfname FROM pg_opfamily f +WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid); + +SELECT c1.oid +FROM pg_opclass AS c1 +WHERE c1.opcmethod = 0 OR c1.opcnamespace = 0 OR c1.opcfamily = 0 + OR c1.opcintype = 0; + +SELECT c1.oid, f1.oid +FROM pg_opclass AS c1, pg_opfamily AS f1 +WHERE c1.opcfamily = f1.oid AND c1.opcmethod != f1.opfmethod; + +SELECT c1.oid, c2.oid +FROM pg_opclass AS c1, pg_opclass AS c2 +WHERE c1.oid != c2.oid AND + c1.opcmethod = c2.opcmethod AND c1.opcintype = c2.opcintype AND + c1.opcdefault AND c2.opcdefault; + +SELECT oid, opcname FROM pg_opclass WHERE NOT amvalidate(oid); + +SELECT a1.oid, a1.amname +FROM pg_am AS a1 +WHERE a1.amhandler = 0; + +SELECT a1.oid, a1.amname, p1.oid, p1.proname +FROM pg_am AS a1, pg_proc AS p1 +WHERE p1.oid = a1.amhandler AND a1.amtype = 'i' AND + (p1.prorettype != 'index_am_handler'::regtype + OR p1.proretset + OR p1.pronargs != 1 + OR p1.proargtypes[0] != 'internal'::regtype); + +SELECT a1.oid, a1.amname, p1.oid, p1.proname +FROM pg_am AS a1, pg_proc AS p1 +WHERE p1.oid = a1.amhandler AND a1.amtype = 't' AND + (p1.prorettype != 'table_am_handler'::regtype + OR p1.proretset + OR p1.pronargs != 1 + OR p1.proargtypes[0] != 'internal'::regtype); + +SELECT a1.amopfamily, a1.amopstrategy +FROM pg_amop as a1 +WHERE a1.amopfamily = 0 OR a1.amoplefttype = 0 OR a1.amoprighttype = 0 + OR a1.amopopr = 0 OR a1.amopmethod = 0 OR a1.amopstrategy < 1; + +SELECT a1.amopfamily, a1.amopstrategy +FROM pg_amop as a1 +WHERE NOT ((a1.amoppurpose = 's' AND a1.amopsortfamily = 0) OR + (a1.amoppurpose = 'o' AND a1.amopsortfamily <> 0)); + +SELECT a1.oid, f1.oid +FROM pg_amop AS a1, pg_opfamily AS f1 +WHERE a1.amopfamily = f1.oid AND a1.amopmethod != f1.opfmethod; + +SELECT DISTINCT amopmethod, amopstrategy, oprname +FROM pg_amop a1 LEFT JOIN pg_operator o1 ON amopopr = o1.oid +ORDER BY 1, 2, 3; + +SELECT a1.amopfamily, a1.amopopr, o1.oid, o1.oprname +FROM pg_amop AS a1, pg_operator AS o1 +WHERE a1.amopopr = o1.oid AND a1.amoppurpose = 's' AND + (o1.oprrest = 0 OR o1.oprjoin = 0); + +SELECT c1.opcname, c1.opcfamily +FROM pg_opclass AS c1 +WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS a1 + WHERE a1.amopfamily = c1.opcfamily + AND binary_coercible(c1.opcintype, a1.amoplefttype)); + +SELECT a1.amopfamily, a1.amopstrategy, a1.amopopr +FROM pg_amop AS a1 +WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS c1 + WHERE c1.opcfamily = a1.amopfamily + AND binary_coercible(c1.opcintype, a1.amoplefttype)); + +SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc +FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1 +WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND + a1.amoplefttype = a1.amoprighttype AND + p1.provolatile != 'i'; + +SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc +FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1 +WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND + a1.amoplefttype != a1.amoprighttype AND + p1.provolatile = 'v'; + +SELECT a1.amprocfamily, a1.amprocnum +FROM pg_amproc as a1 +WHERE a1.amprocfamily = 0 OR a1.amproclefttype = 0 OR a1.amprocrighttype = 0 + OR a1.amprocnum < 0 OR a1.amproc = 0; + +SELECT a1.amprocfamily, a1.amproc, p1.prosrc +FROM pg_amproc AS a1, pg_proc AS p1 +WHERE a1.amproc = p1.oid AND + a1.amproclefttype = a1.amprocrighttype AND + p1.provolatile != 'i'; + +SELECT a1.amprocfamily, a1.amproc, p1.prosrc +FROM pg_amproc AS a1, pg_proc AS p1 +WHERE a1.amproc = p1.oid AND + a1.amproclefttype != a1.amprocrighttype AND + p1.provolatile = 'v'; + +SELECT amp.amproc::regproc AS proc, opf.opfname AS opfamily_name, + opc.opcname AS opclass_name, opc.opcintype::regtype AS opcintype +FROM pg_am AS am +JOIN pg_opclass AS opc ON opc.opcmethod = am.oid +JOIN pg_opfamily AS opf ON opc.opcfamily = opf.oid +LEFT JOIN pg_amproc AS amp ON amp.amprocfamily = opf.oid AND + amp.amproclefttype = opc.opcintype AND amp.amprocnum = 4 +WHERE am.amname = 'btree' AND + amp.amproc IS DISTINCT FROM 'btequalimage'::regproc +ORDER BY 1, 2, 3; + +SELECT indexrelid, indrelid +FROM pg_index +WHERE indexrelid = 0 OR indrelid = 0 OR + indnatts <= 0 OR indnatts > 32; + +SELECT indexrelid, indrelid +FROM pg_index +WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR + array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR + array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR + array_lower(indoption, 1) != 0 OR array_upper(indoption, 1) != indnatts-1; + +SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname +FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index) ss, + pg_attribute a, + pg_opclass opc +WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND + (NOT binary_coercible(atttypid, opcintype) OR icoll != attcollation); + +SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname +FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index + WHERE indrelid < 16384) ss, + pg_attribute a, + pg_opclass opc +WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND + (opcintype != atttypid OR icoll != attcollation) +ORDER BY 1; + +SELECT relname, attname, attcollation +FROM pg_class c, pg_attribute a +WHERE c.oid = attrelid AND c.oid < 16384 AND + c.relkind != 'v' AND -- we don't care about columns in views + attcollation != 0 AND + attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C'); + +SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll +FROM (SELECT indexrelid, indrelid, + unnest(indclass) as iclass, unnest(indcollation) as icoll + FROM pg_index + WHERE indrelid < 16384) ss +WHERE icoll != 0 AND + icoll != (SELECT oid FROM pg_collation WHERE collname = 'C'); diff --git a/crates/pgt_pretty_print/tests/data/multi/partition_aggregate_60.sql b/crates/pgt_pretty_print/tests/data/multi/partition_aggregate_60.sql new file mode 100644 index 000000000..ec5befd44 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/partition_aggregate_60.sql @@ -0,0 +1,269 @@ +SET enable_partitionwise_aggregate TO true; + +SET enable_partitionwise_join TO true; + +SET max_parallel_workers_per_gather TO 0; + +SET enable_incremental_sort TO off; + +CREATE TABLE pagg_tab (a int, b int, c text, d int) PARTITION BY LIST(c); + +CREATE TABLE pagg_tab_p1 PARTITION OF pagg_tab FOR VALUES IN ('0000', '0001', '0002', '0003', '0004'); + +CREATE TABLE pagg_tab_p2 PARTITION OF pagg_tab FOR VALUES IN ('0005', '0006', '0007', '0008'); + +CREATE TABLE pagg_tab_p3 PARTITION OF pagg_tab FOR VALUES IN ('0009', '0010', '0011'); + +INSERT INTO pagg_tab SELECT i % 20, i % 30, to_char(i % 12, 'FM0000'), i % 30 FROM generate_series(0, 2999) i; + +ANALYZE pagg_tab; + +SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT c, sum(a), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY c HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT a, sum(b), avg(b), count(*), min(a), max(b) FROM pagg_tab GROUP BY a HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT a, c, count(*) FROM pagg_tab GROUP BY a, c; + +SELECT a, c, count(*) FROM pagg_tab GROUP BY c, a; + +SELECT c, a, count(*) FROM pagg_tab GROUP BY a, c; + +SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c; + +SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c; + +SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c; + +SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c; + +SET enable_hashagg TO false; + +SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT c, sum(a), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT a, sum(b), avg(b), count(*) FROM pagg_tab GROUP BY 1 HAVING avg(d) < 15 ORDER BY 1, 2, 3; + +SELECT c FROM pagg_tab GROUP BY c ORDER BY 1; + +SELECT c FROM pagg_tab GROUP BY c ORDER BY 1; + +SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1; + +SELECT a FROM pagg_tab WHERE a < 3 GROUP BY a ORDER BY 1; + +RESET enable_hashagg; + +SELECT c, sum(a) FROM pagg_tab GROUP BY rollup(c) ORDER BY 1, 2; + +SELECT c, sum(b order by a) FROM pagg_tab GROUP BY c ORDER BY 1, 2; + +SELECT a, sum(b order by a) FROM pagg_tab GROUP BY a ORDER BY 1, 2; + +CREATE TABLE pagg_tab1(x int, y int) PARTITION BY RANGE(x); + +CREATE TABLE pagg_tab1_p1 PARTITION OF pagg_tab1 FOR VALUES FROM (0) TO (10); + +CREATE TABLE pagg_tab1_p2 PARTITION OF pagg_tab1 FOR VALUES FROM (10) TO (20); + +CREATE TABLE pagg_tab1_p3 PARTITION OF pagg_tab1 FOR VALUES FROM (20) TO (30); + +CREATE TABLE pagg_tab2(x int, y int) PARTITION BY RANGE(y); + +CREATE TABLE pagg_tab2_p1 PARTITION OF pagg_tab2 FOR VALUES FROM (0) TO (10); + +CREATE TABLE pagg_tab2_p2 PARTITION OF pagg_tab2 FOR VALUES FROM (10) TO (20); + +CREATE TABLE pagg_tab2_p3 PARTITION OF pagg_tab2 FOR VALUES FROM (20) TO (30); + +INSERT INTO pagg_tab1 SELECT i % 30, i % 20 FROM generate_series(0, 299, 2) i; + +INSERT INTO pagg_tab2 SELECT i % 20, i % 30 FROM generate_series(0, 299, 3) i; + +ANALYZE pagg_tab1; + +ANALYZE pagg_tab2; + +SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; + +SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; + +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; + +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; + +SELECT t2.y, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t2.y ORDER BY 1, 2, 3; + +SET enable_hashagg TO false; + +SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3; + +SELECT t1.y, sum(t1.x), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.y HAVING avg(t1.x) > 10 ORDER BY 1, 2, 3; + +RESET enable_hashagg; + +SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST; + +SELECT b.y, sum(a.y) FROM pagg_tab1 a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST; + +SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST; + +SELECT b.y, sum(a.y) FROM pagg_tab1 a RIGHT JOIN pagg_tab2 b ON a.x = b.y GROUP BY b.y ORDER BY 1 NULLS LAST; + +SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST; + +SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST; + +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; + +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; + +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; + +SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; + +SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2; + +SELECT a.x, a.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x = 1 AND x = 2) a LEFT JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x, a.y ORDER BY 1, 2; + +CREATE TABLE pagg_tab_m (a int, b int, c int) PARTITION BY RANGE(a, ((a+b)/2)); + +CREATE TABLE pagg_tab_m_p1 PARTITION OF pagg_tab_m FOR VALUES FROM (0, 0) TO (12, 12); + +CREATE TABLE pagg_tab_m_p2 PARTITION OF pagg_tab_m FOR VALUES FROM (12, 12) TO (22, 22); + +CREATE TABLE pagg_tab_m_p3 PARTITION OF pagg_tab_m FOR VALUES FROM (22, 22) TO (30, 30); + +INSERT INTO pagg_tab_m SELECT i % 30, i % 40, i % 50 FROM generate_series(0, 2999) i; + +ANALYZE pagg_tab_m; + +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3; + +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a HAVING avg(c) < 22 ORDER BY 1, 2, 3; + +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3; + +SELECT a, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY a, (a+b)/2 HAVING sum(b) < 50 ORDER BY 1, 2, 3; + +SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3; + +SELECT a, c, sum(b), avg(c), count(*) FROM pagg_tab_m GROUP BY (a+b)/2, 2, 1 HAVING sum(b) = 50 AND avg(c) > 25 ORDER BY 1, 2, 3; + +CREATE TABLE pagg_tab_ml (a int, b int, c text) PARTITION BY RANGE(a); + +CREATE TABLE pagg_tab_ml_p1 PARTITION OF pagg_tab_ml FOR VALUES FROM (0) TO (12); + +CREATE TABLE pagg_tab_ml_p2 PARTITION OF pagg_tab_ml FOR VALUES FROM (12) TO (20) PARTITION BY LIST (c); + +CREATE TABLE pagg_tab_ml_p2_s1 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0000', '0001', '0002'); + +CREATE TABLE pagg_tab_ml_p2_s2 PARTITION OF pagg_tab_ml_p2 FOR VALUES IN ('0003'); + +CREATE TABLE pagg_tab_ml_p3(b int, c text, a int) PARTITION BY RANGE (b); + +CREATE TABLE pagg_tab_ml_p3_s1(c text, a int, b int); + +CREATE TABLE pagg_tab_ml_p3_s2 PARTITION OF pagg_tab_ml_p3 FOR VALUES FROM (7) TO (10); + +ALTER TABLE pagg_tab_ml_p3 ATTACH PARTITION pagg_tab_ml_p3_s1 FOR VALUES FROM (0) TO (7); + +ALTER TABLE pagg_tab_ml ATTACH PARTITION pagg_tab_ml_p3 FOR VALUES FROM (20) TO (30); + +INSERT INTO pagg_tab_ml SELECT i % 30, i % 10, to_char(i % 4, 'FM0000') FROM generate_series(0, 29999) i; + +ANALYZE pagg_tab_ml; + +SET max_parallel_workers_per_gather TO 2; + +SET parallel_setup_cost = 0; + +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3; + +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3; + +SELECT a, sum(b), array_agg(distinct c), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3; + +RESET parallel_setup_cost; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3; + +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3; + +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3; + +SET min_parallel_table_scan_size TO '8kB'; + +SET parallel_setup_cost TO 0; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a HAVING avg(b) < 3 ORDER BY 1, 2, 3; + +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b ORDER BY 1, 2, 3; + +SELECT b, sum(a), count(*) FROM pagg_tab_ml GROUP BY b HAVING avg(a) < 15 ORDER BY 1, 2, 3; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3; + +SELECT a, sum(b), count(*) FROM pagg_tab_ml GROUP BY a, b, c HAVING avg(b) > 7 ORDER BY 1, 2, 3; + +SET parallel_setup_cost TO 10; + +CREATE TABLE pagg_tab_para(x int, y int) PARTITION BY RANGE(x); + +CREATE TABLE pagg_tab_para_p1 PARTITION OF pagg_tab_para FOR VALUES FROM (0) TO (12); + +CREATE TABLE pagg_tab_para_p2 PARTITION OF pagg_tab_para FOR VALUES FROM (12) TO (22); + +CREATE TABLE pagg_tab_para_p3 PARTITION OF pagg_tab_para FOR VALUES FROM (22) TO (30); + +INSERT INTO pagg_tab_para SELECT i % 30, i % 20 FROM generate_series(0, 29999) i; + +ANALYZE pagg_tab_para; + +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3; + +SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3; + +ALTER TABLE pagg_tab_para_p1 SET (parallel_workers = 0); + +ALTER TABLE pagg_tab_para_p3 SET (parallel_workers = 0); + +ANALYZE pagg_tab_para; + +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +ALTER TABLE pagg_tab_para_p2 SET (parallel_workers = 0); + +ANALYZE pagg_tab_para; + +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +SELECT x, sum(y), avg(y), sum(x+y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +RESET min_parallel_table_scan_size; + +RESET parallel_setup_cost; + +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; diff --git a/crates/pgt_pretty_print/tests/data/multi/partition_info_60.sql b/crates/pgt_pretty_print/tests/data/multi/partition_info_60.sql new file mode 100644 index 000000000..dcff14cfe --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/partition_info_60.sql @@ -0,0 +1,168 @@ +SELECT * FROM pg_partition_tree(NULL); + +SELECT * FROM pg_partition_tree(0); + +SELECT * FROM pg_partition_ancestors(NULL); + +SELECT * FROM pg_partition_ancestors(0); + +SELECT pg_partition_root(NULL); + +SELECT pg_partition_root(0); + +CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a); + +CREATE TABLE ptif_test0 PARTITION OF ptif_test + FOR VALUES FROM (minvalue) TO (0) PARTITION BY list (b); + +CREATE TABLE ptif_test01 PARTITION OF ptif_test0 FOR VALUES IN (1); + +CREATE TABLE ptif_test1 PARTITION OF ptif_test + FOR VALUES FROM (0) TO (100) PARTITION BY list (b); + +CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1); + +CREATE TABLE ptif_test2 PARTITION OF ptif_test + FOR VALUES FROM (100) TO (200); + +CREATE TABLE ptif_test3 PARTITION OF ptif_test + FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b); + +SELECT pg_partition_root('ptif_test'); + +SELECT pg_partition_root('ptif_test0'); + +SELECT pg_partition_root('ptif_test01'); + +SELECT pg_partition_root('ptif_test3'); + +CREATE INDEX ptif_test_index ON ONLY ptif_test (a); + +CREATE INDEX ptif_test0_index ON ONLY ptif_test0 (a); + +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test0_index; + +CREATE INDEX ptif_test01_index ON ptif_test01 (a); + +ALTER INDEX ptif_test0_index ATTACH PARTITION ptif_test01_index; + +CREATE INDEX ptif_test1_index ON ONLY ptif_test1 (a); + +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test1_index; + +CREATE INDEX ptif_test11_index ON ptif_test11 (a); + +ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index; + +CREATE INDEX ptif_test2_index ON ptif_test2 (a); + +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index; + +CREATE INDEX ptif_test3_index ON ptif_test3 (a); + +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index; + +SELECT pg_partition_root('ptif_test_index'); + +SELECT pg_partition_root('ptif_test0_index'); + +SELECT pg_partition_root('ptif_test01_index'); + +SELECT pg_partition_root('ptif_test3_index'); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test'); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0') p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01') p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3') p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT * FROM pg_partition_ancestors('ptif_test01'); + +SELECT * FROM pg_partition_ancestors('ptif_test'); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01')) p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test_index'); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0_index') p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01_index') p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3_index') p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p + JOIN pg_class c ON (p.relid = c.oid); + +SELECT * FROM pg_partition_ancestors('ptif_test01_index'); + +SELECT * FROM pg_partition_ancestors('ptif_test_index'); + +DROP TABLE ptif_test; + +CREATE TABLE ptif_normal_table(a int); + +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_normal_table'); + +SELECT * FROM pg_partition_ancestors('ptif_normal_table'); + +SELECT pg_partition_root('ptif_normal_table'); + +DROP TABLE ptif_normal_table; + +CREATE VIEW ptif_test_view AS SELECT 1; + +CREATE MATERIALIZED VIEW ptif_test_matview AS SELECT 1; + +CREATE TABLE ptif_li_parent (); + +CREATE TABLE ptif_li_child () INHERITS (ptif_li_parent); + +SELECT * FROM pg_partition_tree('ptif_test_view'); + +SELECT * FROM pg_partition_tree('ptif_test_matview'); + +SELECT * FROM pg_partition_tree('ptif_li_parent'); + +SELECT * FROM pg_partition_tree('ptif_li_child'); + +SELECT * FROM pg_partition_ancestors('ptif_test_view'); + +SELECT * FROM pg_partition_ancestors('ptif_test_matview'); + +SELECT * FROM pg_partition_ancestors('ptif_li_parent'); + +SELECT * FROM pg_partition_ancestors('ptif_li_child'); + +SELECT pg_partition_root('ptif_test_view'); + +SELECT pg_partition_root('ptif_test_matview'); + +SELECT pg_partition_root('ptif_li_parent'); + +SELECT pg_partition_root('ptif_li_child'); + +DROP VIEW ptif_test_view; + +DROP MATERIALIZED VIEW ptif_test_matview; + +DROP TABLE ptif_li_parent, ptif_li_child; diff --git a/crates/pgt_pretty_print/tests/data/multi/partition_join_60.sql b/crates/pgt_pretty_print/tests/data/multi/partition_join_60.sql new file mode 100644 index 000000000..6c4488695 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/partition_join_60.sql @@ -0,0 +1,1291 @@ +SET enable_partitionwise_join to true; + +CREATE TABLE prt1 (a int, b int, c varchar) PARTITION BY RANGE(a); + +CREATE TABLE prt1_p1 PARTITION OF prt1 FOR VALUES FROM (0) TO (250); + +CREATE TABLE prt1_p3 PARTITION OF prt1 FOR VALUES FROM (500) TO (600); + +CREATE TABLE prt1_p2 PARTITION OF prt1 FOR VALUES FROM (250) TO (500); + +INSERT INTO prt1 SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 2 = 0; + +CREATE INDEX iprt1_p1_a on prt1_p1(a); + +CREATE INDEX iprt1_p2_a on prt1_p2(a); + +CREATE INDEX iprt1_p3_a on prt1_p3(a); + +ANALYZE prt1; + +CREATE TABLE prt2 (a int, b int, c varchar) PARTITION BY RANGE(b); + +CREATE TABLE prt2_p1 PARTITION OF prt2 FOR VALUES FROM (0) TO (250); + +CREATE TABLE prt2_p2 PARTITION OF prt2 FOR VALUES FROM (250) TO (500); + +CREATE TABLE prt2_p3 PARTITION OF prt2 FOR VALUES FROM (500) TO (600); + +INSERT INTO prt2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 3 = 0; + +CREATE INDEX iprt2_p1_b on prt2_p1(b); + +CREATE INDEX iprt2_p2_b on prt2_p2(b); + +CREATE INDEX iprt2_p3_b on prt2_p3(b); + +ANALYZE prt2; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.a AND t1.a = t2.b ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.a AND t1.a = t2.b ORDER BY t1.a, t2.b; + +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a; + +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a; + +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a; + +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b); + +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b); + +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a; + +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a; + +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a; + +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a; + +SELECT * FROM prt1 t1 JOIN LATERAL + (SELECT * FROM prt1 t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a; + +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a; + +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a; + +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b; + +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b; + +SET enable_partitionwise_aggregate TO true; + +SET enable_hashjoin TO false; + +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2; + +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2; + +RESET enable_partitionwise_aggregate; + +RESET enable_hashjoin; + +SELECT * FROM prt1 t1 JOIN prt1 t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM prt1 t3); + +CREATE TABLE prt1_e (a int, b int, c int) PARTITION BY RANGE(((a + b)/2)); + +CREATE TABLE prt1_e_p1 PARTITION OF prt1_e FOR VALUES FROM (0) TO (250); + +CREATE TABLE prt1_e_p2 PARTITION OF prt1_e FOR VALUES FROM (250) TO (500); + +CREATE TABLE prt1_e_p3 PARTITION OF prt1_e FOR VALUES FROM (500) TO (600); + +INSERT INTO prt1_e SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i; + +CREATE INDEX iprt1_e_p1_ab2 on prt1_e_p1(((a+b)/2)); + +CREATE INDEX iprt1_e_p2_ab2 on prt1_e_p2(((a+b)/2)); + +CREATE INDEX iprt1_e_p3_ab2 on prt1_e_p3(((a+b)/2)); + +ANALYZE prt1_e; + +CREATE TABLE prt2_e (a int, b int, c int) PARTITION BY RANGE(((b + a)/2)); + +CREATE TABLE prt2_e_p1 PARTITION OF prt2_e FOR VALUES FROM (0) TO (250); + +CREATE TABLE prt2_e_p2 PARTITION OF prt2_e FOR VALUES FROM (250) TO (500); + +CREATE TABLE prt2_e_p3 PARTITION OF prt2_e FOR VALUES FROM (500) TO (600); + +INSERT INTO prt2_e SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i; + +ANALYZE prt2_e; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + +SET enable_hashjoin TO off; + +SET enable_nestloop TO off; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; + +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; + +RESET enable_hashjoin; + +RESET enable_nestloop; + +CREATE TABLE prt1_m (a int, b int, c int) PARTITION BY RANGE(a, ((a + b)/2)); + +CREATE TABLE prt1_m_p1 PARTITION OF prt1_m FOR VALUES FROM (0, 0) TO (250, 250); + +CREATE TABLE prt1_m_p2 PARTITION OF prt1_m FOR VALUES FROM (250, 250) TO (500, 500); + +CREATE TABLE prt1_m_p3 PARTITION OF prt1_m FOR VALUES FROM (500, 500) TO (600, 600); + +INSERT INTO prt1_m SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i; + +ANALYZE prt1_m; + +CREATE TABLE prt2_m (a int, b int, c int) PARTITION BY RANGE(((b + a)/2), b); + +CREATE TABLE prt2_m_p1 PARTITION OF prt2_m FOR VALUES FROM (0, 0) TO (250, 250); + +CREATE TABLE prt2_m_p2 PARTITION OF prt2_m FOR VALUES FROM (250, 250) TO (500, 500); + +CREATE TABLE prt2_m_p3 PARTITION OF prt2_m FOR VALUES FROM (500, 500) TO (600, 600); + +INSERT INTO prt2_m SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i; + +ANALYZE prt2_m; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b; + +CREATE TABLE plt1 (a int, b int, c text) PARTITION BY LIST(c); + +CREATE TABLE plt1_p1 PARTITION OF plt1 FOR VALUES IN ('0000', '0003', '0004', '0010'); + +CREATE TABLE plt1_p2 PARTITION OF plt1 FOR VALUES IN ('0001', '0005', '0002', '0009'); + +CREATE TABLE plt1_p3 PARTITION OF plt1 FOR VALUES IN ('0006', '0007', '0008', '0011'); + +INSERT INTO plt1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; + +ANALYZE plt1; + +CREATE TABLE plt2 (a int, b int, c text) PARTITION BY LIST(c); + +CREATE TABLE plt2_p1 PARTITION OF plt2 FOR VALUES IN ('0000', '0003', '0004', '0010'); + +CREATE TABLE plt2_p2 PARTITION OF plt2 FOR VALUES IN ('0001', '0005', '0002', '0009'); + +CREATE TABLE plt2_p3 PARTITION OF plt2 FOR VALUES IN ('0006', '0007', '0008', '0011'); + +INSERT INTO plt2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i; + +ANALYZE plt2; + +CREATE TABLE plt1_e (a int, b int, c text) PARTITION BY LIST(ltrim(c, 'A')); + +CREATE TABLE plt1_e_p1 PARTITION OF plt1_e FOR VALUES IN ('0000', '0003', '0004', '0010'); + +CREATE TABLE plt1_e_p2 PARTITION OF plt1_e FOR VALUES IN ('0001', '0005', '0002', '0009'); + +CREATE TABLE plt1_e_p3 PARTITION OF plt1_e FOR VALUES IN ('0006', '0007', '0008', '0011'); + +INSERT INTO plt1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; + +ANALYZE plt1_e; + +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a = 1 AND t1.a = 2; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 LEFT JOIN prt2 t2 ON t1.a = t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b, prt1 t3 WHERE t2.b = t3.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 FULL JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b; + +CREATE TABLE pht1 (a int, b int, c text) PARTITION BY HASH(c); + +CREATE TABLE pht1_p1 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 0); + +CREATE TABLE pht1_p2 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 1); + +CREATE TABLE pht1_p3 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +INSERT INTO pht1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; + +ANALYZE pht1; + +CREATE TABLE pht2 (a int, b int, c text) PARTITION BY HASH(c); + +CREATE TABLE pht2_p1 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 0); + +CREATE TABLE pht2_p2 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 1); + +CREATE TABLE pht2_p3 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +INSERT INTO pht2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i; + +ANALYZE pht2; + +CREATE TABLE pht1_e (a int, b int, c text) PARTITION BY HASH(ltrim(c, 'A')); + +CREATE TABLE pht1_e_p1 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 0); + +CREATE TABLE pht1_e_p2 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 1); + +CREATE TABLE pht1_e_p3 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +INSERT INTO pht1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 299, 2) i; + +ANALYZE pht1_e; + +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + +ALTER TABLE prt1 DETACH PARTITION prt1_p3; + +ALTER TABLE prt1 ATTACH PARTITION prt1_p3 DEFAULT; + +ANALYZE prt1; + +ALTER TABLE prt2 DETACH PARTITION prt2_p3; + +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 DEFAULT; + +ANALYZE prt2; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + +ALTER TABLE plt1 DETACH PARTITION plt1_p3; + +ALTER TABLE plt1 ATTACH PARTITION plt1_p3 DEFAULT; + +ANALYZE plt1; + +ALTER TABLE plt2 DETACH PARTITION plt2_p3; + +ALTER TABLE plt2 ATTACH PARTITION plt2_p3 DEFAULT; + +ANALYZE plt2; + +SELECT avg(t1.a), avg(t2.b), t1.c, t2.c FROM plt1 t1 RIGHT JOIN plt2 t2 ON t1.c = t2.c WHERE t1.a % 25 = 0 GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c; + +CREATE TABLE prt1_l (a int, b int, c varchar) PARTITION BY RANGE(a); + +CREATE TABLE prt1_l_p1 PARTITION OF prt1_l FOR VALUES FROM (0) TO (250); + +CREATE TABLE prt1_l_p2 PARTITION OF prt1_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c); + +CREATE TABLE prt1_l_p2_p1 PARTITION OF prt1_l_p2 FOR VALUES IN ('0000', '0001'); + +CREATE TABLE prt1_l_p2_p2 PARTITION OF prt1_l_p2 FOR VALUES IN ('0002', '0003'); + +CREATE TABLE prt1_l_p3 PARTITION OF prt1_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (b); + +CREATE TABLE prt1_l_p3_p1 PARTITION OF prt1_l_p3 FOR VALUES FROM (0) TO (13); + +CREATE TABLE prt1_l_p3_p2 PARTITION OF prt1_l_p3 FOR VALUES FROM (13) TO (25); + +INSERT INTO prt1_l SELECT i, i % 25, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 2) i; + +ANALYZE prt1_l; + +CREATE TABLE prt2_l (a int, b int, c varchar) PARTITION BY RANGE(b); + +CREATE TABLE prt2_l_p1 PARTITION OF prt2_l FOR VALUES FROM (0) TO (250); + +CREATE TABLE prt2_l_p2 PARTITION OF prt2_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c); + +CREATE TABLE prt2_l_p2_p1 PARTITION OF prt2_l_p2 FOR VALUES IN ('0000', '0001'); + +CREATE TABLE prt2_l_p2_p2 PARTITION OF prt2_l_p2 FOR VALUES IN ('0002', '0003'); + +CREATE TABLE prt2_l_p3 PARTITION OF prt2_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (a); + +CREATE TABLE prt2_l_p3_p1 PARTITION OF prt2_l_p3 FOR VALUES FROM (0) TO (13); + +CREATE TABLE prt2_l_p3_p2 PARTITION OF prt2_l_p3 FOR VALUES FROM (13) TO (25); + +INSERT INTO prt2_l SELECT i % 25, i, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 3) i; + +ANALYZE prt2_l; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.a AND t1.a = t2.b AND t1.c = t2.c ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.a AND t1.a = t2.b AND t1.c = t2.c ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b; + +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a; + +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a; + +SELECT * FROM prt1_l t1 JOIN LATERAL + (SELECT * FROM prt1_l t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a AND t1.b = s.b AND t1.c = s.c; + +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a; + +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c; + +DELETE FROM prt1_l +WHERE EXISTS ( + SELECT 1 + FROM int4_tbl, + LATERAL (SELECT int4_tbl.f1 FROM int8_tbl LIMIT 2) ss + WHERE prt1_l.c IS NULL); + +CREATE TABLE prt1_n (a int, b int, c varchar) PARTITION BY RANGE(c); + +CREATE TABLE prt1_n_p1 PARTITION OF prt1_n FOR VALUES FROM ('0000') TO ('0250'); + +CREATE TABLE prt1_n_p2 PARTITION OF prt1_n FOR VALUES FROM ('0250') TO ('0500'); + +INSERT INTO prt1_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 499, 2) i; + +ANALYZE prt1_n; + +CREATE TABLE prt2_n (a int, b int, c text) PARTITION BY LIST(c); + +CREATE TABLE prt2_n_p1 PARTITION OF prt2_n FOR VALUES IN ('0000', '0003', '0004', '0010', '0006', '0007'); + +CREATE TABLE prt2_n_p2 PARTITION OF prt2_n FOR VALUES IN ('0001', '0005', '0002', '0009', '0008', '0011'); + +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; + +ANALYZE prt2_n; + +CREATE TABLE prt3_n (a int, b int, c text) PARTITION BY LIST(c); + +CREATE TABLE prt3_n_p1 PARTITION OF prt3_n FOR VALUES IN ('0000', '0004', '0006', '0007'); + +CREATE TABLE prt3_n_p2 PARTITION OF prt3_n FOR VALUES IN ('0001', '0002', '0008', '0010'); + +CREATE TABLE prt3_n_p3 PARTITION OF prt3_n FOR VALUES IN ('0003', '0005', '0009', '0011'); + +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; + +ANALYZE prt3_n; + +CREATE TABLE prt4_n (a int, b int, c text) PARTITION BY RANGE(a); + +CREATE TABLE prt4_n_p1 PARTITION OF prt4_n FOR VALUES FROM (0) TO (300); + +CREATE TABLE prt4_n_p2 PARTITION OF prt4_n FOR VALUES FROM (300) TO (500); + +CREATE TABLE prt4_n_p3 PARTITION OF prt4_n FOR VALUES FROM (500) TO (600); + +INSERT INTO prt4_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 599, 2) i; + +ANALYZE prt4_n; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2 WHERE t1.a = t2.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2, prt2 t3 WHERE t1.a = t2.a and t1.a = t3.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 LEFT JOIN prt2 t2 ON (t1.a < t2.b); + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1, prt2_m t2 WHERE t1.a = (t2.b + t2.a)/2; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.a = t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.c = t2.c; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 LEFT JOIN prt2_n t2 ON (t1.c = t2.c); + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 JOIN prt2_n t2 ON (t1.c = t2.c) JOIN plt1 t3 ON (t1.c = t3.c); + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON (t1.c = t2.c); + +create temp table prtx1 (a integer, b integer, c integer) + partition by range (a); + +create temp table prtx1_1 partition of prtx1 for values from (1) to (11); + +create temp table prtx1_2 partition of prtx1 for values from (11) to (21); + +create temp table prtx1_3 partition of prtx1 for values from (21) to (31); + +create temp table prtx2 (a integer, b integer, c integer) + partition by range (a); + +create temp table prtx2_1 partition of prtx2 for values from (1) to (11); + +create temp table prtx2_2 partition of prtx2 for values from (11) to (21); + +create temp table prtx2_3 partition of prtx2 for values from (21) to (31); + +insert into prtx1 select 1 + i%30, i, i + from generate_series(1,1000) i; + +insert into prtx2 select 1 + i%30, i, i + from generate_series(1,500) i, generate_series(1,10) j; + +create index on prtx2 (b); + +create index on prtx2 (c); + +analyze prtx1; + +analyze prtx2; + +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120; + +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120; + +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91; + +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91; + +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a); + +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200); + +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300); + +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400); + +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a); + +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i; + +ANALYZE prt1_adv; + +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b); + +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (150); + +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (300); + +CREATE TABLE prt2_adv_p3 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (500); + +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b); + +INSERT INTO prt2_adv_p1 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 149) i; + +INSERT INTO prt2_adv_p2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(200, 299) i; + +INSERT INTO prt2_adv_p3 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i; + +ANALYZE prt2_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + +CREATE TABLE prt2_adv_extra PARTITION OF prt2_adv FOR VALUES FROM (500) TO (MAXVALUE); + +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(500, 599) i; + +ANALYZE prt2_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.b, t1.c, t2.a, t2.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a; + +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.* FROM prt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt1_adv t2 WHERE t1.b = t2.a) AND t1.a = 0 ORDER BY t1.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a; + +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a; + +DROP TABLE prt2_adv_extra; + +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3; + +CREATE TABLE prt2_adv_p3_1 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (375); + +CREATE TABLE prt2_adv_p3_2 PARTITION OF prt2_adv FOR VALUES FROM (375) TO (500); + +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i; + +ANALYZE prt2_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + +DROP TABLE prt2_adv_p3_1; + +DROP TABLE prt2_adv_p3_2; + +ANALYZE prt2_adv; + +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p1; + +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p1 DEFAULT; + +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p3; + +ANALYZE prt1_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p3 FOR VALUES FROM (300) TO (400); + +ANALYZE prt1_adv; + +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 FOR VALUES FROM (350) TO (500); + +ANALYZE prt2_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3; + +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 DEFAULT; + +ANALYZE prt2_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + +DROP TABLE prt1_adv_p3; + +ANALYZE prt1_adv; + +DROP TABLE prt2_adv_p3; + +ANALYZE prt2_adv; + +CREATE TABLE prt3_adv (a int, b int, c varchar) PARTITION BY RANGE (a); + +CREATE TABLE prt3_adv_p1 PARTITION OF prt3_adv FOR VALUES FROM (200) TO (300); + +CREATE TABLE prt3_adv_p2 PARTITION OF prt3_adv FOR VALUES FROM (300) TO (400); + +CREATE INDEX prt3_adv_a_idx ON prt3_adv (a); + +INSERT INTO prt3_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(200, 399) i; + +ANALYZE prt3_adv; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a; + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a; + +DROP TABLE prt1_adv; + +DROP TABLE prt2_adv; + +DROP TABLE prt3_adv; + +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a); + +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200); + +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300); + +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400); + +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a); + +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i; + +ANALYZE prt1_adv; + +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b); + +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (200); + +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (400); + +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b); + +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 399) i; + +ANALYZE prt2_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + +DROP TABLE prt1_adv_p3; + +CREATE TABLE prt1_adv_default PARTITION OF prt1_adv DEFAULT; + +ANALYZE prt1_adv; + +CREATE TABLE prt2_adv_default PARTITION OF prt2_adv DEFAULT; + +ANALYZE prt2_adv; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + +DROP TABLE prt1_adv; + +DROP TABLE prt2_adv; + +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001', '0003'); + +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0004', '0006'); + +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0008', '0009'); + +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9); + +ANALYZE plt1_adv; + +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002', '0003'); + +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0006'); + +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0007', '0009'); + +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN ('0000'); + +INSERT INTO plt2_adv_extra VALUES (0, 0, '0000'); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt2_adv t1 LEFT JOIN plt1_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt1_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +DROP TABLE plt2_adv_extra; + +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2; + +CREATE TABLE plt2_adv_p2_1 PARTITION OF plt2_adv FOR VALUES IN ('0004'); + +CREATE TABLE plt2_adv_p2_2 PARTITION OF plt2_adv FOR VALUES IN ('0006'); + +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +DROP TABLE plt2_adv_p2_1; + +DROP TABLE plt2_adv_p2_2; + +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006'); + +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1; + +CREATE TABLE plt1_adv_p1_null PARTITION OF plt1_adv FOR VALUES IN (NULL, '0001', '0003'); + +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3); + +INSERT INTO plt1_adv VALUES (-1, -1, NULL); + +ANALYZE plt1_adv; + +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p3; + +CREATE TABLE plt2_adv_p3_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0007', '0009'); + +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (7, 9); + +INSERT INTO plt2_adv VALUES (-1, -1, NULL); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +DROP TABLE plt1_adv_p1_null; + +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 FOR VALUES IN ('0001', '0003'); + +CREATE TABLE plt1_adv_extra PARTITION OF plt1_adv FOR VALUES IN (NULL); + +INSERT INTO plt1_adv VALUES (-1, -1, NULL); + +ANALYZE plt1_adv; + +DROP TABLE plt2_adv_p3_null; + +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p3 FOR VALUES IN ('0007', '0009'); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN (NULL); + +INSERT INTO plt2_adv VALUES (-1, -1, NULL); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + +DROP TABLE plt1_adv_extra; + +DROP TABLE plt2_adv_extra; + +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1; + +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 DEFAULT; + +DROP TABLE plt1_adv_p3; + +ANALYZE plt1_adv; + +DROP TABLE plt2_adv_p3; + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2; + +CREATE TABLE plt2_adv_p2_ext PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005', '0006'); + +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 5, 6); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2_ext; + +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2_ext DEFAULT; + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +DROP TABLE plt2_adv_p2_ext; + +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006'); + +ANALYZE plt2_adv; + +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0004', '0006'); + +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0007', '0009'); + +INSERT INTO plt3_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6, 7, 9); + +ANALYZE plt3_adv; + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + +DROP TABLE plt2_adv_p1; + +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0001', '0003'); + +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3); + +INSERT INTO plt2_adv VALUES (-1, -1, NULL); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +DROP TABLE plt2_adv_p1_null; + +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL); + +INSERT INTO plt2_adv VALUES (-1, -1, NULL); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + +DROP TABLE plt1_adv; + +DROP TABLE plt2_adv; + +DROP TABLE plt3_adv; + +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001'); + +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0002'); + +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0003'); + +CREATE TABLE plt1_adv_p4 PARTITION OF plt1_adv FOR VALUES IN (NULL, '0004', '0005'); + +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5); + +INSERT INTO plt1_adv VALUES (-1, -1, NULL); + +ANALYZE plt1_adv; + +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0001', '0002'); + +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN (NULL); + +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0003'); + +CREATE TABLE plt2_adv_p4 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005'); + +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5); + +INSERT INTO plt2_adv VALUES (-1, -1, NULL); + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + +CREATE TABLE plt1_adv_default PARTITION OF plt1_adv DEFAULT; + +ANALYZE plt1_adv; + +CREATE TABLE plt2_adv_default PARTITION OF plt2_adv DEFAULT; + +ANALYZE plt2_adv; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + +DROP TABLE plt1_adv; + +DROP TABLE plt2_adv; + +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0000', '0001', '0002'); + +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0003', '0004'); + +INSERT INTO plt1_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i; + +ANALYZE plt1_adv; + +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002'); + +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0003', '0004'); + +INSERT INTO plt2_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (2, 3, 4); + +ANALYZE plt2_adv; + +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c); + +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0001'); + +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0003', '0004'); + +INSERT INTO plt3_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (1, 3, 4); + +ANALYZE plt3_adv; + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a; + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a; + +DROP TABLE plt1_adv; + +DROP TABLE plt2_adv; + +DROP TABLE plt3_adv; + +CREATE TABLE alpha (a double precision, b int, c text) PARTITION BY RANGE (a); + +CREATE TABLE alpha_neg PARTITION OF alpha FOR VALUES FROM ('-Infinity') TO (0) PARTITION BY RANGE (b); + +CREATE TABLE alpha_pos PARTITION OF alpha FOR VALUES FROM (0) TO (10.0) PARTITION BY LIST (c); + +CREATE TABLE alpha_neg_p1 PARTITION OF alpha_neg FOR VALUES FROM (100) TO (200); + +CREATE TABLE alpha_neg_p2 PARTITION OF alpha_neg FOR VALUES FROM (200) TO (300); + +CREATE TABLE alpha_neg_p3 PARTITION OF alpha_neg FOR VALUES FROM (300) TO (400); + +CREATE TABLE alpha_pos_p1 PARTITION OF alpha_pos FOR VALUES IN ('0001', '0003'); + +CREATE TABLE alpha_pos_p2 PARTITION OF alpha_pos FOR VALUES IN ('0004', '0006'); + +CREATE TABLE alpha_pos_p3 PARTITION OF alpha_pos FOR VALUES IN ('0008', '0009'); + +INSERT INTO alpha_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9); + +INSERT INTO alpha_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9); + +ANALYZE alpha; + +CREATE TABLE beta (a double precision, b int, c text) PARTITION BY RANGE (a); + +CREATE TABLE beta_neg PARTITION OF beta FOR VALUES FROM (-10.0) TO (0) PARTITION BY RANGE (b); + +CREATE TABLE beta_pos PARTITION OF beta FOR VALUES FROM (0) TO ('Infinity') PARTITION BY LIST (c); + +CREATE TABLE beta_neg_p1 PARTITION OF beta_neg FOR VALUES FROM (100) TO (150); + +CREATE TABLE beta_neg_p2 PARTITION OF beta_neg FOR VALUES FROM (200) TO (300); + +CREATE TABLE beta_neg_p3 PARTITION OF beta_neg FOR VALUES FROM (350) TO (500); + +CREATE TABLE beta_pos_p1 PARTITION OF beta_pos FOR VALUES IN ('0002', '0003'); + +CREATE TABLE beta_pos_p2 PARTITION OF beta_pos FOR VALUES IN ('0004', '0006'); + +CREATE TABLE beta_pos_p3 PARTITION OF beta_pos FOR VALUES IN ('0007', '0009'); + +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); + +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); + +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); + +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); + +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); + +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); + +ANALYZE beta; + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b; + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b; + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b; + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b; + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b; + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b; + +CREATE TABLE fract_t (id BIGINT, PRIMARY KEY (id)) PARTITION BY RANGE (id); + +CREATE TABLE fract_t0 PARTITION OF fract_t FOR VALUES FROM ('0') TO ('1000'); + +CREATE TABLE fract_t1 PARTITION OF fract_t FOR VALUES FROM ('1000') TO ('2000'); + +INSERT INTO fract_t (id) (SELECT generate_series(0, 1999)); + +ANALYZE fract_t; + +SET max_parallel_workers_per_gather = 0; + +SET enable_partitionwise_join = on; + +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id ASC LIMIT 10; + +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id DESC LIMIT 10; + +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) +ORDER BY x.id DESC LIMIT 2; + +CREATE INDEX pht1_c_idx ON pht1(c); + +SELECT * FROM pht1 p1 JOIN pht1 p2 USING (c) LIMIT 1; + +SELECT * FROM pht1 p1 JOIN pht1 p2 USING (c) LIMIT 100; + +SELECT * FROM pht1 p1 JOIN pht1 p2 USING (c) LIMIT 1000; + +SET max_parallel_workers_per_gather = 1; + +SET debug_parallel_query = on; + +SELECT * FROM pht1 p1 JOIN pht1 p2 USING (c) LIMIT 100; + +RESET debug_parallel_query; + +DROP INDEX pht1_c_idx CASCADE; + +DROP TABLE fract_t; + +RESET max_parallel_workers_per_gather; + +RESET enable_partitionwise_join; diff --git a/crates/pgt_pretty_print/tests/data/multi/partition_prune_60.sql b/crates/pgt_pretty_print/tests/data/multi/partition_prune_60.sql new file mode 100644 index 000000000..c99531d71 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/partition_prune_60.sql @@ -0,0 +1,1633 @@ +create function explain_analyze(query text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s', + query) + loop + ln := regexp_replace(ln, 'Maximum Storage: \d+', 'Maximum Storage: N'); + return next ln; + end loop; +end; +$$; + +set plan_cache_mode = force_generic_plan; + +create table lp (a char) partition by list (a); + +create table lp_default partition of lp default; + +create table lp_ef partition of lp for values in ('e', 'f'); + +create table lp_ad partition of lp for values in ('a', 'd'); + +create table lp_bc partition of lp for values in ('b', 'c'); + +create table lp_g partition of lp for values in ('g'); + +create table lp_null partition of lp for values in (null); + +select * from lp; + +select * from lp where a > 'a' and a < 'd'; + +select * from lp where a > 'a' and a <= 'd'; + +select * from lp where a = 'a'; + +select * from lp where 'a' = a; + +select * from lp where a is not null; + +select * from lp where a is null; + +select * from lp where a = 'a' or a = 'c'; + +select * from lp where a is not null and (a = 'a' or a = 'c'); + +select * from lp where a <> 'g'; + +select * from lp where a <> 'a' and a <> 'd'; + +select * from lp where a not in ('a', 'd'); + +create table coll_pruning (a text collate "C") partition by list (a); + +create table coll_pruning_a partition of coll_pruning for values in ('a'); + +create table coll_pruning_b partition of coll_pruning for values in ('b'); + +create table coll_pruning_def partition of coll_pruning default; + +select * from coll_pruning where a collate "C" = 'a' collate "C"; + +select * from coll_pruning where a collate "POSIX" = 'a' collate "POSIX"; + +create table rlp (a int, b varchar) partition by range (a); + +create table rlp_default partition of rlp default partition by list (a); + +create table rlp_default_default partition of rlp_default default; + +create table rlp_default_10 partition of rlp_default for values in (10); + +create table rlp_default_30 partition of rlp_default for values in (30); + +create table rlp_default_null partition of rlp_default for values in (null); + +create table rlp1 partition of rlp for values from (minvalue) to (1); + +create table rlp2 partition of rlp for values from (1) to (10); + +create table rlp3 (b varchar, a int) partition by list (b varchar_ops); + +create table rlp3_default partition of rlp3 default; + +create table rlp3abcd partition of rlp3 for values in ('ab', 'cd'); + +create table rlp3efgh partition of rlp3 for values in ('ef', 'gh'); + +create table rlp3nullxy partition of rlp3 for values in (null, 'xy'); + +alter table rlp attach partition rlp3 for values from (15) to (20); + +create table rlp4 partition of rlp for values from (20) to (30) partition by range (a); + +create table rlp4_default partition of rlp4 default; + +create table rlp4_1 partition of rlp4 for values from (20) to (25); + +create table rlp4_2 partition of rlp4 for values from (25) to (29); + +create table rlp5 partition of rlp for values from (31) to (maxvalue) partition by range (a); + +create table rlp5_default partition of rlp5 default; + +create table rlp5_1 partition of rlp5 for values from (31) to (40); + +select * from rlp where a < 1; + +select * from rlp where 1 > a; + +select * from rlp where a <= 1; + +select * from rlp where a = 1; + +select * from rlp where a = 1::bigint; + +select * from rlp where a = 1::numeric; + +select * from rlp where a <= 10; + +select * from rlp where a > 10; + +select * from rlp where a < 15; + +select * from rlp where a <= 15; + +select * from rlp where a > 15 and b = 'ab'; + +select * from rlp where a = 16; + +select * from rlp where a = 16 and b in ('not', 'in', 'here'); + +select * from rlp where a = 16 and b < 'ab'; + +select * from rlp where a = 16 and b <= 'ab'; + +select * from rlp where a = 16 and b is null; + +select * from rlp where a = 16 and b is not null; + +select * from rlp where a is null; + +select * from rlp where a is not null; + +select * from rlp where a > 30; + +select * from rlp where a = 30; + +select * from rlp where a <= 31; + +select * from rlp where a = 1 or a = 7; + +select * from rlp where a = 1 or b = 'ab'; + +select * from rlp where a > 20 and a < 27; + +select * from rlp where a = 29; + +select * from rlp where a >= 29; + +select * from rlp where a < 1 or (a > 20 and a < 25); + +select * from rlp where a = 20 or a = 40; + +select * from rlp3 where a = 20; + +select * from rlp where a > 1 and a = 10; + +select * from rlp where a > 1 and a >=15; + +select * from rlp where a = 1 and a = 3; + +select * from rlp where (a = 1 and a = 3) or (a > 1 and a = 15); + +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); + +create table mc3p_default partition of mc3p default; + +create table mc3p0 partition of mc3p for values from (minvalue, minvalue, minvalue) to (1, 1, 1); + +create table mc3p1 partition of mc3p for values from (1, 1, 1) to (10, 5, 10); + +create table mc3p2 partition of mc3p for values from (10, 5, 10) to (10, 10, 10); + +create table mc3p3 partition of mc3p for values from (10, 10, 10) to (10, 10, 20); + +create table mc3p4 partition of mc3p for values from (10, 10, 20) to (10, maxvalue, maxvalue); + +create table mc3p5 partition of mc3p for values from (11, 1, 1) to (20, 10, 10); + +create table mc3p6 partition of mc3p for values from (20, 10, 10) to (20, 20, 20); + +create table mc3p7 partition of mc3p for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue); + +select * from mc3p where a = 1; + +select * from mc3p where a = 1 and abs(b) < 1; + +select * from mc3p where a = 1 and abs(b) = 1; + +select * from mc3p where a = 1 and abs(b) = 1 and c < 8; + +select * from mc3p where a = 10 and abs(b) between 5 and 35; + +select * from mc3p where a > 10; + +select * from mc3p where a >= 10; + +select * from mc3p where a < 10; + +select * from mc3p where a <= 10 and abs(b) < 10; + +select * from mc3p where a = 11 and abs(b) = 0; + +select * from mc3p where a = 20 and abs(b) = 10 and c = 100; + +select * from mc3p where a > 20; + +select * from mc3p where a >= 20; + +select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20); + +select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) or a < 1; + +select * from mc3p where (a = 1 and abs(b) = 1 and c = 1) or (a = 10 and abs(b) = 5 and c = 10) or (a > 11 and a < 20) or a < 1 or a = 1; + +select * from mc3p where a = 1 or abs(b) = 1 or c = 1; + +select * from mc3p where (a = 1 and abs(b) = 1) or (a = 10 and abs(b) = 10); + +select * from mc3p where (a = 1 and abs(b) = 1) or (a = 10 and abs(b) = 9); + +create table mc2p (a int, b int) partition by range (a, b); + +create table mc2p_default partition of mc2p default; + +create table mc2p0 partition of mc2p for values from (minvalue, minvalue) to (1, minvalue); + +create table mc2p1 partition of mc2p for values from (1, minvalue) to (1, 1); + +create table mc2p2 partition of mc2p for values from (1, 1) to (2, minvalue); + +create table mc2p3 partition of mc2p for values from (2, minvalue) to (2, 1); + +create table mc2p4 partition of mc2p for values from (2, 1) to (2, maxvalue); + +create table mc2p5 partition of mc2p for values from (2, maxvalue) to (maxvalue, maxvalue); + +select * from mc2p where a < 2; + +select * from mc2p where a = 2 and b < 1; + +select * from mc2p where a > 1; + +select * from mc2p where a = 1 and b > 1; + +select * from mc2p where a = 1 and b is null; + +select * from mc2p where a is null and b is null; + +select * from mc2p where a is null and b = 1; + +select * from mc2p where a is null; + +select * from mc2p where b is null; + +create table boolpart (a bool) partition by list (a); + +create table boolpart_default partition of boolpart default; + +create table boolpart_t partition of boolpart for values in ('true'); + +create table boolpart_f partition of boolpart for values in ('false'); + +insert into boolpart values (true), (false), (null); + +select * from boolpart where a in (true, false); + +select * from boolpart where a = false; + +select * from boolpart where not a = false; + +select * from boolpart where a is true or a is not true; + +select * from boolpart where a is not true; + +select * from boolpart where a is not true and a is not false; + +select * from boolpart where a is unknown; + +select * from boolpart where a is not unknown; + +select * from boolpart where a in (true, false); + +select * from boolpart where a = false; + +select * from boolpart where not a = false; + +select * from boolpart where a is true or a is not true; + +select * from boolpart where a is not true; + +select * from boolpart where a is not true and a is not false; + +select * from boolpart where a is unknown; + +select * from boolpart where a is not unknown; + +delete from boolpart where a is null; + +create table boolpart_null partition of boolpart for values in (null); + +insert into boolpart values(null); + +select * from boolpart where a is not true; + +select * from boolpart where a is not true and a is not false; + +select * from boolpart where a is not false; + +select * from boolpart where a is not unknown; + +select * from boolpart where a is not true; + +select * from boolpart where a is not true and a is not false; + +select * from boolpart where a is not false; + +select * from boolpart where a is not unknown; + +select * from boolpart where a is not unknown and a is unknown; + +select * from boolpart where a is false and a is unknown; + +select * from boolpart where a is true and a is unknown; + +create table iboolpart (a bool) partition by list ((not a)); + +create table iboolpart_default partition of iboolpart default; + +create table iboolpart_f partition of iboolpart for values in ('true'); + +create table iboolpart_t partition of iboolpart for values in ('false'); + +insert into iboolpart values (true), (false), (null); + +select * from iboolpart where a in (true, false); + +select * from iboolpart where a = false; + +select * from iboolpart where not a = false; + +select * from iboolpart where a is true or a is not true; + +select * from iboolpart where a is not true; + +select * from iboolpart where a is not true and a is not false; + +select * from iboolpart where a is unknown; + +select * from iboolpart where a is not unknown; + +select * from iboolpart where a in (true, false); + +select * from iboolpart where a = false; + +select * from iboolpart where not a = false; + +select * from iboolpart where a is true or a is not true; + +select * from iboolpart where a is not true; + +select * from iboolpart where a is not true and a is not false; + +select * from iboolpart where a is unknown; + +select * from iboolpart where a is not unknown; + +delete from iboolpart where a is null; + +create table iboolpart_null partition of iboolpart for values in (null); + +insert into iboolpart values(null); + +select * from iboolpart where a is not true; + +select * from iboolpart where a is not true and a is not false; + +select * from iboolpart where a is not false; + +create table boolrangep (a bool, b bool, c int) partition by range (a,b,c); + +create table boolrangep_tf partition of boolrangep for values from ('true', 'false', 0) to ('true', 'false', 100); + +create table boolrangep_ft partition of boolrangep for values from ('false', 'true', 0) to ('false', 'true', 100); + +create table boolrangep_ff1 partition of boolrangep for values from ('false', 'false', 0) to ('false', 'false', 50); + +create table boolrangep_ff2 partition of boolrangep for values from ('false', 'false', 50) to ('false', 'false', 100); + +create table boolrangep_null partition of boolrangep default; + +select * from boolrangep where not a and not b and c = 25; + +select * from boolrangep where a is not true and not b and c = 25; + +select * from boolrangep where a is not false and not b and c = 25; + +create table coercepart (a varchar) partition by list (a); + +create table coercepart_ab partition of coercepart for values in ('ab'); + +create table coercepart_bc partition of coercepart for values in ('bc'); + +create table coercepart_cd partition of coercepart for values in ('cd'); + +select * from coercepart where a in ('ab', to_char(125, '999')); + +select * from coercepart where a ~ any ('{ab}'); + +select * from coercepart where a !~ all ('{ab}'); + +select * from coercepart where a ~ any ('{ab,bc}'); + +select * from coercepart where a !~ all ('{ab,bc}'); + +select * from coercepart where a = any ('{ab,bc}'); + +select * from coercepart where a = any ('{ab,null}'); + +select * from coercepart where a = any (null::text[]); + +select * from coercepart where a = all ('{ab}'); + +select * from coercepart where a = all ('{ab,bc}'); + +select * from coercepart where a = all ('{ab,null}'); + +select * from coercepart where a = all (null::text[]); + +drop table coercepart; + +CREATE TABLE part (a INT, b INT) PARTITION BY LIST (a); + +CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2); + +CREATE TABLE part_p2 PARTITION OF part DEFAULT PARTITION BY RANGE(a); + +CREATE TABLE part_p2_p1 PARTITION OF part_p2 DEFAULT; + +CREATE TABLE part_rev (b INT, c INT, a INT); + +ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3); + +ALTER TABLE part_rev DROP COLUMN c; + +ALTER TABLE part ATTACH PARTITION part_rev FOR VALUES IN (3); + +INSERT INTO part VALUES (-1,-1), (1,1), (2,NULL), (NULL,-2),(NULL,NULL); + +SELECT tableoid::regclass as part, a, b FROM part WHERE a IS NULL ORDER BY 1, 2, 3; + +SELECT * FROM part p(x) ORDER BY x; + +select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = t1.b and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1; + +select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.c = t1.b and abs(t2.b) = 1 and t2.a = 1) s where t1.a = 1; + +select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = 1 and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1; + +create table rp (a int) partition by range (a); + +create table rp0 partition of rp for values from (minvalue) to (1); + +create table rp1 partition of rp for values from (1) to (2); + +create table rp2 partition of rp for values from (2) to (maxvalue); + +select * from rp where a <> 1; + +select * from rp where a <> 1 and a <> 2; + +select * from lp where a <> 'a'; + +select * from lp where a <> 'a' and a is null; + +select * from lp where (a <> 'a' and a <> 'd') or a is null; + +select * from rlp where a = 15 and b <> 'ab' and b <> 'cd' and b <> 'xy' and b is not null; + +create table coll_pruning_multi (a text) partition by range (substr(a, 1) collate "POSIX", substr(a, 1) collate "C"); + +create table coll_pruning_multi1 partition of coll_pruning_multi for values from ('a', 'a') to ('a', 'e'); + +create table coll_pruning_multi2 partition of coll_pruning_multi for values from ('a', 'e') to ('a', 'z'); + +create table coll_pruning_multi3 partition of coll_pruning_multi for values from ('b', 'a') to ('b', 'e'); + +select * from coll_pruning_multi where substr(a, 1) = 'e' collate "C"; + +select * from coll_pruning_multi where substr(a, 1) = 'a' collate "POSIX"; + +select * from coll_pruning_multi where substr(a, 1) = 'e' collate "C" and substr(a, 1) = 'a' collate "POSIX"; + +create table like_op_noprune (a text) partition by list (a); + +create table like_op_noprune1 partition of like_op_noprune for values in ('ABC'); + +create table like_op_noprune2 partition of like_op_noprune for values in ('BCD'); + +select * from like_op_noprune where a like '%BC'; + +create table lparted_by_int2 (a smallint) partition by list (a); + +create table lparted_by_int2_1 partition of lparted_by_int2 for values in (1); + +create table lparted_by_int2_16384 partition of lparted_by_int2 for values in (16384); + +select * from lparted_by_int2 where a = 100_000_000_000_000; + +create table rparted_by_int2 (a smallint) partition by range (a); + +create table rparted_by_int2_1 partition of rparted_by_int2 for values from (1) to (10); + +create table rparted_by_int2_16384 partition of rparted_by_int2 for values from (10) to (16384); + +select * from rparted_by_int2 where a > 100_000_000_000_000; + +create table rparted_by_int2_maxvalue partition of rparted_by_int2 for values from (16384) to (maxvalue); + +select * from rparted_by_int2 where a > 100_000_000_000_000; + +drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, iboolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2; + +create table asptab (id int primary key) partition by range (id); + +create table asptab0 partition of asptab for values from (0) to (1); + +create table asptab1 partition of asptab for values from (1) to (2); + +select * from + (select exists (select 1 from int4_tbl tinner where f1 = touter.f1) as b + from int4_tbl touter) ss, + asptab +where asptab.id > ss.b::int; + +drop table asptab; + +create table hp (a int, b text, c int) + partition by hash (a part_test_int4_ops, b part_test_text_ops); + +create table hp0 partition of hp for values with (modulus 4, remainder 0); + +create table hp3 partition of hp for values with (modulus 4, remainder 3); + +create table hp1 partition of hp for values with (modulus 4, remainder 1); + +create table hp2 partition of hp for values with (modulus 4, remainder 2); + +insert into hp values (null, null, 0); + +insert into hp values (1, null, 1); + +insert into hp values (1, 'xxx', 2); + +insert into hp values (null, 'xxx', 3); + +insert into hp values (2, 'xxx', 4); + +insert into hp values (1, 'abcde', 5); + +select tableoid::regclass, * from hp order by c; + +select * from hp where a = 1; + +select * from hp where b = 'xxx'; + +select * from hp where a is null; + +select * from hp where b is null; + +select * from hp where a < 1 and b = 'xxx'; + +select * from hp where a <> 1 and b = 'yyy'; + +select * from hp where a <> 1 and b <> 'xxx'; + +select * from hp where a is null and b is null; + +select * from hp where a = 1 and b is null; + +select * from hp where a = 1 and b = 'xxx'; + +select * from hp where a is null and b = 'xxx'; + +select * from hp where a = 2 and b = 'xxx'; + +select * from hp where a = 1 and b = 'abcde'; + +select * from hp where (a = 1 and b = 'abcde') or (a = 2 and b = 'xxx') or (a is null and b is null); + +drop table hp1; + +drop table hp3; + +select * from hp where a = 1 and b = 'abcde'; + +select * from hp where a = 1 and b = 'abcde' and + (c = 2 or c = 3); + +drop table hp2; + +select * from hp where a = 1 and b = 'abcde' and + (c = 2 or c = 3); + +create table ab (a int not null, b int not null) partition by list (a); + +create table ab_a2 partition of ab for values in(2) partition by list (b); + +create table ab_a2_b1 partition of ab_a2 for values in (1); + +create table ab_a2_b2 partition of ab_a2 for values in (2); + +create table ab_a2_b3 partition of ab_a2 for values in (3); + +create table ab_a1 partition of ab for values in(1) partition by list (b); + +create table ab_a1_b1 partition of ab_a1 for values in (1); + +create table ab_a1_b2 partition of ab_a1 for values in (2); + +create table ab_a1_b3 partition of ab_a1 for values in (3); + +create table ab_a3 partition of ab for values in(3) partition by list (b); + +create table ab_a3_b1 partition of ab_a3 for values in (1); + +create table ab_a3_b2 partition of ab_a3 for values in (2); + +create table ab_a3_b3 partition of ab_a3 for values in (3); + +set enable_indexonlyscan = off; + +prepare ab_q1 (int, int, int) as +select * from ab where a between $1 and $2 and b <= $3; + +explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 2, 3); + +explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (1, 2, 3); + +deallocate ab_q1; + +prepare ab_q1 (int, int) as +select a from ab where a between $1 and $2 and b < 3; + +explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 2); + +explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q1 (2, 4); + +prepare ab_q2 (int, int) as +select a from ab where a between $1 and $2 and b < (select 3); + +explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q2 (2, 2); + +prepare ab_q3 (int, int) as +select a from ab where b between $1 and $2 and a < (select 3); + +explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q3 (2, 2); + +create table hp1 partition of hp for values with (modulus 4, remainder 1); + +create table hp2 partition of hp for values with (modulus 4, remainder 2); + +create table hp3 partition of hp for values with (modulus 4, remainder 3); + +prepare hp_q1 (text) as +select * from hp where a is null and b = $1; + +explain (costs off) execute hp_q1('xxx'); + +deallocate hp_q1; + +drop table hp; + +create table list_part (a int) partition by list (a); + +create table list_part1 partition of list_part for values in (1); + +create table list_part2 partition of list_part for values in (2); + +create table list_part3 partition of list_part for values in (3); + +create table list_part4 partition of list_part for values in (4); + +insert into list_part select generate_series(1,4); + +begin; + +declare cur SCROLL CURSOR for select 1 from list_part where a > (select 1) and a < (select 4); + +move 3 from cur; + +fetch backward all from cur; + +commit; + +begin; + +create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable; + +select * from list_part where a = list_part_fn(1); + +select * from list_part where a = list_part_fn(a); + +select * from list_part where a = list_part_fn(1) + a; + +rollback; + +drop table list_part; + +create function explain_parallel_append(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off, buffers off) %s', + $1) + loop + ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N'); + ln := regexp_replace(ln, 'actual rows=\d+(?:\.\d+)? loops=\d+', 'actual rows=N loops=N'); + ln := regexp_replace(ln, 'Rows Removed by Filter: \d+', 'Rows Removed by Filter: N'); + perform regexp_matches(ln, 'Index Searches: \d+'); + if found then + continue; + end if; + return next ln; + end loop; +end; +$$; + +prepare ab_q4 (int, int) as +select avg(a) from ab where a between $1 and $2 and b < 4; + +set parallel_setup_cost = 0; + +set parallel_tuple_cost = 0; + +set min_parallel_table_scan_size = 0; + +set max_parallel_workers_per_gather = 2; + +select explain_parallel_append('execute ab_q4 (2, 2)'); + +prepare ab_q5 (int, int, int) as +select avg(a) from ab where a in($1,$2,$3) and b < 4; + +select explain_parallel_append('execute ab_q5 (1, 1, 1)'); + +select explain_parallel_append('execute ab_q5 (2, 3, 3)'); + +select explain_parallel_append('execute ab_q5 (33, 44, 55)'); + +select explain_parallel_append('select count(*) from ab where (a = (select 1) or a = (select 3)) and b = 2'); + +create table lprt_a (a int not null); + +insert into lprt_a select 0 from generate_series(1,100); + +insert into lprt_a values(1),(1); + +analyze lprt_a; + +create index ab_a2_b1_a_idx on ab_a2_b1 (a); + +create index ab_a2_b2_a_idx on ab_a2_b2 (a); + +create index ab_a2_b3_a_idx on ab_a2_b3 (a); + +create index ab_a1_b1_a_idx on ab_a1_b1 (a); + +create index ab_a1_b2_a_idx on ab_a1_b2 (a); + +create index ab_a1_b3_a_idx on ab_a1_b3 (a); + +create index ab_a3_b1_a_idx on ab_a3_b1 (a); + +create index ab_a3_b2_a_idx on ab_a3_b2 (a); + +create index ab_a3_b3_a_idx on ab_a3_b3 (a); + +set enable_hashjoin = 0; + +set enable_mergejoin = 0; + +set enable_memoize = 0; + +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(0, 0, 1)'); + +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a + 0 where a.a in(0, 0, 1)'); + +insert into lprt_a values(3),(3); + +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 3)'); + +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)'); + +delete from lprt_a where a = 1; + +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)'); + +reset enable_hashjoin; + +reset enable_mergejoin; + +reset enable_memoize; + +reset parallel_setup_cost; + +reset parallel_tuple_cost; + +reset min_parallel_table_scan_size; + +reset max_parallel_workers_per_gather; + +select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a); + +select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1); + +select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1); + +create table xy_1 (x int, y int); + +insert into xy_1 values(100,-10); + +set enable_bitmapscan = 0; + +set enable_indexscan = 0; + +prepare ab_q6 as +select * from ( + select tableoid::regclass,a,b from ab +union all + select tableoid::regclass,x,y from xy_1 +union all + select tableoid::regclass,a,b from ab +) ab where a = $1 and b = (select -10); + +explain (analyze, costs off, summary off, timing off, buffers off) execute ab_q6(1); + +execute ab_q6(100); + +reset enable_bitmapscan; + +reset enable_indexscan; + +deallocate ab_q1; + +deallocate ab_q2; + +deallocate ab_q3; + +deallocate ab_q4; + +deallocate ab_q5; + +deallocate ab_q6; + +insert into ab values (1,2); + +select explain_analyze(' +update ab_a1 set b = 3 from ab where ab.a = 1 and ab.a = ab_a1.a;'); + +table ab; + +truncate ab; + +insert into ab values (1, 1), (1, 2), (1, 3), (2, 1); + +select explain_analyze(' +update ab_a1 set b = 3 from ab_a2 where ab_a2.b = (select 1);'); + +select tableoid::regclass, * from ab; + +drop table ab, lprt_a; + +create table tbl1(col1 int); + +insert into tbl1 values (501), (505); + +create table tprt (col1 int) partition by range (col1); + +create table tprt_1 partition of tprt for values from (1) to (501); + +create table tprt_2 partition of tprt for values from (501) to (1001); + +create table tprt_3 partition of tprt for values from (1001) to (2001); + +create table tprt_4 partition of tprt for values from (2001) to (3001); + +create table tprt_5 partition of tprt for values from (3001) to (4001); + +create table tprt_6 partition of tprt for values from (4001) to (5001); + +create index tprt1_idx on tprt_1 (col1); + +create index tprt2_idx on tprt_2 (col1); + +create index tprt3_idx on tprt_3 (col1); + +create index tprt4_idx on tprt_4 (col1); + +create index tprt5_idx on tprt_5 (col1); + +create index tprt6_idx on tprt_6 (col1); + +insert into tprt values (10), (20), (501), (502), (505), (1001), (4500); + +set enable_hashjoin = off; + +set enable_mergejoin = off; + +select * from tbl1 join tprt on tbl1.col1 > tprt.col1; + +select * from tbl1 join tprt on tbl1.col1 = tprt.col1; + +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 > tprt.col1 +order by tbl1.col1, tprt.col1; + +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1; + +insert into tbl1 values (1001), (1010), (1011); + +select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1; + +select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1; + +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 > tprt.col1 +order by tbl1.col1, tprt.col1; + +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1; + +delete from tbl1; + +insert into tbl1 values (4400); + +select * from tbl1 join tprt on tbl1.col1 < tprt.col1; + +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 < tprt.col1 +order by tbl1.col1, tprt.col1; + +delete from tbl1; + +insert into tbl1 values (10000); + +select * from tbl1 join tprt on tbl1.col1 = tprt.col1; + +select tbl1.col1, tprt.col1 from tbl1 +inner join tprt on tbl1.col1 = tprt.col1 +order by tbl1.col1, tprt.col1; + +drop table tbl1, tprt; + +create table part_abc (a int not null, b int not null, c int not null) partition by list (a); + +create table part_bac (b int not null, a int not null, c int not null) partition by list (b); + +create table part_cab (c int not null, a int not null, b int not null) partition by list (c); + +create table part_abc_p1 (a int not null, b int not null, c int not null); + +alter table part_abc attach partition part_bac for values in(1); + +alter table part_bac attach partition part_cab for values in(2); + +alter table part_cab attach partition part_abc_p1 for values in(3); + +prepare part_abc_q1 (int, int, int) as +select * from part_abc where a = $1 and b = $2 and c = $3; + +explain (analyze, costs off, summary off, timing off, buffers off) execute part_abc_q1 (1, 2, 3); + +deallocate part_abc_q1; + +drop table part_abc; + +create table listp (a int, b int) partition by list (a); + +create table listp_1 partition of listp for values in(1) partition by list (b); + +create table listp_1_1 partition of listp_1 for values in(1); + +create table listp_2 partition of listp for values in(2) partition by list (b); + +create table listp_2_1 partition of listp_2 for values in(2); + +select * from listp where b = 1; + +prepare q1 (int,int) as select * from listp where b in ($1,$2); + +explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,1); + +explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (2,2); + +explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (0,0); + +deallocate q1; + +prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b; + +explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,2,2,0); + +explain (analyze, costs off, summary off, timing off, buffers off) execute q1 (1,2,2,1); + +select * from listp where a = (select null::int); + +drop table listp; + +create table stable_qual_pruning (a timestamp) partition by range (a); + +create table stable_qual_pruning1 partition of stable_qual_pruning + for values from ('2000-01-01') to ('2000-02-01'); + +create table stable_qual_pruning2 partition of stable_qual_pruning + for values from ('2000-02-01') to ('2000-03-01'); + +create table stable_qual_pruning3 partition of stable_qual_pruning + for values from ('3000-02-01') to ('3000-03-01'); + +select * from stable_qual_pruning where a < localtimestamp; + +select * from stable_qual_pruning where a < '2000-02-01'::timestamptz; + +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamp[]); + +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamp[]); + +select * from stable_qual_pruning + where a = any(array['2000-02-01', localtimestamp]::timestamp[]); + +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]); + +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]); + +select * from stable_qual_pruning + where a = any(null::timestamptz[]); + +drop table stable_qual_pruning; + +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); + +create table mc3p0 partition of mc3p + for values from (0, 0, 0) to (0, maxvalue, maxvalue); + +create table mc3p1 partition of mc3p + for values from (1, 1, 1) to (2, minvalue, minvalue); + +create table mc3p2 partition of mc3p + for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue); + +insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1); + +select * from mc3p where a < 3 and abs(b) = 1; + +prepare ps1 as + select * from mc3p where a = $1 and abs(b) < (select 3); + +explain (analyze, costs off, summary off, timing off, buffers off) +execute ps1(1); + +deallocate ps1; + +prepare ps2 as + select * from mc3p where a <= $1 and abs(b) < (select 3); + +explain (analyze, costs off, summary off, timing off, buffers off) +execute ps2(1); + +deallocate ps2; + +drop table mc3p; + +create table boolvalues (value bool not null); + +insert into boolvalues values('t'),('f'); + +create table boolp (a bool) partition by list (a); + +create table boolp_t partition of boolp for values in('t'); + +create table boolp_f partition of boolp for values in('f'); + +select * from boolp where a = (select value from boolvalues where value); + +select * from boolp where a = (select value from boolvalues where not value); + +drop table boolp; + +set enable_seqscan = off; + +set enable_sort = off; + +create table ma_test (a int, b int) partition by range (a); + +create table ma_test_p1 partition of ma_test for values from (0) to (10); + +create table ma_test_p2 partition of ma_test for values from (10) to (20); + +create table ma_test_p3 partition of ma_test for values from (20) to (30); + +insert into ma_test select x,x from generate_series(0,29) t(x); + +create index on ma_test (b); + +analyze ma_test; + +prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b; + +explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(15); + +execute mt_q1(15); + +explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(25); + +execute mt_q1(25); + +explain (analyze, costs off, summary off, timing off, buffers off) execute mt_q1(35); + +execute mt_q1(35); + +deallocate mt_q1; + +prepare mt_q2 (int) as select * from ma_test where a >= $1 order by b limit 1; + +explain (analyze, verbose, costs off, summary off, timing off, buffers off) execute mt_q2 (35); + +deallocate mt_q2; + +select * from ma_test where a >= (select min(b) from ma_test_p2) order by b; + +reset enable_seqscan; + +reset enable_sort; + +drop table ma_test; + +reset enable_indexonlyscan; + +create table pp_arrpart (a int[]) partition by list (a); + +create table pp_arrpart1 partition of pp_arrpart for values in ('{1}'); + +create table pp_arrpart2 partition of pp_arrpart for values in ('{2, 3}', '{4, 5}'); + +select * from pp_arrpart where a = '{1}'; + +select * from pp_arrpart where a = '{1, 2}'; + +select * from pp_arrpart where a in ('{4, 5}', '{1}'); + +update pp_arrpart set a = a where a = '{1}'; + +delete from pp_arrpart where a = '{1}'; + +drop table pp_arrpart; + +create table pph_arrpart (a int[]) partition by hash (a); + +create table pph_arrpart1 partition of pph_arrpart for values with (modulus 2, remainder 0); + +create table pph_arrpart2 partition of pph_arrpart for values with (modulus 2, remainder 1); + +insert into pph_arrpart values ('{1}'), ('{1, 2}'), ('{4, 5}'); + +select tableoid::regclass, * from pph_arrpart order by 1; + +select * from pph_arrpart where a = '{1}'; + +select * from pph_arrpart where a = '{1, 2}'; + +select * from pph_arrpart where a in ('{4, 5}', '{1}'); + +drop table pph_arrpart; + +create type pp_colors as enum ('green', 'blue', 'black'); + +create table pp_enumpart (a pp_colors) partition by list (a); + +create table pp_enumpart_green partition of pp_enumpart for values in ('green'); + +create table pp_enumpart_blue partition of pp_enumpart for values in ('blue'); + +select * from pp_enumpart where a = 'blue'; + +select * from pp_enumpart where a = 'black'; + +drop table pp_enumpart; + +drop type pp_colors; + +create type pp_rectype as (a int, b int); + +create table pp_recpart (a pp_rectype) partition by list (a); + +create table pp_recpart_11 partition of pp_recpart for values in ('(1,1)'); + +create table pp_recpart_23 partition of pp_recpart for values in ('(2,3)'); + +select * from pp_recpart where a = '(1,1)'::pp_rectype; + +select * from pp_recpart where a = '(1,2)'::pp_rectype; + +drop table pp_recpart; + +drop type pp_rectype; + +create table pp_intrangepart (a int4range) partition by list (a); + +create table pp_intrangepart12 partition of pp_intrangepart for values in ('[1,2]'); + +create table pp_intrangepart2inf partition of pp_intrangepart for values in ('[2,)'); + +select * from pp_intrangepart where a = '[1,2]'::int4range; + +select * from pp_intrangepart where a = '(1,2)'::int4range; + +drop table pp_intrangepart; + +create table pp_lp (a int, value int) partition by list (a); + +create table pp_lp1 partition of pp_lp for values in(1); + +create table pp_lp2 partition of pp_lp for values in(2); + +select * from pp_lp where a = 1; + +update pp_lp set value = 10 where a = 1; + +delete from pp_lp where a = 1; + +set enable_partition_pruning = off; + +set constraint_exclusion = 'partition'; + +select * from pp_lp where a = 1; + +update pp_lp set value = 10 where a = 1; + +delete from pp_lp where a = 1; + +set constraint_exclusion = 'off'; + +select * from pp_lp where a = 1; + +update pp_lp set value = 10 where a = 1; + +delete from pp_lp where a = 1; + +drop table pp_lp; + +create table inh_lp (a int, value int); + +create table inh_lp1 (a int, value int, check(a = 1)) inherits (inh_lp); + +create table inh_lp2 (a int, value int, check(a = 2)) inherits (inh_lp); + +set constraint_exclusion = 'partition'; + +select * from inh_lp where a = 1; + +update inh_lp set value = 10 where a = 1; + +delete from inh_lp where a = 1; + +update inh_lp1 set value = 10 where a = 2; + +drop table inh_lp cascade; + +reset enable_partition_pruning; + +reset constraint_exclusion; + +create temp table pp_temp_parent (a int) partition by list (a); + +create temp table pp_temp_part_1 partition of pp_temp_parent for values in (1); + +create temp table pp_temp_part_def partition of pp_temp_parent default; + +select * from pp_temp_parent where true; + +select * from pp_temp_parent where a = 2; + +drop table pp_temp_parent; + +create temp table p (a int, b int, c int) partition by list (a); + +create temp table p1 partition of p for values in (1); + +create temp table p2 partition of p for values in (2); + +create temp table q (a int, b int, c int) partition by list (a); + +create temp table q1 partition of q for values in (1) partition by list (b); + +create temp table q11 partition of q1 for values in (1) partition by list (c); + +create temp table q111 partition of q11 for values in (1); + +create temp table q2 partition of q for values in (2) partition by list (b); + +create temp table q21 partition of q2 for values in (1); + +create temp table q22 partition of q2 for values in (2); + +insert into q22 values (2, 2, 3); + +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1); + +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1); + +prepare q (int, int) as +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = $1 and s.b = $2 and s.c = (select 1); + +explain (costs off) execute q (1, 1); + +execute q (1, 1); + +drop table p, q; + +create table listp (a int, b int) partition by list (a); + +create table listp1 partition of listp for values in(1); + +create table listp2 partition of listp for values in(2) partition by list(b); + +create table listp2_10 partition of listp2 for values in (10); + +select * from listp where a = (select 2) and b <> 10; + +set enable_partition_pruning to off; + +set constraint_exclusion to 'partition'; + +select * from listp1 where a = 2; + +update listp1 set a = 1 where a = 2; + +set constraint_exclusion to 'on'; + +select * from listp1 where a = 2; + +update listp1 set a = 1 where a = 2; + +reset constraint_exclusion; + +reset enable_partition_pruning; + +drop table listp; + +set parallel_setup_cost to 0; + +set parallel_tuple_cost to 0; + +create table listp (a int) partition by list(a); + +create table listp_12 partition of listp for values in(1,2) partition by list(a); + +create table listp_12_1 partition of listp_12 for values in(1); + +create table listp_12_2 partition of listp_12 for values in(2); + +alter table listp_12_1 set (parallel_workers = 0); + +select explain_parallel_append('select * from listp where a = (select 1);'); + +select explain_parallel_append( +'select * from listp where a = (select 1) + union all +select * from listp where a = (select 2);'); + +drop table listp; + +reset parallel_tuple_cost; + +reset parallel_setup_cost; + +set enable_sort to 0; + +create table rangep (a int, b int) partition by range (a); + +create table rangep_0_to_100 partition of rangep for values from (0) to (100) partition by list (b); + +create table rangep_0_to_100_1 partition of rangep_0_to_100 for values in(1); + +create table rangep_0_to_100_2 partition of rangep_0_to_100 for values in(2); + +create table rangep_0_to_100_3 partition of rangep_0_to_100 for values in(3); + +create table rangep_100_to_200 partition of rangep for values from (100) to (200); + +create index on rangep (a); + +select * from rangep where b IN((select 1),(select 2)) order by a; + +reset enable_sort; + +drop table rangep; + +create table rp_prefix_test1 (a int, b varchar) partition by range(a, b); + +create table rp_prefix_test1_p1 partition of rp_prefix_test1 for values from (1, 'a') to (1, 'b'); + +create table rp_prefix_test1_p2 partition of rp_prefix_test1 for values from (2, 'a') to (2, 'b'); + +select * from rp_prefix_test1 where a <= 1 and b = 'a'; + +create table rp_prefix_test2 (a int, b int, c int) partition by range(a, b, c); + +create table rp_prefix_test2_p1 partition of rp_prefix_test2 for values from (1, 1, 0) to (1, 1, 10); + +create table rp_prefix_test2_p2 partition of rp_prefix_test2 for values from (2, 2, 0) to (2, 2, 10); + +select * from rp_prefix_test2 where a <= 1 and b = 1 and c >= 0; + +create table rp_prefix_test3 (a int, b int, c int, d int) partition by range(a, b, c, d); + +create table rp_prefix_test3_p1 partition of rp_prefix_test3 for values from (1, 1, 1, 0) to (1, 1, 1, 10); + +create table rp_prefix_test3_p2 partition of rp_prefix_test3 for values from (2, 2, 2, 0) to (2, 2, 2, 10); + +select * from rp_prefix_test3 where a >= 1 and b >= 1 and b >= 2 and c >= 2 and d >= 0; + +select * from rp_prefix_test3 where a >= 1 and b >= 1 and b = 2 and c = 2 and d >= 0; + +drop table rp_prefix_test1; + +drop table rp_prefix_test2; + +drop table rp_prefix_test3; + +create table hp_prefix_test (a int, b int, c int, d int) + partition by hash (a part_test_int4_ops, b part_test_int4_ops, c part_test_int4_ops, d part_test_int4_ops); + +select 'create table hp_prefix_test_p' || x::text || ' partition of hp_prefix_test for values with (modulus 8, remainder ' || x::text || ');' +from generate_Series(0,7) x; + +insert into hp_prefix_test +select + case a when 0 then null else 1 end, + case b when 0 then null else 2 end, + case c when 0 then null else 3 end, + case d when 0 then null else 4 end +from + generate_series(0,1) a, + generate_series(0,1) b, + generate_Series(0,1) c, + generate_Series(0,1) d; + +select + 'explain (costs off) select tableoid::regclass,* from hp_prefix_test where ' || + string_agg(c.colname || case when g.s & (1 << c.colpos) = 0 then ' is null' else ' = ' || (colpos+1)::text end, ' and ' order by c.colpos) +from (values('a',0),('b',1),('c',2),('d',3)) c(colname, colpos), generate_Series(0,15) g(s) +group by g.s +order by g.s; + +select + 'select tableoid::regclass,* from hp_prefix_test where ' || + string_agg(c.colname || case when g.s & (1 << c.colpos) = 0 then ' is null' else ' = ' || (colpos+1)::text end, ' and ' order by c.colpos) +from (values('a',0),('b',1),('c',2),('d',3)) c(colname, colpos), generate_Series(0,15) g(s) +group by g.s +order by g.s; + +drop table hp_prefix_test; + +create operator === ( + leftarg = int4, + rightarg = int4, + procedure = int4eq, + commutator = ===, + hashes +); + +create operator class part_test_int4_ops2 +for type int4 +using hash as +operator 1 ===, +function 2 part_hashint4_noop(int4, int8); + +create table hp_contradict_test (a int, b int) partition by hash (a part_test_int4_ops2, b part_test_int4_ops2); + +create table hp_contradict_test_p1 partition of hp_contradict_test for values with (modulus 2, remainder 0); + +create table hp_contradict_test_p2 partition of hp_contradict_test for values with (modulus 2, remainder 1); + +select * from hp_contradict_test where a is null and a === 1 and b === 1; + +select * from hp_contradict_test where a === 1 and b === 1 and a is null; + +drop table hp_contradict_test; + +drop operator class part_test_int4_ops2 using hash; + +drop operator ===(int4, int4); + +drop function explain_analyze(text); + +create table part_abc (a int, b text, c bool) partition by list (a); + +create table part_abc_1 (b text, a int, c bool); + +create table part_abc_2 (a int, c bool, b text); + +alter table part_abc attach partition part_abc_1 for values in (1); + +alter table part_abc attach partition part_abc_2 for values in (2); + +insert into part_abc values (1, 'b', true); + +insert into part_abc values (2, 'c', true); + +create view part_abc_view as select * from part_abc where b <> 'a' with check option; + +update part_abc_view set b = $2 where a = $1 returning *; + +explain (verbose, costs off) execute update_part_abc_view (1, 'd'); + +execute update_part_abc_view (1, 'd'); + +explain (verbose, costs off) execute update_part_abc_view (2, 'a'); + +execute update_part_abc_view (2, 'a'); + +explain (verbose, costs off) execute update_part_abc_view (3, 'a'); + +execute update_part_abc_view (3, 'a'); + +deallocate update_part_abc_view; + +create function stable_one() returns int as $$ begin return 1; end; $$ language plpgsql stable; + +table part_abc_view; + +table part_abc_view; + +begin; + +table part_abc_view; + +rollback; + +begin; + +create table part_abc_log (action text, a int, b text, c bool); + +with t as ( + merge into part_abc_view pt + using (select stable_one() + 1 as pid) as q join part_abc_2 pt2 on (q.pid = pt2.a) on pt.a = stable_one() + 2 + when not matched then insert values (1, 'd', false) returning merge_action(), pt.* +) +insert into part_abc_log select * from t returning *; + +with t as ( + merge into part_abc_view pt + using (select stable_one() + 1 as pid) as q join part_abc_2 pt2 on (q.pid = pt2.a) on pt.a = stable_one() + 2 + when not matched then insert values (1, 'd', false) returning merge_action(), pt.* +) +insert into part_abc_log select * from t returning *; + +table part_abc_view; + +table part_abc_log; + +rollback; + +create index on part_abc (a); + +alter table part_abc add d int; + +create table part_abc_3 partition of part_abc for values in (3, 4) partition by range (d); + +create table part_abc_3_1 partition of part_abc_3 for values from (minvalue) to (1); + +create table part_abc_3_2 partition of part_abc_3 for values from (1) to (100); + +create table part_abc_3_3 partition of part_abc_3 for values from (100) to (maxvalue); + +select min(a) over (partition by a order by a) from part_abc where a >= stable_one() + 1 and d <= stable_one() +union all +select min(a) over (partition by a order by a) from part_abc where a >= stable_one() + 1 and d >= stable_one(); + +drop view part_abc_view; + +drop table part_abc; diff --git a/crates/pgt_pretty_print/tests/data/multi/password_60.sql b/crates/pgt_pretty_print/tests/data/multi/password_60.sql new file mode 100644 index 000000000..258fc861c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/password_60.sql @@ -0,0 +1,120 @@ +SET password_encryption = 'novalue'; + +SET password_encryption = true; + +SET password_encryption = 'md5'; + +SET password_encryption = 'scram-sha-256'; + +SET password_encryption = 'md5'; + +CREATE ROLE regress_passwd1; + +ALTER ROLE regress_passwd1 PASSWORD 'role_pwd1'; + +CREATE ROLE regress_passwd2; + +ALTER ROLE regress_passwd2 PASSWORD 'role_pwd2'; + +SET password_encryption = 'scram-sha-256'; + +CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3'; + +CREATE ROLE regress_passwd4 PASSWORD NULL; + +SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword; + +ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new; + +SELECT rolname, rolpassword + FROM pg_authid + WHERE rolname LIKE 'regress_passwd2_new' + ORDER BY rolname, rolpassword; + +ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2; + +SET password_encryption = 'md5'; + +ALTER ROLE regress_passwd2 PASSWORD 'foo'; + +ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70'; + +ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo='; + +SET password_encryption = 'scram-sha-256'; + +ALTER ROLE regress_passwd4 PASSWORD 'foo'; + +CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023'; + +CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234'; + +CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz'; + +CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz'; + +SET scram_iterations = 1024; + +CREATE ROLE regress_passwd9 PASSWORD 'alterediterationcount'; + +SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword; + +CREATE ROLE regress_passwd_empty PASSWORD ''; + +ALTER ROLE regress_passwd_empty PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a'; + +ALTER ROLE regress_passwd_empty PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27ZFKbZ2nV+vtnYM995pDh9ca6WSi120=:qVV5NeluNfUPkwm7Vqat25RjSPLkGeoZBQs6wVv+um4='; + +SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty'; + +CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; + +CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; + +CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='; + +SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed + FROM pg_authid + WHERE rolname LIKE 'regress_passwd_sha_len%' + ORDER BY rolname; + +CREATE ROLE regress_passwd10 PASSWORD 'SCRAM-SHA-256$000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004096:wNFxNSk1hAXBkgub8py3bg==$65zC6E+R0U7tiYTC9+Wtq4Thw6gUDj3eDCINij8TflU=:rC1I7tcVugrHEY2DT0iPjGyjM4aJxkMM9n8WBxtUtHU='; + +ALTER ROLE regress_passwd9 PASSWORD 'SCRAM-SHA-256$000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004096:wNFxNSk1hAXBkgub8py3bg==$65zC6E+R0U7tiYTC9+Wtq4Thw6gUDj3eDCINij8TflU=:rC1I7tcVugrHEY2DT0iPjGyjM4aJxkMM9n8WBxtUtHU='; + +DROP ROLE regress_passwd1; + +DROP ROLE regress_passwd2; + +DROP ROLE regress_passwd3; + +DROP ROLE regress_passwd4; + +DROP ROLE regress_passwd5; + +DROP ROLE regress_passwd6; + +DROP ROLE regress_passwd7; + +DROP ROLE regress_passwd8; + +DROP ROLE regress_passwd9; + +DROP ROLE regress_passwd_empty; + +DROP ROLE regress_passwd_sha_len0; + +DROP ROLE regress_passwd_sha_len1; + +DROP ROLE regress_passwd_sha_len2; + +SELECT rolname, rolpassword + FROM pg_authid + WHERE rolname LIKE 'regress_passwd%' + ORDER BY rolname, rolpassword; diff --git a/crates/pgt_pretty_print/tests/data/multi/path_60.sql b/crates/pgt_pretty_print/tests/data/multi/path_60.sql new file mode 100644 index 000000000..ca0f988e3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/path_60.sql @@ -0,0 +1,45 @@ +CREATE TABLE PATH_TBL (f1 path); + +INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)]'); + +INSERT INTO PATH_TBL VALUES (' ( ( 1 , 2 ) , ( 3 , 4 ) ) '); + +INSERT INTO PATH_TBL VALUES ('[ (0,0),(3,0),(4,5),(1,6) ]'); + +INSERT INTO PATH_TBL VALUES ('((1,2) ,(3,4 ))'); + +INSERT INTO PATH_TBL VALUES ('1,2 ,3,4 '); + +INSERT INTO PATH_TBL VALUES (' [1,2,3, 4] '); + +INSERT INTO PATH_TBL VALUES ('((10,20))'); + +INSERT INTO PATH_TBL VALUES ('[ 11,12,13,14 ]'); + +INSERT INTO PATH_TBL VALUES ('( 11,12,13,14) '); + +INSERT INTO PATH_TBL VALUES ('[]'); + +INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]'); + +INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)'); + +INSERT INTO PATH_TBL VALUES ('(1,2,3,4'); + +INSERT INTO PATH_TBL VALUES ('(1,2),(3,4)]'); + +SELECT f1 AS open_path FROM PATH_TBL WHERE isopen(f1); + +SELECT f1 AS closed_path FROM PATH_TBL WHERE isclosed(f1); + +SELECT pclose(f1) AS closed_path FROM PATH_TBL; + +SELECT popen(f1) AS open_path FROM PATH_TBL; + +SELECT pg_input_is_valid('[(1,2),(3)]', 'path'); + +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'path'); + +SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path'); + +SELECT * FROM pg_input_error_info('[(1,2,6),(3,4,6)]', 'path'); diff --git a/crates/pgt_pretty_print/tests/data/multi/pg_lsn_60.sql b/crates/pgt_pretty_print/tests/data/multi/pg_lsn_60.sql new file mode 100644 index 000000000..2daf94a19 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/pg_lsn_60.sql @@ -0,0 +1,71 @@ +CREATE TABLE PG_LSN_TBL (f1 pg_lsn); + +INSERT INTO PG_LSN_TBL VALUES ('0/0'); + +INSERT INTO PG_LSN_TBL VALUES ('FFFFFFFF/FFFFFFFF'); + +INSERT INTO PG_LSN_TBL VALUES ('G/0'); + +INSERT INTO PG_LSN_TBL VALUES ('-1/0'); + +INSERT INTO PG_LSN_TBL VALUES (' 0/12345678'); + +INSERT INTO PG_LSN_TBL VALUES ('ABCD/'); + +INSERT INTO PG_LSN_TBL VALUES ('/ABCD'); + +SELECT pg_input_is_valid('16AE7F7', 'pg_lsn'); + +SELECT * FROM pg_input_error_info('16AE7F7', 'pg_lsn'); + +SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL; + +DROP TABLE PG_LSN_TBL; + +SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn; + +SELECT '0/16AE7F8'::pg_lsn != '0/16AE7F7'; + +SELECT '0/16AE7F7' < '0/16AE7F8'::pg_lsn; + +SELECT '0/16AE7F8' > pg_lsn '0/16AE7F7'; + +SELECT '0/16AE7F7'::pg_lsn - '0/16AE7F8'::pg_lsn; + +SELECT '0/16AE7F8'::pg_lsn - '0/16AE7F7'::pg_lsn; + +SELECT '0/16AE7F7'::pg_lsn + 16::numeric; + +SELECT 16::numeric + '0/16AE7F7'::pg_lsn; + +SELECT '0/16AE7F7'::pg_lsn - 16::numeric; + +SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 1::numeric; + +SELECT 'FFFFFFFF/FFFFFFFE'::pg_lsn + 2::numeric; + +SELECT '0/1'::pg_lsn - 1::numeric; + +SELECT '0/1'::pg_lsn - 2::numeric; + +SELECT '0/0'::pg_lsn + ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn); + +SELECT 'FFFFFFFF/FFFFFFFF'::pg_lsn - ('FFFFFFFF/FFFFFFFF'::pg_lsn - '0/0'::pg_lsn); + +SELECT '0/16AE7F7'::pg_lsn + 'NaN'::numeric; + +SELECT '0/16AE7F7'::pg_lsn - 'NaN'::numeric; + +SELECT DISTINCT (i || '/' || j)::pg_lsn f + FROM generate_series(1, 10) i, + generate_series(1, 10) j, + generate_series(1, 5) k + WHERE i <= 10 AND j > 0 AND j <= 10 + ORDER BY f; + +SELECT DISTINCT (i || '/' || j)::pg_lsn f + FROM generate_series(1, 10) i, + generate_series(1, 10) j, + generate_series(1, 5) k + WHERE i <= 10 AND j > 0 AND j <= 10 + ORDER BY f; diff --git a/crates/pgt_pretty_print/tests/data/multi/plancache_60.sql b/crates/pgt_pretty_print/tests/data/multi/plancache_60.sql new file mode 100644 index 000000000..51649e0fe --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/plancache_60.sql @@ -0,0 +1,232 @@ +CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl; + +PREPARE prepstmt AS SELECT * FROM pcachetest; + +EXECUTE prepstmt; + +PREPARE prepstmt2(bigint) AS SELECT * FROM pcachetest WHERE q1 = $1; + +EXECUTE prepstmt2(123); + +DROP TABLE pcachetest; + +EXECUTE prepstmt; + +EXECUTE prepstmt2(123); + +CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2; + +EXECUTE prepstmt; + +EXECUTE prepstmt2(123); + +ALTER TABLE pcachetest ADD COLUMN q3 bigint; + +EXECUTE prepstmt; + +EXECUTE prepstmt2(123); + +ALTER TABLE pcachetest DROP COLUMN q3; + +EXECUTE prepstmt; + +EXECUTE prepstmt2(123); + +CREATE TEMP VIEW pcacheview AS + SELECT * FROM pcachetest; + +PREPARE vprep AS SELECT * FROM pcacheview; + +EXECUTE vprep; + +CREATE OR REPLACE TEMP VIEW pcacheview AS + SELECT q1, q2/2 AS q2 FROM pcachetest; + +EXECUTE vprep; + +create function cache_test(int) returns int as $$ +declare total int; +begin + create temp table t1(f1 int); + insert into t1 values($1); + insert into t1 values(11); + insert into t1 values(12); + insert into t1 values(13); + select sum(f1) into total from t1; + drop table t1; + return total; +end +$$ language plpgsql; + +select cache_test(1); + +select cache_test(2); + +select cache_test(3); + +create temp view v1 as + select 2+2 as f1; + +create function cache_test_2() returns int as $$ +begin + return f1 from v1; +end$$ language plpgsql; + +select cache_test_2(); + +create or replace temp view v1 as + select 2+2+4 as f1; + +select cache_test_2(); + +create or replace temp view v1 as + select 2+2+4+(select max(unique1) from tenk1) as f1; + +select cache_test_2(); + +create schema s1 + +create table abc (f1 int); + +create schema s2 + +create table abc (f1 int); + +insert into s1.abc values(123); + +insert into s2.abc values(456); + +set search_path = s1; + +prepare p1 as select f1 from abc; + +execute p1; + +set search_path = s2; + +select f1 from abc; + +execute p1; + +alter table s1.abc add column f2 float8; + +execute p1; + +drop schema s1 cascade; + +drop schema s2 cascade; + +reset search_path; + +create temp sequence seq; + +prepare p2 as select nextval('seq'); + +execute p2; + +drop sequence seq; + +create temp sequence seq; + +execute p2; + +create function cachebug() returns void as $$ +declare r int; +begin + drop table if exists temptable cascade; + create temp table temptable as select * from generate_series(1,3) as f1; + create temp view vv as select * from temptable; + for r in select * from vv loop + raise notice '%', r; + end loop; +end$$ language plpgsql; + +select cachebug(); + +select cachebug(); + +create table pc_list_parted (a int) partition by list(a); + +create table pc_list_part_null partition of pc_list_parted for values in (null); + +create table pc_list_part_1 partition of pc_list_parted for values in (1); + +create table pc_list_part_def partition of pc_list_parted default; + +insert into pc_list_part_def values($1); + +execute pstmt_def_insert(null); + +execute pstmt_def_insert(1); + +create table pc_list_part_2 partition of pc_list_parted for values in (2); + +execute pstmt_def_insert(2); + +alter table pc_list_parted detach partition pc_list_part_null; + +execute pstmt_def_insert(null); + +drop table pc_list_part_1; + +execute pstmt_def_insert(1); + +drop table pc_list_parted, pc_list_part_null; + +deallocate pstmt_def_insert; + +create table test_mode (a int); + +insert into test_mode select 1 from generate_series(1,1000) union all select 2; + +create index on test_mode (a); + +analyze test_mode; + +prepare test_mode_pp (int) as select count(*) from test_mode where a = $1; + +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp'; + +set plan_cache_mode to auto; + +explain (costs off) execute test_mode_pp(2); + +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp'; + +set plan_cache_mode to force_generic_plan; + +explain (costs off) execute test_mode_pp(2); + +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp'; + +set plan_cache_mode to auto; + +execute test_mode_pp(1); + +execute test_mode_pp(1); + +execute test_mode_pp(1); + +execute test_mode_pp(1); + +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp'; + +execute test_mode_pp(1); + +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp'; + +explain (costs off) execute test_mode_pp(2); + +set plan_cache_mode to force_custom_plan; + +explain (costs off) execute test_mode_pp(2); + +select name, generic_plans, custom_plans from pg_prepared_statements + where name = 'test_mode_pp'; + +drop table test_mode; diff --git a/crates/pgt_pretty_print/tests/data/multi/plpgsql_60.sql b/crates/pgt_pretty_print/tests/data/multi/plpgsql_60.sql new file mode 100644 index 000000000..9c385c1fa --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/plpgsql_60.sql @@ -0,0 +1,4537 @@ +create table Room ( + roomno char(8), + comment text +); + +create unique index Room_rno on Room using btree (roomno bpchar_ops); + +create table WSlot ( + slotname char(20), + roomno char(8), + slotlink char(20), + backlink char(20) +); + +create unique index WSlot_name on WSlot using btree (slotname bpchar_ops); + +create table PField ( + name text, + comment text +); + +create unique index PField_name on PField using btree (name text_ops); + +create table PSlot ( + slotname char(20), + pfname text, + slotlink char(20), + backlink char(20) +); + +create unique index PSlot_name on PSlot using btree (slotname bpchar_ops); + +create table PLine ( + slotname char(20), + phonenumber char(20), + comment text, + backlink char(20) +); + +create unique index PLine_name on PLine using btree (slotname bpchar_ops); + +create table Hub ( + name char(14), + comment text, + nslots integer +); + +create unique index Hub_name on Hub using btree (name bpchar_ops); + +create table HSlot ( + slotname char(20), + hubname char(14), + slotno integer, + slotlink char(20) +); + +create unique index HSlot_name on HSlot using btree (slotname bpchar_ops); + +create index HSlot_hubname on HSlot using btree (hubname bpchar_ops); + +create table System ( + name text, + comment text +); + +create unique index System_name on System using btree (name text_ops); + +create table IFace ( + slotname char(20), + sysname text, + ifname text, + slotlink char(20) +); + +create unique index IFace_name on IFace using btree (slotname bpchar_ops); + +create table PHone ( + slotname char(20), + comment text, + slotlink char(20) +); + +create unique index PHone_name on PHone using btree (slotname bpchar_ops); + +create function tg_room_au() returns trigger as ' +begin + if new.roomno != old.roomno then + update WSlot set roomno = new.roomno where roomno = old.roomno; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_room_au after update + on Room for each row execute procedure tg_room_au(); + +create function tg_room_ad() returns trigger as ' +begin + delete from WSlot where roomno = old.roomno; + return old; +end; +' language plpgsql; + +create trigger tg_room_ad after delete + on Room for each row execute procedure tg_room_ad(); + +create function tg_wslot_biu() returns trigger as $$ +begin + if count(*) = 0 from Room where roomno = new.roomno then + raise exception 'Room % does not exist', new.roomno; + end if; + return new; +end; +$$ language plpgsql; + +create trigger tg_wslot_biu before insert or update + on WSlot for each row execute procedure tg_wslot_biu(); + +create function tg_pfield_au() returns trigger as ' +begin + if new.name != old.name then + update PSlot set pfname = new.name where pfname = old.name; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_pfield_au after update + on PField for each row execute procedure tg_pfield_au(); + +create function tg_pfield_ad() returns trigger as ' +begin + delete from PSlot where pfname = old.name; + return old; +end; +' language plpgsql; + +create trigger tg_pfield_ad after delete + on PField for each row execute procedure tg_pfield_ad(); + +create function tg_pslot_biu() returns trigger as $proc$ +declare + pfrec record; + ps alias for new; +begin + select into pfrec * from PField where name = ps.pfname; + if not found then + raise exception $$Patchfield "%" does not exist$$, ps.pfname; + end if; + return ps; +end; +$proc$ language plpgsql; + +create trigger tg_pslot_biu before insert or update + on PSlot for each row execute procedure tg_pslot_biu(); + +create function tg_system_au() returns trigger as ' +begin + if new.name != old.name then + update IFace set sysname = new.name where sysname = old.name; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_system_au after update + on System for each row execute procedure tg_system_au(); + +create function tg_iface_biu() returns trigger as $$ +declare + sname text; + sysrec record; +begin + select into sysrec * from system where name = new.sysname; + if not found then + raise exception $q$system "%" does not exist$q$, new.sysname; + end if; + sname := 'IF.' || new.sysname; + sname := sname || '.'; + sname := sname || new.ifname; + if length(sname) > 20 then + raise exception 'IFace slotname "%" too long (20 char max)', sname; + end if; + new.slotname := sname; + return new; +end; +$$ language plpgsql; + +create trigger tg_iface_biu before insert or update + on IFace for each row execute procedure tg_iface_biu(); + +create function tg_hub_a() returns trigger as ' +declare + hname text; + dummy integer; +begin + if tg_op = ''INSERT'' then + dummy := tg_hub_adjustslots(new.name, 0, new.nslots); + return new; + end if; + if tg_op = ''UPDATE'' then + if new.name != old.name then + update HSlot set hubname = new.name where hubname = old.name; + end if; + dummy := tg_hub_adjustslots(new.name, old.nslots, new.nslots); + return new; + end if; + if tg_op = ''DELETE'' then + dummy := tg_hub_adjustslots(old.name, old.nslots, 0); + return old; + end if; +end; +' language plpgsql; + +create trigger tg_hub_a after insert or update or delete + on Hub for each row execute procedure tg_hub_a(); + +create function tg_hub_adjustslots(hname bpchar, + oldnslots integer, + newnslots integer) +returns integer as ' +begin + if newnslots = oldnslots then + return 0; + end if; + if newnslots < oldnslots then + delete from HSlot where hubname = hname and slotno > newnslots; + return 0; + end if; + for i in oldnslots + 1 .. newnslots loop + insert into HSlot (slotname, hubname, slotno, slotlink) + values (''HS.dummy'', hname, i, ''''); + end loop; + return 0; +end +' language plpgsql; + +COMMENT ON FUNCTION tg_hub_adjustslots_wrong(bpchar, integer, integer) IS 'function with args'; + +COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS 'function with args'; + +COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS NULL; + +create function tg_hslot_biu() returns trigger as ' +declare + sname text; + xname HSlot.slotname%TYPE; + hubrec record; +begin + select into hubrec * from Hub where name = new.hubname; + if not found then + raise exception ''no manual manipulation of HSlot''; + end if; + if new.slotno < 1 or new.slotno > hubrec.nslots then + raise exception ''no manual manipulation of HSlot''; + end if; + if tg_op = ''UPDATE'' and new.hubname != old.hubname then + if count(*) > 0 from Hub where name = old.hubname then + raise exception ''no manual manipulation of HSlot''; + end if; + end if; + sname := ''HS.'' || trim(new.hubname); + sname := sname || ''.''; + sname := sname || new.slotno::text; + if length(sname) > 20 then + raise exception ''HSlot slotname "%" too long (20 char max)'', sname; + end if; + new.slotname := sname; + return new; +end; +' language plpgsql; + +create trigger tg_hslot_biu before insert or update + on HSlot for each row execute procedure tg_hslot_biu(); + +create function tg_hslot_bd() returns trigger as ' +declare + hubrec record; +begin + select into hubrec * from Hub where name = old.hubname; + if not found then + return old; + end if; + if old.slotno > hubrec.nslots then + return old; + end if; + raise exception ''no manual manipulation of HSlot''; +end; +' language plpgsql; + +create trigger tg_hslot_bd before delete + on HSlot for each row execute procedure tg_hslot_bd(); + +create function tg_chkslotname() returns trigger as ' +begin + if substr(new.slotname, 1, 2) != tg_argv[0] then + raise exception ''slotname must begin with %'', tg_argv[0]; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_chkslotname before insert + on PSlot for each row execute procedure tg_chkslotname('PS'); + +create trigger tg_chkslotname before insert + on WSlot for each row execute procedure tg_chkslotname('WS'); + +create trigger tg_chkslotname before insert + on PLine for each row execute procedure tg_chkslotname('PL'); + +create trigger tg_chkslotname before insert + on IFace for each row execute procedure tg_chkslotname('IF'); + +create trigger tg_chkslotname before insert + on PHone for each row execute procedure tg_chkslotname('PH'); + +create function tg_chkslotlink() returns trigger as ' +begin + if new.slotlink isnull then + new.slotlink := ''''; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_chkslotlink before insert or update + on PSlot for each row execute procedure tg_chkslotlink(); + +create trigger tg_chkslotlink before insert or update + on WSlot for each row execute procedure tg_chkslotlink(); + +create trigger tg_chkslotlink before insert or update + on IFace for each row execute procedure tg_chkslotlink(); + +create trigger tg_chkslotlink before insert or update + on HSlot for each row execute procedure tg_chkslotlink(); + +create trigger tg_chkslotlink before insert or update + on PHone for each row execute procedure tg_chkslotlink(); + +create function tg_chkbacklink() returns trigger as ' +begin + if new.backlink isnull then + new.backlink := ''''; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_chkbacklink before insert or update + on PSlot for each row execute procedure tg_chkbacklink(); + +create trigger tg_chkbacklink before insert or update + on WSlot for each row execute procedure tg_chkbacklink(); + +create trigger tg_chkbacklink before insert or update + on PLine for each row execute procedure tg_chkbacklink(); + +create function tg_pslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PSlot where slotname = old.slotname; + insert into PSlot ( + slotname, + pfname, + slotlink, + backlink + ) values ( + new.slotname, + new.pfname, + new.slotlink, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_pslot_bu before update + on PSlot for each row execute procedure tg_pslot_bu(); + +create function tg_wslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from WSlot where slotname = old.slotname; + insert into WSlot ( + slotname, + roomno, + slotlink, + backlink + ) values ( + new.slotname, + new.roomno, + new.slotlink, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_wslot_bu before update + on WSlot for each row execute procedure tg_Wslot_bu(); + +create function tg_pline_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PLine where slotname = old.slotname; + insert into PLine ( + slotname, + phonenumber, + comment, + backlink + ) values ( + new.slotname, + new.phonenumber, + new.comment, + new.backlink + ); + return null; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_pline_bu before update + on PLine for each row execute procedure tg_pline_bu(); + +create function tg_iface_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from IFace where slotname = old.slotname; + insert into IFace ( + slotname, + sysname, + ifname, + slotlink + ) values ( + new.slotname, + new.sysname, + new.ifname, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_iface_bu before update + on IFace for each row execute procedure tg_iface_bu(); + +create function tg_hslot_bu() returns trigger as ' +begin + if new.slotname != old.slotname or new.hubname != old.hubname then + delete from HSlot where slotname = old.slotname; + insert into HSlot ( + slotname, + hubname, + slotno, + slotlink + ) values ( + new.slotname, + new.hubname, + new.slotno, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_hslot_bu before update + on HSlot for each row execute procedure tg_hslot_bu(); + +create function tg_phone_bu() returns trigger as ' +begin + if new.slotname != old.slotname then + delete from PHone where slotname = old.slotname; + insert into PHone ( + slotname, + comment, + slotlink + ) values ( + new.slotname, + new.comment, + new.slotlink + ); + return null; + end if; + return new; +end; +' language plpgsql; + +create trigger tg_phone_bu before update + on PHone for each row execute procedure tg_phone_bu(); + +create function tg_backlink_a() returns trigger as ' +declare + dummy integer; +begin + if tg_op = ''INSERT'' then + if new.backlink != '''' then + dummy := tg_backlink_set(new.backlink, new.slotname); + end if; + return new; + end if; + if tg_op = ''UPDATE'' then + if new.backlink != old.backlink then + if old.backlink != '''' then + dummy := tg_backlink_unset(old.backlink, old.slotname); + end if; + if new.backlink != '''' then + dummy := tg_backlink_set(new.backlink, new.slotname); + end if; + else + if new.slotname != old.slotname and new.backlink != '''' then + dummy := tg_slotlink_set(new.backlink, new.slotname); + end if; + end if; + return new; + end if; + if tg_op = ''DELETE'' then + if old.backlink != '''' then + dummy := tg_backlink_unset(old.backlink, old.slotname); + end if; + return old; + end if; +end; +' language plpgsql; + +create trigger tg_backlink_a after insert or update or delete + on PSlot for each row execute procedure tg_backlink_a('PS'); + +create trigger tg_backlink_a after insert or update or delete + on WSlot for each row execute procedure tg_backlink_a('WS'); + +create trigger tg_backlink_a after insert or update or delete + on PLine for each row execute procedure tg_backlink_a('PL'); + +create function tg_backlink_set(myname bpchar, blname bpchar) +returns integer as ' +declare + mytype char(2); + link char(4); + rec record; +begin + mytype := substr(myname, 1, 2); + link := mytype || substr(blname, 1, 2); + if link = ''PLPL'' then + raise exception + ''backlink between two phone lines does not make sense''; + end if; + if link in (''PLWS'', ''WSPL'') then + raise exception + ''direct link of phone line to wall slot not permitted''; + end if; + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update PSlot set backlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update WSlot set backlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PL'' then + select into rec * from PLine where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.backlink != blname then + update PLine set backlink = blname where slotname = myname; + end if; + return 0; + end if; + raise exception ''illegal backlink beginning with %'', mytype; +end; +' language plpgsql; + +create function tg_backlink_unset(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + rec record; +begin + mytype := substr(myname, 1, 2); + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update PSlot set backlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update WSlot set backlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PL'' then + select into rec * from PLine where slotname = myname; + if not found then + return 0; + end if; + if rec.backlink = blname then + update PLine set backlink = '''' where slotname = myname; + end if; + return 0; + end if; +end +' language plpgsql; + +create function tg_slotlink_a() returns trigger as ' +declare + dummy integer; +begin + if tg_op = ''INSERT'' then + if new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + return new; + end if; + if tg_op = ''UPDATE'' then + if new.slotlink != old.slotlink then + if old.slotlink != '''' then + dummy := tg_slotlink_unset(old.slotlink, old.slotname); + end if; + if new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + else + if new.slotname != old.slotname and new.slotlink != '''' then + dummy := tg_slotlink_set(new.slotlink, new.slotname); + end if; + end if; + return new; + end if; + if tg_op = ''DELETE'' then + if old.slotlink != '''' then + dummy := tg_slotlink_unset(old.slotlink, old.slotname); + end if; + return old; + end if; +end; +' language plpgsql; + +create trigger tg_slotlink_a after insert or update or delete + on PSlot for each row execute procedure tg_slotlink_a('PS'); + +create trigger tg_slotlink_a after insert or update or delete + on WSlot for each row execute procedure tg_slotlink_a('WS'); + +create trigger tg_slotlink_a after insert or update or delete + on IFace for each row execute procedure tg_slotlink_a('IF'); + +create trigger tg_slotlink_a after insert or update or delete + on HSlot for each row execute procedure tg_slotlink_a('HS'); + +create trigger tg_slotlink_a after insert or update or delete + on PHone for each row execute procedure tg_slotlink_a('PH'); + +create function tg_slotlink_set(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + link char(4); + rec record; +begin + mytype := substr(myname, 1, 2); + link := mytype || substr(blname, 1, 2); + if link = ''PHPH'' then + raise exception + ''slotlink between two phones does not make sense''; + end if; + if link in (''PHHS'', ''HSPH'') then + raise exception + ''link of phone to hub does not make sense''; + end if; + if link in (''PHIF'', ''IFPH'') then + raise exception + ''link of phone to hub does not make sense''; + end if; + if link in (''PSWS'', ''WSPS'') then + raise exception + ''slotlink from patchslot to wallslot not permitted''; + end if; + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update PSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update WSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''IF'' then + select into rec * from IFace where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update IFace set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''HS'' then + select into rec * from HSlot where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update HSlot set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PH'' then + select into rec * from PHone where slotname = myname; + if not found then + raise exception ''% does not exist'', myname; + end if; + if rec.slotlink != blname then + update PHone set slotlink = blname where slotname = myname; + end if; + return 0; + end if; + raise exception ''illegal slotlink beginning with %'', mytype; +end; +' language plpgsql; + +create function tg_slotlink_unset(bpchar, bpchar) +returns integer as ' +declare + myname alias for $1; + blname alias for $2; + mytype char(2); + rec record; +begin + mytype := substr(myname, 1, 2); + if mytype = ''PS'' then + select into rec * from PSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update PSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''WS'' then + select into rec * from WSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update WSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''IF'' then + select into rec * from IFace where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update IFace set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''HS'' then + select into rec * from HSlot where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update HSlot set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; + if mytype = ''PH'' then + select into rec * from PHone where slotname = myname; + if not found then + return 0; + end if; + if rec.slotlink = blname then + update PHone set slotlink = '''' where slotname = myname; + end if; + return 0; + end if; +end; +' language plpgsql; + +create function pslot_backlink_view(bpchar) +returns text as ' +<> +declare + rec record; + bltype char(2); + retval text; +begin + select into rec * from PSlot where slotname = $1; + if not found then + return ''''; + end if; + if rec.backlink = '''' then + return ''-''; + end if; + bltype := substr(rec.backlink, 1, 2); + if bltype = ''PL'' then + declare + rec record; + begin + select into rec * from PLine where slotname = "outer".rec.backlink; + retval := ''Phone line '' || trim(rec.phonenumber); + if rec.comment != '''' then + retval := retval || '' (''; + retval := retval || rec.comment; + retval := retval || '')''; + end if; + return retval; + end; + end if; + if bltype = ''WS'' then + select into rec * from WSlot where slotname = rec.backlink; + retval := trim(rec.slotname) || '' in room ''; + retval := retval || trim(rec.roomno); + retval := retval || '' -> ''; + return retval || wslot_slotlink_view(rec.slotname); + end if; + return rec.backlink; +end; +' language plpgsql; + +create function pslot_slotlink_view(bpchar) +returns text as ' +declare + psrec record; + sltype char(2); + retval text; +begin + select into psrec * from PSlot where slotname = $1; + if not found then + return ''''; + end if; + if psrec.slotlink = '''' then + return ''-''; + end if; + sltype := substr(psrec.slotlink, 1, 2); + if sltype = ''PS'' then + retval := trim(psrec.slotlink) || '' -> ''; + return retval || pslot_backlink_view(psrec.slotlink); + end if; + if sltype = ''HS'' then + retval := comment from Hub H, HSlot HS + where HS.slotname = psrec.slotlink + and H.name = HS.hubname; + retval := retval || '' slot ''; + retval := retval || slotno::text from HSlot + where slotname = psrec.slotlink; + return retval; + end if; + return psrec.slotlink; +end; +' language plpgsql; + +create function wslot_slotlink_view(bpchar) +returns text as ' +declare + rec record; + sltype char(2); + retval text; +begin + select into rec * from WSlot where slotname = $1; + if not found then + return ''''; + end if; + if rec.slotlink = '''' then + return ''-''; + end if; + sltype := substr(rec.slotlink, 1, 2); + if sltype = ''PH'' then + select into rec * from PHone where slotname = rec.slotlink; + retval := ''Phone '' || trim(rec.slotname); + if rec.comment != '''' then + retval := retval || '' (''; + retval := retval || rec.comment; + retval := retval || '')''; + end if; + return retval; + end if; + if sltype = ''IF'' then + declare + syrow System%RowType; + ifrow IFace%ROWTYPE; + begin + select into ifrow * from IFace where slotname = rec.slotlink; + select into syrow * from System where name = ifrow.sysname; + retval := syrow.name || '' IF ''; + retval := retval || ifrow.ifname; + if syrow.comment != '''' then + retval := retval || '' (''; + retval := retval || syrow.comment; + retval := retval || '')''; + end if; + return retval; + end; + end if; + return rec.slotlink; +end; +' language plpgsql; + +create view Pfield_v1 as select PF.pfname, PF.slotname, + pslot_backlink_view(PF.slotname) as backside, + pslot_slotlink_view(PF.slotname) as patch + from PSlot PF; + +insert into Room values ('001', 'Entrance'); + +insert into Room values ('002', 'Office'); + +insert into Room values ('003', 'Office'); + +insert into Room values ('004', 'Technical'); + +insert into Room values ('101', 'Office'); + +insert into Room values ('102', 'Conference'); + +insert into Room values ('103', 'Restroom'); + +insert into Room values ('104', 'Technical'); + +insert into Room values ('105', 'Office'); + +insert into Room values ('106', 'Office'); + +insert into WSlot values ('WS.001.1a', '001', '', ''); + +insert into WSlot values ('WS.001.1b', '001', '', ''); + +insert into WSlot values ('WS.001.2a', '001', '', ''); + +insert into WSlot values ('WS.001.2b', '001', '', ''); + +insert into WSlot values ('WS.001.3a', '001', '', ''); + +insert into WSlot values ('WS.001.3b', '001', '', ''); + +insert into WSlot values ('WS.002.1a', '002', '', ''); + +insert into WSlot values ('WS.002.1b', '002', '', ''); + +insert into WSlot values ('WS.002.2a', '002', '', ''); + +insert into WSlot values ('WS.002.2b', '002', '', ''); + +insert into WSlot values ('WS.002.3a', '002', '', ''); + +insert into WSlot values ('WS.002.3b', '002', '', ''); + +insert into WSlot values ('WS.003.1a', '003', '', ''); + +insert into WSlot values ('WS.003.1b', '003', '', ''); + +insert into WSlot values ('WS.003.2a', '003', '', ''); + +insert into WSlot values ('WS.003.2b', '003', '', ''); + +insert into WSlot values ('WS.003.3a', '003', '', ''); + +insert into WSlot values ('WS.003.3b', '003', '', ''); + +insert into WSlot values ('WS.101.1a', '101', '', ''); + +insert into WSlot values ('WS.101.1b', '101', '', ''); + +insert into WSlot values ('WS.101.2a', '101', '', ''); + +insert into WSlot values ('WS.101.2b', '101', '', ''); + +insert into WSlot values ('WS.101.3a', '101', '', ''); + +insert into WSlot values ('WS.101.3b', '101', '', ''); + +insert into WSlot values ('WS.102.1a', '102', '', ''); + +insert into WSlot values ('WS.102.1b', '102', '', ''); + +insert into WSlot values ('WS.102.2a', '102', '', ''); + +insert into WSlot values ('WS.102.2b', '102', '', ''); + +insert into WSlot values ('WS.102.3a', '102', '', ''); + +insert into WSlot values ('WS.102.3b', '102', '', ''); + +insert into WSlot values ('WS.105.1a', '105', '', ''); + +insert into WSlot values ('WS.105.1b', '105', '', ''); + +insert into WSlot values ('WS.105.2a', '105', '', ''); + +insert into WSlot values ('WS.105.2b', '105', '', ''); + +insert into WSlot values ('WS.105.3a', '105', '', ''); + +insert into WSlot values ('WS.105.3b', '105', '', ''); + +insert into WSlot values ('WS.106.1a', '106', '', ''); + +insert into WSlot values ('WS.106.1b', '106', '', ''); + +insert into WSlot values ('WS.106.2a', '106', '', ''); + +insert into WSlot values ('WS.106.2b', '106', '', ''); + +insert into WSlot values ('WS.106.3a', '106', '', ''); + +insert into WSlot values ('WS.106.3b', '106', '', ''); + +insert into PField values ('PF0_1', 'Wallslots basement'); + +insert into PSlot values ('PS.base.a1', 'PF0_1', '', ''); + +insert into PSlot values ('PS.base.a2', 'PF0_1', '', ''); + +insert into PSlot values ('PS.base.a3', 'PF0_1', '', ''); + +insert into PSlot values ('PS.base.a4', 'PF0_1', '', ''); + +insert into PSlot values ('PS.base.a5', 'PF0_1', '', ''); + +insert into PSlot values ('PS.base.a6', 'PF0_1', '', ''); + +insert into PSlot values ('PS.base.b1', 'PF0_1', '', 'WS.002.1a'); + +insert into PSlot values ('PS.base.b2', 'PF0_1', '', 'WS.002.1b'); + +insert into PSlot values ('PS.base.b3', 'PF0_1', '', 'WS.002.2a'); + +insert into PSlot values ('PS.base.b4', 'PF0_1', '', 'WS.002.2b'); + +insert into PSlot values ('PS.base.b5', 'PF0_1', '', 'WS.002.3a'); + +insert into PSlot values ('PS.base.b6', 'PF0_1', '', 'WS.002.3b'); + +insert into PSlot values ('PS.base.c1', 'PF0_1', '', 'WS.003.1a'); + +insert into PSlot values ('PS.base.c2', 'PF0_1', '', 'WS.003.1b'); + +insert into PSlot values ('PS.base.c3', 'PF0_1', '', 'WS.003.2a'); + +insert into PSlot values ('PS.base.c4', 'PF0_1', '', 'WS.003.2b'); + +insert into PSlot values ('PS.base.c5', 'PF0_1', '', 'WS.003.3a'); + +insert into PSlot values ('PS.base.c6', 'PF0_1', '', 'WS.003.3b'); + +insert into PField values ('PF0_X', 'Phonelines basement'); + +insert into PSlot values ('PS.base.ta1', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.ta2', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.ta3', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.ta4', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.ta5', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.ta6', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.tb1', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.tb2', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.tb3', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.tb4', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.tb5', 'PF0_X', '', ''); + +insert into PSlot values ('PS.base.tb6', 'PF0_X', '', ''); + +insert into PField values ('PF1_1', 'Wallslots first floor'); + +insert into PSlot values ('PS.first.a1', 'PF1_1', '', 'WS.101.1a'); + +insert into PSlot values ('PS.first.a2', 'PF1_1', '', 'WS.101.1b'); + +insert into PSlot values ('PS.first.a3', 'PF1_1', '', 'WS.101.2a'); + +insert into PSlot values ('PS.first.a4', 'PF1_1', '', 'WS.101.2b'); + +insert into PSlot values ('PS.first.a5', 'PF1_1', '', 'WS.101.3a'); + +insert into PSlot values ('PS.first.a6', 'PF1_1', '', 'WS.101.3b'); + +insert into PSlot values ('PS.first.b1', 'PF1_1', '', 'WS.102.1a'); + +insert into PSlot values ('PS.first.b2', 'PF1_1', '', 'WS.102.1b'); + +insert into PSlot values ('PS.first.b3', 'PF1_1', '', 'WS.102.2a'); + +insert into PSlot values ('PS.first.b4', 'PF1_1', '', 'WS.102.2b'); + +insert into PSlot values ('PS.first.b5', 'PF1_1', '', 'WS.102.3a'); + +insert into PSlot values ('PS.first.b6', 'PF1_1', '', 'WS.102.3b'); + +insert into PSlot values ('PS.first.c1', 'PF1_1', '', 'WS.105.1a'); + +insert into PSlot values ('PS.first.c2', 'PF1_1', '', 'WS.105.1b'); + +insert into PSlot values ('PS.first.c3', 'PF1_1', '', 'WS.105.2a'); + +insert into PSlot values ('PS.first.c4', 'PF1_1', '', 'WS.105.2b'); + +insert into PSlot values ('PS.first.c5', 'PF1_1', '', 'WS.105.3a'); + +insert into PSlot values ('PS.first.c6', 'PF1_1', '', 'WS.105.3b'); + +insert into PSlot values ('PS.first.d1', 'PF1_1', '', 'WS.106.1a'); + +insert into PSlot values ('PS.first.d2', 'PF1_1', '', 'WS.106.1b'); + +insert into PSlot values ('PS.first.d3', 'PF1_1', '', 'WS.106.2a'); + +insert into PSlot values ('PS.first.d4', 'PF1_1', '', 'WS.106.2b'); + +insert into PSlot values ('PS.first.d5', 'PF1_1', '', 'WS.106.3a'); + +insert into PSlot values ('PS.first.d6', 'PF1_1', '', 'WS.106.3b'); + +update PSlot set backlink = 'WS.001.1a' where slotname = 'PS.base.a1'; + +update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a3'; + +select * from WSlot where roomno = '001' order by slotname; + +select * from PSlot where slotname ~ 'PS.base.a' order by slotname; + +update PSlot set backlink = 'WS.001.2a' where slotname = 'PS.base.a3'; + +select * from WSlot where roomno = '001' order by slotname; + +select * from PSlot where slotname ~ 'PS.base.a' order by slotname; + +update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a2'; + +select * from WSlot where roomno = '001' order by slotname; + +select * from PSlot where slotname ~ 'PS.base.a' order by slotname; + +update WSlot set backlink = 'PS.base.a4' where slotname = 'WS.001.2b'; + +update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3a'; + +select * from WSlot where roomno = '001' order by slotname; + +select * from PSlot where slotname ~ 'PS.base.a' order by slotname; + +update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3b'; + +select * from WSlot where roomno = '001' order by slotname; + +select * from PSlot where slotname ~ 'PS.base.a' order by slotname; + +update WSlot set backlink = 'PS.base.a5' where slotname = 'WS.001.3a'; + +select * from WSlot where roomno = '001' order by slotname; + +select * from PSlot where slotname ~ 'PS.base.a' order by slotname; + +insert into PField values ('PF1_2', 'Phonelines first floor'); + +insert into PSlot values ('PS.first.ta1', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.ta2', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.ta3', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.ta4', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.ta5', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.ta6', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.tb1', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.tb2', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.tb3', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.tb4', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.tb5', 'PF1_2', '', ''); + +insert into PSlot values ('PS.first.tb6', 'PF1_2', '', ''); + +update PField set name = 'PF0_2' where name = 'PF0_X'; + +select * from PSlot order by slotname; + +select * from WSlot order by slotname; + +insert into PLine values ('PL.001', '-0', 'Central call', 'PS.base.ta1'); + +insert into PLine values ('PL.002', '-101', '', 'PS.base.ta2'); + +insert into PLine values ('PL.003', '-102', '', 'PS.base.ta3'); + +insert into PLine values ('PL.004', '-103', '', 'PS.base.ta5'); + +insert into PLine values ('PL.005', '-104', '', 'PS.base.ta6'); + +insert into PLine values ('PL.006', '-106', '', 'PS.base.tb2'); + +insert into PLine values ('PL.007', '-108', '', 'PS.base.tb3'); + +insert into PLine values ('PL.008', '-109', '', 'PS.base.tb4'); + +insert into PLine values ('PL.009', '-121', '', 'PS.base.tb5'); + +insert into PLine values ('PL.010', '-122', '', 'PS.base.tb6'); + +insert into PLine values ('PL.015', '-134', '', 'PS.first.ta1'); + +insert into PLine values ('PL.016', '-137', '', 'PS.first.ta3'); + +insert into PLine values ('PL.017', '-139', '', 'PS.first.ta4'); + +insert into PLine values ('PL.018', '-362', '', 'PS.first.tb1'); + +insert into PLine values ('PL.019', '-363', '', 'PS.first.tb2'); + +insert into PLine values ('PL.020', '-364', '', 'PS.first.tb3'); + +insert into PLine values ('PL.021', '-365', '', 'PS.first.tb5'); + +insert into PLine values ('PL.022', '-367', '', 'PS.first.tb6'); + +insert into PLine values ('PL.028', '-501', 'Fax entrance', 'PS.base.ta2'); + +insert into PLine values ('PL.029', '-502', 'Fax first floor', 'PS.first.ta1'); + +insert into PHone values ('PH.hc001', 'Hicom standard', 'WS.001.1a'); + +update PSlot set slotlink = 'PS.base.ta1' where slotname = 'PS.base.a1'; + +insert into PHone values ('PH.hc002', 'Hicom standard', 'WS.002.1a'); + +update PSlot set slotlink = 'PS.base.ta5' where slotname = 'PS.base.b1'; + +insert into PHone values ('PH.hc003', 'Hicom standard', 'WS.002.2a'); + +update PSlot set slotlink = 'PS.base.tb2' where slotname = 'PS.base.b3'; + +insert into PHone values ('PH.fax001', 'Canon fax', 'WS.001.2a'); + +update PSlot set slotlink = 'PS.base.ta2' where slotname = 'PS.base.a3'; + +insert into Hub values ('base.hub1', 'Patchfield PF0_1 hub', 16); + +insert into System values ('orion', 'PC'); + +insert into IFace values ('IF', 'orion', 'eth0', 'WS.002.1b'); + +update PSlot set slotlink = 'HS.base.hub1.1' where slotname = 'PS.base.b2'; + +select * from PField_v1 where pfname = 'PF0_1' order by slotname; + +select * from PField_v1 where pfname = 'PF0_2' order by slotname; + +insert into PField values ('PF1_1', 'should fail due to unique index'); + +update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1'; + +update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1'; + +update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1'; + +update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1'; + +insert into HSlot values ('HS', 'base.hub1', 1, ''); + +insert into HSlot values ('HS', 'base.hub1', 20, ''); + +delete from HSlot; + +insert into IFace values ('IF', 'notthere', 'eth0', ''); + +insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', ''); + +CREATE FUNCTION recursion_test(int,int) RETURNS text AS ' +DECLARE rslt text; +BEGIN + IF $1 <= 0 THEN + rslt = CAST($2 AS TEXT); + ELSE + rslt = CAST($1 AS TEXT) || '','' || recursion_test($1 - 1, $2); + END IF; + RETURN rslt; +END;' LANGUAGE plpgsql; + +SELECT recursion_test(4,3); + +CREATE TABLE found_test_tbl (a int); + +create function test_found() + returns boolean as ' + declare + begin + insert into found_test_tbl values (1); + if FOUND then + insert into found_test_tbl values (2); + end if; + + update found_test_tbl set a = 100 where a = 1; + if FOUND then + insert into found_test_tbl values (3); + end if; + + delete from found_test_tbl where a = 9999; -- matches no rows + if not FOUND then + insert into found_test_tbl values (4); + end if; + + for i in 1 .. 10 loop + -- no need to do anything + end loop; + if FOUND then + insert into found_test_tbl values (5); + end if; + + -- never executes the loop + for i in 2 .. 1 loop + -- no need to do anything + end loop; + if not FOUND then + insert into found_test_tbl values (6); + end if; + return true; + end;' language plpgsql; + +select test_found(); + +select * from found_test_tbl; + +create function test_table_func_rec() returns setof found_test_tbl as ' +DECLARE + rec RECORD; +BEGIN + FOR rec IN select * from found_test_tbl LOOP + RETURN NEXT rec; + END LOOP; + RETURN; +END;' language plpgsql; + +select * from test_table_func_rec(); + +create function test_table_func_row() returns setof found_test_tbl as ' +DECLARE + row found_test_tbl%ROWTYPE; +BEGIN + FOR row IN select * from found_test_tbl LOOP + RETURN NEXT row; + END LOOP; + RETURN; +END;' language plpgsql; + +select * from test_table_func_row(); + +create function test_ret_set_scalar(int,int) returns setof int as ' +DECLARE + i int; +BEGIN + FOR i IN $1 .. $2 LOOP + RETURN NEXT i + 1; + END LOOP; + RETURN; +END;' language plpgsql; + +select * from test_ret_set_scalar(1,10); + +create function test_ret_set_rec_dyn(int) returns setof record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN NEXT retval; + RETURN NEXT retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN NEXT retval; + RETURN NEXT retval; + END IF; + RETURN; +END;' language plpgsql; + +SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int); + +SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text); + +create function test_ret_rec_dyn(int) returns record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN retval; + END IF; +END;' language plpgsql; + +SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int); + +SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text); + +create function f1(x anyelement) returns anyelement as $$ +begin + return x + 1; +end$$ language plpgsql; + +select f1(42) as int, f1(4.5) as num; + +select f1(point(3,4)); + +drop function f1(x anyelement); + +create function f1(x anyelement) returns anyarray as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql; + +select f1(42) as int, f1(4.5) as num; + +drop function f1(x anyelement); + +create function f1(x anyarray) returns anyelement as $$ +begin + return x[1]; +end$$ language plpgsql; + +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num; + +select f1(stavalues1) from pg_statistic; + +drop function f1(x anyarray); + +create function f1(x anyarray) returns anyarray as $$ +begin + return x; +end$$ language plpgsql; + +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num; + +select f1(stavalues1) from pg_statistic; + +drop function f1(x anyarray); + +create function f1(x anyelement) returns anyrange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql; + +create function f1(x anyrange) returns anyarray as $$ +begin + return array[lower(x), upper(x)]; +end$$ language plpgsql; + +select f1(int4range(42, 49)) as int, f1(float8range(4.5, 7.8)) as num; + +drop function f1(x anyrange); + +create function f1(x anycompatible, y anycompatible) returns anycompatiblearray as $$ +begin + return array[x, y]; +end$$ language plpgsql; + +select f1(2, 4) as int, f1(2, 4.5) as num; + +drop function f1(x anycompatible, y anycompatible); + +create function f1(x anycompatiblerange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ +begin + return array[lower(x), upper(x), y, z]; +end$$ language plpgsql; + +select f1(int4range(42, 49), 11, 2::smallint) as int, f1(float8range(4.5, 7.8), 7.8, 11::real) as num; + +select f1(int4range(42, 49), 11, 4.5) as fail; + +drop function f1(x anycompatiblerange, y anycompatible, z anycompatible); + +create function f1(x anycompatible) returns anycompatiblerange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql; + +create function f1(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ +begin + return x; +end$$ language plpgsql; + +select f1(int4range(42, 49), array[11]) as int, f1(float8range(4.5, 7.8), array[7]) as num; + +drop function f1(x anycompatiblerange, y anycompatiblearray); + +create function f1(a anyelement, b anyarray, + c anycompatible, d anycompatible, + OUT x anyarray, OUT y anycompatiblearray) +as $$ +begin + x := a || b; + y := array[c, d]; +end$$ language plpgsql; + +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2], 42, 34.5); + +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2], point(1,2), point(3,4)); + +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, '{1,2}', point(1,2), '(3,4)'); + +select x, pg_typeof(x), y, pg_typeof(y) + from f1(11, array[1, 2.2], 42, 34.5); + +drop function f1(a anyelement, b anyarray, + c anycompatible, d anycompatible); + +create function f1(in i int, out j int) returns int as $$ +begin + return i+1; +end$$ language plpgsql; + +create function f1(in i int, out j int) as $$ +begin + j := i+1; + return; +end$$ language plpgsql; + +select f1(42); + +select * from f1(42); + +create or replace function f1(inout i int) as $$ +begin + i := i+1; +end$$ language plpgsql; + +select f1(42); + +select * from f1(42); + +drop function f1(int); + +create function f1(in i int, out j int) returns setof int as $$ +begin + j := i+1; + return next; + j := i+2; + return next; + return; +end$$ language plpgsql; + +select * from f1(42); + +drop function f1(int); + +create function f1(in i int, out j int, out k text) as $$ +begin + j := i; + j := j+1; + k := 'foo'; +end$$ language plpgsql; + +select f1(42); + +select * from f1(42); + +drop function f1(int); + +create function f1(in i int, out j int, out k text) returns setof record as $$ +begin + j := i+1; + k := 'foo'; + return next; + j := j+1; + k := 'foot'; + return next; +end$$ language plpgsql; + +select * from f1(42); + +drop function f1(int); + +create function duplic(in i anyelement, out j anyelement, out k anyarray) as $$ +begin + j := i; + k := array[j,j]; + return; +end$$ language plpgsql; + +select * from duplic(42); + +select * from duplic('foo'::text); + +drop function duplic(anyelement); + +create function duplic(in i anycompatiblerange, out j anycompatible, out k anycompatiblearray) as $$ +begin + j := lower(i); + k := array[lower(i),upper(i)]; + return; +end$$ language plpgsql; + +select * from duplic(int4range(42,49)); + +select * from duplic(textrange('aaa', 'bbb')); + +drop function duplic(anycompatiblerange); + +create table perform_test ( + a INT, + b INT +); + +create function perform_simple_func(int) returns boolean as ' +BEGIN + IF $1 < 20 THEN + INSERT INTO perform_test VALUES ($1, $1 + 10); + RETURN TRUE; + ELSE + RETURN FALSE; + END IF; +END;' language plpgsql; + +create function perform_test_func() returns void as ' +BEGIN + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + PERFORM perform_simple_func(5); + + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + PERFORM perform_simple_func(50); + + IF FOUND then + INSERT INTO perform_test VALUES (100, 100); + END IF; + + RETURN; +END;' language plpgsql; + +SELECT perform_test_func(); + +SELECT * FROM perform_test; + +drop table perform_test; + +create temp table users(login text, id serial); + +create function sp_id_user(a_login text) returns int as $$ +declare x int; +begin + select into x id from users where login = a_login; + if found then return x; end if; + return 0; +end$$ language plpgsql stable; + +insert into users values('user1'); + +select sp_id_user('user1'); + +select sp_id_user('userx'); + +create function sp_add_user(a_login text) returns int as $$ +declare my_id_user int; +begin + my_id_user = sp_id_user( a_login ); + IF my_id_user > 0 THEN + RETURN -1; -- error code for existing user + END IF; + INSERT INTO users ( login ) VALUES ( a_login ); + my_id_user = sp_id_user( a_login ); + IF my_id_user = 0 THEN + RETURN -2; -- error code for insertion failure + END IF; + RETURN my_id_user; +end$$ language plpgsql; + +select sp_add_user('user1'); + +select sp_add_user('user2'); + +select sp_add_user('user2'); + +select sp_add_user('user3'); + +select sp_add_user('user3'); + +drop function sp_add_user(text); + +drop function sp_id_user(text); + +create table rc_test (a int, b int); + +copy rc_test from stdin; + +create function return_unnamed_refcursor() returns refcursor as $$ +declare + rc refcursor; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql; + +create function use_refcursor(rc refcursor) returns int as $$ +declare + rc refcursor; + x record; +begin + rc := return_unnamed_refcursor(); + fetch next from rc into x; + return x.a; +end +$$ language plpgsql; + +select use_refcursor(return_unnamed_refcursor()); + +create function return_refcursor(rc refcursor) returns refcursor as $$ +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql; + +create function refcursor_test1(refcursor) returns refcursor as $$ +begin + perform return_refcursor($1); + return $1; +end +$$ language plpgsql; + +begin; + +select refcursor_test1('test1'); + +fetch next in test1; + +select refcursor_test1('test2'); + +fetch all from test2; + +commit; + +fetch next from test1; + +create function refcursor_test2(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; + nonsense record; +begin + open c1($1, $2); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql; + +select refcursor_test2(20000, 20000) as "Should be false", + refcursor_test2(20, 20) as "Should be true"; + +create function constant_refcursor() returns refcursor as $$ +declare + rc constant refcursor; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql; + +select constant_refcursor(); + +create or replace function constant_refcursor() returns refcursor as $$ +declare + rc constant refcursor := 'my_cursor_name'; +begin + open rc for select a from rc_test; + return rc; +end +$$ language plpgsql; + +select constant_refcursor(); + +create function namedparmcursor_test1(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param12 int) for select * from rc_test where a > param1 and b > param12; + nonsense record; +begin + open c1(param12 := $2, param1 := $1); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql; + +select namedparmcursor_test1(20000, 20000) as "Should be false", + namedparmcursor_test1(20, 20) as "Should be true"; + +create function namedparmcursor_test2(int, int) returns boolean as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; + nonsense record; +begin + open c1(param1 := $1, $2); + fetch c1 into nonsense; + close c1; + if found then + return true; + else + return false; + end if; +end +$$ language plpgsql; + +select namedparmcursor_test2(20, 20); + +create function namedparmcursor_test3() returns void as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; +begin + open c1(param2 := 20, 21); +end +$$ language plpgsql; + +create function namedparmcursor_test4() returns void as $$ +declare + c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2; +begin + open c1(20, param1 := 21); +end +$$ language plpgsql; + +create function namedparmcursor_test5() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77, p2 := 42); +end +$$ language plpgsql; + +create function namedparmcursor_test6() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77); +end +$$ language plpgsql; + +create function namedparmcursor_test7() returns void as $$ +declare + c1 cursor (p1 int, p2 int) for + select * from tenk1 where thousand = p1 and tenthous = p2; +begin + open c1 (p2 := 77, p1 := 42/0); +end $$ language plpgsql; + +select namedparmcursor_test7(); + +create function namedparmcursor_test8() returns int4 as $$ +declare + c1 cursor (p1 int, p2 int) for + select count(*) from tenk1 where thousand = p1 and tenthous = p2; + n int4; +begin + open c1 (77 -- test + , 42); + fetch c1 into n; + return n; +end $$ language plpgsql; + +select namedparmcursor_test8(); + +create function namedparmcursor_test9(p1 int) returns int4 as $$ +declare + c1 cursor (p1 int, p2 int, debug int) for + select count(*) from tenk1 where thousand = p1 and tenthous = p2 + and four = debug; + p2 int4 := 1006; + n int4; +begin + -- use both supported syntaxes for named arguments + open c1 (p1 := p1, p2 => p2, debug => 2); + fetch c1 into n; + return n; +end $$ language plpgsql; + +select namedparmcursor_test9(6); + +create function raise_test1(int) returns int as $$ +begin + raise notice 'This message has too many parameters!', $1; + return $1; +end; +$$ language plpgsql; + +create function raise_test2(int) returns int as $$ +begin + raise notice 'This message has too few parameters: %, %, %', $1, $1; + return $1; +end; +$$ language plpgsql; + +create function raise_test3(int) returns int as $$ +begin + raise notice 'This message has no parameters (despite having %% signs in it)!'; + return $1; +end; +$$ language plpgsql; + +select raise_test3(1); + +CREATE FUNCTION reraise_test() RETURNS void AS $$ +BEGIN + BEGIN + RAISE syntax_error; + EXCEPTION + WHEN syntax_error THEN + BEGIN + raise notice 'exception % thrown in inner block, reraising', sqlerrm; + RAISE; + EXCEPTION + WHEN OTHERS THEN + raise notice 'RIGHT - exception % caught in inner block', sqlerrm; + END; + END; +EXCEPTION + WHEN OTHERS THEN + raise notice 'WRONG - exception % caught in outer block', sqlerrm; +END; +$$ LANGUAGE plpgsql; + +SELECT reraise_test(); + +create function bad_sql1() returns int as $$ +declare a int; +begin + a := 5; + Johnny Yuma; + a := 10; + return a; +end$$ language plpgsql; + +create function bad_sql2() returns int as $$ +declare r record; +begin + for r in select I fought the law, the law won LOOP + raise notice 'in loop'; + end loop; + return 5; +end;$$ language plpgsql; + +create function missing_return_expr() returns int as $$ +begin + return ; +end;$$ language plpgsql; + +create function void_return_expr() returns void as $$ +begin + return 5; +end;$$ language plpgsql; + +create function void_return_expr() returns void as $$ +begin + perform 2+2; +end;$$ language plpgsql; + +select void_return_expr(); + +create function missing_return_expr() returns int as $$ +begin + perform 2+2; +end;$$ language plpgsql; + +select missing_return_expr(); + +drop function void_return_expr(); + +drop function missing_return_expr(); + +create table eifoo (i integer, y integer); + +create type eitype as (i integer, y integer); + +create or replace function execute_into_test(varchar) returns record as $$ +declare + _r record; + _rt eifoo%rowtype; + _v eitype; + i int; + j int; + k int; +begin + execute 'insert into '||$1||' values(10,15)'; + execute 'select (row).* from (select row(10,1)::eifoo) s' into _r; + raise notice '% %', _r.i, _r.y; + execute 'select * from '||$1||' limit 1' into _rt; + raise notice '% %', _rt.i, _rt.y; + execute 'select *, 20 from '||$1||' limit 1' into i, j, k; + raise notice '% % %', i, j, k; + execute 'select 1,2' into _v; + return _v; +end; $$ language plpgsql; + +select execute_into_test('eifoo'); + +drop table eifoo cascade; + +drop type eitype cascade; + +create function excpt_test1() returns void as $$ +begin + raise notice '% %', sqlstate, sqlerrm; +end; $$ language plpgsql; + +select excpt_test1(); + +create function excpt_test2() returns void as $$ +begin + begin + begin + raise notice '% %', sqlstate, sqlerrm; + end; + end; +end; $$ language plpgsql; + +select excpt_test2(); + +create function excpt_test3() returns void as $$ +begin + begin + raise exception 'user exception'; + exception when others then + raise notice 'caught exception % %', sqlstate, sqlerrm; + begin + raise notice '% %', sqlstate, sqlerrm; + perform 10/0; + exception + when substring_error then + -- this exception handler shouldn't be invoked + raise notice 'unexpected exception: % %', sqlstate, sqlerrm; + when division_by_zero then + raise notice 'caught exception % %', sqlstate, sqlerrm; + end; + raise notice '% %', sqlstate, sqlerrm; + end; +end; $$ language plpgsql; + +select excpt_test3(); + +create function excpt_test4() returns text as $$ +begin + begin perform 1/0; + exception when others then return sqlerrm; end; +end; $$ language plpgsql; + +select excpt_test4(); + +drop function excpt_test1(); + +drop function excpt_test2(); + +drop function excpt_test3(); + +drop function excpt_test4(); + +create function raise_exprs() returns void as $$ +declare + a integer[] = '{10,20,30}'; + c varchar = 'xyz'; + i integer; +begin + i := 2; + raise notice '%; %; %; %; %; %', a, a[i], c, (select c || 'abc'), row(10,'aaa',NULL,30), NULL; +end;$$ language plpgsql; + +select raise_exprs(); + +drop function raise_exprs(); + +create function multi_datum_use(p1 int) returns bool as $$ +declare + x int; + y int; +begin + select into x,y unique1/p1, unique1/$1 from tenk1 group by unique1/p1; + return x = y; +end$$ language plpgsql; + +select multi_datum_use(42); + +create temp table foo (f1 int, f2 int); + +insert into foo values (1,2), (3,4); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + insert into foo values(5,6) returning * into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail due to implicit strict + insert into foo values(7,8),(9,10) returning * into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + execute 'insert into foo values(5,6) returning *' into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- this should work since EXECUTE isn't as picky + execute 'insert into foo values(7,8),(9,10) returning *' into x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +select * from foo; + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + select * from foo where f1 = 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, no rows + select * from foo where f1 = 0 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, too many rows + select * from foo where f1 > 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should work + execute 'select * from foo where f1 = 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, no rows + execute 'select * from foo where f1 = 0' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- should fail, too many rows + execute 'select * from foo where f1 > 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +drop function stricttest(); + +set plpgsql.print_strict_params to true; + +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- no rows + select * from foo where f1 = p1 and f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := $a$'Valame Dios!' dijo Sancho; 'no le dije yo a vuestra merced que mirase bien lo que hacia?'$a$; +begin + -- no rows + select * from foo where f1 = p1 and f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows, no params + select * from foo where f1 > 3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- no rows + execute 'select * from foo where f1 = $1 or f1::text = $2' using 0, 'foo' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows + execute 'select * from foo where f1 > $1' using 1 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +declare x record; +begin + -- too many rows, no parameters + execute 'select * from foo where f1 > 3' into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +create or replace function stricttest() returns void as $$ +-- override the global +#print_strict_params off +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +reset plpgsql.print_strict_params; + +create or replace function stricttest() returns void as $$ +-- override the global +#print_strict_params on +declare +x record; +p1 int := 2; +p3 text := 'foo'; +begin + -- too many rows + select * from foo where f1 > p1 or f1::text = p3 into strict x; + raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2; +end$$ language plpgsql; + +select stricttest(); + +set plpgsql.extra_warnings to 'all'; + +set plpgsql.extra_warnings to 'none'; + +set plpgsql.extra_errors to 'all'; + +set plpgsql.extra_errors to 'none'; + +set plpgsql.extra_warnings to 'shadowed_variables'; + +create or replace function shadowtest(in1 int) + returns table (out1 int) as $$ +declare +in1 int; +out1 int; +begin +end +$$ language plpgsql; + +select shadowtest(1); + +set plpgsql.extra_warnings to 'shadowed_variables'; + +select shadowtest(1); + +create or replace function shadowtest(in1 int) + returns table (out1 int) as $$ +declare +in1 int; +out1 int; +begin +end +$$ language plpgsql; + +select shadowtest(1); + +drop function shadowtest(int); + +create or replace function shadowtest() + returns void as $$ +declare +f1 int; +begin + declare + f1 int; + begin + end; +end$$ language plpgsql; + +drop function shadowtest(); + +create or replace function shadowtest(in1 int) + returns void as $$ +declare +in1 int; +begin + declare + in1 int; + begin + end; +end$$ language plpgsql; + +drop function shadowtest(int); + +create or replace function shadowtest() + returns void as $$ +declare +f1 int; +c1 cursor (f1 int) for select 1; +begin +end$$ language plpgsql; + +drop function shadowtest(); + +set plpgsql.extra_errors to 'shadowed_variables'; + +create or replace function shadowtest(f1 int) + returns boolean as $$ +declare f1 int; begin return 1; end $$ language plpgsql; + +select shadowtest(1); + +reset plpgsql.extra_errors; + +reset plpgsql.extra_warnings; + +create or replace function shadowtest(f1 int) + returns boolean as $$ +declare f1 int; begin return 1; end $$ language plpgsql; + +select shadowtest(1); + +set plpgsql.extra_warnings to 'too_many_rows'; + +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$; + +set plpgsql.extra_errors to 'too_many_rows'; + +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$; + +reset plpgsql.extra_errors; + +reset plpgsql.extra_warnings; + +set plpgsql.extra_warnings to 'strict_multi_assignment'; + +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$; + +set plpgsql.extra_errors to 'strict_multi_assignment'; + +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$; + +create table test_01(a int, b int, c int); + +alter table test_01 drop column a; + +insert into test_01 values(10,20); + +do $$ +declare + x int; + y int; +begin + select * from test_01 into x, y; -- should be ok + raise notice 'ok'; + select * from test_01 into x; -- should to fail +end; +$$; + +do $$ +declare + t test_01; +begin + select 1, 2 into t; -- should be ok + raise notice 'ok'; + select 1, 2, 3 into t; -- should fail; +end; +$$; + +do $$ +declare + t test_01; +begin + select 1 into t; -- should fail; +end; +$$; + +drop table test_01; + +reset plpgsql.extra_errors; + +reset plpgsql.extra_warnings; + +create function sc_test() returns setof integer as $$ +declare + c scroll cursor for select f1 from int4_tbl; + x integer; +begin + open c; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql; + +select * from sc_test(); + +create or replace function sc_test() returns setof integer as $$ +declare + c no scroll cursor for select f1 from int4_tbl; + x integer; +begin + open c; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql; + +select * from sc_test(); + +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for select f1 from int4_tbl; + fetch last from c into x; + while found loop + return next x; + fetch prior from c into x; + end loop; + close c; +end; +$$ language plpgsql; + +select * from sc_test(); + +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for execute 'select f1 from int4_tbl'; + fetch last from c into x; + while found loop + return next x; + fetch relative -2 from c into x; + end loop; + close c; +end; +$$ language plpgsql; + +select * from sc_test(); + +create or replace function sc_test() returns setof integer as $$ +declare + c refcursor; + x integer; +begin + open c scroll for execute 'select f1 from int4_tbl'; + fetch last from c into x; + while found loop + return next x; + move backward 2 from c; + fetch relative -1 from c into x; + end loop; + close c; +end; +$$ language plpgsql; + +select * from sc_test(); + +create or replace function sc_test() returns setof integer as $$ +declare + c cursor for select * from generate_series(1, 10); + x integer; +begin + open c; + loop + move relative 2 in c; + if not found then + exit; + end if; + fetch next from c into x; + if found then + return next x; + end if; + end loop; + close c; +end; +$$ language plpgsql; + +select * from sc_test(); + +create or replace function sc_test() returns setof integer as $$ +declare + c cursor for select * from generate_series(1, 10); + x integer; +begin + open c; + move forward all in c; + fetch backward from c into x; + if found then + return next x; + end if; + close c; +end; +$$ language plpgsql; + +select * from sc_test(); + +drop function sc_test(); + +create function pl_qual_names (param1 int) returns void as $$ +<> +declare + param1 int := 1; +begin + <> + declare + param1 int := 2; + begin + raise notice 'param1 = %', param1; + raise notice 'pl_qual_names.param1 = %', pl_qual_names.param1; + raise notice 'outerblock.param1 = %', outerblock.param1; + raise notice 'innerblock.param1 = %', innerblock.param1; + end; +end; +$$ language plpgsql; + +select pl_qual_names(42); + +drop function pl_qual_names(int); + +create function ret_query1(out int, out int) returns setof record as $$ +begin + $1 := -1; + $2 := -2; + return next; + return query select x + 1, x * 10 from generate_series(0, 10) s (x); + return next; +end; +$$ language plpgsql; + +select * from ret_query1(); + +create type record_type as (x text, y int, z boolean); + +create or replace function ret_query2(lim int) returns setof record_type as $$ +begin + return query select fipshash(s.x::text), s.x, s.x > 0 + from generate_series(-8, lim) s (x) where s.x % 2 = 0; +end; +$$ language plpgsql; + +select * from ret_query2(8); + +create function exc_using(int, text) returns int as $$ +declare i int; +begin + for i in execute 'select * from generate_series(1,$1)' using $1+1 loop + raise notice '%', i; + end loop; + execute 'select $2 + $2*3 + length($1)' into i using $2,$1; + return i; +end +$$ language plpgsql; + +select exc_using(5, 'foobar'); + +drop function exc_using(int, text); + +create or replace function exc_using(int) returns void as $$ +declare + c refcursor; + i int; +begin + open c for execute 'select * from generate_series(1,$1)' using $1+1; + loop + fetch c into i; + exit when not found; + raise notice '%', i; + end loop; + close c; + return; +end; +$$ language plpgsql; + +select exc_using(5); + +drop function exc_using(int); + +create or replace function forc01() returns void as $$ +declare + c cursor(r1 integer, r2 integer) + for select * from generate_series(r1,r2) i; + c2 cursor + for select * from generate_series(41,43) i; +begin + -- assign portal names to cursors to get stable output + c := 'c'; + c2 := 'c2'; + for r in c(5,7) loop + raise notice '% from %', r.i, c; + end loop; + -- again, to test if cursor was closed properly + -- (and while we're at it, test named-parameter notation) + for r in c(r2 := 10, r1 => 9) loop + raise notice '% from %', r.i, c; + end loop; + -- and test a parameterless cursor + for r in c2 loop + raise notice '% from %', r.i, c2; + end loop; + -- and try it with a hand-assigned name + raise notice 'after loop, c2 = %', c2; + c2 := 'special_name'; + for r in c2 loop + raise notice '% from %', r.i, c2; + end loop; + raise notice 'after loop, c2 = %', c2; + -- and try it with a generated name + -- (which we can't show in the output because it's variable) + c2 := null; + for r in c2 loop + raise notice '%', r.i; + end loop; + raise notice 'after loop, c2 = %', c2; + return; +end; +$$ language plpgsql; + +select forc01(); + +create temp table forc_test as + select n as i, n as j from generate_series(1,10) n; + +create or replace function forc01() returns void as $$ +declare + c cursor for select * from forc_test; +begin + for r in c loop + raise notice '%, %', r.i, r.j; + update forc_test set i = i * 100, j = r.j * 2 where current of c; + end loop; +end; +$$ language plpgsql; + +select forc01(); + +select * from forc_test; + +create or replace function forc01() returns void as $$ +declare + c refcursor := 'fooled_ya'; + r record; +begin + open c for select * from forc_test; + loop + fetch c into r; + exit when not found; + raise notice '%, %', r.i, r.j; + update forc_test set i = i * 100, j = r.j * 2 where current of c; + end loop; +end; +$$ language plpgsql; + +select forc01(); + +select * from forc_test; + +drop function forc01(); + +do $$ +declare cnt int := 0; + c1 cursor for select * from forc_test; +begin + for r1 in c1 loop + declare c1 cursor for select * from forc_test; + begin + for r2 in c1 loop + cnt := cnt + 1; + end loop; + end; + end loop; + raise notice 'cnt = %', cnt; +end $$; + +create or replace function forc_bad() returns void as $$ +declare + c refcursor; +begin + for r in c loop + raise notice '%', r.i; + end loop; +end; +$$ language plpgsql; + +create or replace function return_dquery() +returns setof int as $$ +begin + return query execute 'select * from (values(10),(20)) f'; + return query execute 'select * from (values($1),($2)) f' using 40,50; +end; +$$ language plpgsql; + +select * from return_dquery(); + +drop function return_dquery(); + +create table tabwithcols(a int, b int, c int, d int); + +insert into tabwithcols values(10,20,30,40),(50,60,70,80); + +create or replace function returnqueryf() +returns setof tabwithcols as $$ +begin + return query select * from tabwithcols; + return query execute 'select * from tabwithcols'; +end; +$$ language plpgsql; + +select * from returnqueryf(); + +alter table tabwithcols drop column b; + +select * from returnqueryf(); + +alter table tabwithcols drop column d; + +select * from returnqueryf(); + +alter table tabwithcols add column d int; + +select * from returnqueryf(); + +drop function returnqueryf(); + +drop table tabwithcols; + +create type compostype as (x int, y varchar); + +create or replace function compos() returns compostype as $$ +declare + v compostype; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql; + +select compos(); + +create or replace function compos() returns compostype as $$ +declare + v record; +begin + v := (1, 'hello'::varchar); + return v; +end; +$$ language plpgsql; + +select compos(); + +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello'::varchar); +end; +$$ language plpgsql; + +select compos(); + +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello'); +end; +$$ language plpgsql; + +select compos(); + +create or replace function compos() returns compostype as $$ +begin + return (1, 'hello')::compostype; +end; +$$ language plpgsql; + +select compos(); + +drop function compos(); + +create or replace function composrec() returns record as $$ +declare + v record; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql; + +select composrec(); + +create or replace function composrec() returns record as $$ +begin + return (1, 'hello'); +end; +$$ language plpgsql; + +select composrec(); + +drop function composrec(); + +create or replace function compos() returns setof compostype as $$ +begin + for i in 1..3 + loop + return next (1, 'hello'::varchar); + end loop; + return next null::compostype; + return next (2, 'goodbye')::compostype; +end; +$$ language plpgsql; + +select * from compos(); + +drop function compos(); + +create or replace function compos() returns compostype as $$ +begin + return 1 + 1; +end; +$$ language plpgsql; + +select compos(); + +create or replace function compos() returns compostype as $$ +declare x int := 42; +begin + return x; +end; +$$ language plpgsql; + +select * from compos(); + +drop function compos(); + +create or replace function compos() returns int as $$ +declare + v compostype; +begin + v := (1, 'hello'); + return v; +end; +$$ language plpgsql; + +select compos(); + +create or replace function compos() returns int as $$ +begin + return (1, 'hello')::compostype; +end; +$$ language plpgsql; + +select compos(); + +drop function compos(); + +drop type compostype; + +create or replace function raise_test() returns void as $$ +begin + raise notice '% % %', 1, 2, 3 + using errcode = '55001', detail = 'some detail info', hint = 'some hint'; + raise '% % %', 1, 2, 3 + using errcode = 'division_by_zero', detail = 'some detail info'; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = 'division_by_zero', detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = '1234F', detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise 'check me' + using errcode = '1234F', detail = 'some detail info'; + exception + when sqlstate '1234F' then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using detail = 'some detail info'; + exception + when others then + raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm; + raise; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise sqlstate '1234F'; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using message = 'custom' || ' message'; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise notice 'some message' using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise division_by_zero using message = 'custom' || ' message', errcode = '22012'; +end; +$$ language plpgsql; + +select raise_test(); + +create or replace function raise_test() returns void as $$ +begin + raise; +end; +$$ language plpgsql; + +select raise_test(); + +create function zero_divide() returns int as $$ +declare v int := 0; +begin + return 10 / v; +end; +$$ language plpgsql parallel safe; + +create or replace function raise_test() returns void as $$ +begin + raise exception 'custom exception' + using detail = 'some detail of custom exception', + hint = 'some hint related to custom exception'; +end; +$$ language plpgsql; + +create function stacked_diagnostics_test() returns void as $$ +declare _sqlstate text; + _message text; + _context text; +begin + perform zero_divide(); +exception when others then + get stacked diagnostics + _sqlstate = returned_sqlstate, + _message = message_text, + _context = pg_exception_context; + raise notice 'sqlstate: %, message: %, context: [%]', + _sqlstate, _message, replace(_context, E'\n', ' <- '); +end; +$$ language plpgsql; + +select stacked_diagnostics_test(); + +create or replace function stacked_diagnostics_test() returns void as $$ +declare _detail text; + _hint text; + _message text; +begin + perform raise_test(); +exception when others then + get stacked diagnostics + _message = message_text, + _detail = pg_exception_detail, + _hint = pg_exception_hint; + raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint; +end; +$$ language plpgsql; + +select stacked_diagnostics_test(); + +create or replace function stacked_diagnostics_test() returns void as $$ +declare _detail text; + _hint text; + _message text; +begin + get stacked diagnostics + _message = message_text, + _detail = pg_exception_detail, + _hint = pg_exception_hint; + raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint; +end; +$$ language plpgsql; + +select stacked_diagnostics_test(); + +drop function stacked_diagnostics_test(); + +create function error_trap_test() returns text as $$ +begin + perform zero_divide(); + return 'no error detected!'; +exception when division_by_zero then + return 'division_by_zero detected'; +end; +$$ language plpgsql parallel safe; + +set debug_parallel_query to on; + +select error_trap_test(); + +select error_trap_test(); + +reset debug_parallel_query; + +drop function error_trap_test(); + +drop function zero_divide(); + +create or replace function raise_test() returns void as $$ +begin + perform 1/0; +exception + when sqlstate '22012' then + raise notice using message = sqlstate; + raise sqlstate '22012' using message = 'substitute message'; +end; +$$ language plpgsql; + +select raise_test(); + +drop function raise_test(); + +create or replace function stacked_diagnostics_test() returns void as $$ +declare _column_name text; + _constraint_name text; + _datatype_name text; + _table_name text; + _schema_name text; +begin + raise exception using + column = '>>some column name<<', + constraint = '>>some constraint name<<', + datatype = '>>some datatype name<<', + table = '>>some table name<<', + schema = '>>some schema name<<'; +exception when others then + get stacked diagnostics + _column_name = column_name, + _constraint_name = constraint_name, + _datatype_name = pg_datatype_name, + _table_name = table_name, + _schema_name = schema_name; + raise notice 'column %, constraint %, type %, table %, schema %', + _column_name, _constraint_name, _datatype_name, _table_name, _schema_name; +end; +$$ language plpgsql; + +select stacked_diagnostics_test(); + +drop function stacked_diagnostics_test(); + +create or replace function vari(variadic int[]) +returns void as $$ +begin + for i in array_lower($1,1)..array_upper($1,1) loop + raise notice '%', $1[i]; + end loop; end; +$$ language plpgsql; + +select vari(1,2,3,4,5); + +select vari(3,4,5); + +select vari(variadic array[5,6,7]); + +drop function vari(int[]); + +create or replace function pleast(variadic numeric[]) +returns numeric as $$ +declare aux numeric = $1[array_lower($1,1)]; +begin + for i in array_lower($1,1)+1..array_upper($1,1) loop + if $1[i] < aux then aux := $1[i]; end if; + end loop; + return aux; +end; +$$ language plpgsql immutable strict; + +select pleast(10,1,2,3,-16); + +select pleast(10.2,2.2,-1.1); + +select pleast(10.2,10, -20); + +select pleast(10,20, -1.0); + +create or replace function pleast(numeric) +returns numeric as $$ +begin + raise notice 'non-variadic function called'; + return $1; +end; +$$ language plpgsql immutable strict; + +select pleast(10); + +drop function pleast(numeric[]); + +drop function pleast(numeric); + +create function tftest(int) returns table(a int, b int) as $$ +begin + return query select $1, $1+i from generate_series(1,5) g(i); +end; +$$ language plpgsql immutable strict; + +select * from tftest(10); + +create or replace function tftest(a1 int) returns table(a int, b int) as $$ +begin + a := a1; b := a1 + 1; + return next; + a := a1 * 10; b := a1 * 10 + 1; + return next; +end; +$$ language plpgsql immutable strict; + +select * from tftest(10); + +drop function tftest(int); + +create function rttest() +returns setof int as $$ +declare rc int; +begin + return query values(10),(20); + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query select * from (values(10),(20)) f(a) where false; + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query execute 'values(10),(20)'; + get diagnostics rc = row_count; + raise notice '% %', found, rc; + return query execute 'select * from (values(10),(20)) f(a) where false'; + get diagnostics rc = row_count; + raise notice '% %', found, rc; +end; +$$ language plpgsql; + +select * from rttest(); + +create or replace function rttest() +returns setof int as $$ +begin + return query select 10 into no_such_table; +end; +$$ language plpgsql; + +select * from rttest(); + +create or replace function rttest() +returns setof int as $$ +begin + return query execute 'select 10 into no_such_table'; +end; +$$ language plpgsql; + +select * from rttest(); + +select * from no_such_table; + +drop function rttest(); + +CREATE FUNCTION leaker_1(fail BOOL) RETURNS INTEGER AS $$ +DECLARE + v_var INTEGER; +BEGIN + BEGIN + v_var := (leaker_2(fail)).error_code; + EXCEPTION + WHEN others THEN RETURN 0; + END; + RETURN 1; +END; +$$ LANGUAGE plpgsql; + +CREATE FUNCTION leaker_2(fail BOOL, OUT error_code INTEGER, OUT new_id INTEGER) + RETURNS RECORD AS $$ +BEGIN + IF fail THEN + RAISE EXCEPTION 'fail ...'; + END IF; + error_code := 1; + new_id := 1; + RETURN; +END; +$$ LANGUAGE plpgsql; + +SELECT * FROM leaker_1(false); + +SELECT * FROM leaker_1(true); + +DROP FUNCTION leaker_1(bool); + +DROP FUNCTION leaker_2(bool); + +CREATE FUNCTION nonsimple_expr_test() RETURNS text[] AS $$ +DECLARE + arr text[]; + lr text; + i integer; +BEGIN + arr := array[array['foo','bar'], array['baz', 'quux']]; + lr := 'fool'; + i := 1; + -- use sub-SELECTs to make expressions non-simple + arr[(SELECT i)][(SELECT i+1)] := (SELECT lr); + RETURN arr; +END; +$$ LANGUAGE plpgsql; + +SELECT nonsimple_expr_test(); + +DROP FUNCTION nonsimple_expr_test(); + +CREATE FUNCTION nonsimple_expr_test() RETURNS integer AS $$ +declare + i integer NOT NULL := 0; +begin + begin + i := (SELECT NULL::integer); -- should throw error + exception + WHEN OTHERS THEN + i := (SELECT 1::integer); + end; + return i; +end; +$$ LANGUAGE plpgsql; + +SELECT nonsimple_expr_test(); + +DROP FUNCTION nonsimple_expr_test(); + +create function recurse(float8) returns float8 as +$$ +begin + if ($1 > 0) then + return sql_recurse($1 - 1); + else + return $1; + end if; +end; +$$ language plpgsql; + +create function sql_recurse(float8) returns float8 as +$$ select recurse($1) limit 1; $$ language sql; + +select recurse(10); + +create function error1(text) returns text language sql as +$$ SELECT relname::text FROM pg_class c WHERE c.oid = $1::regclass $$; + +create function error2(p_name_table text) returns text language plpgsql as $$ +begin + return error1(p_name_table); +end$$; + +BEGIN; + +create table public.stuffs (stuff text); + +SAVEPOINT a; + +select error2('nonexistent.stuffs'); + +ROLLBACK TO a; + +select error2('public.stuffs'); + +rollback; + +drop function error2(p_name_table text); + +drop function error1(text); + +create function sql_to_date(integer) returns date as $$ +select $1::text::date +$$ language sql immutable strict; + +create cast (integer as date) with function sql_to_date(integer) as assignment; + +create function cast_invoker(integer) returns date as $$ +begin + return $1; +end$$ language plpgsql; + +select cast_invoker(20150717); + +select cast_invoker(20150718); + +begin; + +select cast_invoker(20150717); + +select cast_invoker(20150718); + +savepoint s1; + +select cast_invoker(20150718); + +select cast_invoker(-1); + +rollback to savepoint s1; + +select cast_invoker(20150719); + +select cast_invoker(20150720); + +commit; + +drop function cast_invoker(integer); + +drop function sql_to_date(integer) cascade; + +begin; + +do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$; + +do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$; + +end; + +create function fail() returns int language plpgsql as $$ +begin + return 1/0; +end +$$; + +select fail(); + +select fail(); + +drop function fail(); + +set standard_conforming_strings = off; + +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz'; + return 'foo\\bar\041baz'; +end +$$ language plpgsql; + +select strtest(); + +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql; + +select strtest(); + +set standard_conforming_strings = on; + +create or replace function strtest() returns text as $$ +begin + raise notice 'foo\\bar\041baz\'; + return 'foo\\bar\041baz\'; +end +$$ language plpgsql; + +select strtest(); + +create or replace function strtest() returns text as $$ +begin + raise notice E'foo\\bar\041baz'; + return E'foo\\bar\041baz'; +end +$$ language plpgsql; + +select strtest(); + +drop function strtest(); + +DO $$ +DECLARE r record; +BEGIN + FOR r IN SELECT rtrim(roomno) AS roomno, comment FROM Room ORDER BY roomno + LOOP + RAISE NOTICE '%, %', r.roomno, r.comment; + END LOOP; +END$$; + +DO LANGUAGE plpgsql $$begin return 1; end$$; + +DO $$ +DECLARE r record; +BEGIN + FOR r IN SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno + LOOP + RAISE NOTICE '%, %', r.roomno, r.comment; + END LOOP; +END$$; + +do $outer$ +begin + for i in 1..10 loop + begin + execute $ex$ + do $$ + declare x int = 0; + begin + x := 1 / x; + end; + $$; + $ex$; + exception when division_by_zero then + raise notice 'caught division by zero'; + end; + end loop; +end; +$outer$; + +do $$ +declare x int := x + 1; -- error +begin + raise notice 'x = %', x; +end; +$$; + +do $$ +declare y int := x + 1; -- error + x int := 42; +begin + raise notice 'x = %, y = %', x, y; +end; +$$; + +do $$ +declare x int := 42; + y int := x + 1; +begin + raise notice 'x = %, y = %', x, y; +end; +$$; + +do $$ +declare x int := 42; +begin + declare y int := x + 1; + x int := x + 2; + z int := x * 10; + begin + raise notice 'x = %, y = %, z = %', x, y, z; + end; +end; +$$; + +set plpgsql.variable_conflict = error; + +create function conflict_test() returns setof int8_tbl as $$ +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql; + +select * from conflict_test(); + +create or replace function conflict_test() returns setof int8_tbl as $$ +#variable_conflict use_variable +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql; + +select * from conflict_test(); + +create or replace function conflict_test() returns setof int8_tbl as $$ +#variable_conflict use_column +declare r record; + q1 bigint := 42; +begin + for r in select q1,q2 from int8_tbl loop + return next r; + end loop; +end; +$$ language plpgsql; + +select * from conflict_test(); + +drop function conflict_test(); + +create function unreserved_test() returns int as $$ +declare + forward int := 21; +begin + forward := forward * 2; + return forward; +end +$$ language plpgsql; + +select unreserved_test(); + +create or replace function unreserved_test() returns int as $$ +declare + return int := 42; +begin + return := return + 1; + return return; +end +$$ language plpgsql; + +select unreserved_test(); + +create or replace function unreserved_test() returns int as $$ +declare + comment int := 21; +begin + comment := comment * 2; + comment on function unreserved_test() is 'this is a test'; + return comment; +end +$$ language plpgsql; + +select unreserved_test(); + +select obj_description('unreserved_test()'::regprocedure, 'pg_proc'); + +drop function unreserved_test(); + +create function foreach_test(anyarray) +returns void as $$ +declare x int; +begin + foreach x in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql; + +select foreach_test(ARRAY[1,2,3,4]); + +select foreach_test(ARRAY[[1,2],[3,4]]); + +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql; + +select foreach_test(ARRAY[1,2,3,4]); + +select foreach_test(ARRAY[[1,2],[3,4]]); + +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int[]; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql; + +select foreach_test(ARRAY[1,2,3,4]); + +select foreach_test(ARRAY[[1,2],[3,4]]); + +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int[]; +begin + foreach x slice 2 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql; + +select foreach_test(ARRAY[1,2,3,4]); + +select foreach_test(ARRAY[[1,2],[3,4]]); + +select foreach_test(ARRAY[[[1,2]],[[3,4]]]); + +create type xy_tuple AS (x int, y int); + +create or replace function foreach_test(anyarray) +returns void as $$ +declare r record; +begin + foreach r in array $1 + loop + raise notice '%', r; + end loop; + end; +$$ language plpgsql; + +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]); + +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]); + +create or replace function foreach_test(anyarray) +returns void as $$ +declare x int; y int; +begin + foreach x, y in array $1 + loop + raise notice 'x = %, y = %', x, y; + end loop; + end; +$$ language plpgsql; + +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]); + +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]); + +create or replace function foreach_test(anyarray) +returns void as $$ +declare x xy_tuple[]; +begin + foreach x slice 1 in array $1 + loop + raise notice '%', x; + end loop; + end; +$$ language plpgsql; + +select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]); + +select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]); + +drop function foreach_test(anyarray); + +drop type xy_tuple; + +create temp table rtype (id int, ar text[]); + +create function arrayassign1() returns text[] language plpgsql as $$ +declare + r record; +begin + r := row(12, '{foo,bar,baz}')::rtype; + r.ar[2] := 'replace'; + return r.ar; +end$$; + +select arrayassign1(); + +select arrayassign1(); + +create domain orderedarray as int[2] + constraint sorted check (value[1] < value[2]); + +select '{1,2}'::orderedarray; + +select '{2,1}'::orderedarray; + +create function testoa(x1 int, x2 int, x3 int) returns orderedarray +language plpgsql as $$ +declare res orderedarray; +begin + res := array[x1, x2]; + res[2] := x3; + return res; +end$$; + +select testoa(1,2,3); + +select testoa(1,2,3); + +select testoa(2,1,3); + +select testoa(1,2,1); + +drop function arrayassign1(); + +drop function testoa(x1 int, x2 int, x3 int); + +create function returns_rw_array(int) returns int[] +language plpgsql as $$ + declare r int[]; + begin r := array[$1, $1]; return r; end; +$$ stable; + +create function consumes_rw_array(int[]) returns int +language plpgsql as $$ + begin return $1[1]; end; +$$ stable; + +select consumes_rw_array(returns_rw_array(42)); + +select i, a from + (select returns_rw_array(1) as a offset 0) ss, + lateral consumes_rw_array(a) i; + +select i, a from + (select returns_rw_array(1) as a offset 0) ss, + lateral consumes_rw_array(a) i; + +select consumes_rw_array(a), a from returns_rw_array(1) a; + +select consumes_rw_array(a), a from returns_rw_array(1) a; + +select consumes_rw_array(a), a from + (values (returns_rw_array(1)), (returns_rw_array(2))) v(a); + +select consumes_rw_array(a), a from + (values (returns_rw_array(1)), (returns_rw_array(2))) v(a); + +do $$ +declare a int[] := array[1,2]; +begin + a := a || 3; + raise notice 'a = %', a; +end$$; + +create function inner_func(int) +returns int as $$ +declare _context text; +begin + get diagnostics _context = pg_context; + raise notice '***%***', _context; + -- lets do it again, just for fun.. + get diagnostics _context = pg_context; + raise notice '***%***', _context; + raise notice 'lets make sure we didnt break anything'; + return 2 * $1; +end; +$$ language plpgsql; + +create or replace function outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into inner_func()'; + myresult := inner_func($1); + raise notice 'inner_func() done'; + return myresult; +end; +$$ language plpgsql; + +create or replace function outer_outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into outer_func()'; + myresult := outer_func($1); + raise notice 'outer_func() done'; + return myresult; +end; +$$ language plpgsql; + +select outer_outer_func(10); + +select outer_outer_func(20); + +drop function outer_outer_func(int); + +drop function outer_func(int); + +drop function inner_func(int); + +create function inner_func(int) +returns int as $$ +declare + _context text; + sx int := 5; +begin + begin + perform sx / 0; + exception + when division_by_zero then + get diagnostics _context = pg_context; + raise notice '***%***', _context; + end; + + -- lets do it again, just for fun.. + get diagnostics _context = pg_context; + raise notice '***%***', _context; + raise notice 'lets make sure we didnt break anything'; + return 2 * $1; +end; +$$ language plpgsql; + +create or replace function outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into inner_func()'; + myresult := inner_func($1); + raise notice 'inner_func() done'; + return myresult; +end; +$$ language plpgsql; + +create or replace function outer_outer_func(int) +returns int as $$ +declare + myresult int; +begin + raise notice 'calling down into outer_func()'; + myresult := outer_func($1); + raise notice 'outer_func() done'; + return myresult; +end; +$$ language plpgsql; + +select outer_outer_func(10); + +select outer_outer_func(20); + +drop function outer_outer_func(int); + +drop function outer_func(int); + +drop function inner_func(int); + +create function current_function(text) +returns regprocedure as $$ +declare + fn_oid regprocedure; +begin + get diagnostics fn_oid = pg_routine_oid; + return fn_oid; +end; +$$ language plpgsql; + +select current_function('foo'); + +drop function current_function(text); + +do $$ +declare + fn_oid oid; +begin + get diagnostics fn_oid = pg_routine_oid; + raise notice 'pg_routine_oid = %', fn_oid; +end; +$$; + +do $$ +begin + assert 1=1; -- should succeed +end; +$$; + +do $$ +begin + assert 1=0; -- should fail +end; +$$; + +do $$ +begin + assert NULL; -- should fail +end; +$$; + +set plpgsql.check_asserts = off; + +do $$ +begin + assert 1=0; -- won't be tested +end; +$$; + +reset plpgsql.check_asserts; + +do $$ +declare var text := 'some value'; +begin + assert 1=0, format('assertion failed, var = "%s"', var); +end; +$$; + +do $$ +begin + assert 1=0, 'unhandled assertion'; +exception when others then + null; -- do nothing +end; +$$; + +create function plpgsql_domain_check(val int) returns boolean as $$ +begin return val > 0; end +$$ language plpgsql immutable; + +create domain plpgsql_domain as integer check(plpgsql_domain_check(value)); + +do $$ +declare v_test plpgsql_domain; +begin + v_test := 1; +end; +$$; + +do $$ +declare v_test plpgsql_domain := 1; +begin + v_test := 0; -- fail +end; +$$; + +create function plpgsql_arr_domain_check(val int[]) returns boolean as $$ +begin return val[1] > 0; end +$$ language plpgsql immutable; + +create domain plpgsql_arr_domain as int[] check(plpgsql_arr_domain_check(value)); + +do $$ +declare v_test plpgsql_arr_domain; +begin + v_test := array[1]; + v_test := v_test || 2; +end; +$$; + +do $$ +declare v_test plpgsql_arr_domain := array[1]; +begin + v_test := 0 || v_test; -- fail +end; +$$; + +CREATE TABLE transition_table_base (id int PRIMARY KEY, val text); + +CREATE FUNCTION transition_table_base_ins_func() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +DECLARE + t text; + l text; +BEGIN + t = ''; + FOR l IN EXECUTE + $q$ + EXPLAIN (TIMING off, COSTS off, VERBOSE on) + SELECT * FROM newtable + $q$ LOOP + t = t || l || E'\n'; + END LOOP; + + RAISE INFO '%', t; + RETURN new; +END; +$$; + +CREATE TRIGGER transition_table_base_ins_trig + AFTER INSERT ON transition_table_base + REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_ins_func(); + +CREATE TRIGGER transition_table_base_ins_trig + AFTER INSERT ON transition_table_base + REFERENCING NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_ins_func(); + +INSERT INTO transition_table_base VALUES (1, 'One'), (2, 'Two'); + +INSERT INTO transition_table_base VALUES (3, 'Three'), (4, 'Four'); + +CREATE OR REPLACE FUNCTION transition_table_base_upd_func() + RETURNS trigger + LANGUAGE plpgsql +AS $$ +DECLARE + t text; + l text; +BEGIN + t = ''; + FOR l IN EXECUTE + $q$ + EXPLAIN (TIMING off, COSTS off, VERBOSE on) + SELECT * FROM oldtable ot FULL JOIN newtable nt USING (id) + $q$ LOOP + t = t || l || E'\n'; + END LOOP; + + RAISE INFO '%', t; + RETURN new; +END; +$$; + +CREATE TRIGGER transition_table_base_upd_trig + AFTER UPDATE ON transition_table_base + REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable + FOR EACH STATEMENT + EXECUTE PROCEDURE transition_table_base_upd_func(); + +UPDATE transition_table_base + SET val = '*' || val || '*' + WHERE id BETWEEN 2 AND 3; + +CREATE TABLE transition_table_level1 +( + level1_no serial NOT NULL , + level1_node_name varchar(255), + PRIMARY KEY (level1_no) +) WITHOUT OIDS; + +CREATE TABLE transition_table_level2 +( + level2_no serial NOT NULL , + parent_no int NOT NULL, + level1_node_name varchar(255), + PRIMARY KEY (level2_no) +) WITHOUT OIDS; + +CREATE TABLE transition_table_status +( + level int NOT NULL, + node_no int NOT NULL, + status int, + PRIMARY KEY (level, node_no) +) WITHOUT OIDS; + +CREATE FUNCTION transition_table_level1_ri_parent_del_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + DECLARE n bigint; + BEGIN + PERFORM FROM p JOIN transition_table_level2 c ON c.parent_no = p.level1_no; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$; + +CREATE TRIGGER transition_table_level1_ri_parent_del_trigger + AFTER DELETE ON transition_table_level1 + REFERENCING OLD TABLE AS p + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level1_ri_parent_del_func(); + +CREATE FUNCTION transition_table_level1_ri_parent_upd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + DECLARE + x int; + BEGIN + WITH p AS (SELECT level1_no, sum(delta) cnt + FROM (SELECT level1_no, 1 AS delta FROM i + UNION ALL + SELECT level1_no, -1 AS delta FROM d) w + GROUP BY level1_no + HAVING sum(delta) < 0) + SELECT level1_no + FROM p JOIN transition_table_level2 c ON c.parent_no = p.level1_no + INTO x; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$; + +CREATE TRIGGER transition_table_level1_ri_parent_upd_trigger + AFTER UPDATE ON transition_table_level1 + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level1_ri_parent_upd_func(); + +CREATE FUNCTION transition_table_level2_ri_child_insupd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + BEGIN + PERFORM FROM i + LEFT JOIN transition_table_level1 p + ON p.level1_no IS NOT NULL AND p.level1_no = i.parent_no + WHERE p.level1_no IS NULL; + IF FOUND THEN + RAISE EXCEPTION 'RI error'; + END IF; + RETURN NULL; + END; +$$; + +CREATE TRIGGER transition_table_level2_ri_child_ins_trigger + AFTER INSERT ON transition_table_level2 + REFERENCING NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_ri_child_insupd_func(); + +CREATE TRIGGER transition_table_level2_ri_child_upd_trigger + AFTER UPDATE ON transition_table_level2 + REFERENCING NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_ri_child_insupd_func(); + +INSERT INTO transition_table_level1 (level1_no) + SELECT generate_series(1,200); + +ANALYZE transition_table_level1; + +INSERT INTO transition_table_level2 (level2_no, parent_no) + SELECT level2_no, level2_no / 50 + 1 AS parent_no + FROM generate_series(1,9999) level2_no; + +ANALYZE transition_table_level2; + +INSERT INTO transition_table_status (level, node_no, status) + SELECT 1, level1_no, 0 FROM transition_table_level1; + +INSERT INTO transition_table_status (level, node_no, status) + SELECT 2, level2_no, 0 FROM transition_table_level2; + +ANALYZE transition_table_status; + +INSERT INTO transition_table_level1(level1_no) + SELECT generate_series(201,1000); + +ANALYZE transition_table_level1; + +CREATE FUNCTION transition_table_level2_bad_usage_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ + BEGIN + INSERT INTO dx VALUES (1000000, 1000000, 'x'); + RETURN NULL; + END; +$$; + +CREATE TRIGGER transition_table_level2_bad_usage_trigger + AFTER DELETE ON transition_table_level2 + REFERENCING OLD TABLE AS dx + FOR EACH STATEMENT EXECUTE PROCEDURE + transition_table_level2_bad_usage_func(); + +DELETE FROM transition_table_level2 + WHERE level2_no BETWEEN 301 AND 305; + +DROP TRIGGER transition_table_level2_bad_usage_trigger + ON transition_table_level2; + +DELETE FROM transition_table_level1 + WHERE level1_no = 25; + +UPDATE transition_table_level1 SET level1_no = -1 + WHERE level1_no = 30; + +INSERT INTO transition_table_level2 (level2_no, parent_no) + VALUES (10000, 10000); + +UPDATE transition_table_level2 SET parent_no = 2000 + WHERE level2_no = 40; + +DELETE FROM transition_table_level1 + WHERE level1_no BETWEEN 201 AND 1000; + +DELETE FROM transition_table_level1 + WHERE level1_no BETWEEN 100000000 AND 100000010; + +SELECT count(*) FROM transition_table_level1; + +DELETE FROM transition_table_level2 + WHERE level2_no BETWEEN 211 AND 220; + +SELECT count(*) FROM transition_table_level2; + +CREATE TABLE alter_table_under_transition_tables +( + id int PRIMARY KEY, + name text +); + +CREATE FUNCTION alter_table_under_transition_tables_upd_func() + RETURNS TRIGGER + LANGUAGE plpgsql +AS $$ +BEGIN + RAISE WARNING 'old table = %, new table = %', + (SELECT string_agg(id || '=' || name, ',') FROM d), + (SELECT string_agg(id || '=' || name, ',') FROM i); + RAISE NOTICE 'one = %', (SELECT 1 FROM alter_table_under_transition_tables LIMIT 1); + RETURN NULL; +END; +$$; + +CREATE TRIGGER alter_table_under_transition_tables_upd_trigger + AFTER TRUNCATE OR UPDATE ON alter_table_under_transition_tables + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + alter_table_under_transition_tables_upd_func(); + +CREATE TRIGGER alter_table_under_transition_tables_upd_trigger + AFTER UPDATE ON alter_table_under_transition_tables + REFERENCING OLD TABLE AS d NEW TABLE AS i + FOR EACH STATEMENT EXECUTE PROCEDURE + alter_table_under_transition_tables_upd_func(); + +INSERT INTO alter_table_under_transition_tables + VALUES (1, '1'), (2, '2'), (3, '3'); + +UPDATE alter_table_under_transition_tables + SET name = name || name; + +ALTER TABLE alter_table_under_transition_tables + ALTER COLUMN name TYPE int USING name::integer; + +UPDATE alter_table_under_transition_tables + SET name = (name::text || name::text)::integer; + +ALTER TABLE alter_table_under_transition_tables + DROP column name; + +UPDATE alter_table_under_transition_tables + SET id = id; + +CREATE TABLE multi_test (i int); + +INSERT INTO multi_test VALUES (1); + +CREATE OR REPLACE FUNCTION multi_test_trig() RETURNS trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'count = %', (SELECT COUNT(*) FROM new_test); + RAISE NOTICE 'count union = %', + (SELECT COUNT(*) + FROM (SELECT * FROM new_test UNION ALL SELECT * FROM new_test) ss); + RETURN NULL; +END$$; + +CREATE TRIGGER my_trigger AFTER UPDATE ON multi_test + REFERENCING NEW TABLE AS new_test OLD TABLE as old_test + FOR EACH STATEMENT EXECUTE PROCEDURE multi_test_trig(); + +UPDATE multi_test SET i = i; + +DROP TABLE multi_test; + +DROP FUNCTION multi_test_trig(); + +CREATE TABLE partitioned_table (a int, b text) PARTITION BY LIST (a); + +CREATE TABLE pt_part1 PARTITION OF partitioned_table FOR VALUES IN (1); + +CREATE TABLE pt_part2 PARTITION OF partitioned_table FOR VALUES IN (2); + +INSERT INTO partitioned_table VALUES (1, 'Row 1'); + +INSERT INTO partitioned_table VALUES (2, 'Row 2'); + +CREATE OR REPLACE FUNCTION get_from_partitioned_table(partitioned_table.a%type) +RETURNS partitioned_table AS $$ +DECLARE + a_val partitioned_table.a%TYPE; + result partitioned_table%ROWTYPE; +BEGIN + a_val := $1; + SELECT * INTO result FROM partitioned_table WHERE a = a_val; + RETURN result; +END; $$ LANGUAGE plpgsql; + +SELECT * FROM get_from_partitioned_table(1) AS t; + +CREATE OR REPLACE FUNCTION list_partitioned_table() +RETURNS SETOF public.partitioned_table.a%TYPE AS $$ +DECLARE + row public.partitioned_table%ROWTYPE; + a_val public.partitioned_table.a%TYPE; +BEGIN + FOR row IN SELECT * FROM public.partitioned_table ORDER BY a LOOP + a_val := row.a; + RETURN NEXT a_val; + END LOOP; + RETURN; +END; $$ LANGUAGE plpgsql; + +SELECT * FROM list_partitioned_table() AS t; + +CREATE FUNCTION fx(x WSlot) RETURNS void AS $$ +BEGIN + GET DIAGNOSTICS x = ROW_COUNT; + RETURN; +END; $$ LANGUAGE plpgsql; diff --git a/crates/pgt_pretty_print/tests/data/multi/point_60.sql b/crates/pgt_pretty_print/tests/data/multi/point_60.sql new file mode 100644 index 000000000..8dc594172 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/point_60.sql @@ -0,0 +1,102 @@ +SET extra_float_digits = 0; + +INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf'); + +INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)'); + +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 10.0) x'); + +INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0'); + +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 1e+500)'); + +SELECT * FROM POINT_TBL; + +SELECT p.* FROM POINT_TBL p WHERE p.f1 << '(0.0, 0.0)'; + +SELECT p.* FROM POINT_TBL p WHERE '(0.0,0.0)' >> p.f1; + +SELECT p.* FROM POINT_TBL p WHERE '(0.0,0.0)' |>> p.f1; + +SELECT p.* FROM POINT_TBL p WHERE p.f1 <<| '(0.0, 0.0)'; + +SELECT p.* FROM POINT_TBL p WHERE p.f1 ~= '(5.1, 34.5)'; + +SELECT p.* FROM POINT_TBL p + WHERE p.f1 <@ box '(0,0,100,100)'; + +SELECT p.* FROM POINT_TBL p + WHERE box '(0,0,100,100)' @> p.f1; + +SELECT p.* FROM POINT_TBL p + WHERE not p.f1 <@ box '(0,0,100,100)'; + +SELECT p.* FROM POINT_TBL p + WHERE p.f1 <@ path '[(0,0),(-10,0),(-10,10)]'; + +SELECT p.* FROM POINT_TBL p + WHERE not box '(0,0,100,100)' @> p.f1; + +SELECT p.f1, p.f1 <-> point '(0,0)' AS dist + FROM POINT_TBL p + ORDER BY dist; + +SELECT p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dist + FROM POINT_TBL p1, POINT_TBL p2 + ORDER BY dist, p1.f1[0], p2.f1[0]; + +SELECT p1.f1 AS point1, p2.f1 AS point2 + FROM POINT_TBL p1, POINT_TBL p2 + WHERE (p1.f1 <-> p2.f1) > 3; + +SELECT p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance + FROM POINT_TBL p1, POINT_TBL p2 + WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 + ORDER BY distance, p1.f1[0], p2.f1[0]; + +SELECT p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance + FROM POINT_TBL p1, POINT_TBL p2 + WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 |>> p2.f1 + ORDER BY distance; + +CREATE TEMP TABLE point_gist_tbl(f1 point); + +INSERT INTO point_gist_tbl SELECT '(0,0)' FROM generate_series(0,1000); + +CREATE INDEX point_gist_tbl_index ON point_gist_tbl USING gist (f1); + +INSERT INTO point_gist_tbl VALUES ('(0.0000009,0.0000009)'); + +SET enable_seqscan TO true; + +SET enable_indexscan TO false; + +SET enable_bitmapscan TO false; + +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point; + +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box; + +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point; + +SET enable_seqscan TO false; + +SET enable_indexscan TO true; + +SET enable_bitmapscan TO true; + +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point; + +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box; + +SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +SELECT pg_input_is_valid('1,y', 'point'); + +SELECT * FROM pg_input_error_info('1,y', 'point'); diff --git a/crates/pgt_pretty_print/tests/data/multi/polygon_60.sql b/crates/pgt_pretty_print/tests/data/multi/polygon_60.sql new file mode 100644 index 000000000..4c3d03903 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/polygon_60.sql @@ -0,0 +1,141 @@ +CREATE TABLE POLYGON_TBL(f1 polygon); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(2.0,0.0),(2.0,4.0),(0.0,0.0)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(3.0,1.0),(3.0,3.0),(1.0,0.0)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(3,4),(5,6),(7,8)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(7,8),(5,6),(3,4),(1,2)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(7,8),(5,6),(3,-4)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,0.0)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,1.0),(0.0,1.0)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('0.0'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0 0.0'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2)'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2,3'); + +INSERT INTO POLYGON_TBL(f1) VALUES ('asdf'); + +SELECT * FROM POLYGON_TBL; + +CREATE TABLE quad_poly_tbl (id int, p polygon); + +INSERT INTO quad_poly_tbl + SELECT (x - 1) * 100 + y, polygon(circle(point(x * 10, y * 10), 1 + (x + y) % 10)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y; + +INSERT INTO quad_poly_tbl + SELECT i, polygon '((200, 300),(210, 310),(230, 290))' + FROM generate_series(10001, 11000) AS i; + +INSERT INTO quad_poly_tbl + VALUES + (11001, NULL), + (11002, NULL), + (11003, NULL); + +CREATE INDEX quad_poly_tbl_idx ON quad_poly_tbl USING spgist(p); + +SET enable_seqscan = ON; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = OFF; + +CREATE TEMP TABLE quad_poly_tbl_ord_seq2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + +SET enable_seqscan = OFF; + +SET enable_indexscan = OFF; + +SET enable_bitmapscan = ON; + +SELECT count(*) FROM quad_poly_tbl WHERE p << polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p << polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p &< polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p &< polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p && polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p && polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p &> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p &> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p >> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p >> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p <<| polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p <<| polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p &<| polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p &<| polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p |&> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p |&> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p |>> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p |>> polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p @> polygon '((340,550),(343,552),(341,553))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p @> polygon '((340,550),(343,552),(341,553))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))'; + +SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))'; + +SET enable_indexscan = ON; + +SET enable_bitmapscan = OFF; + +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + +CREATE TEMP TABLE quad_poly_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT * +FROM quad_poly_tbl_ord_seq2 seq FULL JOIN quad_poly_tbl_ord_idx2 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +SELECT pg_input_is_valid('(2.0,0.8,0.1)', 'polygon'); + +SELECT * FROM pg_input_error_info('(2.0,0.8,0.1)', 'polygon'); + +SELECT pg_input_is_valid('(2.0,xyz)', 'polygon'); + +SELECT * FROM pg_input_error_info('(2.0,xyz)', 'polygon'); diff --git a/crates/pgt_pretty_print/tests/data/multi/polymorphism_60.sql b/crates/pgt_pretty_print/tests/data/multi/polymorphism_60.sql new file mode 100644 index 000000000..899f62008 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/polymorphism_60.sql @@ -0,0 +1,1132 @@ +create function polyf(x anyelement) returns anyelement as $$ + select x + 1 +$$ language sql; + +select polyf(42) as int, polyf(4.5) as num; + +select polyf(point(3,4)); + +drop function polyf(x anyelement); + +create function polyf(x anyelement) returns anyarray as $$ + select array[x + 1, x + 2] +$$ language sql; + +select polyf(42) as int, polyf(4.5) as num; + +drop function polyf(x anyelement); + +create function polyf(x anyarray) returns anyelement as $$ + select x[1] +$$ language sql; + +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num; + +select polyf(stavalues1) from pg_statistic; + +drop function polyf(x anyarray); + +create function polyf(x anyarray) returns anyarray as $$ + select x +$$ language sql; + +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num; + +select polyf(stavalues1) from pg_statistic; + +drop function polyf(x anyarray); + +create function polyf(x anyelement) returns anyrange as $$ + select array[x + 1, x + 2] +$$ language sql; + +create function polyf(x anyrange) returns anyarray as $$ + select array[lower(x), upper(x)] +$$ language sql; + +select polyf(int4range(42, 49)) as int, polyf(float8range(4.5, 7.8)) as num; + +drop function polyf(x anyrange); + +create function polyf(x anycompatible, y anycompatible) returns anycompatiblearray as $$ + select array[x, y] +$$ language sql; + +select polyf(2, 4) as int, polyf(2, 4.5) as num; + +drop function polyf(x anycompatible, y anycompatible); + +create function polyf(x anycompatiblerange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ + select array[lower(x), upper(x), y, z] +$$ language sql; + +select polyf(int4range(42, 49), 11, 2::smallint) as int, polyf(float8range(4.5, 7.8), 7.8, 11::real) as num; + +select polyf(int4range(42, 49), 11, 4.5) as fail; + +drop function polyf(x anycompatiblerange, y anycompatible, z anycompatible); + +create function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ + select array[lower(x), upper(x), y, z] +$$ language sql; + +select polyf(multirange(int4range(42, 49)), 11, 2::smallint) as int, polyf(multirange(float8range(4.5, 7.8)), 7.8, 11::real) as num; + +select polyf(multirange(int4range(42, 49)), 11, 4.5) as fail; + +drop function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible); + +create function polyf(x anycompatible) returns anycompatiblerange as $$ + select array[x + 1, x + 2] +$$ language sql; + +create function polyf(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ + select x +$$ language sql; + +select polyf(int4range(42, 49), array[11]) as int, polyf(float8range(4.5, 7.8), array[7]) as num; + +drop function polyf(x anycompatiblerange, y anycompatiblearray); + +create function polyf(x anycompatible) returns anycompatiblemultirange as $$ + select array[x + 1, x + 2] +$$ language sql; + +create function polyf(x anycompatiblemultirange, y anycompatiblearray) returns anycompatiblemultirange as $$ + select x +$$ language sql; + +select polyf(multirange(int4range(42, 49)), array[11]) as int, polyf(multirange(float8range(4.5, 7.8)), array[7]) as num; + +drop function polyf(x anycompatiblemultirange, y anycompatiblearray); + +create function polyf(a anyelement, b anyarray, + c anycompatible, d anycompatible, + OUT x anyarray, OUT y anycompatiblearray) +as $$ + select a || b, array[c, d] +$$ language sql; + +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2], 42, 34.5); + +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2], point(1,2), point(3,4)); + +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, '{1,2}', point(1,2), '(3,4)'); + +select x, pg_typeof(x), y, pg_typeof(y) + from polyf(11, array[1, 2.2], 42, 34.5); + +drop function polyf(a anyelement, b anyarray, + c anycompatible, d anycompatible); + +create function polyf(anyrange) returns anymultirange +as 'select multirange($1);' language sql; + +select polyf(int4range(1,10)); + +select polyf(null); + +drop function polyf(anyrange); + +create function polyf(anymultirange) returns anyelement +as 'select lower($1);' language sql; + +select polyf(int4multirange(int4range(1,10), int4range(20,30))); + +select polyf(null); + +drop function polyf(anymultirange); + +create function polyf(anycompatiblerange) returns anycompatiblemultirange +as 'select multirange($1);' language sql; + +select polyf(int4range(1,10)); + +select polyf(null); + +drop function polyf(anycompatiblerange); + +create function polyf(anymultirange) returns anyrange +as 'select range_merge($1);' language sql; + +select polyf(int4multirange(int4range(1,10), int4range(20,30))); + +select polyf(null); + +drop function polyf(anymultirange); + +create function polyf(anycompatiblemultirange) returns anycompatiblerange +as 'select range_merge($1);' language sql; + +select polyf(int4multirange(int4range(1,10), int4range(20,30))); + +select polyf(null); + +drop function polyf(anycompatiblemultirange); + +create function polyf(anycompatiblemultirange) returns anycompatible +as 'select lower($1);' language sql; + +select polyf(int4multirange(int4range(1,10), int4range(20,30))); + +select polyf(null); + +drop function polyf(anycompatiblemultirange); + +CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS +'select $1' LANGUAGE SQL; + +CREATE FUNCTION stfnp(int[]) RETURNS int[] AS +'select $1' LANGUAGE SQL; + +CREATE FUNCTION tfp(anyarray,anyelement) RETURNS anyarray AS +'select $1 || $2' LANGUAGE SQL; + +CREATE FUNCTION tfnp(int[],int) RETURNS int[] AS +'select $1 || $2' LANGUAGE SQL; + +CREATE FUNCTION tf1p(anyarray,int) RETURNS anyarray AS +'select $1' LANGUAGE SQL; + +CREATE FUNCTION tf2p(int[],anyelement) RETURNS int[] AS +'select $1' LANGUAGE SQL; + +CREATE FUNCTION sum3(anyelement,anyelement,anyelement) returns anyelement AS +'select $1+$2+$3' language sql strict; + +CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS +'select $1' LANGUAGE SQL; + +CREATE FUNCTION ffnp(int[]) returns int[] as +'select $1' LANGUAGE SQL; + +CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray, + INITCOND = '{}'); + +CREATE AGGREGATE myaggp05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp09b(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggp10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp10b(BASETYPE = int, SFUNC = tfp, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggp11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp11b(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggp12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp12b(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp16a(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + INITCOND = '{}'); + +CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + INITCOND = '{}'); + +CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp19b(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, INITCOND = '{}'); + +CREATE AGGREGATE myaggp20a(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); + +CREATE AGGREGATE myaggp20b(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, INITCOND = '{}'); + +CREATE AGGREGATE myaggn01a(*) (SFUNC = stfnp, STYPE = int4[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray, + INITCOND = '{}'); + +CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn05a(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn05b(BASETYPE = int, SFUNC = tfnp, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggn06a(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn06b(BASETYPE = int, SFUNC = tf2p, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggn07a(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn07b(BASETYPE = anyelement, SFUNC = tfnp, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggn08a(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn08b(BASETYPE = anyelement, SFUNC = tf2p, STYPE = int[], + INITCOND = '{}'); + +CREATE AGGREGATE myaggn09a(BASETYPE = int, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn10a(BASETYPE = int, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn11a(BASETYPE = anyelement, SFUNC = tf1p, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn12a(BASETYPE = anyelement, SFUNC = tfp, STYPE = int[], + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, + INITCOND = '{}'); + +CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, + INITCOND = '{}'); + +CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn15b(BASETYPE = anyelement, SFUNC = tfnp, + STYPE = anyarray, INITCOND = '{}'); + +CREATE AGGREGATE myaggn16a(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn16b(BASETYPE = anyelement, SFUNC = tf2p, + STYPE = anyarray, INITCOND = '{}'); + +CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, + FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE myaggn20a(BASETYPE = anyelement, SFUNC = tfp, + STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); + +CREATE AGGREGATE mysum2(anyelement,anyelement) (SFUNC = sum3, + STYPE = anyelement, INITCOND = '0'); + +create temp table t(f1 int, f2 int[], f3 text); + +insert into t values(1,array[1],'a'); + +insert into t values(1,array[11],'b'); + +insert into t values(1,array[111],'c'); + +insert into t values(2,array[2],'a'); + +insert into t values(2,array[22],'b'); + +insert into t values(2,array[222],'c'); + +insert into t values(3,array[3],'a'); + +insert into t values(3,array[3],'b'); + +select f3, myaggp01a(*) from t group by f3 order by f3; + +select f3, myaggp03a(*) from t group by f3 order by f3; + +select f3, myaggp03b(*) from t group by f3 order by f3; + +select f3, myaggp05a(f1) from t group by f3 order by f3; + +select f3, myaggp06a(f1) from t group by f3 order by f3; + +select f3, myaggp08a(f1) from t group by f3 order by f3; + +select f3, myaggp09a(f1) from t group by f3 order by f3; + +select f3, myaggp09b(f1) from t group by f3 order by f3; + +select f3, myaggp10a(f1) from t group by f3 order by f3; + +select f3, myaggp10b(f1) from t group by f3 order by f3; + +select f3, myaggp20a(f1) from t group by f3 order by f3; + +select f3, myaggp20b(f1) from t group by f3 order by f3; + +select f3, myaggn01a(*) from t group by f3 order by f3; + +select f3, myaggn01b(*) from t group by f3 order by f3; + +select f3, myaggn03a(*) from t group by f3 order by f3; + +select f3, myaggn05a(f1) from t group by f3 order by f3; + +select f3, myaggn05b(f1) from t group by f3 order by f3; + +select f3, myaggn06a(f1) from t group by f3 order by f3; + +select f3, myaggn06b(f1) from t group by f3 order by f3; + +select f3, myaggn08a(f1) from t group by f3 order by f3; + +select f3, myaggn08b(f1) from t group by f3 order by f3; + +select f3, myaggn09a(f1) from t group by f3 order by f3; + +select f3, myaggn10a(f1) from t group by f3 order by f3; + +select mysum2(f1, f1 + 1) from t; + +create function bleat(int) returns int as $$ +begin + raise notice 'bleat %', $1; + return $1; +end$$ language plpgsql; + +create function sql_if(bool, anyelement, anyelement) returns anyelement as $$ +select case when $1 then $2 else $3 end $$ language sql; + +select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from int4_tbl; + +select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl; + +CREATE AGGREGATE array_larger_accum (anyarray) +( + sfunc = array_larger, + stype = anyarray, + initcond = '{}' +); + +SELECT array_larger_accum(i) +FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) as t(i); + +SELECT array_larger_accum(i) +FROM (VALUES (ARRAY[row(1,2),row(3,4)]), (ARRAY[row(5,6),row(7,8)])) as t(i); + +create function add_group(grp anyarray, ad anyelement, size integer) + returns anyarray + as $$ +begin + if grp is null then + return array[ad]; + end if; + if array_upper(grp, 1) < size then + return grp || ad; + end if; + return grp; +end; +$$ + language plpgsql immutable; + +create aggregate build_group(anyelement, integer) ( + SFUNC = add_group, + STYPE = anyarray +); + +select build_group(q1,3) from int8_tbl; + +create aggregate build_group(int8, integer) ( + SFUNC = add_group, + STYPE = int2[] +); + +create aggregate build_group(int8, integer) ( + SFUNC = add_group, + STYPE = int8[] +); + +create function first_el_transfn(anyarray, anyelement) returns anyarray as +'select $1 || $2' language sql immutable; + +create function first_el(anyarray) returns anyelement as +'select $1[1]' language sql strict immutable; + +create aggregate first_el_agg_f8(float8) ( + SFUNC = array_append, + STYPE = float8[], + FINALFUNC = first_el +); + +create aggregate first_el_agg_any(anyelement) ( + SFUNC = first_el_transfn, + STYPE = anyarray, + FINALFUNC = first_el +); + +select first_el_agg_f8(x::float8) from generate_series(1,10) x; + +select first_el_agg_any(x) from generate_series(1,10) x; + +select first_el_agg_f8(x::float8) over(order by x) from generate_series(1,10) x; + +select first_el_agg_any(x) over(order by x) from generate_series(1,10) x; + +select distinct array_ndims(histogram_bounds) from pg_stats +where histogram_bounds is not null; + +select max(histogram_bounds) from pg_stats where tablename = 'pg_am'; + +select array_in('{1,2,3}','int4'::regtype,-1); + +select * from array_in('{1,2,3}','int4'::regtype,-1); + +select anyrange_in('[10,20)','int4range'::regtype,-1); + +create function myleast(variadic anyarray) returns anyelement as $$ + select min($1[i]) from generate_subscripts($1,1) g(i) +$$ language sql immutable strict; + +select myleast(10, 1, 20, 33); + +select myleast(1.1, 0.22, 0.55); + +select myleast('z'::text); + +select myleast(); + +select myleast(variadic array[1,2,3,4,-1]); + +select myleast(variadic array[1.1, -5.5]); + +select myleast(variadic array[]::int[]); + +create function concat(text, variadic anyarray) returns text as $$ + select array_to_string($2, $1); +$$ language sql immutable strict; + +select concat('%', 1, 2, 3, 4, 5); + +select concat('|', 'a'::text, 'b', 'c'); + +select concat('|', variadic array[1,2,33]); + +select concat('|', variadic array[]::int[]); + +drop function concat(text, anyarray); + +create function formarray(anyelement, variadic anyarray) returns anyarray as $$ + select array_prepend($1, $2); +$$ language sql immutable strict; + +select formarray(1,2,3,4,5); + +select formarray(1.1, variadic array[1.2,55.5]); + +select formarray(1.1, array[1.2,55.5]); + +select formarray(1, 'x'::text); + +select formarray(1, variadic array['x'::text]); + +drop function formarray(anyelement, variadic anyarray); + +select pg_typeof(null); + +select pg_typeof(0); + +select pg_typeof(0.0); + +select pg_typeof(1+1 = 2); + +select pg_typeof('x'); + +select pg_typeof('' || ''); + +select pg_typeof(pg_typeof(0)); + +select pg_typeof(array[1.2,55.5]); + +select pg_typeof(myleast(10, 1, 20, 33)); + +create function dfunc(a int = 1, int = 2) returns int as $$ + select $1 + $2; +$$ language sql; + +select dfunc(); + +select dfunc(10); + +select dfunc(10, 20); + +select dfunc(10, 20, 30); + +drop function dfunc(); + +drop function dfunc(int); + +drop function dfunc(int, int); + +create function dfunc(a int = 1, b int) returns int as $$ + select $1 + $2; +$$ language sql; + +create function dfunc(a int = 1, out sum int, b int = 2) as $$ + select $1 + $2; +$$ language sql; + +select dfunc(); + +drop function dfunc(int, int); + +create function dfunc(a int DEFAULT 1.0, int DEFAULT '-1') returns int as $$ + select $1 + $2; +$$ language sql; + +select dfunc(); + +create function dfunc(a text DEFAULT 'Hello', b text DEFAULT 'World') returns text as $$ + select $1 || ', ' || $2; +$$ language sql; + +select dfunc(); + +select dfunc('Hi'); + +select dfunc('Hi', 'City'); + +select dfunc(0); + +select dfunc(10, 20); + +drop function dfunc(int, int); + +drop function dfunc(text, text); + +create function dfunc(int = 1, int = 2) returns int as $$ + select 2; +$$ language sql; + +create function dfunc(int = 1, int = 2, int = 3, int = 4) returns int as $$ + select 4; +$$ language sql; + +select dfunc(); + +select dfunc(1); + +select dfunc(1, 2); + +select dfunc(1, 2, 3); + +select dfunc(1, 2, 3, 4); + +drop function dfunc(int, int); + +drop function dfunc(int, int, int, int); + +create function dfunc(out int = 20) returns int as $$ + select 1; +$$ language sql; + +create function dfunc(anyelement = 'World'::text) returns text as $$ + select 'Hello, ' || $1::text; +$$ language sql; + +select dfunc(); + +select dfunc(0); + +select dfunc(to_date('20081215','YYYYMMDD')); + +select dfunc('City'::text); + +drop function dfunc(anyelement); + +create function dfunc(a variadic int[]) returns int as +$$ select array_upper($1, 1) $$ language sql; + +select dfunc(); + +select dfunc(10); + +select dfunc(10,20); + +create or replace function dfunc(a variadic int[] default array[]::int[]) returns int as +$$ select array_upper($1, 1) $$ language sql; + +select dfunc(); + +select dfunc(10); + +select dfunc(10,20); + +create or replace function dfunc(a variadic int[]) returns int as +$$ select array_upper($1, 1) $$ language sql; + +drop function dfunc(a variadic int[]); + +create function dfunc(int = 1, int = 2, int = 3) returns int as $$ + select 3; +$$ language sql; + +create function dfunc(int = 1, int = 2) returns int as $$ + select 2; +$$ language sql; + +create function dfunc(text) returns text as $$ + select $1; +$$ language sql; + +select dfunc(1); + +select dfunc('Hi'); + +drop function dfunc(int, int, int); + +drop function dfunc(int, int); + +drop function dfunc(text); + +create function dfunc(a int, b int, c int = 0, d int = 0) + returns table (a int, b int, c int, d int) as $$ + select $1, $2, $3, $4; +$$ language sql; + +select (dfunc(10,20,30)).*; + +select (dfunc(a := 10, b := 20, c := 30)).*; + +select * from dfunc(a := 10, b := 20); + +select * from dfunc(b := 10, a := 20); + +select * from dfunc(0); + +select * from dfunc(1,2); + +select * from dfunc(1,2,c := 3); + +select * from dfunc(1,2,d := 3); + +select * from dfunc(x := 20, b := 10, x := 30); + +select * from dfunc(10, b := 20, 30); + +select * from dfunc(x := 10, b := 20, c := 30); + +select * from dfunc(10, 10, a := 20); + +select * from dfunc(1,c := 2,d := 3); + +drop function dfunc(int, int, int, int); + +create function xleast(x numeric, variadic arr numeric[]) + returns numeric as $$ + select least(x, min(arr[i])) from generate_subscripts(arr, 1) g(i); +$$ language sql; + +select xleast(x => 1, variadic arr => array[2,3]); + +select xleast(1, variadic arr => array[2,3]); + +set search_path = pg_catalog; + +select xleast(1, variadic arr => array[2,3]); + +reset search_path; + +select xleast(foo => 1, variadic arr => array[2,3]); + +select xleast(x => 1, variadic array[2,3]); + +select xleast(1, variadic x => array[2,3]); + +select xleast(arr => array[1], variadic x => 3); + +select xleast(arr => array[1], x => 3); + +select xleast(arr => 1, variadic x => array[2,3]); + +drop function xleast(x numeric, variadic arr numeric[]); + +create function dfunc(a varchar, b numeric, c date = current_date) + returns table (a varchar, b numeric, c date) as $$ + select $1, $2, $3; +$$ language sql; + +select (dfunc('Hello World', 20, '2009-07-25'::date)).*; + +select * from dfunc('Hello World', 20, '2009-07-25'::date); + +select * from dfunc(c := '2009-07-25'::date, a := 'Hello World', b := 20); + +select * from dfunc('Hello World', b := 20, c := '2009-07-25'::date); + +select * from dfunc('Hello World', c := '2009-07-25'::date, b := 20); + +select * from dfunc('Hello World', c := 20, b := '2009-07-25'::date); + +drop function dfunc(varchar, numeric, date); + +create function dfunc(a varchar = 'def a', out _a varchar, c numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql; + +select (dfunc()).*; + +select * from dfunc(); + +select * from dfunc('Hello', 100); + +select * from dfunc(a := 'Hello', c := 100); + +select * from dfunc(c := 100, a := 'Hello'); + +select * from dfunc('Hello'); + +select * from dfunc('Hello', c := 100); + +select * from dfunc(c := 100); + +create or replace function dfunc(a varchar = 'def a', out _a varchar, x numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql; + +create or replace function dfunc(a varchar = 'def a', out _a varchar, numeric = NULL, out _c numeric) +returns record as $$ + select $1, $2; +$$ language sql; + +drop function dfunc(varchar, numeric); + +create function testpolym(a int, a int) returns int as $$ select 1;$$ language sql; + +create function testpolym(int, out a int, out a int) returns int as $$ select 1;$$ language sql; + +create function testpolym(out a int, inout a int) returns int as $$ select 1;$$ language sql; + +create function testpolym(a int, inout a int) returns int as $$ select 1;$$ language sql; + +create function testpolym(a int, out a int) returns int as $$ select $1;$$ language sql; + +select testpolym(37); + +drop function testpolym(int); + +create function testpolym(a int) returns table(a int) as $$ select $1;$$ language sql; + +select * from testpolym(37); + +drop function testpolym(int); + +create function dfunc(a anyelement, b anyelement = null, flag bool = true) +returns anyelement as $$ + select case when $3 then $1 else $2 end; +$$ language sql; + +select dfunc(1,2); + +select dfunc('a'::text, 'b'); + +select dfunc(a := 1, b := 2); + +select dfunc(a := 'a'::text, b := 'b'); + +select dfunc(a := 'a'::text, b := 'b', flag := false); + +select dfunc(b := 'b'::text, a := 'a'); + +select dfunc(a := 'a'::text, flag := true); + +select dfunc(a := 'a'::text, flag := false); + +select dfunc(b := 'b'::text, a := 'a', flag := true); + +select dfunc('a'::text, 'b', false); + +select dfunc('a'::text, 'b', flag := false); + +select dfunc('a'::text, 'b', true); + +select dfunc('a'::text, 'b', flag := true); + +select dfunc(a => 1, b => 2); + +select dfunc(a => 'a'::text, b => 'b'); + +select dfunc(a => 'a'::text, b => 'b', flag => false); + +select dfunc(b => 'b'::text, a => 'a'); + +select dfunc(a => 'a'::text, flag => true); + +select dfunc(a => 'a'::text, flag => false); + +select dfunc(b => 'b'::text, a => 'a', flag => true); + +select dfunc('a'::text, 'b', false); + +select dfunc('a'::text, 'b', flag => false); + +select dfunc('a'::text, 'b', true); + +select dfunc('a'::text, 'b', flag => true); + +select dfunc(a =>-1); + +select dfunc(a =>+1); + +select dfunc(a =>/**/1); + +select dfunc(a =>--comment to be removed by psql + 1); + +do $$ + declare r integer; + begin + select dfunc(a=>-- comment + 1) into r; + raise info 'r = %', r; + end; +$$; + +CREATE VIEW dfview AS + SELECT q1, q2, + dfunc(q1,q2, flag := q1>q2) as c3, + dfunc(q1, flag := q1 2)); + +CREATE TABLE pred_tab2 (a int, b int, + CONSTRAINT check_a CHECK (a IS NOT NULL)); + +SET constraint_exclusion TO ON; + +SELECT * FROM pred_tab1, pred_tab2 WHERE pred_tab2.a IS NULL; + +SELECT * FROM pred_tab2, pred_tab1 WHERE pred_tab1.a IS NULL OR pred_tab1.b < 2; + +RESET constraint_exclusion; + +DROP TABLE pred_tab1; + +DROP TABLE pred_tab2; diff --git a/crates/pgt_pretty_print/tests/data/multi/prepare_60.sql b/crates/pgt_pretty_print/tests/data/multi/prepare_60.sql new file mode 100644 index 000000000..0406a355e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/prepare_60.sql @@ -0,0 +1,77 @@ +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + +PREPARE q1 AS SELECT 1 AS a; + +EXECUTE q1; + +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + +PREPARE q1 AS SELECT 2; + +DEALLOCATE q1; + +PREPARE q1 AS SELECT 2; + +EXECUTE q1; + +PREPARE q2 AS SELECT 2 AS b; + +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + +DEALLOCATE PREPARE q1; + +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + +DEALLOCATE PREPARE q2; + +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + +PREPARE q2(text) AS + SELECT datname, datistemplate, datallowconn + FROM pg_database WHERE datname = $1; + +EXECUTE q2('postgres'); + +PREPARE q3(text, int, float, boolean, smallint) AS + SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR + ten = $3::bigint OR true = $4 OR odd = $5::int) + ORDER BY unique1; + +EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); + +EXECUTE q3('bool'); + +EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true); + +EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea'); + +PREPARE q4(nonexistenttype) AS SELECT $1; + +PREPARE q5(int, text) AS + SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 + ORDER BY unique1; + +CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA'); + +SELECT * FROM q5_prep_results; + +CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') + WITH NO DATA; + +SELECT * FROM q5_prep_nodata; + +PREPARE q6 AS + SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; + +PREPARE q7(unknown) AS + SELECT * FROM road WHERE thepath = $1; + +UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1; + +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements + ORDER BY name; + +DEALLOCATE ALL; + +SELECT name, statement, parameter_types FROM pg_prepared_statements + ORDER BY name; diff --git a/crates/pgt_pretty_print/tests/data/multi/prepared_xacts_60.sql b/crates/pgt_pretty_print/tests/data/multi/prepared_xacts_60.sql new file mode 100644 index 000000000..d9395a9a5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/prepared_xacts_60.sql @@ -0,0 +1,165 @@ +CREATE TABLE pxtest1 (foobar VARCHAR(10)); + +INSERT INTO pxtest1 VALUES ('aaa'); + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +UPDATE pxtest1 SET foobar = 'bbb' WHERE foobar = 'aaa'; + +SELECT * FROM pxtest1; + +PREPARE TRANSACTION 'regress_foo1'; + +SELECT * FROM pxtest1; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +ROLLBACK PREPARED 'regress_foo1'; + +SELECT * FROM pxtest1; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +INSERT INTO pxtest1 VALUES ('ddd'); + +SELECT * FROM pxtest1; + +PREPARE TRANSACTION 'regress_foo2'; + +SELECT * FROM pxtest1; + +COMMIT PREPARED 'regress_foo2'; + +SELECT * FROM pxtest1; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd'; + +SELECT * FROM pxtest1; + +PREPARE TRANSACTION 'regress_foo3'; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +INSERT INTO pxtest1 VALUES ('fff'); + +PREPARE TRANSACTION 'regress_foo3'; + +SELECT * FROM pxtest1; + +ROLLBACK PREPARED 'regress_foo3'; + +SELECT * FROM pxtest1; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +UPDATE pxtest1 SET foobar = 'eee' WHERE foobar = 'ddd'; + +SELECT * FROM pxtest1; + +PREPARE TRANSACTION 'regress_foo4'; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +SELECT * FROM pxtest1; + +INSERT INTO pxtest1 VALUES ('fff'); + +PREPARE TRANSACTION 'regress_foo5'; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +ROLLBACK PREPARED 'regress_foo4'; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +DROP TABLE pxtest1; + +BEGIN; + +SELECT pg_advisory_lock(1); + +SELECT pg_advisory_xact_lock_shared(1); + +PREPARE TRANSACTION 'regress_foo6'; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +CREATE TABLE pxtest2 (a int); + +INSERT INTO pxtest2 VALUES (1); + +SAVEPOINT a; + +INSERT INTO pxtest2 VALUES (2); + +ROLLBACK TO a; + +SAVEPOINT b; + +INSERT INTO pxtest2 VALUES (3); + +PREPARE TRANSACTION 'regress_sub1'; + +CREATE TABLE pxtest3(fff int); + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +DROP TABLE pxtest3; + +CREATE TABLE pxtest4 (a int); + +INSERT INTO pxtest4 VALUES (1); + +INSERT INTO pxtest4 VALUES (2); + +DECLARE foo CURSOR FOR SELECT * FROM pxtest4; + +FETCH 1 FROM foo; + +PREPARE TRANSACTION 'regress_sub2'; + +FETCH 1 FROM foo; + +SELECT * FROM pxtest2; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +begin; + +lock table pxtest3 in access share mode nowait; + +rollback; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +begin; + +lock table pxtest3 in access share mode nowait; + +rollback; + +COMMIT PREPARED 'regress_sub1'; + +SELECT * FROM pxtest2; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +COMMIT PREPARED 'regress_sub2'; + +SELECT * FROM pxtest3; + +SELECT gid FROM pg_prepared_xacts WHERE gid ~ '^regress_' ORDER BY gid; + +DROP TABLE pxtest2; + +DROP TABLE pxtest3; + +DROP TABLE pxtest4; diff --git a/crates/pgt_pretty_print/tests/data/multi/privileges_60.sql b/crates/pgt_pretty_print/tests/data/multi/privileges_60.sql new file mode 100644 index 000000000..9b3b886eb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/privileges_60.sql @@ -0,0 +1,2729 @@ +SET client_min_messages TO 'warning'; + +DROP ROLE IF EXISTS regress_priv_group1; + +DROP ROLE IF EXISTS regress_priv_group2; + +DROP ROLE IF EXISTS regress_priv_user1; + +DROP ROLE IF EXISTS regress_priv_user2; + +DROP ROLE IF EXISTS regress_priv_user3; + +DROP ROLE IF EXISTS regress_priv_user4; + +DROP ROLE IF EXISTS regress_priv_user5; + +DROP ROLE IF EXISTS regress_priv_user6; + +DROP ROLE IF EXISTS regress_priv_user7; + +SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid; + +RESET client_min_messages; + +CREATE USER regress_priv_user1; + +CREATE USER regress_priv_user2; + +CREATE USER regress_priv_user3; + +CREATE USER regress_priv_user4; + +CREATE USER regress_priv_user5; + +CREATE USER regress_priv_user5; + +CREATE USER regress_priv_user6; + +CREATE USER regress_priv_user7; + +CREATE USER regress_priv_user8; + +CREATE USER regress_priv_user9; + +CREATE USER regress_priv_user10; + +CREATE ROLE regress_priv_role; + +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION; + +GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION GRANTED BY regress_priv_user2; + +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION GRANTED BY regress_priv_user3; + +REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2; + +REVOKE regress_priv_user1 FROM regress_priv_user2; + +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole; + +BEGIN; + +REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2 CASCADE; + +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole; + +ROLLBACK; + +REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE; + +SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole; + +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION; + +GRANT regress_priv_user2 TO regress_priv_user3; + +SET ROLE regress_priv_user3; + +GRANT regress_priv_user1 TO regress_priv_user4; + +SELECT grantor::regrole FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole and member = 'regress_priv_user4'::regrole; + +RESET ROLE; + +REVOKE regress_priv_user2 FROM regress_priv_user3; + +REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE; + +GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION; + +GRANT regress_priv_user1 TO regress_priv_user3 GRANTED BY regress_priv_user2; + +DROP ROLE regress_priv_user2; + +REASSIGN OWNED BY regress_priv_user2 TO regress_priv_user4; + +DROP ROLE regress_priv_user2; + +DROP OWNED BY regress_priv_user2; + +DROP ROLE regress_priv_user2; + +GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION; + +GRANT regress_priv_user1 TO regress_priv_user4 GRANTED BY regress_priv_user3; + +DROP ROLE regress_priv_user3; + +DROP ROLE regress_priv_user4; + +DROP ROLE regress_priv_user3; + +GRANT regress_priv_user1 TO regress_priv_user5 WITH ADMIN OPTION; + +GRANT regress_priv_user1 TO regress_priv_user6 GRANTED BY regress_priv_user5; + +DROP ROLE regress_priv_user5; + +DROP ROLE regress_priv_user1, regress_priv_user5; + +CREATE USER regress_priv_user1; + +CREATE USER regress_priv_user2; + +CREATE USER regress_priv_user3; + +CREATE USER regress_priv_user4; + +CREATE USER regress_priv_user5; + +GRANT pg_read_all_data TO regress_priv_user6; + +GRANT pg_write_all_data TO regress_priv_user7; + +GRANT pg_read_all_settings TO regress_priv_user8 WITH ADMIN OPTION; + +GRANT regress_priv_user9 TO regress_priv_user8; + +SET SESSION AUTHORIZATION regress_priv_user8; + +GRANT pg_read_all_settings TO regress_priv_user9 WITH ADMIN OPTION; + +SET SESSION AUTHORIZATION regress_priv_user9; + +GRANT pg_read_all_settings TO regress_priv_user10; + +SET SESSION AUTHORIZATION regress_priv_user8; + +REVOKE pg_read_all_settings FROM regress_priv_user10 GRANTED BY regress_priv_user9; + +REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user9; + +REVOKE pg_read_all_settings FROM regress_priv_user9; + +RESET SESSION AUTHORIZATION; + +REVOKE regress_priv_user9 FROM regress_priv_user8; + +REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user8; + +SET SESSION AUTHORIZATION regress_priv_user8; + +SET ROLE pg_read_all_settings; + +RESET ROLE; + +RESET SESSION AUTHORIZATION; + +REVOKE SET OPTION FOR pg_read_all_settings FROM regress_priv_user8; + +GRANT pg_read_all_stats TO regress_priv_user8 WITH SET FALSE; + +SET SESSION AUTHORIZATION regress_priv_user8; + +SET ROLE pg_read_all_settings; + +SET ROLE pg_read_all_stats; + +RESET ROLE; + +RESET SESSION AUTHORIZATION; + +GRANT regress_priv_user9 TO regress_priv_user8; + +SET SESSION AUTHORIZATION regress_priv_user8; + +SET ROLE regress_priv_user9; + +SET debug_parallel_query = 0; + +SELECT session_user, current_role, current_user, current_setting('role') as role; + +SET debug_parallel_query = 1; + +SELECT session_user, current_role, current_user, current_setting('role') as role; + +BEGIN; + +SET SESSION AUTHORIZATION regress_priv_user10; + +SET debug_parallel_query = 0; + +SELECT session_user, current_role, current_user, current_setting('role') as role; + +SET debug_parallel_query = 1; + +SELECT session_user, current_role, current_user, current_setting('role') as role; + +ROLLBACK; + +SET debug_parallel_query = 0; + +SELECT session_user, current_role, current_user, current_setting('role') as role; + +SET debug_parallel_query = 1; + +SELECT session_user, current_role, current_user, current_setting('role') as role; + +RESET SESSION AUTHORIZATION; + +SET debug_parallel_query = 0; + +SELECT session_user = current_role as c_r_ok, session_user = current_user as c_u_ok, current_setting('role') as role; + +SET debug_parallel_query = 1; + +SELECT session_user = current_role as c_r_ok, session_user = current_user as c_u_ok, current_setting('role') as role; + +RESET debug_parallel_query; + +REVOKE pg_read_all_settings FROM regress_priv_user8; + +DROP USER regress_priv_user10; + +DROP USER regress_priv_user9; + +DROP USER regress_priv_user8; + +CREATE GROUP regress_priv_group1; + +CREATE GROUP regress_priv_group2 WITH ADMIN regress_priv_user1 USER regress_priv_user2; + +ALTER GROUP regress_priv_group1 ADD USER regress_priv_user4; + +GRANT regress_priv_group2 TO regress_priv_user2 GRANTED BY regress_priv_user1; + +SET SESSION AUTHORIZATION regress_priv_user3; + +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2; + +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2; + +SET SESSION AUTHORIZATION regress_priv_user1; + +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2; + +ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2; + +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2; + +ALTER USER regress_priv_user2 PASSWORD 'verysecret'; + +RESET SESSION AUTHORIZATION; + +ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2; + +REVOKE ADMIN OPTION FOR regress_priv_group2 FROM regress_priv_user1; + +GRANT regress_priv_group2 TO regress_priv_user4 WITH ADMIN OPTION; + +CREATE FUNCTION leak(integer,integer) RETURNS boolean + AS 'int4lt' + LANGUAGE internal IMMUTABLE STRICT; + +ALTER FUNCTION leak(integer,integer) OWNER TO regress_priv_user1; + +GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY regress_priv_role; + +GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY CURRENT_ROLE; + +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY foo; + +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY regress_priv_user2; + +REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_USER; + +REVOKE regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_ROLE; + +DROP ROLE regress_priv_role; + +SET SESSION AUTHORIZATION regress_priv_user1; + +SELECT session_user, current_user; + +CREATE TABLE atest1 ( a int, b text ); + +SELECT * FROM atest1; + +INSERT INTO atest1 VALUES (1, 'one'); + +DELETE FROM atest1; + +UPDATE atest1 SET a = 1 WHERE b = 'blech'; + +TRUNCATE atest1; + +BEGIN; + +LOCK atest1 IN ACCESS EXCLUSIVE MODE; + +COMMIT; + +REVOKE ALL ON atest1 FROM PUBLIC; + +SELECT * FROM atest1; + +GRANT ALL ON atest1 TO regress_priv_user2; + +GRANT SELECT ON atest1 TO regress_priv_user3, regress_priv_user4; + +SELECT * FROM atest1; + +CREATE TABLE atest2 (col1 varchar(10), col2 boolean); + +SELECT pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid, 0); + +GRANT SELECT ON atest2 TO regress_priv_user2; + +GRANT UPDATE ON atest2 TO regress_priv_user3; + +GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER; + +GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE; + +SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid, 0)); + +SELECT pg_get_acl('pg_class'::regclass, 0, 0); + +SELECT pg_get_acl(0, 0, 0); + +GRANT TRUNCATE ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT session_user, current_user; + +SELECT * FROM atest1; + +SELECT * FROM atest2; + +INSERT INTO atest1 VALUES (2, 'two'); + +INSERT INTO atest2 VALUES ('foo', true); + +INSERT INTO atest1 SELECT 1, b FROM atest1; + +UPDATE atest1 SET a = 1 WHERE a = 2; + +UPDATE atest2 SET col2 = NOT col2; + +SELECT * FROM atest1 FOR UPDATE; + +SELECT * FROM atest2 FOR UPDATE; + +DELETE FROM atest2; + +TRUNCATE atest2; + +BEGIN; + +LOCK atest2 IN ACCESS EXCLUSIVE MODE; + +COMMIT; + +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); + +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + +SET SESSION AUTHORIZATION regress_priv_user6; + +SELECT * FROM atest1; + +SELECT * FROM atest2; + +INSERT INTO atest2 VALUES ('foo', true); + +SET SESSION AUTHORIZATION regress_priv_user7; + +SELECT * FROM atest1; + +SELECT * FROM atest2; + +INSERT INTO atest2 VALUES ('foo', true); + +UPDATE atest2 SET col2 = true; + +DELETE FROM atest2; + +UPDATE pg_catalog.pg_class SET relname = '123'; + +DELETE FROM pg_catalog.pg_class; + +UPDATE pg_toast.pg_toast_1213 SET chunk_id = 1; + +SET SESSION AUTHORIZATION regress_priv_user3; + +SELECT session_user, current_user; + +SELECT * FROM atest1; + +SELECT * FROM atest2; + +INSERT INTO atest1 VALUES (2, 'two'); + +INSERT INTO atest2 VALUES ('foo', true); + +INSERT INTO atest1 SELECT 1, b FROM atest1; + +UPDATE atest1 SET a = 1 WHERE a = 2; + +UPDATE atest2 SET col2 = NULL; + +UPDATE atest2 SET col2 = NOT col2; + +UPDATE atest2 SET col2 = true FROM atest1 WHERE atest1.a = 5; + +SELECT * FROM atest1 FOR UPDATE; + +SELECT * FROM atest2 FOR UPDATE; + +DELETE FROM atest2; + +TRUNCATE atest2; + +BEGIN; + +LOCK atest2 IN ACCESS EXCLUSIVE MODE; + +COMMIT; + +SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) ); + +SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) ); + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT * FROM atest1; + +SET SESSION AUTHORIZATION regress_priv_user1; + +CREATE TABLE atest12 as + SELECT x AS a, 10001 - x AS b FROM generate_series(1,10000) x; + +CREATE INDEX ON atest12 (a); + +CREATE INDEX ON atest12 (abs(a)); + +ALTER TABLE atest12 SET (autovacuum_enabled = off); + +SET default_statistics_target = 10000; + +VACUUM ANALYZE atest12; + +RESET default_statistics_target; + +CREATE OPERATOR <<< (procedure = leak, leftarg = integer, rightarg = integer, + restrict = scalarltsel); + +CREATE VIEW atest12v AS + SELECT * FROM atest12 WHERE b <<< 5; + +CREATE VIEW atest12sbv WITH (security_barrier=true) AS + SELECT * FROM atest12 WHERE b <<< 5; + +SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; + +SELECT * FROM atest12 x, atest12 y + WHERE x.a = y.b and abs(y.a) <<< 5; + +SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b; + +SET SESSION AUTHORIZATION regress_priv_user2; + +CREATE FUNCTION leak2(integer,integer) RETURNS boolean + AS $$begin raise notice 'leak % %', $1, $2; return $1 > $2; end$$ + LANGUAGE plpgsql immutable; + +CREATE OPERATOR >>> (procedure = leak2, leftarg = integer, rightarg = integer, + restrict = scalargtsel); + +SELECT * FROM atest12 WHERE a >>> 0; + +SELECT * FROM atest12v WHERE a >>> 0; + +SELECT * FROM atest12sbv WHERE a >>> 0; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT SELECT ON atest12v TO PUBLIC; + +GRANT SELECT ON atest12sbv TO PUBLIC; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; + +SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b; + +SELECT * FROM atest12v x, atest12v y + WHERE x.a = y.b and abs(y.a) <<< 5; + +SELECT * FROM atest12sbv x, atest12sbv y + WHERE x.a = y.b and abs(y.a) <<< 5; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT SELECT (a, b) ON atest12 TO PUBLIC; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; + +SELECT * FROM atest12 x, atest12 y + WHERE x.a = y.b and abs(y.a) <<< 5; + +DROP FUNCTION leak2(integer, integer) CASCADE; + +SET SESSION AUTHORIZATION regress_priv_user3; + +CREATE TABLE atest3 (one int, two int, three int); + +GRANT DELETE ON atest3 TO GROUP regress_priv_group2; + +SET SESSION AUTHORIZATION regress_priv_user1; + +SELECT * FROM atest3; + +DELETE FROM atest3; + +BEGIN; + +RESET SESSION AUTHORIZATION; + +ALTER ROLE regress_priv_user1 NOINHERIT; + +SET SESSION AUTHORIZATION regress_priv_user1; + +SAVEPOINT s1; + +DELETE FROM atest3; + +ROLLBACK TO s1; + +RESET SESSION AUTHORIZATION; + +GRANT regress_priv_group2 TO regress_priv_user1 WITH INHERIT FALSE; + +SET SESSION AUTHORIZATION regress_priv_user1; + +DELETE FROM atest3; + +ROLLBACK TO s1; + +RESET SESSION AUTHORIZATION; + +REVOKE INHERIT OPTION FOR regress_priv_group2 FROM regress_priv_user1; + +SET SESSION AUTHORIZATION regress_priv_user1; + +DELETE FROM atest3; + +ROLLBACK; + +SET SESSION AUTHORIZATION regress_priv_user3; + +CREATE VIEW atestv1 AS SELECT * FROM atest1; + +CREATE VIEW atestv2 AS SELECT * FROM atest2; + +CREATE VIEW atestv3 AS SELECT * FROM atest3; + +CREATE VIEW atestv0 AS SELECT 0 as x WHERE false; + +SELECT * FROM atestv1; + +SELECT * FROM atestv2; + +GRANT SELECT ON atestv1, atestv3 TO regress_priv_user4; + +GRANT SELECT ON atestv2 TO regress_priv_user2; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT * FROM atestv1; + +SELECT * FROM atestv2; + +SELECT * FROM atestv3; + +SELECT * FROM atestv0; + +select * from + ((select a.q1 as x from int8_tbl a offset 0) + union all + (select b.q2 as x from int8_tbl b offset 0)) ss +where false; + +set constraint_exclusion = on; + +select * from + ((select a.q1 as x, random() from int8_tbl a where q1 > 0) + union all + (select b.q2 as x, random() from int8_tbl b where q2 > 0)) ss +where x < 0; + +reset constraint_exclusion; + +CREATE VIEW atestv4 AS SELECT * FROM atestv3; + +SELECT * FROM atestv4; + +GRANT SELECT ON atestv4 TO regress_priv_user2; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT * FROM atestv3; + +SELECT * FROM atestv4; + +SELECT * FROM atest2; + +SELECT * FROM atestv2; + +SET SESSION AUTHORIZATION regress_priv_user1; + +CREATE TABLE atest5 (one int, two int unique, three int, four int unique); + +CREATE TABLE atest6 (one int, two int, blue int); + +GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regress_priv_user4; + +GRANT ALL (one) ON atest5 TO regress_priv_user3; + +SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 1)); + +SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 2)); + +SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 3)); + +SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 4)); + +INSERT INTO atest5 VALUES (1,2,3); + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT * FROM atest5; + +SELECT one FROM atest5; + +COPY atest5 (one) TO stdout; + +SELECT two FROM atest5; + +COPY atest5 (two) TO stdout; + +SELECT atest5 FROM atest5; + +COPY atest5 (one,two) TO stdout; + +SELECT 1 FROM atest5; + +SELECT 1 FROM atest5 a JOIN atest5 b USING (one); + +SELECT 1 FROM atest5 a JOIN atest5 b USING (two); + +SELECT 1 FROM atest5 a NATURAL JOIN atest5 b; + +SELECT * FROM (atest5 a JOIN atest5 b USING (one)) j; + +SELECT j.* FROM (atest5 a JOIN atest5 b USING (one)) j; + +SELECT (j.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) j; + +SELECT one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; + +SELECT j.one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; + +SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; + +SELECT j.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; + +SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; + +SELECT j.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; + +SELECT * FROM (atest5 a JOIN atest5 b USING (one)); + +SELECT a.* FROM (atest5 a JOIN atest5 b USING (one)); + +SELECT (a.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)); + +SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT a.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT b.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT b.y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT b.y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)); + +SELECT 1 FROM atest5 WHERE two = 2; + +SELECT * FROM atest1, atest5; + +SELECT atest1.* FROM atest1, atest5; + +SELECT atest1.*,atest5.one FROM atest1, atest5; + +SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.two); + +SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.one); + +SELECT one, two FROM atest5; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT SELECT (one,two) ON atest6 TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT one, two FROM atest5 NATURAL JOIN atest6; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT SELECT (two) ON atest5 TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT one, two FROM atest5 NATURAL JOIN atest6; + +INSERT INTO atest5 (two) VALUES (3); + +INSERT INTO atest5 (three) VALUES (4); + +INSERT INTO atest5 VALUES (5,5,5); + +UPDATE atest5 SET three = 10; + +UPDATE atest5 SET one = 8; + +UPDATE atest5 SET three = 5, one = 2; + +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10; + +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 RETURNING atest5.three; + +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 RETURNING atest5.one; + +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = EXCLUDED.one; + +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = EXCLUDED.three; + +INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set one = 8; + +INSERT INTO atest5(three) VALUES (4) ON CONFLICT (two) DO UPDATE set three = 10; + +INSERT INTO atest5(four) VALUES (4); + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT INSERT (four) ON atest5 TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +INSERT INTO atest5(four) VALUES (4) ON CONFLICT (four) DO UPDATE set three = 3; + +INSERT INTO atest5(four) VALUES (4) ON CONFLICT ON CONSTRAINT atest5_four_key DO UPDATE set three = 3; + +INSERT INTO atest5(four) VALUES (4); + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT SELECT (four) ON atest5 TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +INSERT INTO atest5(four) VALUES (4) ON CONFLICT (four) DO UPDATE set three = 3; + +INSERT INTO atest5(four) VALUES (4) ON CONFLICT ON CONSTRAINT atest5_four_key DO UPDATE set three = 3; + +SET SESSION AUTHORIZATION regress_priv_user1; + +REVOKE ALL (one) ON atest5 FROM regress_priv_user4; + +GRANT SELECT (one,two,blue) ON atest6 TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT one FROM atest5; + +UPDATE atest5 SET one = 1; + +SELECT atest6 FROM atest6; + +COPY atest6 TO stdout; + +SET SESSION AUTHORIZATION regress_priv_user1; + +CREATE TABLE mtarget (a int, b text); + +CREATE TABLE msource (a int, b text); + +INSERT INTO mtarget VALUES (1, 'init1'), (2, 'init2'); + +INSERT INTO msource VALUES (1, 'source1'), (2, 'source2'), (3, 'source3'); + +GRANT SELECT (a) ON msource TO regress_priv_user4; + +GRANT SELECT (a) ON mtarget TO regress_priv_user4; + +GRANT INSERT (a,b) ON mtarget TO regress_priv_user4; + +GRANT UPDATE (b) ON mtarget TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +BEGIN; + +ROLLBACK; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT SELECT (b) ON msource TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +BEGIN; + +ROLLBACK; + +BEGIN; + +ROLLBACK; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT DELETE ON mtarget TO regress_priv_user4; + +BEGIN; + +ROLLBACK; + +SET SESSION AUTHORIZATION regress_priv_user1; + +CREATE TABLE t1 (c1 int, c2 int, c3 int check (c3 < 5), primary key (c1, c2)); + +GRANT SELECT (c1) ON t1 TO regress_priv_user2; + +GRANT INSERT (c1, c2, c3) ON t1 TO regress_priv_user2; + +GRANT UPDATE (c1, c2, c3) ON t1 TO regress_priv_user2; + +INSERT INTO t1 VALUES (1, 1, 1); + +INSERT INTO t1 VALUES (1, 2, 1); + +INSERT INTO t1 VALUES (2, 1, 2); + +INSERT INTO t1 VALUES (2, 2, 2); + +INSERT INTO t1 VALUES (3, 1, 3); + +SET SESSION AUTHORIZATION regress_priv_user2; + +INSERT INTO t1 (c1, c2) VALUES (1, 1); + +UPDATE t1 SET c2 = 1; + +INSERT INTO t1 (c1, c2) VALUES (null, null); + +INSERT INTO t1 (c3) VALUES (null); + +INSERT INTO t1 (c1) VALUES (5); + +UPDATE t1 SET c3 = 10; + +SET SESSION AUTHORIZATION regress_priv_user1; + +DROP TABLE t1; + +CREATE TABLE errtst(a text, b text NOT NULL, c text, secret1 text, secret2 text) PARTITION BY LIST (a); + +CREATE TABLE errtst_part_1(secret2 text, c text, a text, b text NOT NULL, secret1 text); + +CREATE TABLE errtst_part_2(secret1 text, secret2 text, a text, c text, b text NOT NULL); + +ALTER TABLE errtst ATTACH PARTITION errtst_part_1 FOR VALUES IN ('aaa'); + +ALTER TABLE errtst ATTACH PARTITION errtst_part_2 FOR VALUES IN ('aaaa'); + +GRANT SELECT (a, b, c) ON TABLE errtst TO regress_priv_user2; + +GRANT UPDATE (a, b, c) ON TABLE errtst TO regress_priv_user2; + +GRANT INSERT (a, b, c) ON TABLE errtst TO regress_priv_user2; + +INSERT INTO errtst_part_1 (a, b, c, secret1, secret2) +VALUES ('aaa', 'bbb', 'ccc', 'the body', 'is in the attic'); + +SET SESSION AUTHORIZATION regress_priv_user2; + +INSERT INTO errtst (a, b) VALUES ('aaa', NULL); + +UPDATE errtst SET b = NULL; + +UPDATE errtst SET a = 'aaa', b = NULL; + +UPDATE errtst SET a = 'aaaa', b = NULL; + +UPDATE errtst SET a = 'aaaa', b = NULL WHERE a = 'aaa'; + +SET SESSION AUTHORIZATION regress_priv_user1; + +DROP TABLE errtst; + +SET SESSION AUTHORIZATION regress_priv_user1; + +ALTER TABLE atest6 ADD COLUMN three integer; + +GRANT DELETE ON atest5 TO regress_priv_user3; + +GRANT SELECT (two) ON atest5 TO regress_priv_user3; + +REVOKE ALL (one) ON atest5 FROM regress_priv_user3; + +GRANT SELECT (one) ON atest5 TO regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT atest6 FROM atest6; + +SELECT one FROM atest5 NATURAL JOIN atest6; + +SET SESSION AUTHORIZATION regress_priv_user1; + +ALTER TABLE atest6 DROP COLUMN three; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT atest6 FROM atest6; + +SELECT one FROM atest5 NATURAL JOIN atest6; + +SET SESSION AUTHORIZATION regress_priv_user1; + +ALTER TABLE atest6 DROP COLUMN two; + +REVOKE SELECT (one,blue) ON atest6 FROM regress_priv_user4; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT * FROM atest6; + +SELECT 1 FROM atest6; + +SET SESSION AUTHORIZATION regress_priv_user3; + +DELETE FROM atest5 WHERE one = 1; + +DELETE FROM atest5 WHERE two = 2; + +SET SESSION AUTHORIZATION regress_priv_user1; + +CREATE TABLE atestp1 (f1 int, f2 int); + +CREATE TABLE atestp2 (fx int, fy int); + +CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2); + +GRANT SELECT(fx,fy,tableoid) ON atestp2 TO regress_priv_user2; + +GRANT SELECT(fx) ON atestc TO regress_priv_user2; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT fx FROM atestp2; + +SELECT fy FROM atestp2; + +SELECT atestp2 FROM atestp2; + +SELECT tableoid FROM atestp2; + +SELECT fy FROM atestc; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT SELECT(fy,tableoid) ON atestc TO regress_priv_user2; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT fx FROM atestp2; + +SELECT fy FROM atestp2; + +SELECT atestp2 FROM atestp2; + +SELECT tableoid FROM atestp2; + +SET SESSION AUTHORIZATION regress_priv_user1; + +REVOKE ALL ON atestc FROM regress_priv_user2; + +GRANT ALL ON atestp1 TO regress_priv_user2; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT f2 FROM atestp1; + +SELECT f2 FROM atestc; + +DELETE FROM atestp1; + +DELETE FROM atestc; + +UPDATE atestp1 SET f1 = 1; + +UPDATE atestc SET f1 = 1; + +TRUNCATE atestp1; + +TRUNCATE atestc; + +BEGIN; + +LOCK atestp1; + +END; + +BEGIN; + +LOCK atestc; + +END; + +REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC; + +GRANT USAGE ON LANGUAGE sql TO regress_priv_user1; + +GRANT USAGE ON LANGUAGE c TO PUBLIC; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT USAGE ON LANGUAGE sql TO regress_priv_user2; + +CREATE FUNCTION priv_testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; + +CREATE FUNCTION priv_testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql; + +CREATE AGGREGATE priv_testagg1(int) (sfunc = int4pl, stype = int4); + +CREATE PROCEDURE priv_testproc1(int) AS 'select $1;' LANGUAGE sql; + +REVOKE ALL ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) FROM PUBLIC; + +GRANT EXECUTE ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) TO regress_priv_user2; + +REVOKE ALL ON FUNCTION priv_testproc1(int) FROM PUBLIC; + +REVOKE ALL ON PROCEDURE priv_testproc1(int) FROM PUBLIC; + +GRANT EXECUTE ON PROCEDURE priv_testproc1(int) TO regress_priv_user2; + +GRANT USAGE ON FUNCTION priv_testfunc1(int) TO regress_priv_user3; + +GRANT USAGE ON FUNCTION priv_testagg1(int) TO regress_priv_user3; + +GRANT USAGE ON PROCEDURE priv_testproc1(int) TO regress_priv_user3; + +GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc1(int) TO regress_priv_user4; + +GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc_nosuch(int) TO regress_priv_user4; + +GRANT ALL PRIVILEGES ON FUNCTION priv_testagg1(int) TO regress_priv_user4; + +GRANT ALL PRIVILEGES ON PROCEDURE priv_testproc1(int) TO regress_priv_user4; + +CREATE FUNCTION priv_testfunc4(boolean) RETURNS text + AS 'select col1 from atest2 where col2 = $1;' + LANGUAGE sql SECURITY DEFINER; + +GRANT EXECUTE ON FUNCTION priv_testfunc4(boolean) TO regress_priv_user3; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT priv_testfunc1(5), priv_testfunc2(5); + +CREATE FUNCTION priv_testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; + +SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); + +CALL priv_testproc1(6); + +SET SESSION AUTHORIZATION regress_priv_user3; + +SELECT priv_testfunc1(5); + +SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); + +CALL priv_testproc1(6); + +SELECT col1 FROM atest2 WHERE col2 = true; + +SELECT priv_testfunc4(true); + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT priv_testfunc1(5); + +SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); + +CALL priv_testproc1(6); + +DROP FUNCTION priv_testfunc1(int); + +DROP AGGREGATE priv_testagg1(int); + +DROP PROCEDURE priv_testproc1(int); + +DROP FUNCTION priv_testfunc1(int); + +GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC; + +BEGIN; + +SELECT '{1}'::int4[]::int8[]; + +REVOKE ALL ON FUNCTION int8(integer) FROM PUBLIC; + +SELECT '{1}'::int4[]::int8[]; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT '{1}'::int4[]::int8[]; + +ROLLBACK; + +CREATE TYPE priv_testtype1 AS (a int, b text); + +REVOKE USAGE ON TYPE priv_testtype1 FROM PUBLIC; + +GRANT USAGE ON TYPE priv_testtype1 TO regress_priv_user2; + +GRANT USAGE ON TYPE _priv_testtype1 TO regress_priv_user2; + +GRANT USAGE ON DOMAIN priv_testtype1 TO regress_priv_user2; + +CREATE DOMAIN priv_testdomain1 AS int; + +REVOKE USAGE on DOMAIN priv_testdomain1 FROM PUBLIC; + +GRANT USAGE ON DOMAIN priv_testdomain1 TO regress_priv_user2; + +GRANT USAGE ON TYPE priv_testdomain1 TO regress_priv_user2; + +SET SESSION AUTHORIZATION regress_priv_user1; + +CREATE AGGREGATE priv_testagg1a(priv_testdomain1) (sfunc = int4_sum, stype = bigint); + +CREATE DOMAIN priv_testdomain2a AS priv_testdomain1; + +CREATE DOMAIN priv_testdomain3a AS int; + +CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3a AS $$ SELECT $1::priv_testdomain3a $$ LANGUAGE SQL; + +CREATE CAST (priv_testdomain1 AS priv_testdomain3a) WITH FUNCTION castfunc(int); + +DROP FUNCTION castfunc(int) CASCADE; + +DROP DOMAIN priv_testdomain3a; + +CREATE FUNCTION priv_testfunc5a(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; + +CREATE FUNCTION priv_testfunc6a(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$; + +CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = priv_testdomain1, RIGHTARG = priv_testdomain1); + +CREATE TABLE test5a (a int, b priv_testdomain1); + +CREATE TABLE test6a OF priv_testtype1; + +CREATE TABLE test10a (a int[], b priv_testtype1[]); + +CREATE TABLE test9a (a int, b int); + +ALTER TABLE test9a ADD COLUMN c priv_testdomain1; + +ALTER TABLE test9a ALTER COLUMN b TYPE priv_testdomain1; + +CREATE TYPE test7a AS (a int, b priv_testdomain1); + +CREATE TYPE test8a AS (a int, b int); + +ALTER TYPE test8a ADD ATTRIBUTE c priv_testdomain1; + +ALTER TYPE test8a ALTER ATTRIBUTE b TYPE priv_testdomain1; + +CREATE TABLE test11a AS (SELECT 1::priv_testdomain1 AS a); + +REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC; + +SET SESSION AUTHORIZATION regress_priv_user2; + +CREATE AGGREGATE priv_testagg1b(priv_testdomain1) (sfunc = int4_sum, stype = bigint); + +CREATE DOMAIN priv_testdomain2b AS priv_testdomain1; + +CREATE DOMAIN priv_testdomain3b AS int; + +CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3b AS $$ SELECT $1::priv_testdomain3b $$ LANGUAGE SQL; + +CREATE CAST (priv_testdomain1 AS priv_testdomain3b) WITH FUNCTION castfunc(int); + +CREATE FUNCTION priv_testfunc5b(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; + +CREATE FUNCTION priv_testfunc6b(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$; + +CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1); + +CREATE TABLE test5b (a int, b priv_testdomain1); + +CREATE TABLE test6b OF priv_testtype1; + +CREATE TABLE test10b (a int[], b priv_testtype1[]); + +CREATE TABLE test9b (a int, b int); + +ALTER TABLE test9b ADD COLUMN c priv_testdomain1; + +ALTER TABLE test9b ALTER COLUMN b TYPE priv_testdomain1; + +CREATE TYPE test7b AS (a int, b priv_testdomain1); + +CREATE TYPE test8b AS (a int, b int); + +ALTER TYPE test8b ADD ATTRIBUTE c priv_testdomain1; + +ALTER TYPE test8b ALTER ATTRIBUTE b TYPE priv_testdomain1; + +CREATE TABLE test11b AS (SELECT 1::priv_testdomain1 AS a); + +REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC; + +DROP AGGREGATE priv_testagg1b(priv_testdomain1); + +DROP DOMAIN priv_testdomain2b; + +DROP OPERATOR !! (NONE, priv_testdomain1); + +DROP FUNCTION priv_testfunc5b(a priv_testdomain1); + +DROP FUNCTION priv_testfunc6b(b int); + +DROP TABLE test5b; + +DROP TABLE test6b; + +DROP TABLE test9b; + +DROP TABLE test10b; + +DROP TYPE test7b; + +DROP TYPE test8b; + +DROP CAST (priv_testdomain1 AS priv_testdomain3b); + +DROP FUNCTION castfunc(int) CASCADE; + +DROP DOMAIN priv_testdomain3b; + +DROP TABLE test11b; + +DROP TYPE priv_testtype1; + +DROP DOMAIN priv_testdomain1; + +SET SESSION AUTHORIZATION regress_priv_user5; + +TRUNCATE atest2; + +TRUNCATE atest3; + +select has_table_privilege(NULL,'pg_authid','select'); + +select has_table_privilege('pg_shad','select'); + +select has_table_privilege('nosuchuser','pg_authid','select'); + +select has_table_privilege('pg_authid','sel'); + +select has_table_privilege(-999999,'pg_authid','update'); + +select has_table_privilege(1,'select'); + +select has_table_privilege(current_user,'pg_authid','select'); + +select has_table_privilege(current_user,'pg_authid','insert'); + +select has_table_privilege(t2.oid,'pg_authid','update') +from (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(t2.oid,'pg_authid','delete') +from (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(current_user,t1.oid,'references') +from (select oid from pg_class where relname = 'pg_authid') as t1; + +select has_table_privilege(t2.oid,t1.oid,'select') +from (select oid from pg_class where relname = 'pg_authid') as t1, + (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(t2.oid,t1.oid,'insert') +from (select oid from pg_class where relname = 'pg_authid') as t1, + (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege('pg_authid','update'); + +select has_table_privilege('pg_authid','delete'); + +select has_table_privilege('pg_authid','truncate'); + +select has_table_privilege(t1.oid,'select') +from (select oid from pg_class where relname = 'pg_authid') as t1; + +select has_table_privilege(t1.oid,'trigger') +from (select oid from pg_class where relname = 'pg_authid') as t1; + +SET SESSION AUTHORIZATION regress_priv_user3; + +select has_table_privilege(current_user,'pg_class','select'); + +select has_table_privilege(current_user,'pg_class','insert'); + +select has_table_privilege(t2.oid,'pg_class','update') +from (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(t2.oid,'pg_class','delete') +from (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(current_user,t1.oid,'references') +from (select oid from pg_class where relname = 'pg_class') as t1; + +select has_table_privilege(t2.oid,t1.oid,'select') +from (select oid from pg_class where relname = 'pg_class') as t1, + (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(t2.oid,t1.oid,'insert') +from (select oid from pg_class where relname = 'pg_class') as t1, + (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege('pg_class','update'); + +select has_table_privilege('pg_class','delete'); + +select has_table_privilege('pg_class','truncate'); + +select has_table_privilege(t1.oid,'select') +from (select oid from pg_class where relname = 'pg_class') as t1; + +select has_table_privilege(t1.oid,'trigger') +from (select oid from pg_class where relname = 'pg_class') as t1; + +select has_table_privilege(current_user,'atest1','select'); + +select has_table_privilege(current_user,'atest1','insert'); + +select has_table_privilege(t2.oid,'atest1','update') +from (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(t2.oid,'atest1','delete') +from (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(current_user,t1.oid,'references') +from (select oid from pg_class where relname = 'atest1') as t1; + +select has_table_privilege(t2.oid,t1.oid,'select') +from (select oid from pg_class where relname = 'atest1') as t1, + (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege(t2.oid,t1.oid,'insert') +from (select oid from pg_class where relname = 'atest1') as t1, + (select oid from pg_roles where rolname = current_user) as t2; + +select has_table_privilege('atest1','update'); + +select has_table_privilege('atest1','delete'); + +select has_table_privilege('atest1','truncate'); + +select has_table_privilege(t1.oid,'select') +from (select oid from pg_class where relname = 'atest1') as t1; + +select has_table_privilege(t1.oid,'trigger') +from (select oid from pg_class where relname = 'atest1') as t1; + +select has_column_privilege('pg_authid',NULL,'select'); + +select has_column_privilege('pg_authid','nosuchcol','select'); + +select has_column_privilege(9999,'nosuchcol','select'); + +select has_column_privilege(9999,99::int2,'select'); + +select has_column_privilege('pg_authid',99::int2,'select'); + +select has_column_privilege(9999,99::int2,'select'); + +create temp table mytable(f1 int, f2 int, f3 int); + +alter table mytable drop column f2; + +select has_column_privilege('mytable','f2','select'); + +select has_column_privilege('mytable','........pg.dropped.2........','select'); + +select has_column_privilege('mytable',2::int2,'select'); + +select has_column_privilege('mytable',99::int2,'select'); + +revoke select on table mytable from regress_priv_user3; + +select has_column_privilege('mytable',2::int2,'select'); + +select has_column_privilege('mytable',99::int2,'select'); + +drop table mytable; + +SET SESSION AUTHORIZATION regress_priv_user1; + +CREATE TABLE atest4 (a int); + +GRANT SELECT ON atest4 TO regress_priv_user2 WITH GRANT OPTION; + +GRANT UPDATE ON atest4 TO regress_priv_user2; + +GRANT SELECT ON atest4 TO GROUP regress_priv_group1 WITH GRANT OPTION; + +SET SESSION AUTHORIZATION regress_priv_user2; + +GRANT SELECT ON atest4 TO regress_priv_user3; + +GRANT UPDATE ON atest4 TO regress_priv_user3; + +SET SESSION AUTHORIZATION regress_priv_user1; + +REVOKE SELECT ON atest4 FROM regress_priv_user3; + +SELECT has_table_privilege('regress_priv_user3', 'atest4', 'SELECT'); + +REVOKE SELECT ON atest4 FROM regress_priv_user2; + +REVOKE GRANT OPTION FOR SELECT ON atest4 FROM regress_priv_user2 CASCADE; + +SELECT has_table_privilege('regress_priv_user2', 'atest4', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user3', 'atest4', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'atest4', 'SELECT WITH GRANT OPTION'); + +CREATE ROLE regress_sro_user; + +CREATE FUNCTION sro_ifun(int) RETURNS int AS $$ +BEGIN + -- Below we set the table's owner to regress_sro_user + ASSERT current_user = 'regress_sro_user', + format('sro_ifun(%s) called by %s', $1, current_user); + RETURN $1; +END; +$$ LANGUAGE plpgsql IMMUTABLE; + +CREATE TABLE sro_tab (a int); + +ALTER TABLE sro_tab OWNER TO regress_sro_user; + +INSERT INTO sro_tab VALUES (1), (2), (3); + +CREATE INDEX sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) + WHERE sro_ifun(a + 10) > sro_ifun(10); + +DROP INDEX sro_idx; + +CREATE INDEX CONCURRENTLY sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))) + WHERE sro_ifun(a + 10) > sro_ifun(10); + +REINDEX TABLE sro_tab; + +REINDEX INDEX sro_idx; + +REINDEX TABLE CONCURRENTLY sro_tab; + +DROP INDEX sro_idx; + +CREATE INDEX sro_cluster_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0))); + +CLUSTER sro_tab USING sro_cluster_idx; + +DROP INDEX sro_cluster_idx; + +CREATE INDEX sro_brin ON sro_tab USING brin ((sro_ifun(a) + sro_ifun(0))); + +SELECT brin_desummarize_range('sro_brin', 0); + +SELECT brin_summarize_range('sro_brin', 0); + +DROP TABLE sro_tab; + +CREATE TABLE sro_ptab (a int) PARTITION BY RANGE (a); + +ALTER TABLE sro_ptab OWNER TO regress_sro_user; + +CREATE TABLE sro_part PARTITION OF sro_ptab FOR VALUES FROM (1) TO (10); + +ALTER TABLE sro_part OWNER TO regress_sro_user; + +INSERT INTO sro_ptab VALUES (1), (2), (3); + +CREATE INDEX sro_pidx ON sro_ptab ((sro_ifun(a) + sro_ifun(0))) + WHERE sro_ifun(a + 10) > sro_ifun(10); + +REINDEX TABLE sro_ptab; + +REINDEX INDEX CONCURRENTLY sro_pidx; + +SET SESSION AUTHORIZATION regress_sro_user; + +CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS + 'GRANT regress_priv_group2 TO regress_sro_user'; + +CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS + 'DECLARE c CURSOR WITH HOLD FOR SELECT public.unwanted_grant(); SELECT true'; + +CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA; + +REFRESH MATERIALIZED VIEW sro_mv; + +REFRESH MATERIALIZED VIEW sro_mv; + +SET SESSION AUTHORIZATION regress_sro_user; + +CREATE TABLE sro_trojan_table (); + +CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS + 'BEGIN PERFORM public.unwanted_grant(); RETURN NULL; END'; + +CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table + INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan(); + +CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS + 'INSERT INTO public.sro_trojan_table DEFAULT VALUES; SELECT true'; + +REFRESH MATERIALIZED VIEW sro_mv; + +REFRESH MATERIALIZED VIEW sro_mv; + +BEGIN; + +SET CONSTRAINTS ALL IMMEDIATE; + +REFRESH MATERIALIZED VIEW sro_mv; + +COMMIT; + +SET SESSION AUTHORIZATION regress_sro_user; + +CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int + IMMUTABLE LANGUAGE plpgsql AS $$ +BEGIN + PERFORM public.unwanted_grant(); + RAISE WARNING 'owned'; + RETURN 1; +EXCEPTION WHEN OTHERS THEN + RETURN 2; +END$$; + +CREATE MATERIALIZED VIEW sro_index_mv AS SELECT 1 AS c; + +CREATE UNIQUE INDEX ON sro_index_mv (c) WHERE unwanted_grant_nofail(1) > 0; + +REFRESH MATERIALIZED VIEW CONCURRENTLY sro_index_mv; + +REFRESH MATERIALIZED VIEW sro_index_mv; + +DROP OWNED BY regress_sro_user; + +DROP ROLE regress_sro_user; + +SET SESSION AUTHORIZATION regress_priv_user4; + +CREATE FUNCTION dogrant_ok() RETURNS void LANGUAGE sql SECURITY DEFINER AS + 'GRANT regress_priv_group2 TO regress_priv_user5'; + +GRANT regress_priv_group2 TO regress_priv_user5; + +SET ROLE regress_priv_group2; + +GRANT regress_priv_group2 TO regress_priv_user5; + +SET SESSION AUTHORIZATION regress_priv_user1; + +GRANT regress_priv_group2 TO regress_priv_user5; + +SELECT dogrant_ok(); + +SET ROLE regress_priv_group2; + +GRANT regress_priv_group2 TO regress_priv_user5; + +SET SESSION AUTHORIZATION regress_priv_group2; + +GRANT regress_priv_group2 TO regress_priv_user5; + +SET SESSION AUTHORIZATION regress_priv_user4; + +DROP FUNCTION dogrant_ok(); + +REVOKE regress_priv_group2 FROM regress_priv_user5; + +CREATE SEQUENCE x_seq; + +GRANT USAGE on x_seq to regress_priv_user2; + +SELECT has_sequence_privilege('regress_priv_user1', 'atest1', 'SELECT'); + +SELECT has_sequence_privilege('regress_priv_user1', 'x_seq', 'INSERT'); + +SELECT has_sequence_privilege('regress_priv_user1', 'x_seq', 'SELECT'); + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT has_sequence_privilege('x_seq', 'USAGE'); + +SET SESSION AUTHORIZATION regress_priv_user1; + +SELECT lo_create(1001); + +SELECT lo_create(1002); + +SELECT lo_create(1003); + +SELECT lo_create(1004); + +SELECT lo_create(1005); + +GRANT ALL ON LARGE OBJECT 1001 TO PUBLIC; + +GRANT SELECT ON LARGE OBJECT 1003 TO regress_priv_user2; + +GRANT SELECT,UPDATE ON LARGE OBJECT 1004 TO regress_priv_user2; + +GRANT ALL ON LARGE OBJECT 1005 TO regress_priv_user2; + +GRANT SELECT ON LARGE OBJECT 1005 TO regress_priv_user2 WITH GRANT OPTION; + +GRANT SELECT, INSERT ON LARGE OBJECT 1001 TO PUBLIC; + +GRANT SELECT, UPDATE ON LARGE OBJECT 1001 TO nosuchuser; + +GRANT SELECT, UPDATE ON LARGE OBJECT 999 TO PUBLIC; + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT lo_create(2001); + +SELECT lo_create(2002); + +SELECT loread(lo_open(1001, x'20000'::int), 32); + +SELECT lowrite(lo_open(1001, x'40000'::int), 'abcd'); + +SELECT loread(lo_open(1001, x'40000'::int), 32); + +SELECT loread(lo_open(1002, x'40000'::int), 32); + +SELECT loread(lo_open(1003, x'40000'::int), 32); + +SELECT loread(lo_open(1004, x'40000'::int), 32); + +SELECT lowrite(lo_open(1001, x'20000'::int), 'abcd'); + +SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); + +SELECT lowrite(lo_open(1003, x'20000'::int), 'abcd'); + +SELECT lowrite(lo_open(1004, x'20000'::int), 'abcd'); + +GRANT SELECT ON LARGE OBJECT 1005 TO regress_priv_user3; + +GRANT UPDATE ON LARGE OBJECT 1006 TO regress_priv_user3; + +REVOKE ALL ON LARGE OBJECT 2001, 2002 FROM PUBLIC; + +GRANT ALL ON LARGE OBJECT 2001 TO regress_priv_user3; + +SELECT lo_unlink(1001); + +SELECT lo_unlink(2002); + +SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid; + +SET SESSION AUTHORIZATION regress_priv_user3; + +SELECT loread(lo_open(1001, x'40000'::int), 32); + +SELECT loread(lo_open(1003, x'40000'::int), 32); + +SELECT loread(lo_open(1005, x'40000'::int), 32); + +SELECT lo_truncate(lo_open(1005, x'20000'::int), 10); + +SELECT lo_truncate(lo_open(2001, x'20000'::int), 10); + +SELECT has_largeobject_privilege(1001, 'SELECT'); + +SELECT has_largeobject_privilege(1002, 'SELECT'); + +SELECT has_largeobject_privilege(1003, 'SELECT'); + +SELECT has_largeobject_privilege(1004, 'SELECT'); + +SELECT has_largeobject_privilege(1001, 'UPDATE'); + +SELECT has_largeobject_privilege(1002, 'UPDATE'); + +SELECT has_largeobject_privilege(1003, 'UPDATE'); + +SELECT has_largeobject_privilege(1004, 'UPDATE'); + +SELECT has_largeobject_privilege(9999, 'SELECT'); + +SET SESSION AUTHORIZATION regress_priv_user2; + +SELECT has_largeobject_privilege(1001, 'SELECT'); + +SELECT has_largeobject_privilege(1002, 'SELECT'); + +SELECT has_largeobject_privilege(1003, 'SELECT'); + +SELECT has_largeobject_privilege(1004, 'SELECT'); + +SELECT has_largeobject_privilege(1001, 'UPDATE'); + +SELECT has_largeobject_privilege(1002, 'UPDATE'); + +SELECT has_largeobject_privilege(1003, 'UPDATE'); + +SELECT has_largeobject_privilege(1004, 'UPDATE'); + +SELECT has_largeobject_privilege('regress_priv_user3', 1001, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user3', 1003, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user3', 1005, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user3', 1005, 'UPDATE'); + +SELECT has_largeobject_privilege('regress_priv_user3', 2001, 'UPDATE'); + +SET lo_compat_privileges = false; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT has_largeobject_privilege(1002, 'SELECT'); + +SELECT has_largeobject_privilege(1002, 'UPDATE'); + +SELECT loread(lo_open(1002, x'40000'::int), 32); + +SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); + +SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); + +SELECT lo_put(1002, 1, 'abcd'); + +SELECT lo_unlink(1002); + +SELECT lo_export(1001, '/dev/null'); + +SELECT lo_import('/dev/null'); + +SELECT lo_import('/dev/null', 2003); + +SET lo_compat_privileges = true; + +SET SESSION AUTHORIZATION regress_priv_user4; + +SELECT has_largeobject_privilege(1002, 'SELECT'); + +SELECT has_largeobject_privilege(1002, 'UPDATE'); + +SELECT loread(lo_open(1002, x'40000'::int), 32); + +SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); + +SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); + +SELECT lo_unlink(1002); + +SELECT lo_export(1001, '/dev/null'); + +SELECT * FROM pg_largeobject LIMIT 0; + +SET SESSION AUTHORIZATION regress_priv_user1; + +SELECT * FROM pg_largeobject LIMIT 0; + +RESET SESSION AUTHORIZATION; + +BEGIN; + +CREATE OR REPLACE FUNCTION terminate_nothrow(pid int) RETURNS bool + LANGUAGE plpgsql SECURITY DEFINER SET client_min_messages = error AS $$ +BEGIN + RETURN pg_terminate_backend($1); +EXCEPTION WHEN OTHERS THEN + RETURN false; +END$$; + +ALTER FUNCTION terminate_nothrow OWNER TO pg_signal_backend; + +SELECT backend_type FROM pg_stat_activity +WHERE CASE WHEN COALESCE(usesysid, 10) = 10 THEN terminate_nothrow(pid) END; + +ROLLBACK; + +RESET SESSION AUTHORIZATION; + +GRANT pg_database_owner TO regress_priv_user1; + +GRANT regress_priv_user1 TO pg_database_owner; + +CREATE TABLE datdba_only (); + +ALTER TABLE datdba_only OWNER TO pg_database_owner; + +REVOKE DELETE ON datdba_only FROM pg_database_owner; + +SELECT + pg_has_role('regress_priv_user1', 'pg_database_owner', 'USAGE') as priv, + pg_has_role('regress_priv_user1', 'pg_database_owner', 'MEMBER') as mem, + pg_has_role('regress_priv_user1', 'pg_database_owner', + 'MEMBER WITH ADMIN OPTION') as admin; + +BEGIN; + +DO $$BEGIN EXECUTE format( + 'ALTER DATABASE %I OWNER TO regress_priv_group2', current_catalog); END$$; + +SELECT + pg_has_role('regress_priv_user1', 'pg_database_owner', 'USAGE') as priv, + pg_has_role('regress_priv_user1', 'pg_database_owner', 'MEMBER') as mem, + pg_has_role('regress_priv_user1', 'pg_database_owner', + 'MEMBER WITH ADMIN OPTION') as admin; + +SET SESSION AUTHORIZATION regress_priv_user1; + +TABLE information_schema.enabled_roles ORDER BY role_name COLLATE "C"; + +TABLE information_schema.applicable_roles ORDER BY role_name COLLATE "C"; + +INSERT INTO datdba_only DEFAULT VALUES; + +SAVEPOINT q; + +DELETE FROM datdba_only; + +ROLLBACK TO q; + +SET SESSION AUTHORIZATION regress_priv_user2; + +TABLE information_schema.enabled_roles; + +INSERT INTO datdba_only DEFAULT VALUES; + +ROLLBACK; + +CREATE SCHEMA testns; + +GRANT ALL ON SCHEMA testns TO regress_priv_user1; + +CREATE TABLE testns.acltest1 (x int); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns,testns GRANT SELECT ON TABLES TO public,public; + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); + +DROP TABLE testns.acltest1; + +CREATE TABLE testns.acltest1 (x int); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT INSERT ON TABLES TO regress_priv_user1; + +DROP TABLE testns.acltest1; + +CREATE TABLE testns.acltest1 (x int); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns REVOKE INSERT ON TABLES FROM regress_priv_user1; + +DROP TABLE testns.acltest1; + +CREATE TABLE testns.acltest1 (x int); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); + +ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE EXECUTE ON FUNCTIONS FROM public; + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_priv_user2; + +SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole, + 'SELECT', TRUE); + +SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole, + 'SELECT, INSERT, UPDATE , DELETE ', FALSE); + +SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole, + 'SELECT, fake_privilege', FALSE); + +CREATE ROLE "regress_""quoted"; + +SELECT makeaclitem('regress_"quoted'::regrole, 'regress_"quoted'::regrole, + 'SELECT', TRUE); + +SELECT '"regress_""quoted"=r*/"regress_""quoted"'::aclitem; + +SELECT '""=r*/""'::aclitem; + +DROP ROLE "regress_""quoted"; + +SELECT pg_input_is_valid('regress_priv_user1=r/regress_priv_user2', 'aclitem'); + +SELECT pg_input_is_valid('regress_priv_user1=r/', 'aclitem'); + +SELECT * FROM pg_input_error_info('regress_priv_user1=r/', 'aclitem'); + +SELECT pg_input_is_valid('regress_priv_user1=r/regress_no_such_user', 'aclitem'); + +SELECT * FROM pg_input_error_info('regress_priv_user1=r/regress_no_such_user', 'aclitem'); + +SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem'); + +SELECT * FROM pg_input_error_info('regress_priv_user1=rY', 'aclitem'); + +BEGIN; + +ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO regress_priv_user2; + +CREATE SCHEMA testns2; + +SELECT has_schema_privilege('regress_priv_user2', 'testns2', 'USAGE'); + +SELECT has_schema_privilege('regress_priv_user6', 'testns2', 'USAGE'); + +SELECT has_schema_privilege('regress_priv_user2', 'testns2', 'CREATE'); + +ALTER DEFAULT PRIVILEGES REVOKE USAGE ON SCHEMAS FROM regress_priv_user2; + +CREATE SCHEMA testns3; + +SELECT has_schema_privilege('regress_priv_user2', 'testns3', 'USAGE'); + +SELECT has_schema_privilege('regress_priv_user2', 'testns3', 'CREATE'); + +ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2; + +CREATE SCHEMA testns4; + +SELECT has_schema_privilege('regress_priv_user2', 'testns4', 'USAGE'); + +SELECT has_schema_privilege('regress_priv_user2', 'testns4', 'CREATE'); + +ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_priv_user2; + +COMMIT; + +BEGIN; + +SELECT lo_create(1007); + +SELECT has_largeobject_privilege('regress_priv_user2', 1007, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user2', 1007, 'UPDATE'); + +SELECT lo_create(1008); + +SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user6', 1008, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'UPDATE'); + +SELECT lo_create(1009); + +SELECT has_largeobject_privilege('regress_priv_user2', 1009, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user2', 1009, 'UPDATE'); + +SELECT lo_create(1010); + +SELECT has_largeobject_privilege('regress_priv_user2', 1010, 'SELECT'); + +SELECT has_largeobject_privilege('regress_priv_user2', 1010, 'UPDATE'); + +ROLLBACK; + +BEGIN; + +ALTER DEFAULT PRIVILEGES GRANT ALL ON FUNCTIONS TO regress_priv_user2; + +ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2; + +ALTER DEFAULT PRIVILEGES GRANT ALL ON SEQUENCES TO regress_priv_user2; + +ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES TO regress_priv_user2; + +ALTER DEFAULT PRIVILEGES GRANT ALL ON TYPES TO regress_priv_user2; + +SELECT count(*) FROM pg_shdepend + WHERE deptype = 'a' AND + refobjid = 'regress_priv_user2'::regrole AND + classid = 'pg_default_acl'::regclass; + +DROP OWNED BY regress_priv_user2, regress_priv_user2; + +SELECT count(*) FROM pg_shdepend + WHERE deptype = 'a' AND + refobjid = 'regress_priv_user2'::regrole AND + classid = 'pg_default_acl'::regclass; + +ROLLBACK; + +CREATE SCHEMA testns5; + +SELECT has_schema_privilege('regress_priv_user2', 'testns5', 'USAGE'); + +SELECT has_schema_privilege('regress_priv_user2', 'testns5', 'CREATE'); + +SET ROLE regress_priv_user1; + +CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql; + +CREATE AGGREGATE testns.agg1(int) (sfunc = int4pl, stype = int4); + +CREATE PROCEDURE testns.bar() AS 'select 1' LANGUAGE sql; + +SELECT has_function_privilege('regress_priv_user2', 'testns.foo()', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user2', 'testns.agg1(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user2', 'testns.bar()', 'EXECUTE'); + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT EXECUTE ON ROUTINES to public; + +DROP FUNCTION testns.foo(); + +CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql; + +DROP AGGREGATE testns.agg1(int); + +CREATE AGGREGATE testns.agg1(int) (sfunc = int4pl, stype = int4); + +DROP PROCEDURE testns.bar(); + +CREATE PROCEDURE testns.bar() AS 'select 1' LANGUAGE sql; + +SELECT has_function_privilege('regress_priv_user2', 'testns.foo()', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user2', 'testns.agg1(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user2', 'testns.bar()', 'EXECUTE'); + +DROP FUNCTION testns.foo(); + +DROP AGGREGATE testns.agg1(int); + +DROP PROCEDURE testns.bar(); + +ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE USAGE ON TYPES FROM public; + +CREATE DOMAIN testns.priv_testdomain1 AS int; + +SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public; + +DROP DOMAIN testns.priv_testdomain1; + +CREATE DOMAIN testns.priv_testdomain1 AS int; + +SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); + +DROP DOMAIN testns.priv_testdomain1; + +RESET ROLE; + +SELECT count(*) + FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid + WHERE nspname = 'testns'; + +DROP SCHEMA testns CASCADE; + +DROP SCHEMA testns2 CASCADE; + +DROP SCHEMA testns3 CASCADE; + +DROP SCHEMA testns4 CASCADE; + +DROP SCHEMA testns5 CASCADE; + +SELECT d.* -- check that entries went away + FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid + WHERE nspname IS NULL AND defaclnamespace != 0; + +CREATE SCHEMA testns; + +CREATE TABLE testns.t1 (f1 int); + +CREATE TABLE testns.t2 (f1 int); + +SELECT has_table_privilege('regress_priv_user1', 'testns.t1', 'SELECT'); + +GRANT ALL ON ALL TABLES IN SCHEMA testns TO regress_priv_user1; + +SELECT has_table_privilege('regress_priv_user1', 'testns.t1', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'testns.t2', 'SELECT'); + +REVOKE ALL ON ALL TABLES IN SCHEMA testns FROM regress_priv_user1; + +SELECT has_table_privilege('regress_priv_user1', 'testns.t1', 'SELECT'); + +SELECT has_table_privilege('regress_priv_user1', 'testns.t2', 'SELECT'); + +CREATE FUNCTION testns.priv_testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql; + +CREATE AGGREGATE testns.priv_testagg(int) (sfunc = int4pl, stype = int4); + +CREATE PROCEDURE testns.priv_testproc(int) AS 'select 3' LANGUAGE sql; + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); + +REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC; + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); + +REVOKE ALL ON ALL PROCEDURES IN SCHEMA testns FROM PUBLIC; + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); + +GRANT ALL ON ALL ROUTINES IN SCHEMA testns TO PUBLIC; + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); + +SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); + +DROP SCHEMA testns CASCADE; + +CREATE ROLE regress_schemauser1 superuser login; + +CREATE ROLE regress_schemauser2 superuser login; + +SET SESSION ROLE regress_schemauser1; + +CREATE SCHEMA testns; + +SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = 'testns' AND pg_namespace.nspowner = pg_roles.oid; + +ALTER SCHEMA testns OWNER TO regress_schemauser2; + +ALTER ROLE regress_schemauser2 RENAME TO regress_schemauser_renamed; + +SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = 'testns' AND pg_namespace.nspowner = pg_roles.oid; + +set session role regress_schemauser_renamed; + +DROP SCHEMA testns CASCADE; + +DROP ROLE regress_schemauser1; + +DROP ROLE regress_schemauser_renamed; + +set session role regress_priv_user1; + +create table dep_priv_test (a int); + +grant select on dep_priv_test to regress_priv_user2 with grant option; + +grant select on dep_priv_test to regress_priv_user3 with grant option; + +set session role regress_priv_user2; + +grant select on dep_priv_test to regress_priv_user4 with grant option; + +set session role regress_priv_user3; + +grant select on dep_priv_test to regress_priv_user4 with grant option; + +set session role regress_priv_user4; + +grant select on dep_priv_test to regress_priv_user5; + +set session role regress_priv_user2; + +revoke select on dep_priv_test from regress_priv_user4 cascade; + +set session role regress_priv_user3; + +revoke select on dep_priv_test from regress_priv_user4 cascade; + +set session role regress_priv_user1; + +drop table dep_priv_test; + +drop sequence x_seq; + +DROP AGGREGATE priv_testagg1(int); + +DROP FUNCTION priv_testfunc2(int); + +DROP FUNCTION priv_testfunc4(boolean); + +DROP PROCEDURE priv_testproc1(int); + +DROP VIEW atestv0; + +DROP VIEW atestv1; + +DROP VIEW atestv2; + +DROP VIEW atestv3 CASCADE; + +DROP VIEW atestv4; + +DROP TABLE atest1; + +DROP TABLE atest2; + +DROP TABLE atest3; + +DROP TABLE atest4; + +DROP TABLE atest5; + +DROP TABLE atest6; + +DROP TABLE atestc; + +DROP TABLE atestp1; + +DROP TABLE atestp2; + +SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid; + +DROP GROUP regress_priv_group1; + +DROP GROUP regress_priv_group2; + +REVOKE USAGE ON LANGUAGE sql FROM regress_priv_user1; + +DROP OWNED BY regress_priv_user1; + +DROP USER regress_priv_user1; + +DROP USER regress_priv_user2; + +DROP USER regress_priv_user3; + +DROP USER regress_priv_user4; + +DROP USER regress_priv_user5; + +DROP USER regress_priv_user6; + +DROP USER regress_priv_user7; + +DROP USER regress_priv_user8; + +ALTER DEFAULT PRIVILEGES FOR ROLE pg_signal_backend + REVOKE USAGE ON TYPES FROM pg_signal_backend; + +ALTER DEFAULT PRIVILEGES FOR ROLE pg_read_all_settings + REVOKE USAGE ON TYPES FROM pg_read_all_settings; + +CREATE USER regress_locktable_user; + +CREATE TABLE lock_table (a int); + +GRANT SELECT ON lock_table TO regress_locktable_user; + +SET SESSION AUTHORIZATION regress_locktable_user; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS SHARE MODE; + +COMMIT; + +BEGIN; + +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; + +ROLLBACK; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; + +ROLLBACK; + +REVOKE SELECT ON lock_table FROM regress_locktable_user; + +GRANT INSERT ON lock_table TO regress_locktable_user; + +SET SESSION AUTHORIZATION regress_locktable_user; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS SHARE MODE; + +ROLLBACK; + +BEGIN; + +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; + +COMMIT; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; + +ROLLBACK; + +REVOKE INSERT ON lock_table FROM regress_locktable_user; + +GRANT UPDATE ON lock_table TO regress_locktable_user; + +SET SESSION AUTHORIZATION regress_locktable_user; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS SHARE MODE; + +ROLLBACK; + +BEGIN; + +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; + +COMMIT; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; + +COMMIT; + +REVOKE UPDATE ON lock_table FROM regress_locktable_user; + +GRANT DELETE ON lock_table TO regress_locktable_user; + +SET SESSION AUTHORIZATION regress_locktable_user; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS SHARE MODE; + +ROLLBACK; + +BEGIN; + +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; + +COMMIT; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; + +COMMIT; + +REVOKE DELETE ON lock_table FROM regress_locktable_user; + +GRANT TRUNCATE ON lock_table TO regress_locktable_user; + +SET SESSION AUTHORIZATION regress_locktable_user; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS SHARE MODE; + +ROLLBACK; + +BEGIN; + +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; + +COMMIT; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; + +COMMIT; + +REVOKE TRUNCATE ON lock_table FROM regress_locktable_user; + +GRANT MAINTAIN ON lock_table TO regress_locktable_user; + +SET SESSION AUTHORIZATION regress_locktable_user; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS SHARE MODE; + +ROLLBACK; + +BEGIN; + +LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; + +COMMIT; + +BEGIN; + +LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; + +COMMIT; + +REVOKE MAINTAIN ON lock_table FROM regress_locktable_user; + +DROP TABLE lock_table; + +DROP USER regress_locktable_user; + +CREATE ROLE regress_readallstats; + +SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); + +GRANT pg_read_all_stats TO regress_readallstats; + +SELECT has_table_privilege('regress_readallstats','pg_aios','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations_numa','SELECT'); + +SELECT has_table_privilege('regress_readallstats','pg_dsm_registry_allocations','SELECT'); + +SET ROLE regress_readallstats; + +SELECT COUNT(*) >= 0 AS ok FROM pg_aios; + +SELECT COUNT(*) >= 0 AS ok FROM pg_backend_memory_contexts; + +SELECT COUNT(*) >= 0 AS ok FROM pg_shmem_allocations; + +RESET ROLE; + +DROP ROLE regress_readallstats; + +CREATE ROLE regress_group; + +CREATE ROLE regress_group_direct_manager; + +CREATE ROLE regress_group_indirect_manager; + +CREATE ROLE regress_group_member; + +GRANT regress_group TO regress_group_direct_manager WITH INHERIT FALSE, ADMIN TRUE; + +GRANT regress_group_direct_manager TO regress_group_indirect_manager; + +SET SESSION AUTHORIZATION regress_group_direct_manager; + +GRANT regress_group TO regress_group_member; + +SELECT member::regrole::text, CASE WHEN grantor = 10 THEN 'BOOTSTRAP SUPERUSER' ELSE grantor::regrole::text END FROM pg_auth_members WHERE roleid = 'regress_group'::regrole ORDER BY 1, 2; + +REVOKE regress_group FROM regress_group_member; + +SET SESSION AUTHORIZATION regress_group_indirect_manager; + +GRANT regress_group TO regress_group_member; + +SELECT member::regrole::text, CASE WHEN grantor = 10 THEN 'BOOTSTRAP SUPERUSER' ELSE grantor::regrole::text END FROM pg_auth_members WHERE roleid = 'regress_group'::regrole ORDER BY 1, 2; + +REVOKE regress_group FROM regress_group_member; + +RESET SESSION AUTHORIZATION; + +DROP ROLE regress_group; + +DROP ROLE regress_group_direct_manager; + +DROP ROLE regress_group_indirect_manager; + +DROP ROLE regress_group_member; + +CREATE ROLE regress_roleoption_protagonist; + +CREATE ROLE regress_roleoption_donor; + +CREATE ROLE regress_roleoption_recipient; + +CREATE SCHEMA regress_roleoption; + +GRANT CREATE, USAGE ON SCHEMA regress_roleoption TO PUBLIC; + +GRANT regress_roleoption_donor TO regress_roleoption_protagonist WITH INHERIT TRUE, SET FALSE; + +GRANT regress_roleoption_recipient TO regress_roleoption_protagonist WITH INHERIT FALSE, SET TRUE; + +SET SESSION AUTHORIZATION regress_roleoption_protagonist; + +CREATE TABLE regress_roleoption.t1 (a int); + +CREATE TABLE regress_roleoption.t2 (a int); + +SET SESSION AUTHORIZATION regress_roleoption_donor; + +CREATE TABLE regress_roleoption.t3 (a int); + +SET SESSION AUTHORIZATION regress_roleoption_recipient; + +CREATE TABLE regress_roleoption.t4 (a int); + +SET SESSION AUTHORIZATION regress_roleoption_protagonist; + +ALTER TABLE regress_roleoption.t1 OWNER TO regress_roleoption_donor; + +ALTER TABLE regress_roleoption.t2 OWNER TO regress_roleoption_recipient; + +ALTER TABLE regress_roleoption.t3 OWNER TO regress_roleoption_protagonist; + +ALTER TABLE regress_roleoption.t4 OWNER TO regress_roleoption_protagonist; + +RESET SESSION AUTHORIZATION; + +DROP TABLE regress_roleoption.t1; + +DROP TABLE regress_roleoption.t2; + +DROP TABLE regress_roleoption.t3; + +DROP TABLE regress_roleoption.t4; + +DROP SCHEMA regress_roleoption; + +DROP ROLE regress_roleoption_protagonist; + +DROP ROLE regress_roleoption_donor; + +DROP ROLE regress_roleoption_recipient; + +CREATE ROLE regress_no_maintain; + +CREATE ROLE regress_maintain; + +CREATE ROLE regress_maintain_all IN ROLE pg_maintain; + +CREATE TABLE maintain_test (a INT); + +CREATE INDEX ON maintain_test (a); + +GRANT MAINTAIN ON maintain_test TO regress_maintain; + +CREATE MATERIALIZED VIEW refresh_test AS SELECT 1; + +GRANT MAINTAIN ON refresh_test TO regress_maintain; + +CREATE SCHEMA reindex_test; + +SET ROLE regress_no_maintain; + +VACUUM maintain_test; + +ANALYZE maintain_test; + +VACUUM (ANALYZE) maintain_test; + +CLUSTER maintain_test USING maintain_test_a_idx; + +REFRESH MATERIALIZED VIEW refresh_test; + +REINDEX TABLE maintain_test; + +REINDEX INDEX maintain_test_a_idx; + +REINDEX SCHEMA reindex_test; + +RESET ROLE; + +SET ROLE regress_maintain; + +VACUUM maintain_test; + +ANALYZE maintain_test; + +VACUUM (ANALYZE) maintain_test; + +CLUSTER maintain_test USING maintain_test_a_idx; + +REFRESH MATERIALIZED VIEW refresh_test; + +REINDEX TABLE maintain_test; + +REINDEX INDEX maintain_test_a_idx; + +REINDEX SCHEMA reindex_test; + +RESET ROLE; + +SET ROLE regress_maintain_all; + +VACUUM maintain_test; + +ANALYZE maintain_test; + +VACUUM (ANALYZE) maintain_test; + +CLUSTER maintain_test USING maintain_test_a_idx; + +REFRESH MATERIALIZED VIEW refresh_test; + +REINDEX TABLE maintain_test; + +REINDEX INDEX maintain_test_a_idx; + +REINDEX SCHEMA reindex_test; + +RESET ROLE; + +DROP TABLE maintain_test; + +DROP MATERIALIZED VIEW refresh_test; + +DROP SCHEMA reindex_test; + +DROP ROLE regress_no_maintain; + +DROP ROLE regress_maintain; + +DROP ROLE regress_maintain_all; + +CREATE ROLE regress_grantor1; + +CREATE ROLE regress_grantor2 ROLE regress_grantor1; + +CREATE ROLE regress_grantor3; + +CREATE TABLE grantor_test1 (); + +CREATE TABLE grantor_test2 (); + +CREATE TABLE grantor_test3 (); + +GRANT SELECT ON grantor_test2 TO regress_grantor1 WITH GRANT OPTION; + +GRANT SELECT, UPDATE ON grantor_test3 TO regress_grantor2 WITH GRANT OPTION; + +SET ROLE regress_grantor1; + +GRANT SELECT, UPDATE ON grantor_test1 TO regress_grantor3; + +GRANT SELECT, UPDATE ON grantor_test2 TO regress_grantor3; + +GRANT SELECT, UPDATE ON grantor_test3 TO regress_grantor3; + +RESET ROLE; + +SELECT * FROM information_schema.table_privileges t + WHERE grantor LIKE 'regress_grantor%' ORDER BY ROW(t.*); + +DROP TABLE grantor_test1, grantor_test2, grantor_test3; + +DROP ROLE regress_grantor1, regress_grantor2, regress_grantor3; diff --git a/crates/pgt_pretty_print/tests/data/multi/publication_60.sql b/crates/pgt_pretty_print/tests/data/multi/publication_60.sql new file mode 100644 index 000000000..5a5bfbcf9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/publication_60.sql @@ -0,0 +1,1398 @@ +CREATE ROLE regress_publication_user LOGIN SUPERUSER; + +CREATE ROLE regress_publication_user2; + +CREATE ROLE regress_publication_user_dummy LOGIN NOSUPERUSER; + +SET SESSION AUTHORIZATION 'regress_publication_user'; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_default; + +RESET client_min_messages; + +COMMENT ON PUBLICATION testpub_default IS 'test publication'; + +SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_ins_trunct WITH (publish = insert); + +RESET client_min_messages; + +ALTER PUBLICATION testpub_default SET (publish = update); + +CREATE PUBLICATION testpub_xxx WITH (foo); + +CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum'); + +CREATE PUBLICATION testpub_xxx WITH (publish_via_partition_root = 'true', publish_via_partition_root = '0'); + +CREATE PUBLICATION testpub_xxx WITH (publish_generated_columns = stored, publish_generated_columns = none); + +CREATE PUBLICATION testpub_xxx WITH (publish_generated_columns = foo); + +CREATE PUBLICATION testpub_xxx WITH (publish_generated_columns); + +ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete'); + +CREATE SCHEMA pub_test; + +CREATE TABLE testpub_tbl1 (id serial primary key, data text); + +CREATE TABLE pub_test.testpub_nopk (foo int, bar int); + +CREATE VIEW testpub_view AS SELECT 1; + +CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert'); + +RESET client_min_messages; + +ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update'); + +CREATE TABLE testpub_tbl2 (id serial primary key, data text); + +ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2; + +ALTER PUBLICATION testpub_foralltables DROP TABLE testpub_tbl2; + +ALTER PUBLICATION testpub_foralltables SET TABLE pub_test.testpub_nopk; + +ALTER PUBLICATION testpub_foralltables ADD TABLES IN SCHEMA pub_test; + +ALTER PUBLICATION testpub_foralltables DROP TABLES IN SCHEMA pub_test; + +ALTER PUBLICATION testpub_foralltables SET TABLES IN SCHEMA pub_test; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1; + +RESET client_min_messages; + +ALTER PUBLICATION testpub_fortable ADD TABLES IN SCHEMA pub_test; + +ALTER PUBLICATION testpub_fortable DROP TABLES IN SCHEMA pub_test; + +ALTER PUBLICATION testpub_fortable SET TABLES IN SCHEMA pub_test; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test; + +CREATE PUBLICATION testpub_for_tbl_schema FOR TABLES IN SCHEMA pub_test, TABLE pub_test.testpub_nopk; + +RESET client_min_messages; + +ALTER PUBLICATION testpub_forschema ADD TABLE pub_test.testpub_nopk; + +ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk; + +ALTER PUBLICATION testpub_forschema DROP TABLE pub_test.testpub_nopk; + +ALTER PUBLICATION testpub_forschema SET TABLE pub_test.testpub_nopk; + +SELECT pubname, puballtables FROM pg_publication WHERE pubname = 'testpub_foralltables'; + +DROP TABLE testpub_tbl2; + +DROP PUBLICATION testpub_foralltables, testpub_fortable, testpub_forschema, testpub_for_tbl_schema; + +CREATE TABLE testpub_tbl3 (a int); + +CREATE TABLE testpub_tbl3a (b text) INHERITS (testpub_tbl3); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub3 FOR TABLE testpub_tbl3; + +CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3; + +RESET client_min_messages; + +DROP TABLE testpub_tbl3, testpub_tbl3a; + +DROP PUBLICATION testpub3, testpub4; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_forparted; + +CREATE PUBLICATION testpub_forparted1; + +RESET client_min_messages; + +CREATE TABLE testpub_parted1 (LIKE testpub_parted); + +CREATE TABLE testpub_parted2 (LIKE testpub_parted); + +ALTER PUBLICATION testpub_forparted1 SET (publish='insert'); + +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted1 FOR VALUES IN (1); + +ALTER TABLE testpub_parted ATTACH PARTITION testpub_parted2 FOR VALUES IN (2); + +UPDATE testpub_parted1 SET a = 1; + +ALTER PUBLICATION testpub_forparted ADD TABLE testpub_parted; + +UPDATE testpub_parted SET a = 1 WHERE false; + +UPDATE testpub_parted1 SET a = 1; + +ALTER TABLE testpub_parted DETACH PARTITION testpub_parted1; + +UPDATE testpub_parted1 SET a = 1; + +ALTER PUBLICATION testpub_forparted SET (publish_via_partition_root = true); + +UPDATE testpub_parted2 SET a = 2; + +ALTER PUBLICATION testpub_forparted DROP TABLE testpub_parted; + +UPDATE testpub_parted2 SET a = 2; + +DROP TABLE testpub_parted1, testpub_parted2; + +DROP PUBLICATION testpub_forparted, testpub_forparted1; + +CREATE TABLE testpub_rf_tbl1 (a integer, b text); + +CREATE TABLE testpub_rf_tbl2 (c text, d integer); + +CREATE TABLE testpub_rf_tbl3 (e integer); + +CREATE TABLE testpub_rf_tbl4 (g text); + +CREATE TABLE testpub_rf_tbl5 (a xml); + +CREATE SCHEMA testpub_rf_schema1; + +CREATE TABLE testpub_rf_schema1.testpub_rf_tbl5 (h integer); + +CREATE SCHEMA testpub_rf_schema2; + +CREATE TABLE testpub_rf_schema2.testpub_rf_tbl6 (i integer); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub5 FOR TABLE testpub_rf_tbl1, testpub_rf_tbl2 WHERE (c <> 'test' AND d < 5) WITH (publish = 'insert'); + +RESET client_min_messages; + +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl3 WHERE (e > 1000 AND e < 2000); + +ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl2; + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e > 300 AND e < 500); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_rf_yes FOR TABLE testpub_rf_tbl1 WHERE (a > 1) WITH (publish = 'insert'); + +CREATE PUBLICATION testpub_rf_no FOR TABLE testpub_rf_tbl1; + +RESET client_min_messages; + +DROP PUBLICATION testpub_rf_yes, testpub_rf_no; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_syntax1 FOR TABLE testpub_rf_tbl1, ONLY testpub_rf_tbl3 WHERE (e < 999) WITH (publish = 'insert'); + +RESET client_min_messages; + +DROP PUBLICATION testpub_syntax1; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_syntax2 FOR TABLE testpub_rf_tbl1, testpub_rf_schema1.testpub_rf_tbl5 WHERE (h < 999) WITH (publish = 'insert'); + +RESET client_min_messages; + +DROP PUBLICATION testpub_syntax2; + +SET client_min_messages = 'ERROR'; + +RESET client_min_messages; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1 WHERE (a = 1), testpub_rf_tbl1 WITH (publish = 'insert'); + +CREATE PUBLICATION testpub_dups FOR TABLE testpub_rf_tbl1, testpub_rf_tbl1 WHERE (a = 2) WITH (publish = 'insert'); + +RESET client_min_messages; + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (1234); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl3 WHERE (e < AVG(e)); + +CREATE FUNCTION testpub_rf_func1(integer, integer) RETURNS boolean AS $$ SELECT hashint4($1) > $2 $$ LANGUAGE SQL; + +CREATE OPERATOR =#> (PROCEDURE = testpub_rf_func1, LEFTARG = integer, RIGHTARG = integer); + +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl3 WHERE (e =#> 27); + +CREATE FUNCTION testpub_rf_func2() RETURNS integer IMMUTABLE AS $$ BEGIN RETURN 123; END; $$ LANGUAGE plpgsql; + +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a >= testpub_rf_func2()); + +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (a < random()); + +CREATE COLLATION user_collation FROM "C"; + +ALTER PUBLICATION testpub5 ADD TABLE testpub_rf_tbl1 WHERE (b < '2' COLLATE user_collation); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (NULLIF(1,2) = a); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS NULL); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((a > 5) IS FALSE); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IS DISTINCT FROM 5); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE ((a, a + 1) < (2, 3)); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (b::varchar < '2'); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl4 WHERE (length(g) < 6); + +CREATE TYPE rf_bug_status AS ENUM ('new', 'open', 'closed'); + +CREATE TABLE rf_bug (id serial, description text, status rf_bug_status); + +CREATE PUBLICATION testpub6 FOR TABLE rf_bug WHERE (status = 'open') WITH (publish = 'insert'); + +DROP TABLE rf_bug; + +DROP TYPE rf_bug_status; + +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE (a IN (SELECT generate_series(1,5))); + +CREATE PUBLICATION testpub6 FOR TABLE testpub_rf_tbl1 WHERE ('(0,1)'::tid = ctid); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (a IS DOCUMENT); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl5 WHERE (xmlexists('//foo[text() = ''bar'']' PASSING BY VALUE a)); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (NULLIF(1, 2) = a); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (CASE a WHEN 5 THEN true ELSE false END); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (COALESCE(b, 'foo') = 'foo'); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (GREATEST(a, 10) > 10); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (a IN (2, 4, 6)); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ARRAY[a] <@ ARRAY[2, 4, 6]); + +ALTER PUBLICATION testpub5 SET TABLE testpub_rf_tbl1 WHERE (ROW(a, 2) IS NULL); + +ALTER PUBLICATION testpub5 DROP TABLE testpub_rf_tbl1 WHERE (e < 27); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub6 FOR TABLES IN SCHEMA testpub_rf_schema2; + +ALTER PUBLICATION testpub6 SET TABLES IN SCHEMA testpub_rf_schema2, TABLE testpub_rf_schema2.testpub_rf_tbl6 WHERE (i < 99); + +RESET client_min_messages; + +CREATE PUBLICATION testpub7 FOR TABLE testpub_rf_tbl6 WHERE (y > 100); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub8 FOR TABLE testpub_rf_tbl7 WHERE (y > 100); + +ALTER TABLE testpub_rf_tbl7 ALTER COLUMN y SET EXPRESSION AS (x * testpub_rf_func2()); + +RESET client_min_messages; + +DROP TABLE testpub_rf_tbl1; + +DROP TABLE testpub_rf_tbl2; + +DROP TABLE testpub_rf_tbl3; + +DROP TABLE testpub_rf_tbl4; + +DROP TABLE testpub_rf_tbl5; + +DROP TABLE testpub_rf_schema1.testpub_rf_tbl5; + +DROP TABLE testpub_rf_schema2.testpub_rf_tbl6; + +DROP SCHEMA testpub_rf_schema1; + +DROP SCHEMA testpub_rf_schema2; + +DROP PUBLICATION testpub5; + +DROP PUBLICATION testpub6; + +DROP PUBLICATION testpub8; + +DROP TABLE testpub_rf_tbl7; + +DROP OPERATOR =#>(integer, integer); + +DROP FUNCTION testpub_rf_func1(integer, integer); + +DROP FUNCTION testpub_rf_func2(); + +DROP COLLATION user_collation; + +CREATE TABLE rf_tbl_abcd_nopk(a int, b int, c int, d int); + +CREATE TABLE rf_tbl_abcd_pk(a int, b int, c int, d int, PRIMARY KEY(a,b)); + +CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION by RANGE (a); + +CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY); + +ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk WHERE (a > 99); + +RESET client_min_messages; + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (b > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (d > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL; + +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING; + +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL; + +CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk(c); + +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c; + +ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL; + +CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk(c); + +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (a > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk WHERE (c > 99); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (a > 99); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk WHERE (c > 99); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (a > 99); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (a > 99); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99); + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk WHERE (b > 99); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +DROP PUBLICATION testpub6; + +DROP TABLE rf_tbl_abcd_pk; + +DROP TABLE rf_tbl_abcd_nopk; + +DROP TABLE rf_tbl_abcd_part_pk; + +SET client_min_messages = 'ERROR'; + +CREATE TABLE testpub_gencol (a INT, b INT GENERATED ALWAYS AS (a + 1) STORED NOT NULL); + +CREATE UNIQUE INDEX testpub_gencol_idx ON testpub_gencol (b); + +ALTER TABLE testpub_gencol REPLICA IDENTITY USING index testpub_gencol_idx; + +CREATE PUBLICATION pub_gencol FOR TABLE testpub_gencol; + +UPDATE testpub_gencol SET a = 100 WHERE a = 1; + +ALTER TABLE testpub_gencol REPLICA IDENTITY FULL; + +UPDATE testpub_gencol SET a = 100 WHERE a = 1; + +DROP PUBLICATION pub_gencol; + +CREATE PUBLICATION pub_gencol FOR TABLE testpub_gencol with (publish_generated_columns = stored); + +UPDATE testpub_gencol SET a = 100 WHERE a = 1; + +DROP PUBLICATION pub_gencol; + +DROP TABLE testpub_gencol; + +CREATE PUBLICATION pub_gencol FOR TABLE testpub_gencol; + +ALTER TABLE testpub_gencol REPLICA IDENTITY FULL; + +UPDATE testpub_gencol SET a = 100 WHERE a = 1; + +DROP PUBLICATION pub_gencol; + +CREATE PUBLICATION pub_gencol FOR TABLE testpub_gencol with (publish_generated_columns = stored); + +UPDATE testpub_gencol SET a = 100 WHERE a = 1; + +DROP PUBLICATION pub_gencol; + +DROP TABLE testpub_gencol; + +RESET client_min_messages; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1 (a), testpub_tbl1 WITH (publish = 'insert'); + +CREATE PUBLICATION testpub_dups FOR TABLE testpub_tbl1, testpub_tbl1 (a) WITH (publish = 'insert'); + +RESET client_min_messages; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_fortable FOR TABLE testpub_tbl1; + +CREATE PUBLICATION testpub_fortable_insert WITH (publish = 'insert'); + +RESET client_min_messages; + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, x); + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (b, c); + +UPDATE testpub_tbl5 SET a = 1; + +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5; + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, ctid); + +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl1 (id, ctid); + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, a); + +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl5 (a, a); + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, c); + +ALTER TABLE testpub_tbl5 DROP COLUMN c; + +ALTER PUBLICATION testpub_fortable_insert ADD TABLE testpub_tbl5 (b, c); + +CREATE UNIQUE INDEX testpub_tbl5_b_key ON testpub_tbl5 (b, c); + +ALTER TABLE testpub_tbl5 ALTER b SET NOT NULL, ALTER c SET NOT NULL; + +ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key; + +UPDATE testpub_tbl5 SET a = 1; + +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5; + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, d); + +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl5; + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, e); + +ALTER TABLE testpub_tbl5 REPLICA IDENTITY USING INDEX testpub_tbl5_b_key; + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5 (a, c); + +UPDATE testpub_tbl5 SET a = 1; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_table_ins WITH (publish = 'insert, truncate'); + +RESET client_min_messages; + +ALTER PUBLICATION testpub_table_ins ADD TABLE testpub_tbl5 (a); + +CREATE TABLE testpub_tbl5d (a int PRIMARY KEY DEFERRABLE); + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl5d; + +UPDATE testpub_tbl5d SET a = 1; + +ALTER TABLE testpub_tbl5d REPLICA IDENTITY FULL; + +UPDATE testpub_tbl5d SET a = 1; + +DROP TABLE testpub_tbl5d; + +CREATE TABLE testpub_tbl6 (a int, b text, c text); + +ALTER TABLE testpub_tbl6 REPLICA IDENTITY FULL; + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6 (a, b, c); + +UPDATE testpub_tbl6 SET a = 1; + +ALTER PUBLICATION testpub_fortable DROP TABLE testpub_tbl6; + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl6; + +UPDATE testpub_tbl6 SET a = 1; + +CREATE TABLE testpub_tbl7 (a int primary key, b text, c text); + +ALTER PUBLICATION testpub_fortable ADD TABLE testpub_tbl7 (a, b); + +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7 (a, b); + +ALTER PUBLICATION testpub_fortable SET TABLE testpub_tbl7 (a, c); + +CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a); + +CREATE TABLE testpub_tbl8_0 PARTITION OF testpub_tbl8 FOR VALUES WITH (modulus 2, remainder 0); + +ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a); + +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey; + +CREATE TABLE testpub_tbl8_1 PARTITION OF testpub_tbl8 FOR VALUES WITH (modulus 2, remainder 1); + +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (b); + +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_col_list FOR TABLE testpub_tbl8 (a, b) WITH (publish_via_partition_root = 'true'); + +RESET client_min_messages; + +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8; + +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b); + +UPDATE testpub_tbl8 SET a = 1; + +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8; + +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, c); + +UPDATE testpub_tbl8 SET a = 1; + +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8; + +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL; + +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, c); + +UPDATE testpub_tbl8 SET a = 1; + +ALTER PUBLICATION testpub_col_list DROP TABLE testpub_tbl8; + +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey; + +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b); + +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY FULL; + +UPDATE testpub_tbl8 SET a = 1; + +ALTER TABLE testpub_tbl8_1 DROP CONSTRAINT testpub_tbl8_1_pkey; + +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c); + +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey; + +UPDATE testpub_tbl8 SET a = 1; + +DROP TABLE testpub_tbl8; + +CREATE TABLE testpub_tbl8 (a int, b text, c text) PARTITION BY HASH (a); + +ALTER PUBLICATION testpub_col_list ADD TABLE testpub_tbl8 (a, b); + +CREATE TABLE testpub_tbl8_0 (a int, b text, c text); + +ALTER TABLE testpub_tbl8_0 ADD PRIMARY KEY (a); + +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY USING INDEX testpub_tbl8_0_pkey; + +CREATE TABLE testpub_tbl8_1 (a int, b text, c text); + +ALTER TABLE testpub_tbl8_1 ADD PRIMARY KEY (c); + +ALTER TABLE testpub_tbl8_1 REPLICA IDENTITY USING INDEX testpub_tbl8_1_pkey; + +UPDATE testpub_tbl8 SET a = 1; + +ALTER TABLE testpub_tbl8_0 REPLICA IDENTITY FULL; + +UPDATE testpub_tbl8 SET a = 1; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a); + +CREATE PUBLICATION testpub_tbl9 FOR TABLES IN SCHEMA public; + +ALTER PUBLICATION testpub_tbl9 ADD TABLE public.testpub_tbl7(a); + +ALTER PUBLICATION testpub_tbl9 SET TABLE public.testpub_tbl7(a); + +ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public; + +ALTER PUBLICATION testpub_tbl9 SET TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a); + +ALTER PUBLICATION testpub_tbl9 DROP TABLE public.testpub_tbl7; + +ALTER PUBLICATION testpub_tbl9 ADD TABLES IN SCHEMA public, TABLE public.testpub_tbl7(a); + +RESET client_min_messages; + +DROP TABLE testpub_tbl5, testpub_tbl6, testpub_tbl7, testpub_tbl8, testpub_tbl8_1; + +DROP PUBLICATION testpub_table_ins, testpub_fortable, testpub_fortable_insert, testpub_col_list, testpub_tbl9; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_both_filters; + +RESET client_min_messages; + +CREATE TABLE testpub_tbl_both_filters (a int, b int, c int, PRIMARY KEY (a,c)); + +ALTER TABLE testpub_tbl_both_filters REPLICA IDENTITY USING INDEX testpub_tbl_both_filters_pkey; + +ALTER PUBLICATION testpub_both_filters ADD TABLE testpub_tbl_both_filters (a,c) WHERE (c != 1); + +DROP TABLE testpub_tbl_both_filters; + +DROP PUBLICATION testpub_both_filters; + +CREATE TABLE rf_tbl_abcd_nopk(a int, b int, c int, d int); + +CREATE TABLE rf_tbl_abcd_pk(a int, b int, c int, d int, PRIMARY KEY(a,b)); + +CREATE TABLE rf_tbl_abcd_part_pk (a int PRIMARY KEY, b int) PARTITION by RANGE (a); + +CREATE TABLE rf_tbl_abcd_part_pk_1 (b int, a int PRIMARY KEY); + +ALTER TABLE rf_tbl_abcd_part_pk ATTACH PARTITION rf_tbl_abcd_part_pk_1 FOR VALUES FROM (1) TO (10); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub6 FOR TABLE rf_tbl_abcd_pk (a, b); + +RESET client_min_messages; + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a, b, c); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (b); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY FULL; + +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY FULL; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (c); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a, b, c, d); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY NOTHING; + +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY NOTHING; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a, b, c, d); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (d); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER TABLE rf_tbl_abcd_pk ALTER COLUMN c SET NOT NULL; + +CREATE UNIQUE INDEX idx_abcd_pk_c ON rf_tbl_abcd_pk(c); + +ALTER TABLE rf_tbl_abcd_pk REPLICA IDENTITY USING INDEX idx_abcd_pk_c; + +ALTER TABLE rf_tbl_abcd_nopk ALTER COLUMN c SET NOT NULL; + +CREATE UNIQUE INDEX idx_abcd_nopk_c ON rf_tbl_abcd_nopk(c); + +ALTER TABLE rf_tbl_abcd_nopk REPLICA IDENTITY USING INDEX idx_abcd_nopk_c; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (a); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_pk (c); + +UPDATE rf_tbl_abcd_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (a); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_nopk (c); + +UPDATE rf_tbl_abcd_nopk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (a); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (a); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (b); + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=1); + +ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk (b); + +UPDATE rf_tbl_abcd_part_pk SET a = 1; + +DROP PUBLICATION testpub6; + +DROP TABLE rf_tbl_abcd_pk; + +DROP TABLE rf_tbl_abcd_nopk; + +DROP TABLE rf_tbl_abcd_part_pk; + +SET client_min_messages = 'ERROR'; + +CREATE TABLE testpub_tbl4(a int); + +INSERT INTO testpub_tbl4 values(1); + +UPDATE testpub_tbl4 set a = 2; + +CREATE PUBLICATION testpub_foralltables FOR ALL TABLES; + +RESET client_min_messages; + +UPDATE testpub_tbl4 set a = 3; + +DROP PUBLICATION testpub_foralltables; + +UPDATE testpub_tbl4 set a = 3; + +DROP TABLE testpub_tbl4; + +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view; + +CREATE TEMPORARY TABLE testpub_temptbl(a int); + +CREATE PUBLICATION testpub_fortemptbl FOR TABLE testpub_temptbl; + +DROP TABLE testpub_temptbl; + +CREATE UNLOGGED TABLE testpub_unloggedtbl(a int); + +CREATE PUBLICATION testpub_forunloggedtbl FOR TABLE testpub_unloggedtbl; + +DROP TABLE testpub_unloggedtbl; + +CREATE PUBLICATION testpub_forsystemtbl FOR TABLE pg_publication; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1, pub_test.testpub_nopk; + +RESET client_min_messages; + +ALTER PUBLICATION testpub_fortbl ADD TABLE testpub_tbl1; + +CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1; + +ALTER PUBLICATION testpub_default ADD TABLE testpub_view; + +ALTER PUBLICATION testpub_default ADD TABLE testpub_tbl1; + +ALTER PUBLICATION testpub_default SET TABLE testpub_tbl1; + +ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_nopk; + +ALTER PUBLICATION testpub_ins_trunct ADD TABLE pub_test.testpub_nopk, testpub_tbl1; + +ALTER PUBLICATION testpub_default DROP TABLE testpub_tbl1, pub_test.testpub_nopk; + +ALTER PUBLICATION testpub_default DROP TABLE pub_test.testpub_nopk; + +CREATE TABLE pub_test.testpub_addpk (id int not null, data int); + +ALTER PUBLICATION testpub_default ADD TABLE pub_test.testpub_addpk; + +INSERT INTO pub_test.testpub_addpk VALUES(1, 11); + +CREATE UNIQUE INDEX testpub_addpk_id_idx ON pub_test.testpub_addpk(id); + +UPDATE pub_test.testpub_addpk SET id = 2; + +ALTER TABLE pub_test.testpub_addpk ADD PRIMARY KEY USING INDEX testpub_addpk_id_idx; + +UPDATE pub_test.testpub_addpk SET id = 2; + +DROP TABLE pub_test.testpub_addpk; + +SET ROLE regress_publication_user2; + +CREATE PUBLICATION testpub2; + +SET ROLE regress_publication_user; + +GRANT CREATE ON DATABASE regression TO regress_publication_user2; + +SET ROLE regress_publication_user2; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub2; + +CREATE PUBLICATION testpub3 FOR TABLES IN SCHEMA pub_test; + +CREATE PUBLICATION testpub3; + +RESET client_min_messages; + +ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1; + +ALTER PUBLICATION testpub3 ADD TABLES IN SCHEMA pub_test; + +SET ROLE regress_publication_user; + +GRANT regress_publication_user TO regress_publication_user2; + +SET ROLE regress_publication_user2; + +ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1; + +DROP PUBLICATION testpub2; + +DROP PUBLICATION testpub3; + +SET ROLE regress_publication_user; + +CREATE ROLE regress_publication_user3; + +GRANT regress_publication_user2 TO regress_publication_user3; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub4 FOR TABLES IN SCHEMA pub_test; + +RESET client_min_messages; + +ALTER PUBLICATION testpub4 OWNER TO regress_publication_user3; + +SET ROLE regress_publication_user3; + +ALTER PUBLICATION testpub4 owner to regress_publication_user2; + +ALTER PUBLICATION testpub4 owner to regress_publication_user; + +SET ROLE regress_publication_user; + +DROP PUBLICATION testpub4; + +DROP ROLE regress_publication_user3; + +REVOKE CREATE ON DATABASE regression FROM regress_publication_user2; + +DROP TABLE testpub_parted; + +DROP TABLE testpub_tbl1; + +SET ROLE regress_publication_user_dummy; + +ALTER PUBLICATION testpub_default RENAME TO testpub_dummy; + +RESET ROLE; + +ALTER PUBLICATION testpub_default RENAME TO testpub_foo; + +ALTER PUBLICATION testpub_foo RENAME TO testpub_default; + +ALTER PUBLICATION testpub_default OWNER TO regress_publication_user2; + +CREATE SCHEMA pub_test1; + +CREATE SCHEMA pub_test2; + +CREATE SCHEMA pub_test3; + +CREATE SCHEMA "CURRENT_SCHEMA"; + +CREATE TABLE pub_test1.tbl (id int, data text); + +CREATE TABLE pub_test1.tbl1 (id serial primary key, data text); + +CREATE TABLE pub_test2.tbl1 (id serial primary key, data text); + +CREATE TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"(id int); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub1_forschema FOR TABLES IN SCHEMA pub_test1; + +CREATE PUBLICATION testpub2_forschema FOR TABLES IN SCHEMA pub_test1, pub_test2, pub_test3; + +CREATE PUBLICATION testpub3_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA; + +CREATE PUBLICATION testpub4_forschema FOR TABLES IN SCHEMA "CURRENT_SCHEMA"; + +CREATE PUBLICATION testpub5_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA, "CURRENT_SCHEMA"; + +CREATE PUBLICATION testpub6_forschema FOR TABLES IN SCHEMA "CURRENT_SCHEMA", CURRENT_SCHEMA; + +CREATE PUBLICATION testpub_fortable FOR TABLE "CURRENT_SCHEMA"."CURRENT_SCHEMA"; + +RESET client_min_messages; + +SET SEARCH_PATH=''; + +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA CURRENT_SCHEMA; + +RESET SEARCH_PATH; + +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA non_existent_schema; + +CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pg_catalog; + +CREATE PUBLICATION testpub1_forschema1 FOR TABLES IN SCHEMA testpub_view; + +DROP SCHEMA pub_test3; + +ALTER SCHEMA pub_test1 RENAME to pub_test1_renamed; + +ALTER SCHEMA pub_test1_renamed RENAME to pub_test1; + +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test2; + +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA non_existent_schema; + +ALTER PUBLICATION testpub1_forschema ADD TABLES IN SCHEMA pub_test1; + +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2; + +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test2; + +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA non_existent_schema; + +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1; + +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test2; + +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA non_existent_schema; + +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1, pub_test1; + +ALTER PUBLICATION testpub2_forschema DROP TABLES IN SCHEMA pub_test1; + +DROP PUBLICATION testpub3_forschema, testpub4_forschema, testpub5_forschema, testpub6_forschema, testpub_fortable; + +DROP SCHEMA "CURRENT_SCHEMA" CASCADE; + +INSERT INTO pub_test1.tbl VALUES(1, 'test'); + +UPDATE pub_test1.tbl SET id = 2; + +ALTER PUBLICATION testpub1_forschema DROP TABLES IN SCHEMA pub_test1; + +UPDATE pub_test1.tbl SET id = 2; + +ALTER PUBLICATION testpub1_forschema SET TABLES IN SCHEMA pub_test1; + +UPDATE pub_test1.tbl SET id = 2; + +CREATE SCHEMA pub_testpart1; + +CREATE SCHEMA pub_testpart2; + +CREATE TABLE pub_testpart1.parent1 (a int) partition by list (a); + +CREATE TABLE pub_testpart2.child_parent1 partition of pub_testpart1.parent1 for values in (1); + +INSERT INTO pub_testpart2.child_parent1 values(1); + +UPDATE pub_testpart2.child_parent1 set a = 1; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart1; + +RESET client_min_messages; + +UPDATE pub_testpart1.parent1 set a = 1; + +UPDATE pub_testpart2.child_parent1 set a = 1; + +DROP PUBLICATION testpubpart_forschema; + +CREATE TABLE pub_testpart2.parent2 (a int) partition by list (a); + +CREATE TABLE pub_testpart1.child_parent2 partition of pub_testpart2.parent2 for values in (1); + +INSERT INTO pub_testpart1.child_parent2 values(1); + +UPDATE pub_testpart1.child_parent2 set a = 1; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpubpart_forschema FOR TABLES IN SCHEMA pub_testpart2; + +RESET client_min_messages; + +UPDATE pub_testpart2.child_parent1 set a = 1; + +UPDATE pub_testpart2.parent2 set a = 1; + +UPDATE pub_testpart1.child_parent2 set a = 1; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub3_forschema; + +RESET client_min_messages; + +ALTER PUBLICATION testpub3_forschema SET TABLES IN SCHEMA pub_test1; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION testpub_forschema_fortable FOR TABLES IN SCHEMA pub_test1, TABLE pub_test2.tbl1; + +CREATE PUBLICATION testpub_fortable_forschema FOR TABLE pub_test2.tbl1, TABLES IN SCHEMA pub_test1; + +RESET client_min_messages; + +DROP VIEW testpub_view; + +DROP PUBLICATION testpub_default; + +DROP PUBLICATION testpub_ins_trunct; + +DROP PUBLICATION testpub_fortbl; + +DROP PUBLICATION testpub1_forschema; + +DROP PUBLICATION testpub2_forschema; + +DROP PUBLICATION testpub3_forschema; + +DROP PUBLICATION testpub_forschema_fortable; + +DROP PUBLICATION testpub_fortable_forschema; + +DROP PUBLICATION testpubpart_forschema; + +DROP SCHEMA pub_test CASCADE; + +DROP SCHEMA pub_test1 CASCADE; + +DROP SCHEMA pub_test2 CASCADE; + +DROP SCHEMA pub_testpart1 CASCADE; + +DROP SCHEMA pub_testpart2 CASCADE; + +SET client_min_messages = 'ERROR'; + +CREATE SCHEMA sch1; + +CREATE SCHEMA sch2; + +CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a); + +CREATE TABLE sch2.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10); + +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=1); + +SELECT * FROM pg_publication_tables; + +DROP PUBLICATION pub; + +CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=1); + +SELECT * FROM pg_publication_tables; + +ALTER PUBLICATION pub ADD TABLE sch1.tbl1; + +SELECT * FROM pg_publication_tables; + +DROP PUBLICATION pub; + +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch2 WITH (PUBLISH_VIA_PARTITION_ROOT=0); + +SELECT * FROM pg_publication_tables; + +DROP PUBLICATION pub; + +CREATE PUBLICATION pub FOR TABLE sch2.tbl1_part1 WITH (PUBLISH_VIA_PARTITION_ROOT=0); + +SELECT * FROM pg_publication_tables; + +ALTER PUBLICATION pub ADD TABLE sch1.tbl1; + +SELECT * FROM pg_publication_tables; + +DROP PUBLICATION pub; + +DROP TABLE sch2.tbl1_part1; + +DROP TABLE sch1.tbl1; + +CREATE TABLE sch1.tbl1 (a int) PARTITION BY RANGE(a); + +CREATE TABLE sch1.tbl1_part1 PARTITION OF sch1.tbl1 FOR VALUES FROM (1) to (10); + +CREATE TABLE sch1.tbl1_part2 PARTITION OF sch1.tbl1 FOR VALUES FROM (10) to (20); + +CREATE TABLE sch1.tbl1_part3 (a int) PARTITION BY RANGE(a); + +ALTER TABLE sch1.tbl1 ATTACH PARTITION sch1.tbl1_part3 FOR VALUES FROM (20) to (30); + +CREATE PUBLICATION pub FOR TABLES IN SCHEMA sch1 WITH (PUBLISH_VIA_PARTITION_ROOT=1); + +SELECT * FROM pg_publication_tables; + +RESET client_min_messages; + +DROP PUBLICATION pub; + +DROP TABLE sch1.tbl1; + +DROP SCHEMA sch1 cascade; + +DROP SCHEMA sch2 cascade; + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION pub1 FOR ALL TABLES WITH (publish_generated_columns = stored); + +CREATE PUBLICATION pub2 FOR ALL TABLES WITH (publish_generated_columns = none); + +DROP PUBLICATION pub1; + +DROP PUBLICATION pub2; + +CREATE TABLE gencols (a int, gen1 int GENERATED ALWAYS AS (a * 2) STORED); + +CREATE PUBLICATION pub1 FOR table gencols(a, gen1) WITH (publish_generated_columns = none); + +CREATE PUBLICATION pub2 FOR table gencols(a, gen1) WITH (publish_generated_columns = stored); + +ALTER PUBLICATION pub2 SET (publish_generated_columns = none); + +ALTER PUBLICATION pub2 SET TABLE gencols(a); + +ALTER PUBLICATION pub2 SET TABLE gencols(a, gen1); + +DROP PUBLICATION pub1; + +DROP PUBLICATION pub2; + +DROP TABLE gencols; + +RESET client_min_messages; + +CREATE TABLE testpub_insert_onconfl_no_ri (a int unique, b int); + +CREATE TABLE testpub_insert_onconfl_parted (a int unique, b int) PARTITION by RANGE (a); + +CREATE TABLE testpub_insert_onconfl_part_no_ri PARTITION OF testpub_insert_onconfl_parted FOR VALUES FROM (1) TO (10); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION pub1 FOR ALL TABLES; + +RESET client_min_messages; + +INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2; + +INSERT INTO testpub_insert_onconfl_no_ri VALUES (1, 1) ON CONFLICT DO NOTHING; + +INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = 2; + +INSERT INTO testpub_insert_onconfl_parted VALUES (1, 1) ON CONFLICT DO NOTHING; + +DROP PUBLICATION pub1; + +DROP TABLE testpub_insert_onconfl_no_ri; + +DROP TABLE testpub_insert_onconfl_parted; + +CREATE TABLE testpub_merge_no_ri (a int, b int); + +CREATE TABLE testpub_merge_pk (a int primary key, b int); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION pub1 FOR ALL TABLES; + +RESET client_min_messages; + +DROP PUBLICATION pub1; + +DROP TABLE testpub_merge_no_ri; + +DROP TABLE testpub_merge_pk; + +RESET SESSION AUTHORIZATION; + +DROP ROLE regress_publication_user, regress_publication_user2; + +DROP ROLE regress_publication_user_dummy; + +CREATE SCHEMA pubme + +CREATE TABLE t0 (c int, d int) + +CREATE TABLE t1 (c int); + +CREATE SCHEMA pubme2 + +CREATE TABLE t0 (c int, d int); + +SET client_min_messages = 'ERROR'; + +CREATE PUBLICATION dump_pub_qual_1ct FOR + TABLE ONLY pubme.t0 (c, d) WHERE (c > 0); + +CREATE PUBLICATION dump_pub_qual_2ct FOR + TABLE ONLY pubme.t0 (c) WHERE (c > 0), + TABLE ONLY pubme.t1 (c); + +CREATE PUBLICATION dump_pub_nsp_1ct FOR + TABLES IN SCHEMA pubme; + +CREATE PUBLICATION dump_pub_nsp_2ct FOR + TABLES IN SCHEMA pubme, + TABLES IN SCHEMA pubme2; + +CREATE PUBLICATION dump_pub_all FOR + TABLE ONLY pubme.t0, + TABLE ONLY pubme.t1 WHERE (c < 0), + TABLES IN SCHEMA pubme, + TABLES IN SCHEMA pubme2 + WITH (publish_via_partition_root = true); + +RESET client_min_messages; diff --git a/crates/pgt_pretty_print/tests/data/multi/random_60.sql b/crates/pgt_pretty_print/tests/data/multi/random_60.sql new file mode 100644 index 000000000..9fc0db97c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/random_60.sql @@ -0,0 +1,281 @@ +SELECT r, count(*) +FROM (SELECT random() r FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1; + +SELECT count(*) FILTER (WHERE r < 0 OR r >= 1) AS out_of_range, + (count(*) FILTER (WHERE r < 0.01)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 0.99)) > 0 AS has_large +FROM (SELECT random() r FROM generate_series(1, 2000)) ss; + +CREATE FUNCTION ks_test_uniform_random() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random() r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql; + +SELECT ks_test_uniform_random() OR + ks_test_uniform_random() OR + ks_test_uniform_random() AS uniform; + +SELECT r, count(*) +FROM (SELECT random_normal() r FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1; + +SELECT r, count(*) +FROM (SELECT random_normal(10, 0) r FROM generate_series(1, 100)) ss +GROUP BY r; + +SELECT r, count(*) +FROM (SELECT random_normal(-10, 0) r FROM generate_series(1, 100)) ss +GROUP BY r; + +CREATE FUNCTION ks_test_normal_random() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random_normal() r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs((1+erf(r/sqrt(2)))/2 - i/n)) < c / sqrt(n) + FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql; + +SELECT ks_test_normal_random() OR + ks_test_normal_random() OR + ks_test_normal_random() AS standard_normal; + +SELECT random(1, 0); + +SELECT random(1000000000001, 1000000000000); + +SELECT random(-2.0, -3.0); + +SELECT random('NaN'::numeric, 10); + +SELECT random('-Inf'::numeric, 0); + +SELECT random(0, 'NaN'::numeric); + +SELECT random(0, 'Inf'::numeric); + +SELECT random(101, 101); + +SELECT random(1000000000001, 1000000000001); + +SELECT random(3.14, 3.14); + +SELECT r, count(*) +FROM (SELECT random(-2147483648, 2147483647) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 2; + +SELECT r, count(*) +FROM (SELECT random_normal(-9223372036854775808, 9223372036854775807) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1; + +SELECT r, count(*) +FROM (SELECT random_normal(0, 1 - 1e-15) r + FROM generate_series(1, 1000)) ss +GROUP BY r HAVING count(*) > 1; + +SELECT (count(*) FILTER (WHERE r < -2104533975)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 2104533974)) > 0 AS has_large +FROM (SELECT random(-2147483648, 2147483647) r FROM generate_series(1, 2000)) ss; + +SELECT count(*) FILTER (WHERE r < -1500000000 OR r > 1500000000) AS out_of_range, + (count(*) FILTER (WHERE r < -1470000000)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1470000000)) > 0 AS has_large +FROM (SELECT random(-1500000000, 1500000000) r FROM generate_series(1, 2000)) ss; + +SELECT (count(*) FILTER (WHERE r < -9038904596117680292)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 9038904596117680291)) > 0 AS has_large +FROM (SELECT random(-9223372036854775808, 9223372036854775807) r + FROM generate_series(1, 2000)) ss; + +SELECT count(*) FILTER (WHERE r < -1500000000000000 OR r > 1500000000000000) AS out_of_range, + (count(*) FILTER (WHERE r < -1470000000000000)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1470000000000000)) > 0 AS has_large +FROM (SELECT random(-1500000000000000, 1500000000000000) r + FROM generate_series(1, 2000)) ss; + +SELECT count(*) FILTER (WHERE r < -1.5 OR r > 1.5) AS out_of_range, + (count(*) FILTER (WHERE r < -1.47)) > 0 AS has_small, + (count(*) FILTER (WHERE r > 1.47)) > 0 AS has_large +FROM (SELECT random(-1.500000000000000, 1.500000000000000) r + FROM generate_series(1, 2000)) ss; + +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(-50, 49) r FROM generate_series(1, 2500)); + +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(123000000000, 123000000099) r + FROM generate_series(1, 2500)); + +SELECT min(r), max(r), count(r) FROM ( + SELECT DISTINCT random(-0.5, 0.49) r FROM generate_series(1, 2500)); + +CREATE FUNCTION ks_test_uniform_random_int_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 999999) / 1000000.0 r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql; + +SELECT ks_test_uniform_random_int_in_range() OR + ks_test_uniform_random_int_in_range() OR + ks_test_uniform_random_int_in_range() AS uniform_int; + +CREATE FUNCTION ks_test_uniform_random_bigint_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 999999999999) / 1000000000000.0 r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql; + +SELECT ks_test_uniform_random_bigint_in_range() OR + ks_test_uniform_random_bigint_in_range() OR + ks_test_uniform_random_bigint_in_range() AS uniform_bigint; + +CREATE FUNCTION ks_test_uniform_random_numeric_in_range() +RETURNS boolean AS +$$ +DECLARE + n int := 1000; -- Number of samples + c float8 := 1.94947; -- Critical value for 99.9% confidence + ok boolean; +BEGIN + ok := ( + WITH samples AS ( + SELECT random(0, 0.999999) r FROM generate_series(1, n) ORDER BY 1 + ), indexed_samples AS ( + SELECT (row_number() OVER())-1.0 i, r FROM samples + ) + SELECT max(abs(i/n-r)) < c / sqrt(n) FROM indexed_samples + ); + RETURN ok; +END +$$ +LANGUAGE plpgsql; + +SELECT ks_test_uniform_random_numeric_in_range() OR + ks_test_uniform_random_numeric_in_range() OR + ks_test_uniform_random_numeric_in_range() AS uniform_numeric; + +SELECT setseed(0.5); + +SELECT random() FROM generate_series(1, 10); + +SET extra_float_digits = -1; + +SELECT random_normal() FROM generate_series(1, 10); + +SELECT random_normal(mean => 1, stddev => 0.1) r FROM generate_series(1, 10); + +SELECT random(1, 6) FROM generate_series(1, 10); + +SELECT random(-2147483648, 2147483647) FROM generate_series(1, 10); + +SELECT random(-9223372036854775808, 9223372036854775807) FROM generate_series(1, 10); + +SELECT random(-1e30, 1e30) FROM generate_series(1, 10); + +SELECT random(-0.4, 0.4) FROM generate_series(1, 10); + +SELECT random(0, 1 - 1e-30) FROM generate_series(1, 10); + +SELECT n, random(0, trim_scale(abs(1 - 10.0^(-n)))) FROM generate_series(-20, 20) n; + +SELECT random('1979-02-08'::date,'2025-07-03'::date) AS random_date_multiple_years; + +SELECT random('4714-11-24 BC'::date,'5874897-12-31 AD'::date) AS random_date_maximum_range; + +SELECT random('1979-02-08'::date,'1979-02-08'::date) AS random_date_empty_range; + +SELECT random('2024-12-31'::date, '2024-01-01'::date); + +SELECT random('-infinity'::date, '2024-01-01'::date); + +SELECT random('2024-12-31'::date, 'infinity'::date); + +SELECT random('1979-02-08'::timestamp,'2025-07-03'::timestamp) AS random_timestamp_multiple_years; + +SELECT random('4714-11-24 BC'::timestamp,'294276-12-31 23:59:59.999999'::timestamp) AS random_timestamp_maximum_range; + +SELECT random('2024-07-01 12:00:00.000001'::timestamp, '2024-07-01 12:00:00.999999'::timestamp) AS random_narrow_range; + +SELECT random('1979-02-08'::timestamp,'1979-02-08'::timestamp) AS random_timestamp_empty_range; + +SELECT random('2024-12-31'::timestamp, '2024-01-01'::timestamp); + +SELECT random('-infinity'::timestamp, '2024-01-01'::timestamp); + +SELECT random('2024-12-31'::timestamp, 'infinity'::timestamp); + +SELECT random('1979-02-08 +01'::timestamptz,'2025-07-03 +02'::timestamptz) AS random_timestamptz_multiple_years; + +SELECT random('4714-11-24 BC +00'::timestamptz,'294276-12-31 23:59:59.999999 +00'::timestamptz) AS random_timestamptz_maximum_range; + +SELECT random('2024-07-01 12:00:00.000001 +04'::timestamptz, '2024-07-01 12:00:00.999999 +04'::timestamptz) AS random_timestamptz_narrow_range; + +SELECT random('1979-02-08 +05'::timestamptz,'1979-02-08 +05'::timestamptz) AS random_timestamptz_empty_range; + +SELECT random('2024-01-01 +06'::timestamptz, '2024-01-01 +07'::timestamptz); + +SELECT random('-infinity'::timestamptz, '2024-01-01 +07'::timestamptz); + +SELECT random('2024-01-01 +06'::timestamptz, 'infinity'::timestamptz); diff --git a/crates/pgt_pretty_print/tests/data/multi/rangefuncs_60.sql b/crates/pgt_pretty_print/tests/data/multi/rangefuncs_60.sql new file mode 100644 index 000000000..2f9fb9950 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/rangefuncs_60.sql @@ -0,0 +1,987 @@ +CREATE TABLE rngfunc2(rngfuncid int, f2 int); + +INSERT INTO rngfunc2 VALUES(1, 11); + +INSERT INTO rngfunc2 VALUES(2, 22); + +INSERT INTO rngfunc2 VALUES(1, 111); + +CREATE FUNCTION rngfunct(int) returns setof rngfunc2 as 'SELECT * FROM rngfunc2 WHERE rngfuncid = $1 ORDER BY f2;' LANGUAGE SQL; + +select * from rngfunct(1) with ordinality as z(a,b,ord); + +select * from rngfunct(1) with ordinality as z(a,b,ord) where b > 100; + +select a,b,ord from rngfunct(1) with ordinality as z(a,b,ord); + +select a,ord from unnest(array['a','b']) with ordinality as z(a,ord); + +select * from unnest(array['a','b']) with ordinality as z(a,ord); + +select a,ord from unnest(array[1.0::float8]) with ordinality as z(a,ord); + +select * from unnest(array[1.0::float8]) with ordinality as z(a,ord); + +select row_to_json(s.*) from generate_series(11,14) with ordinality s; + +create temporary view vw_ord as select * from (values (1)) v(n) join rngfunct(1) with ordinality as z(a,b,ord) on (n=ord); + +select * from vw_ord; + +select definition from pg_views where viewname='vw_ord'; + +drop view vw_ord; + +select * from rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord); + +create temporary view vw_ord as select * from (values (1)) v(n) join rows from(rngfunct(1),rngfunct(2)) with ordinality as z(a,b,c,d,ord) on (n=ord); + +select * from vw_ord; + +select definition from pg_views where viewname='vw_ord'; + +drop view vw_ord; + +select * from unnest(array[10,20],array['foo','bar'],array[1.0]); + +select * from unnest(array[10,20],array['foo','bar'],array[1.0]) with ordinality as z(a,b,c,ord); + +select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) with ordinality as z(a,b,c,ord); + +select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(101,102)) with ordinality as z(a,b,c,ord); + +create temporary view vw_ord as select * from unnest(array[10,20],array['foo','bar'],array[1.0]) as z(a,b,c); + +select * from vw_ord; + +select definition from pg_views where viewname='vw_ord'; + +drop view vw_ord; + +create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) as z(a,b,c); + +select * from vw_ord; + +select definition from pg_views where viewname='vw_ord'; + +drop view vw_ord; + +create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(1,2)) as z(a,b,c); + +select * from vw_ord; + +select definition from pg_views where viewname='vw_ord'; + +drop view vw_ord; + +begin; + +declare rf_cur scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o); + +fetch all from rf_cur; + +fetch backward all from rf_cur; + +fetch all from rf_cur; + +fetch next from rf_cur; + +fetch next from rf_cur; + +fetch prior from rf_cur; + +fetch absolute 1 from rf_cur; + +fetch next from rf_cur; + +fetch next from rf_cur; + +fetch next from rf_cur; + +fetch prior from rf_cur; + +fetch prior from rf_cur; + +fetch prior from rf_cur; + +commit; + +select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) z where rngfunc2.f2 = z.f2; + +select * from rngfunc2, rngfunct(rngfunc2.rngfuncid) with ordinality as z(rngfuncid,f2,ord) where rngfunc2.f2 = z.f2; + +select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2; + +select * from rngfunc2 where f2 in (select f2 from rngfunct(1) z where z.rngfuncid = rngfunc2.rngfuncid) ORDER BY 1,2; + +select * from rngfunc2 where f2 in (select f2 from rngfunct(rngfunc2.rngfuncid) z where z.rngfuncid = 1) ORDER BY 1,2; + +select rngfunct.rngfuncid, rngfunct.f2 from rngfunct(sin(pi()/2)::int) ORDER BY 1,2; + +CREATE TABLE rngfunc (rngfuncid int, rngfuncsubid int, rngfuncname text, primary key(rngfuncid,rngfuncsubid)); + +INSERT INTO rngfunc VALUES(1,1,'Joe'); + +INSERT INTO rngfunc VALUES(1,2,'Ed'); + +INSERT INTO rngfunc VALUES(2,1,'Mary'); + +CREATE FUNCTION getrngfunc1(int) RETURNS int AS 'SELECT $1;' LANGUAGE SQL; + +SELECT * FROM getrngfunc1(1) AS t1; + +SELECT * FROM getrngfunc1(1) WITH ORDINALITY AS t1(v,o); + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc1(1) WITH ORDINALITY as t1(v,o); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc2(int) RETURNS setof int AS 'SELECT rngfuncid FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL; + +SELECT * FROM getrngfunc2(1) AS t1; + +SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o); + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc2(1) WITH ORDINALITY AS t1(v,o); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc3(int) RETURNS setof text AS 'SELECT rngfuncname FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL; + +SELECT * FROM getrngfunc3(1) AS t1; + +SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o); + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc3(1) WITH ORDINALITY AS t1(v,o); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc4(int) RETURNS rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL; + +SELECT * FROM getrngfunc4(1) AS t1; + +SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o); + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1) WITH ORDINALITY AS t1(a,b,c,o); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc5(int) RETURNS setof rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL; + +SELECT * FROM getrngfunc5(1) AS t1; + +SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o); + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1) WITH ORDINALITY AS t1(a,b,c,o); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc6(int) RETURNS RECORD AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL; + +SELECT * FROM getrngfunc6(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text); + +SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc6(1) AS +(rngfuncid int, rngfuncsubid int, rngfuncname text); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS + SELECT * FROM ROWS FROM( getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) + WITH ORDINALITY; + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc7(int) RETURNS setof record AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL; + +SELECT * FROM getrngfunc7(1) AS t1(rngfuncid int, rngfuncsubid int, rngfuncname text); + +SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) WITH ORDINALITY; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc7(1) AS +(rngfuncid int, rngfuncsubid int, rngfuncname text); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS + SELECT * FROM ROWS FROM( getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text) ) + WITH ORDINALITY; + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc8(int) RETURNS int AS 'DECLARE rngfuncint int; BEGIN SELECT rngfuncid into rngfuncint FROM rngfunc WHERE rngfuncid = $1; RETURN rngfuncint; END;' LANGUAGE plpgsql; + +SELECT * FROM getrngfunc8(1) AS t1; + +SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o); + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc8(1) WITH ORDINALITY AS t1(v,o); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE FUNCTION getrngfunc9(int) RETURNS rngfunc AS 'DECLARE rngfunctup rngfunc%ROWTYPE; BEGIN SELECT * into rngfunctup FROM rngfunc WHERE rngfuncid = $1; RETURN rngfunctup; END;' LANGUAGE plpgsql; + +SELECT * FROM getrngfunc9(1) AS t1; + +SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o); + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1) WITH ORDINALITY AS t1(a,b,c,o); + +SELECT * FROM vw_getrngfunc; + +DROP VIEW vw_getrngfunc; + +select * from rows from(getrngfunc1(1),getrngfunc2(1),getrngfunc3(1),getrngfunc4(1),getrngfunc5(1), + getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc8(1),getrngfunc9(1)) + with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u); + +select * from rows from(getrngfunc9(1),getrngfunc8(1), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc6(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc5(1),getrngfunc4(1),getrngfunc3(1),getrngfunc2(1),getrngfunc1(1)) + with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u); + +create temporary view vw_rngfunc as + select * from rows from(getrngfunc9(1), + getrngfunc7(1) AS (rngfuncid int, rngfuncsubid int, rngfuncname text), + getrngfunc1(1)) + with ordinality as t1(a,b,c,d,e,f,g,n); + +select * from vw_rngfunc; + +select pg_get_viewdef('vw_rngfunc'); + +drop view vw_rngfunc; + +DROP FUNCTION getrngfunc1(int); + +DROP FUNCTION getrngfunc2(int); + +DROP FUNCTION getrngfunc3(int); + +DROP FUNCTION getrngfunc4(int); + +DROP FUNCTION getrngfunc5(int); + +DROP FUNCTION getrngfunc6(int); + +DROP FUNCTION getrngfunc7(int); + +DROP FUNCTION getrngfunc8(int); + +DROP FUNCTION getrngfunc9(int); + +DROP FUNCTION rngfunct(int); + +DROP TABLE rngfunc2; + +DROP TABLE rngfunc; + +CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq1; + +CREATE TEMPORARY SEQUENCE rngfunc_rescan_seq2; + +CREATE TYPE rngfunc_rescan_t AS (i integer, s bigint); + +CREATE FUNCTION rngfunc_sql(int,int) RETURNS setof rngfunc_rescan_t AS 'SELECT i, nextval(''rngfunc_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL; + +CREATE FUNCTION rngfunc_mat(int,int) RETURNS setof rngfunc_rescan_t AS 'begin for i in $1..$2 loop return next (i, nextval(''rngfunc_rescan_seq2'')); end loop; end;' LANGUAGE plpgsql; + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) ON (r+i)<100; + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_sql(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100; + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) ON (r+i)<100; + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN rngfunc_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100; + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( rngfunc_sql(11,13), rngfunc_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100; + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) f(i) ON (r+i)<100; + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) WITH ORDINALITY AS f(i,o) ON (r+i)<100; + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) f(i) ON (r+i)<100; + +SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN unnest(array[10,20,30]) WITH ORDINALITY AS f(i,o) ON (r+i)<100; + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(10+r,13) WITH ORDINALITY AS f(i,s,o); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_sql(11,10+r) WITH ORDINALITY AS f(i,s,o); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_sql(r1,r2) WITH ORDINALITY AS f(i,s,o); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(10+r,13) WITH ORDINALITY AS f(i,s,o); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), rngfunc_mat(11,10+r) WITH ORDINALITY AS f(i,s,o); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), rngfunc_mat(r1,r2) WITH ORDINALITY AS f(i,s,o); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(11,11), rngfunc_mat(10+r,13) ); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(11,11) ); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( rngfunc_sql(10+r,13), rngfunc_mat(10+r,13) ); + +SELECT setval('rngfunc_rescan_seq1',1,false),setval('rngfunc_rescan_seq2',1,false); + +SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( rngfunc_sql(10+r1,13), rngfunc_mat(10+r2,13) ); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) f(i); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) WITH ORDINALITY AS f(i,o); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), unnest(array[r*10,r*20,r*30]) f(i); + +SELECT * FROM (VALUES (1),(2),(3)) v(r), unnest(array[r*10,r*20,r*30]) WITH ORDINALITY AS f(i,o); + +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(21,23) f(i) ON ((r2+i)<100) OFFSET 0) s1; + +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(20+r1,23) f(i) ON ((r2+i)<100) OFFSET 0) s1; + +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(r2,r2+3) f(i) ON ((r2+i)<100) OFFSET 0) s1; + +SELECT * FROM (VALUES (1),(2),(3)) v1(r1), + LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) + LEFT JOIN generate_series(r1,2+r2/5) f(i) ON ((r2+i)<100) OFFSET 0) s1; + +SELECT * +FROM (VALUES (1),(2)) v1(r1) + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, v1.r1) AS gs1 + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, gs1) AS gs2 + LEFT JOIN generate_series(1, gs2) AS gs3 ON TRUE + ) AS ss1 ON TRUE + FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE + ) AS ss0 ON TRUE; + +DROP FUNCTION rngfunc_sql(int,int); + +DROP FUNCTION rngfunc_mat(int,int); + +DROP SEQUENCE rngfunc_rescan_seq1; + +DROP SEQUENCE rngfunc_rescan_seq2; + +CREATE FUNCTION rngfunc(in f1 int, out f2 int) +AS 'select $1+1' LANGUAGE sql; + +SELECT rngfunc(42); + +SELECT * FROM rngfunc(42); + +SELECT * FROM rngfunc(42) AS p(x); + +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS int +AS 'select $1+1' LANGUAGE sql; + +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS float +AS 'select $1+1' LANGUAGE sql; + +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) RETURNS int +AS 'select $1+1' LANGUAGE sql; + +CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) +RETURNS record +AS 'select $1+1' LANGUAGE sql; + +CREATE OR REPLACE FUNCTION rngfuncr(in f1 int, out f2 int, out text) +AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql; + +SELECT f1, rngfuncr(f1) FROM int4_tbl; + +SELECT * FROM rngfuncr(42); + +SELECT * FROM rngfuncr(42) AS p(a,b); + +CREATE OR REPLACE FUNCTION rngfuncb(in f1 int, inout f2 int, out text) +AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql; + +SELECT f1, rngfuncb(f1, f1/2) FROM int4_tbl; + +SELECT * FROM rngfuncb(42, 99); + +SELECT * FROM rngfuncb(42, 99) AS p(a,b); + +DROP FUNCTION rngfunc(int); + +DROP FUNCTION rngfuncr(in f2 int, out f1 int, out text); + +DROP FUNCTION rngfuncb(in f1 int, inout f2 int); + +CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray) +AS 'select $1, array[$1,$1]' LANGUAGE sql; + +SELECT dup(22); + +SELECT dup('xyz'); + +SELECT dup('xyz'::text); + +SELECT * FROM dup('xyz'::text); + +CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray) +AS 'select $1, array[$1,$1]' LANGUAGE sql; + +DROP FUNCTION dup(anyelement); + +CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray) +AS 'select $1, array[$1,$1]' LANGUAGE sql; + +SELECT dup(22); + +DROP FUNCTION dup(anyelement); + +CREATE FUNCTION bad (f1 int, out f2 anyelement, out f3 anyarray) +AS 'select $1, array[$1,$1]' LANGUAGE sql; + +CREATE FUNCTION dup (f1 anycompatible, f2 anycompatiblearray, f3 out anycompatible, f4 out anycompatiblearray) +AS 'select $1, $2' LANGUAGE sql; + +SELECT dup(22, array[44]); + +SELECT dup(4.5, array[44]); + +SELECT dup(22, array[44::bigint]); + +SELECT *, pg_typeof(f3), pg_typeof(f4) FROM dup(22, array[44::bigint]); + +DROP FUNCTION dup(f1 anycompatible, f2 anycompatiblearray); + +CREATE FUNCTION dup (f1 anycompatiblerange, f2 out anycompatible, f3 out anycompatiblearray, f4 out anycompatiblerange) +AS 'select lower($1), array[lower($1), upper($1)], $1' LANGUAGE sql; + +SELECT dup(int4range(4,7)); + +SELECT dup(numrange(4,7)); + +SELECT dup(textrange('aaa', 'bbb')); + +DROP FUNCTION dup(f1 anycompatiblerange); + +CREATE FUNCTION bad (f1 anyarray, out f2 anycompatible, out f3 anycompatiblearray) +AS 'select $1, array[$1,$1]' LANGUAGE sql; + +CREATE OR REPLACE FUNCTION rngfunc() +RETURNS TABLE(a int) +AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql; + +SELECT * FROM rngfunc(); + +DROP FUNCTION rngfunc(); + +CREATE OR REPLACE FUNCTION rngfunc(int) +RETURNS TABLE(a int, b int) +AS $$ SELECT a, b + FROM generate_series(1,$1) a(a), + generate_series(1,$1) b(b) $$ LANGUAGE sql; + +SELECT * FROM rngfunc(3); + +DROP FUNCTION rngfunc(int); + +CREATE OR REPLACE FUNCTION rngfunc() +RETURNS TABLE(a varchar(5)) +AS $$ SELECT 'hello'::varchar(5) $$ LANGUAGE sql STABLE; + +SELECT * FROM rngfunc() GROUP BY 1; + +DROP FUNCTION rngfunc(); + +create temp table tt(f1 serial, data text); + +create function insert_tt(text) returns int as +$$ insert into tt(data) values($1) returning f1 $$ +language sql; + +select insert_tt('foo'); + +select insert_tt('bar'); + +select * from tt; + +create or replace function insert_tt(text) returns int as +$$ insert into tt(data) values($1),($1||$1) returning f1 $$ +language sql; + +select insert_tt('fool'); + +select * from tt; + +create or replace function insert_tt2(text,text) returns setof int as +$$ insert into tt(data) values($1),($2) returning f1 $$ +language sql; + +select insert_tt2('foolish','barrish'); + +select * from insert_tt2('baz','quux'); + +select * from tt; + +select insert_tt2('foolish','barrish') limit 1; + +select * from tt; + +create function noticetrigger() returns trigger as $$ +begin + raise notice 'noticetrigger % %', new.f1, new.data; + return null; +end $$ language plpgsql; + +create trigger tnoticetrigger after insert on tt for each row +execute procedure noticetrigger(); + +select insert_tt2('foolme','barme') limit 1; + +select * from tt; + +create temp table tt_log(f1 int, data text); + +create rule insert_tt_rule as on insert to tt do also + insert into tt_log values(new.*); + +select insert_tt2('foollog','barlog') limit 1; + +select * from tt; + +select * from tt_log; + +create function rngfunc1(n integer, out a text, out b text) + returns setof record + language sql + as $$ select 'foo ' || i, 'bar ' || i from generate_series(1,$1) i $$; + +set work_mem='64kB'; + +select t.a, t, t.a from rngfunc1(10000) t limit 1; + +reset work_mem; + +select t.a, t, t.a from rngfunc1(10000) t limit 1; + +drop function rngfunc1(n integer); + +create function array_to_set(anyarray) returns setof record as $$ + select i AS "index", $1[i] AS "value" from generate_subscripts($1, 1) i +$$ language sql strict immutable; + +select array_to_set(array['one', 'two']); + +select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text); + +select * from array_to_set(array['one', 'two']); + +select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); + +select * from array_to_set(array['one', 'two']) as t(f1 point,f2 text); + +select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); + +create or replace function array_to_set(anyarray) returns setof record as $$ + select i AS "index", $1[i] AS "value" from generate_subscripts($1, 1) i +$$ language sql immutable; + +select array_to_set(array['one', 'two']); + +select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text); + +select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); + +select * from array_to_set(array['one', 'two']) as t(f1 point,f2 text); + +select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); + +create temp table rngfunc(f1 int8, f2 int8); + +create function testrngfunc() returns record as $$ + insert into rngfunc values (1,2) returning *; +$$ language sql; + +select testrngfunc(); + +select * from testrngfunc() as t(f1 int8,f2 int8); + +select * from testrngfunc(); + +drop function testrngfunc(); + +create function testrngfunc() returns setof record as $$ + insert into rngfunc values (1,2), (3,4) returning *; +$$ language sql; + +select testrngfunc(); + +select * from testrngfunc() as t(f1 int8,f2 int8); + +select * from testrngfunc(); + +drop function testrngfunc(); + +create type rngfunc_type as (f1 numeric(35,6), f2 numeric(35,2)); + +create function testrngfunc() returns rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql immutable; + +select testrngfunc(); + +select testrngfunc(); + +select * from testrngfunc(); + +select * from testrngfunc(); + +create or replace function testrngfunc() returns rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql volatile; + +select testrngfunc(); + +select testrngfunc(); + +select * from testrngfunc(); + +select * from testrngfunc(); + +drop function testrngfunc(); + +create function testrngfunc() returns setof rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql immutable; + +select testrngfunc(); + +select testrngfunc(); + +select * from testrngfunc(); + +select * from testrngfunc(); + +create or replace function testrngfunc() returns setof rngfunc_type as $$ + select 7.136178319899999964, 7.136178319899999964; +$$ language sql volatile; + +select testrngfunc(); + +select testrngfunc(); + +select * from testrngfunc(); + +select * from testrngfunc(); + +create or replace function testrngfunc() returns setof rngfunc_type as $$ + select 1, 2 union select 3, 4 order by 1; +$$ language sql immutable; + +select testrngfunc(); + +select testrngfunc(); + +select * from testrngfunc(); + +select * from testrngfunc(); + +select * from testrngfunc() as t(f1 int8,f2 int8); + +select * from pg_get_keywords() as t(f1 int8,f2 int8); + +select * from sin(3) as t(f1 int8,f2 int8); + +drop type rngfunc_type cascade; + +create temp table users (userid text, seq int, email text, todrop bool, moredrop int, enabled bool); + +insert into users values ('id',1,'email',true,11,true); + +insert into users values ('id2',2,'email2',true,12,true); + +alter table users drop column todrop; + +create or replace function get_first_user() returns users as +$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$ +language sql stable; + +SELECT get_first_user(); + +SELECT * FROM get_first_user(); + +create or replace function get_users() returns setof users as +$$ SELECT * FROM users ORDER BY userid; $$ +language sql stable; + +SELECT get_users(); + +SELECT * FROM get_users(); + +SELECT * FROM get_users() WITH ORDINALITY; + +SELECT * FROM ROWS FROM(generate_series(10,11), get_users()) WITH ORDINALITY; + +SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY; + +create temp view usersview as +SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY; + +select * from usersview; + +alter table users add column junk text; + +select * from usersview; + +alter table users drop column moredrop; + +begin; + +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'usersview'::regclass and rulename = '_RETURN') + and refobjsubid = 5 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype; + +alter table users drop column moredrop; + +select * from usersview; + +rollback; + +alter table users alter column seq type numeric; + +begin; + +delete from pg_depend where + objid = (select oid from pg_rewrite + where ev_class = 'usersview'::regclass and rulename = '_RETURN') + and refobjsubid = 2 +returning pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as ref, + deptype; + +alter table users alter column seq type numeric; + +select * from usersview; + +rollback; + +drop view usersview; + +drop function get_first_user(); + +drop function get_users(); + +drop table users; + +create or replace function rngfuncbar() returns setof text as +$$ select 'foo'::varchar union all select 'bar'::varchar ; $$ +language sql stable; + +select rngfuncbar(); + +select * from rngfuncbar(); + +select * from rngfuncbar(); + +drop function rngfuncbar(); + +create or replace function rngfuncbar(out integer, out numeric) as +$$ select (1, 2.1) $$ language sql; + +select * from rngfuncbar(); + +create or replace function rngfuncbar(out integer, out numeric) as +$$ select (1, 2) $$ language sql; + +select * from rngfuncbar(); + +create or replace function rngfuncbar(out integer, out numeric) as +$$ select (1, 2.1, 3) $$ language sql; + +select * from rngfuncbar(); + +drop function rngfuncbar(); + +create function extractq2(t int8_tbl) returns int8 as $$ + select t.q2 +$$ language sql immutable; + +select x from int8_tbl, extractq2(int8_tbl) f(x); + +select x from int8_tbl, extractq2(int8_tbl) f(x); + +create function extractq2_2(t int8_tbl) returns table(ret1 int8) as $$ + select extractq2(t) offset 0 +$$ language sql immutable; + +select x from int8_tbl, extractq2_2(int8_tbl) f(x); + +select x from int8_tbl, extractq2_2(int8_tbl) f(x); + +create function extractq2_2_opt(t int8_tbl) returns table(ret1 int8) as $$ + select extractq2(t) +$$ language sql immutable; + +select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x); + +select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x); + +create type rngfunc2 as (a integer, b text); + +select *, row_to_json(u) from unnest(array[(1,'foo')::rngfunc2, null::rngfunc2]) u; + +select *, row_to_json(u) from unnest(array[null::rngfunc2, null::rngfunc2]) u; + +select *, row_to_json(u) from unnest(array[null::rngfunc2, (1,'foo')::rngfunc2, null::rngfunc2]) u; + +select *, row_to_json(u) from unnest(array[]::rngfunc2[]) u; + +drop type rngfunc2; + +select * from + (select jsonb_path_query_array(module->'lectures', '$[*]') as lecture + from unnest(array['{"lectures": [{"id": "1"}]}'::jsonb]) + as unnested_modules(module)) as ss, + jsonb_to_recordset(ss.lecture) as j (id text); + +select * from + (select jsonb_path_query_array(module->'lectures', '$[*]') as lecture + from unnest(array['{"lectures": [{"id": "1"}]}'::jsonb]) + as unnested_modules(module)) as ss, + jsonb_to_recordset(ss.lecture) as j (id text); + +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int); + +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int, f int, g int); + +with a(b) as (values (row(1,2,3))) +select * from a, coalesce(b) as c(d int, e int, f float); + +select * from int8_tbl, coalesce(row(1)) as (a int, b int); diff --git a/crates/pgt_pretty_print/tests/data/multi/rangetypes_60.sql b/crates/pgt_pretty_print/tests/data/multi/rangetypes_60.sql new file mode 100644 index 000000000..8034083e8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/rangetypes_60.sql @@ -0,0 +1,848 @@ +select ''::textrange; + +select '-[a,z)'::textrange; + +select '[a,z) - '::textrange; + +select '(",a)'::textrange; + +select '(,,a)'::textrange; + +select '(),a)'::textrange; + +select '(a,))'::textrange; + +select '(],a)'::textrange; + +select '(a,])'::textrange; + +select '[z,a]'::textrange; + +select ' empty '::textrange; + +select ' ( empty, empty ) '::textrange; + +select ' ( " a " " a ", " z " " z " ) '::textrange; + +select '(a,)'::textrange; + +select '[,z]'::textrange; + +select '[a,]'::textrange; + +select '(,)'::textrange; + +select '[ , ]'::textrange; + +select '["",""]'::textrange; + +select '[",",","]'::textrange; + +select '["\\","\\"]'::textrange; + +select '(\\,a)'::textrange; + +select '((,z)'::textrange; + +select '([,z)'::textrange; + +select '(!,()'::textrange; + +select '(!,[)'::textrange; + +select '[a,a]'::textrange; + +select '[a,a)'::textrange; + +select '(a,a]'::textrange; + +select '(a,a)'::textrange; + +select pg_input_is_valid('(1,4)', 'int4range'); + +select pg_input_is_valid('(1,4', 'int4range'); + +select * from pg_input_error_info('(1,4', 'int4range'); + +select pg_input_is_valid('(4,1)', 'int4range'); + +select * from pg_input_error_info('(4,1)', 'int4range'); + +select pg_input_is_valid('(4,zed)', 'int4range'); + +select * from pg_input_error_info('(4,zed)', 'int4range'); + +select pg_input_is_valid('[1,2147483647]', 'int4range'); + +select * from pg_input_error_info('[1,2147483647]', 'int4range'); + +select pg_input_is_valid('[2000-01-01,5874897-12-31]', 'daterange'); + +select * from pg_input_error_info('[2000-01-01,5874897-12-31]', 'daterange'); + +CREATE TABLE numrange_test (nr NUMRANGE); + +create index numrange_test_btree on numrange_test(nr); + +INSERT INTO numrange_test VALUES('[,)'); + +INSERT INTO numrange_test VALUES('[3,]'); + +INSERT INTO numrange_test VALUES('[, 5)'); + +INSERT INTO numrange_test VALUES(numrange(1.1, 2.2)); + +INSERT INTO numrange_test VALUES('empty'); + +INSERT INTO numrange_test VALUES(numrange(1.7, 1.7, '[]')); + +SELECT nr, isempty(nr), lower(nr), upper(nr) FROM numrange_test; + +SELECT nr, lower_inc(nr), lower_inf(nr), upper_inc(nr), upper_inf(nr) FROM numrange_test; + +SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91)); + +SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1); + +SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr); + +SELECT * FROM numrange_test WHERE 1.9 <@ nr; + +select * from numrange_test where nr = 'empty'; + +select * from numrange_test where nr = '(1.1, 2.2)'; + +select * from numrange_test where nr = '[1.1, 2.2)'; + +select * from numrange_test where nr < 'empty'; + +select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]'); + +select * from numrange_test where nr < numrange(0.0, 1.0,'[]'); + +select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]'); + +select * from numrange_test where nr <= 'empty'; + +select * from numrange_test where nr >= 'empty'; + +select * from numrange_test where nr > 'empty'; + +select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]'); + +select * from numrange_test where nr > numrange(0.0, 1.0,'[]'); + +select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]'); + +select numrange(2.0, 1.0); + +select numrange(2.0, 3.0) -|- numrange(3.0, 4.0); + +select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0)); + +select range_adjacent(numrange(2.0, 3.0), numrange(3.1, null)); + +select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()'); + +select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]'); + +select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]')); + +select numrange(1.1, 3.3) <@ numrange(0.1,10.1); + +select numrange(0.1, 10.1) <@ numrange(1.1,3.3); + +select numrange(1.1, 2.2) - numrange(2.0, 3.0); + +select numrange(1.1, 2.2) - numrange(2.2, 3.0); + +select numrange(1.1, 2.2,'[]') - numrange(2.0, 3.0); + +select range_minus(numrange(10.1,12.2,'[]'), numrange(110.0,120.2,'(]')); + +select range_minus(numrange(10.1,12.2,'[]'), numrange(0.0,120.2,'(]')); + +select numrange(4.5, 5.5, '[]') && numrange(5.5, 6.5); + +select numrange(1.0, 2.0) << numrange(3.0, 4.0); + +select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]'); + +select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()'); + +select numrange(1.0, 2.0) >> numrange(3.0, 4.0); + +select numrange(3.0, 70.0) &< numrange(6.6, 100.0); + +select numrange(1.1, 2.2) < numrange(1.0, 200.2); + +select numrange(1.1, 2.2) < numrange(1.1, 1.2); + +select numrange(1.0, 2.0) + numrange(2.0, 3.0); + +select numrange(1.0, 2.0) + numrange(1.5, 3.0); + +select numrange(1.0, 2.0) + numrange(2.5, 3.0); + +select range_merge(numrange(1.0, 2.0), numrange(2.0, 3.0)); + +select range_merge(numrange(1.0, 2.0), numrange(1.5, 3.0)); + +select range_merge(numrange(1.0, 2.0), numrange(2.5, 3.0)); + +select numrange(1.0, 2.0) * numrange(2.0, 3.0); + +select numrange(1.0, 2.0) * numrange(1.5, 3.0); + +select numrange(1.0, 2.0) * numrange(2.5, 3.0); + +select range_intersect_agg(nr) from numrange_test; + +select range_intersect_agg(nr) from numrange_test where false; + +select range_intersect_agg(nr) from numrange_test where nr @> 4.0; + +analyze numrange_test; + +create table numrange_test2(nr numrange); + +create index numrange_test2_hash_idx on numrange_test2 using hash (nr); + +INSERT INTO numrange_test2 VALUES('[, 5)'); + +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); + +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); + +INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2,'()')); + +INSERT INTO numrange_test2 VALUES('empty'); + +select * from numrange_test2 where nr = 'empty'::numrange; + +select * from numrange_test2 where nr = numrange(1.1, 2.2); + +select * from numrange_test2 where nr = numrange(1.1, 2.3); + +set enable_nestloop=t; + +set enable_hashjoin=f; + +set enable_mergejoin=f; + +select * from numrange_test natural join numrange_test2 order by nr; + +set enable_nestloop=f; + +set enable_hashjoin=t; + +set enable_mergejoin=f; + +select * from numrange_test natural join numrange_test2 order by nr; + +set enable_nestloop=f; + +set enable_hashjoin=f; + +set enable_mergejoin=t; + +select * from numrange_test natural join numrange_test2 order by nr; + +set enable_nestloop to default; + +set enable_hashjoin to default; + +set enable_mergejoin to default; + +DROP TABLE numrange_test2; + +CREATE TABLE textrange_test (tr textrange); + +create index textrange_test_btree on textrange_test(tr); + +INSERT INTO textrange_test VALUES('[,)'); + +INSERT INTO textrange_test VALUES('["a",]'); + +INSERT INTO textrange_test VALUES('[,"q")'); + +INSERT INTO textrange_test VALUES(textrange('b', 'g')); + +INSERT INTO textrange_test VALUES('empty'); + +INSERT INTO textrange_test VALUES(textrange('d', 'd', '[]')); + +SELECT tr, isempty(tr), lower(tr), upper(tr) FROM textrange_test; + +SELECT tr, lower_inc(tr), lower_inf(tr), upper_inc(tr), upper_inf(tr) FROM textrange_test; + +SELECT * FROM textrange_test WHERE range_contains(tr, textrange('f', 'fx')); + +SELECT * FROM textrange_test WHERE tr @> textrange('a', 'z'); + +SELECT * FROM textrange_test WHERE range_contained_by(textrange('0','9'), tr); + +SELECT * FROM textrange_test WHERE 'e'::text <@ tr; + +select * from textrange_test where tr = 'empty'; + +select * from textrange_test where tr = '("b","g")'; + +select * from textrange_test where tr = '["b","g")'; + +select * from textrange_test where tr < 'empty'; + +select int4range(1, 10, '[]'); + +select int4range(1, 10, '[)'); + +select int4range(1, 10, '(]'); + +select int4range(1, 10, '()'); + +select int4range(1, 2, '()'); + +select daterange('2000-01-10'::date, '2000-01-20'::date, '[]'); + +select daterange('2000-01-10'::date, '2000-01-20'::date, '[)'); + +select daterange('2000-01-10'::date, '2000-01-20'::date, '(]'); + +select daterange('2000-01-10'::date, '2000-01-20'::date, '()'); + +select daterange('2000-01-10'::date, '2000-01-11'::date, '()'); + +select daterange('2000-01-10'::date, '2000-01-11'::date, '(]'); + +select daterange('-infinity'::date, '2000-01-01'::date, '()'); + +select daterange('-infinity'::date, '2000-01-01'::date, '[)'); + +select daterange('2000-01-01'::date, 'infinity'::date, '[)'); + +select daterange('2000-01-01'::date, 'infinity'::date, '[]'); + +create table test_range_gist(ir int4range); + +create index test_range_gist_idx on test_range_gist using gist (ir); + +insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g; + +insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g; + +insert into test_range_gist select int4range(g, g+10000) from generate_series(1,1000) g; + +insert into test_range_gist select 'empty'::int4range from generate_series(1,500) g; + +insert into test_range_gist select int4range(NULL,g*10,'(]') from generate_series(1,100) g; + +insert into test_range_gist select int4range(g*10,NULL,'(]') from generate_series(1,100) g; + +insert into test_range_gist select int4range(g, g+10) from generate_series(1,2000) g; + +analyze test_range_gist; + +SET enable_seqscan = t; + +SET enable_indexscan = f; + +SET enable_bitmapscan = f; + +select count(*) from test_range_gist where ir @> 'empty'::int4range; + +select count(*) from test_range_gist where ir = int4range(10,20); + +select count(*) from test_range_gist where ir @> 10; + +select count(*) from test_range_gist where ir @> int4range(10,20); + +select count(*) from test_range_gist where ir && int4range(10,20); + +select count(*) from test_range_gist where ir <@ int4range(10,50); + +select count(*) from test_range_gist where ir << int4range(100,500); + +select count(*) from test_range_gist where ir >> int4range(100,500); + +select count(*) from test_range_gist where ir &< int4range(100,500); + +select count(*) from test_range_gist where ir &> int4range(100,500); + +select count(*) from test_range_gist where ir -|- int4range(100,500); + +select count(*) from test_range_gist where ir @> '{}'::int4multirange; + +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)); + +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange; + +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange; + +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)); + +SET enable_seqscan = f; + +SET enable_indexscan = t; + +SET enable_bitmapscan = f; + +select count(*) from test_range_gist where ir @> 'empty'::int4range; + +select count(*) from test_range_gist where ir = int4range(10,20); + +select count(*) from test_range_gist where ir @> 10; + +select count(*) from test_range_gist where ir @> int4range(10,20); + +select count(*) from test_range_gist where ir && int4range(10,20); + +select count(*) from test_range_gist where ir <@ int4range(10,50); + +select count(*) from test_range_gist where ir << int4range(100,500); + +select count(*) from test_range_gist where ir >> int4range(100,500); + +select count(*) from test_range_gist where ir &< int4range(100,500); + +select count(*) from test_range_gist where ir &> int4range(100,500); + +select count(*) from test_range_gist where ir -|- int4range(100,500); + +select count(*) from test_range_gist where ir @> '{}'::int4multirange; + +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)); + +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange; + +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange; + +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)); + +drop index test_range_gist_idx; + +create index test_range_gist_idx on test_range_gist using gist (ir); + +select count(*) from test_range_gist where ir @> 'empty'::int4range; + +select count(*) from test_range_gist where ir = int4range(10,20); + +select count(*) from test_range_gist where ir @> 10; + +select count(*) from test_range_gist where ir @> int4range(10,20); + +select count(*) from test_range_gist where ir && int4range(10,20); + +select count(*) from test_range_gist where ir <@ int4range(10,50); + +select count(*) from test_range_gist where ir << int4range(100,500); + +select count(*) from test_range_gist where ir >> int4range(100,500); + +select count(*) from test_range_gist where ir &< int4range(100,500); + +select count(*) from test_range_gist where ir &> int4range(100,500); + +select count(*) from test_range_gist where ir -|- int4range(100,500); + +select count(*) from test_range_gist where ir @> '{}'::int4multirange; + +select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40)); + +select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange; + +select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange; + +select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500)); + +select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500)); + +create table test_range_spgist(ir int4range); + +create index test_range_spgist_idx on test_range_spgist using spgist (ir); + +insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g; + +insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g; + +insert into test_range_spgist select int4range(g, g+10000) from generate_series(1,1000) g; + +insert into test_range_spgist select 'empty'::int4range from generate_series(1,500) g; + +insert into test_range_spgist select int4range(NULL,g*10,'(]') from generate_series(1,100) g; + +insert into test_range_spgist select int4range(g*10,NULL,'(]') from generate_series(1,100) g; + +insert into test_range_spgist select int4range(g, g+10) from generate_series(1,2000) g; + +SET enable_seqscan = t; + +SET enable_indexscan = f; + +SET enable_bitmapscan = f; + +select count(*) from test_range_spgist where ir @> 'empty'::int4range; + +select count(*) from test_range_spgist where ir = int4range(10,20); + +select count(*) from test_range_spgist where ir @> 10; + +select count(*) from test_range_spgist where ir @> int4range(10,20); + +select count(*) from test_range_spgist where ir && int4range(10,20); + +select count(*) from test_range_spgist where ir <@ int4range(10,50); + +select count(*) from test_range_spgist where ir << int4range(100,500); + +select count(*) from test_range_spgist where ir >> int4range(100,500); + +select count(*) from test_range_spgist where ir &< int4range(100,500); + +select count(*) from test_range_spgist where ir &> int4range(100,500); + +select count(*) from test_range_spgist where ir -|- int4range(100,500); + +SET enable_seqscan = f; + +SET enable_indexscan = t; + +SET enable_bitmapscan = f; + +select count(*) from test_range_spgist where ir @> 'empty'::int4range; + +select count(*) from test_range_spgist where ir = int4range(10,20); + +select count(*) from test_range_spgist where ir @> 10; + +select count(*) from test_range_spgist where ir @> int4range(10,20); + +select count(*) from test_range_spgist where ir && int4range(10,20); + +select count(*) from test_range_spgist where ir <@ int4range(10,50); + +select count(*) from test_range_spgist where ir << int4range(100,500); + +select count(*) from test_range_spgist where ir >> int4range(100,500); + +select count(*) from test_range_spgist where ir &< int4range(100,500); + +select count(*) from test_range_spgist where ir &> int4range(100,500); + +select count(*) from test_range_spgist where ir -|- int4range(100,500); + +drop index test_range_spgist_idx; + +create index test_range_spgist_idx on test_range_spgist using spgist (ir); + +select count(*) from test_range_spgist where ir @> 'empty'::int4range; + +select count(*) from test_range_spgist where ir = int4range(10,20); + +select count(*) from test_range_spgist where ir @> 10; + +select count(*) from test_range_spgist where ir @> int4range(10,20); + +select count(*) from test_range_spgist where ir && int4range(10,20); + +select count(*) from test_range_spgist where ir <@ int4range(10,50); + +select count(*) from test_range_spgist where ir << int4range(100,500); + +select count(*) from test_range_spgist where ir >> int4range(100,500); + +select count(*) from test_range_spgist where ir &< int4range(100,500); + +select count(*) from test_range_spgist where ir &> int4range(100,500); + +select count(*) from test_range_spgist where ir -|- int4range(100,500); + +select ir from test_range_spgist where ir -|- int4range(10,20) order by ir; + +select ir from test_range_spgist where ir -|- int4range(10,20) order by ir; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +create table test_range_elem(i int4); + +create index test_range_elem_idx on test_range_elem (i); + +insert into test_range_elem select i from generate_series(1,100) i; + +SET enable_seqscan = f; + +select count(*) from test_range_elem where i <@ int4range(10,50); + +create index on test_range_elem using spgist(int4range(i,i+10)); + +select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30); + +select count(*) from test_range_elem where int4range(i,i+10) <@ int4range(10,30); + +RESET enable_seqscan; + +drop table test_range_elem; + +create table test_range_excl( + room int4range, + speaker int4range, + during tsrange, + exclude using gist (room with =, during with &&), + exclude using gist (speaker with =, during with &&) +); + +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:00, 2010-01-02 11:00)'); + +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(2, 2, '[]'), '[2010-01-02 11:00, 2010-01-02 12:00)'); + +insert into test_range_excl + values(int4range(123, 123, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)'); + +insert into test_range_excl + values(int4range(124, 124, '[]'), int4range(3, 3, '[]'), '[2010-01-02 10:10, 2010-01-02 11:10)'); + +insert into test_range_excl + values(int4range(125, 125, '[]'), int4range(1, 1, '[]'), '[2010-01-02 10:10, 2010-01-02 11:00)'); + +select int8range(10000000000::int8, 20000000000::int8,'(]'); + +set timezone to '-08'; + +select '[2010-01-01 01:00:00 -05, 2010-01-01 02:00:00 -08)'::tstzrange; + +select '[2010-01-01 01:00:00 -08, 2010-01-01 02:00:00 -05)'::tstzrange; + +set timezone to default; + +create type bogus_float8range as range (subtype=float8, subtype_diff=float4mi); + +select '[123.001, 5.e9)'::float8range @> 888.882::float8; + +create table float8range_test(f8r float8range, i int); + +insert into float8range_test values(float8range(-100.00007, '1.111113e9'), 42); + +select * from float8range_test; + +drop table float8range_test; + +create domain mydomain as int4; + +create type mydomainrange as range(subtype=mydomain); + +select '[4,50)'::mydomainrange @> 7::mydomain; + +drop domain mydomain; + +drop domain mydomain cascade; + +create domain restrictedrange as int4range check (upper(value) < 10); + +select '[4,5)'::restrictedrange @> 7; + +select '[4,50)'::restrictedrange @> 7; + +drop domain restrictedrange; + +create type textrange1 as range(subtype=text, collation="C"); + +create type textrange2 as range(subtype=text, collation="C"); + +select textrange1('a','Z') @> 'b'::text; + +select textrange2('a','z') @> 'b'::text; + +drop type textrange1; + +drop type textrange2; + +create function anyarray_anyrange_func(a anyarray, r anyrange) + returns anyelement as 'select $1[1] + lower($2);' language sql; + +select anyarray_anyrange_func(ARRAY[1,2], int4range(10,20)); + +select anyarray_anyrange_func(ARRAY[1,2], numrange(10,20)); + +drop function anyarray_anyrange_func(anyarray, anyrange); + +create function bogus_func(anyelement) + returns anyrange as 'select int4range(1,10)' language sql; + +create function bogus_func(int) + returns anyrange as 'select int4range(1,10)' language sql; + +create function range_add_bounds(anyrange) + returns anyelement as 'select lower($1) + upper($1)' language sql; + +select range_add_bounds(int4range(1, 17)); + +select range_add_bounds(numrange(1.0001, 123.123)); + +create function rangetypes_sql(q anyrange, b anyarray, out c anyelement) + as $$ select upper($1) + $2[1] $$ + language sql; + +select rangetypes_sql(int4range(1,10), ARRAY[2,20]); + +select rangetypes_sql(numrange(1,10), ARRAY[2,20]); + +create function anycompatiblearray_anycompatiblerange_func(a anycompatiblearray, r anycompatiblerange) + returns anycompatible as 'select $1[1] + lower($2);' language sql; + +select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], int4range(10,20)); + +select anycompatiblearray_anycompatiblerange_func(ARRAY[1,2], numrange(10,20)); + +select anycompatiblearray_anycompatiblerange_func(ARRAY[1.1,2], int4range(10,20)); + +drop function anycompatiblearray_anycompatiblerange_func(anycompatiblearray, anycompatiblerange); + +create function bogus_func(anycompatible) + returns anycompatiblerange as 'select int4range(1,10)' language sql; + +select ARRAY[numrange(1.1, 1.2), numrange(12.3, 155.5)]; + +create table i8r_array (f1 int, f2 int8range[]); + +insert into i8r_array values (42, array[int8range(1,10), int8range(2,20)]); + +select * from i8r_array; + +drop table i8r_array; + +create type arrayrange as range (subtype=int4[]); + +select arrayrange(ARRAY[1,2], ARRAY[2,1]); + +select arrayrange(ARRAY[2,1], ARRAY[1,2]); + +select array[1,1] <@ arrayrange(array[1,2], array[2,1]); + +select array[1,3] <@ arrayrange(array[1,2], array[2,1]); + +create type two_ints as (a int, b int); + +create type two_ints_range as range (subtype = two_ints); + +select *, row_to_json(upper(t)) as u from + (values (two_ints_range(row(1,2), row(3,4))), + (two_ints_range(row(5,6), row(7,8)))) v(t); + +alter type two_ints add attribute c two_ints_range; + +drop type two_ints cascade; + +create type varbitrange as range (subtype = varbit); + +set enable_sort = off; + +select '(01,10)'::varbitrange except select '(10,11)'::varbitrange; + +reset enable_sort; + +create function outparam_succeed(i anyrange, out r anyrange, out t text) + as $$ select $1, 'foo'::text $$ language sql; + +select * from outparam_succeed(int4range(1,2)); + +create function outparam2_succeed(r anyrange, out lu anyarray, out ul anyarray) + as $$ select array[lower($1), upper($1)], array[upper($1), lower($1)] $$ + language sql; + +select * from outparam2_succeed(int4range(1,11)); + +create function outparam_succeed2(i anyrange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql; + +select * from outparam_succeed2(int4range(int4range(1,2))); + +create function inoutparam_succeed(out i anyelement, inout r anyrange) + as $$ select upper($1), $1 $$ language sql; + +select * from inoutparam_succeed(int4range(1,2)); + +create function table_succeed(r anyrange) + returns table(l anyelement, u anyelement) + as $$ select lower($1), upper($1) $$ + language sql; + +select * from table_succeed(int4range(1,11)); + +create function outparam_fail(i anyelement, out r anyrange, out t text) + as $$ select '[1,10]', 'foo' $$ language sql; + +create function inoutparam_fail(inout i anyelement, out r anyrange) + as $$ select $1, '[1,10]' $$ language sql; + +create function table_fail(i anyelement) returns table(i anyelement, r anyrange) + as $$ select $1, '[1,10]' $$ language sql; + +select current_date <@ daterange 'empty'; + +select current_date <@ daterange(NULL, NULL); + +select current_date <@ daterange('2000-01-01', NULL, '[)'); + +select current_date <@ daterange(NULL, '2000-01-01', '(]'); + +select current_date <@ daterange('-Infinity', '1997-04-10'::date, '()'); + +select current_date <@ daterange('-Infinity', '1997-04-10'::date, '[)'); + +select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[)'); + +select current_date <@ daterange('2002-09-25'::date, 'Infinity', '[]'); + +select daterange('-Infinity', '1997-04-10'::date, '()') @> current_date; + +select daterange('2002-09-25'::date, 'Infinity', '[]') @> current_date; + +select now() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00'); + +select clock_timestamp() <@ tstzrange('2024-01-20 00:00', '2024-01-21 00:00'); + +select clock_timestamp() <@ tstzrange('2024-01-20 00:00', NULL); + +create type textrange_supp as range ( + subtype = text, + subtype_opclass = text_pattern_ops +); + +create temp table text_support_test (t text collate "C"); + +insert into text_support_test values ('a'), ('c'), ('d'), ('ch'); + +select * from text_support_test where t <@ textrange_supp('a', 'd'); + +select * from text_support_test where t <@ textrange_supp('a', 'd'); + +drop table text_support_test; + +drop type textrange_supp; diff --git a/crates/pgt_pretty_print/tests/data/multi/regex_60.sql b/crates/pgt_pretty_print/tests/data/multi/regex_60.sql new file mode 100644 index 000000000..ac21eccee --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/regex_60.sql @@ -0,0 +1,210 @@ +set standard_conforming_strings = on; + +select 'bbbbb' ~ '^([bc])\1*$' as t; + +select 'ccc' ~ '^([bc])\1*$' as t; + +select 'xxx' ~ '^([bc])\1*$' as f; + +select 'bbc' ~ '^([bc])\1*$' as f; + +select 'b' ~ '^([bc])\1*$' as t; + +select 'abc abc abc' ~ '^(\w+)( \1)+$' as t; + +select 'abc abd abc' ~ '^(\w+)( \1)+$' as f; + +select 'abc abc abd' ~ '^(\w+)( \1)+$' as f; + +select 'abc abc abc' ~ '^(.+)( \1)+$' as t; + +select 'abc abd abc' ~ '^(.+)( \1)+$' as f; + +select 'abc abc abd' ~ '^(.+)( \1)+$' as f; + +select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)'); + +select substring('a' from '((a))+'); + +select substring('a' from '((a)+)'); + +select regexp_match('abc', ''); + +select regexp_match('abc', 'bc'); + +select regexp_match('abc', 'd') is null; + +select regexp_match('abc', '(B)(c)', 'i'); + +select regexp_match('abc', 'Bd', 'ig'); + +select regexp_matches('ab', 'a(?=b)b*'); + +select regexp_matches('a', 'a(?=b)b*'); + +select regexp_matches('abc', 'a(?=b)b*(?=c)c*'); + +select regexp_matches('ab', 'a(?=b)b*(?=c)c*'); + +select regexp_matches('ab', 'a(?!b)b*'); + +select regexp_matches('a', 'a(?!b)b*'); + +select regexp_matches('b', '(?=b)b'); + +select regexp_matches('a', '(?=b)b'); + +select regexp_matches('abb', '(?<=a)b*'); + +select regexp_matches('a', 'a(?<=a)b*'); + +select regexp_matches('abc', 'a(?<=a)b*(?<=b)c*'); + +select regexp_matches('ab', 'a(?<=a)b*(?<=b)c*'); + +select regexp_matches('ab', 'a*(? 0; + +SELECT reloptions FROM pg_class WHERE oid = + (SELECT reltoastrelid FROM pg_class + WHERE oid = 'reloptions_test'::regclass); + +ALTER TABLE reloptions_test RESET (vacuum_truncate); + +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); + +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) reloptions_test; + +SELECT pg_relation_size('reloptions_test') = 0; + +DROP TABLE reloptions_test; + +CREATE TABLE reloptions_test (s VARCHAR) + WITH (toast.autovacuum_vacuum_cost_delay = 23); + +SELECT reltoastrelid as toast_oid + FROM pg_class WHERE oid = 'reloptions_test'::regclass ; + +SELECT reloptions FROM pg_class WHERE oid = 'toast_oid'; + +ALTER TABLE reloptions_test SET (toast.autovacuum_vacuum_cost_delay = 24); + +SELECT reloptions FROM pg_class WHERE oid = 'toast_oid'; + +ALTER TABLE reloptions_test RESET (toast.autovacuum_vacuum_cost_delay); + +SELECT reloptions FROM pg_class WHERE oid = 'toast_oid'; + +CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42); + +DROP TABLE reloptions_test; + +CREATE TABLE reloptions_test (s VARCHAR) WITH + (toast.autovacuum_vacuum_cost_delay = 23, + autovacuum_vacuum_cost_delay = 24, fillfactor = 40); + +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +SELECT reloptions FROM pg_class WHERE oid = ( + SELECT reltoastrelid FROM pg_class WHERE oid = 'reloptions_test'::regclass); + +CREATE INDEX reloptions_test_idx ON reloptions_test (s) WITH (fillfactor=30); + +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; + +CREATE INDEX reloptions_test_idx ON reloptions_test (s) + WITH (not_existing_option=2); + +CREATE INDEX reloptions_test_idx ON reloptions_test (s) + WITH (not_existing_ns.fillfactor=2); + +CREATE INDEX reloptions_test_idx2 ON reloptions_test (s) WITH (fillfactor=1); + +CREATE INDEX reloptions_test_idx2 ON reloptions_test (s) WITH (fillfactor=130); + +ALTER INDEX reloptions_test_idx SET (fillfactor=40); + +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx'::regclass; + +CREATE INDEX reloptions_test_idx3 ON reloptions_test (s); + +ALTER INDEX reloptions_test_idx3 SET (fillfactor=40); + +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test_idx3'::regclass; diff --git a/crates/pgt_pretty_print/tests/data/multi/replica_identity_60.sql b/crates/pgt_pretty_print/tests/data/multi/replica_identity_60.sql new file mode 100644 index 000000000..ec6e48934 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/replica_identity_60.sql @@ -0,0 +1,144 @@ +CREATE TABLE test_replica_identity ( + id serial primary key, + keya text not null, + keyb text not null, + nonkey text, + CONSTRAINT test_replica_identity_unique_defer UNIQUE (keya, keyb) DEFERRABLE, + CONSTRAINT test_replica_identity_unique_nondefer UNIQUE (keya, keyb) +) ; + +CREATE TABLE test_replica_identity_othertable (id serial primary key); + +CREATE TABLE test_replica_identity_t3 (id serial constraint pk primary key deferrable); + +CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb); + +CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity (keya, keyb); + +CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity (keya, nonkey); + +CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey); + +CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, keyb, (3)); + +CREATE UNIQUE INDEX test_replica_identity_partial ON test_replica_identity (keya, keyb) WHERE keyb != '3'; + +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; + +SELECT relreplident FROM pg_class WHERE oid = 'pg_class'::regclass; + +SELECT relreplident FROM pg_class WHERE oid = 'pg_constraint'::regclass; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_nonkey; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_hash; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_expr; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_partial; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_othertable_pkey; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_defer; + +ALTER TABLE test_replica_identity_t3 REPLICA IDENTITY USING INDEX pk; + +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_pkey; + +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key; + +ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_keyab_key; + +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; + +SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident; + +ALTER TABLE test_replica_identity REPLICA IDENTITY DEFAULT; + +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; + +SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident; + +ALTER TABLE test_replica_identity REPLICA IDENTITY FULL; + +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; + +ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING; + +SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; + +CREATE TABLE test_replica_identity2 (id int UNIQUE NOT NULL); + +ALTER TABLE test_replica_identity2 REPLICA IDENTITY USING INDEX test_replica_identity2_id_key; + +ALTER TABLE test_replica_identity2 ALTER COLUMN id TYPE bigint; + +CREATE TABLE test_replica_identity3 (id int NOT NULL); + +CREATE UNIQUE INDEX test_replica_identity3_id_key ON test_replica_identity3 (id); + +ALTER TABLE test_replica_identity3 REPLICA IDENTITY USING INDEX test_replica_identity3_id_key; + +ALTER TABLE test_replica_identity3 ALTER COLUMN id TYPE bigint; + +ALTER TABLE test_replica_identity3 ALTER COLUMN id DROP NOT NULL; + +ALTER TABLE test_replica_identity3 REPLICA IDENTITY FULL; + +ALTER TABLE test_replica_identity3 ALTER COLUMN id DROP NOT NULL; + +CREATE TABLE test_replica_identity4(id integer NOT NULL) PARTITION BY LIST (id); + +CREATE TABLE test_replica_identity4_1(id integer NOT NULL); + +ALTER TABLE ONLY test_replica_identity4 + ATTACH PARTITION test_replica_identity4_1 FOR VALUES IN (1); + +ALTER TABLE ONLY test_replica_identity4 + ADD CONSTRAINT test_replica_identity4_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY test_replica_identity4 + REPLICA IDENTITY USING INDEX test_replica_identity4_pkey; + +ALTER TABLE ONLY test_replica_identity4_1 + ADD CONSTRAINT test_replica_identity4_1_pkey PRIMARY KEY (id); + +ALTER INDEX test_replica_identity4_pkey + ATTACH PARTITION test_replica_identity4_1_pkey; + +CREATE TABLE test_replica_identity5 (a int not null, b int, c int, + PRIMARY KEY (b, c)); + +CREATE UNIQUE INDEX test_replica_identity5_a_b_key ON test_replica_identity5 (a, b); + +ALTER TABLE test_replica_identity5 REPLICA IDENTITY USING INDEX test_replica_identity5_a_b_key; + +ALTER TABLE test_replica_identity5 DROP CONSTRAINT test_replica_identity5_pkey; + +ALTER TABLE test_replica_identity5 ALTER b SET NOT NULL; + +ALTER TABLE test_replica_identity5 DROP CONSTRAINT test_replica_identity5_pkey; + +ALTER TABLE test_replica_identity5 ALTER b DROP NOT NULL; + +DROP TABLE test_replica_identity; + +DROP TABLE test_replica_identity2; + +DROP TABLE test_replica_identity3; + +DROP TABLE test_replica_identity4; + +DROP TABLE test_replica_identity5; + +DROP TABLE test_replica_identity_othertable; + +DROP TABLE test_replica_identity_t3; diff --git a/crates/pgt_pretty_print/tests/data/multi/returning_60.sql b/crates/pgt_pretty_print/tests/data/multi/returning_60.sql new file mode 100644 index 000000000..efa200980 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/returning_60.sql @@ -0,0 +1,379 @@ +CREATE TEMP TABLE foo (f1 serial, f2 text, f3 int default 42); + +INSERT INTO foo (f2,f3) + VALUES ('test', DEFAULT), ('More', 11), (upper('more'), 7+9) + RETURNING *, f1+f3 AS sum; + +SELECT * FROM foo; + +UPDATE foo SET f2 = lower(f2), f3 = DEFAULT RETURNING foo.*, f1+f3 AS sum13; + +SELECT * FROM foo; + +DELETE FROM foo WHERE f1 > 2 RETURNING f3, f2, f1, least(f1,f3); + +SELECT * FROM foo; + +INSERT INTO foo SELECT f1+10, f2, f3+99 FROM foo + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan; + +UPDATE foo SET f3 = f3 * 2 + WHERE f1 > 10 + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan; + +DELETE FROM foo + WHERE f1 > 10 + RETURNING *, f1+112 IN (SELECT q1 FROM int8_tbl) AS subplan, + EXISTS(SELECT * FROM int4_tbl) AS initplan; + +UPDATE foo SET f3 = f3*2 + FROM int4_tbl i + WHERE foo.f1 + 123455 = i.f1 + RETURNING foo.*, i.f1 as "i.f1"; + +SELECT * FROM foo; + +DELETE FROM foo + USING int4_tbl i + WHERE foo.f1 + 123455 = i.f1 + RETURNING foo.*, i.f1 as "i.f1"; + +SELECT * FROM foo; + +CREATE TEMP TABLE foochild (fc int) INHERITS (foo); + +INSERT INTO foochild VALUES(123,'child',999,-123); + +ALTER TABLE foo ADD COLUMN f4 int8 DEFAULT 99; + +SELECT * FROM foo; + +SELECT * FROM foochild; + +UPDATE foo SET f4 = f4 + f3 WHERE f4 = 99 RETURNING *; + +SELECT * FROM foo; + +SELECT * FROM foochild; + +UPDATE foo SET f3 = f3*2 + FROM int8_tbl i + WHERE foo.f1 = i.q2 + RETURNING *; + +SELECT * FROM foo; + +SELECT * FROM foochild; + +DELETE FROM foo + USING int8_tbl i + WHERE foo.f1 = i.q2 + RETURNING *; + +SELECT * FROM foo; + +SELECT * FROM foochild; + +DROP TABLE foochild; + +CREATE TEMP VIEW voo AS SELECT f1, f2 FROM foo; + +CREATE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57); + +INSERT INTO voo VALUES(11,'zit'); + +INSERT INTO voo VALUES(12,'zoo') RETURNING *, f1*2; + +CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) RETURNING *; + +CREATE OR REPLACE RULE voo_i AS ON INSERT TO voo DO INSTEAD + INSERT INTO foo VALUES(new.*, 57) RETURNING f1, f2; + +INSERT INTO voo VALUES(13,'zit2'); + +INSERT INTO voo VALUES(14,'zoo2') RETURNING *; + +SELECT * FROM foo; + +SELECT * FROM voo; + +CREATE OR REPLACE RULE voo_u AS ON UPDATE TO voo DO INSTEAD + UPDATE foo SET f1 = new.f1, f2 = new.f2 WHERE f1 = old.f1 + RETURNING f1, f2; + +update voo set f1 = f1 + 1 where f2 = 'zoo2'; + +update voo set f1 = f1 + 1 where f2 = 'zoo2' RETURNING *, f1*2; + +SELECT * FROM foo; + +SELECT * FROM voo; + +CREATE OR REPLACE RULE voo_d AS ON DELETE TO voo DO INSTEAD + DELETE FROM foo WHERE f1 = old.f1 + RETURNING f1, f2; + +DELETE FROM foo WHERE f1 = 13; + +DELETE FROM foo WHERE f2 = 'zit' RETURNING *; + +SELECT * FROM foo; + +SELECT * FROM voo; + +CREATE TEMP VIEW foo_v AS SELECT * FROM foo OFFSET 0; + +UPDATE foo SET f2 = foo_v.f2 FROM foo_v WHERE foo_v.f1 = foo.f1 + RETURNING foo_v; + +SELECT * FROM foo; + +CREATE FUNCTION foo_f() RETURNS SETOF foo AS + $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE; + +UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 + RETURNING foo_f; + +SELECT * FROM foo; + +DROP FUNCTION foo_f(); + +CREATE TYPE foo_t AS (f1 int, f2 text, f3 int, f4 int8); + +CREATE FUNCTION foo_f() RETURNS SETOF foo_t AS + $$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE; + +UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1 + RETURNING foo_f; + +SELECT * FROM foo; + +DROP FUNCTION foo_f(); + +DROP TYPE foo_t; + +CREATE TEMP TABLE joinme (f2j text, other int); + +INSERT INTO joinme VALUES('more', 12345); + +INSERT INTO joinme VALUES('zoo2', 54321); + +INSERT INTO joinme VALUES('other', 0); + +CREATE TEMP VIEW joinview AS + SELECT foo.*, other FROM foo JOIN joinme ON (f2 = f2j); + +SELECT * FROM joinview; + +CREATE RULE joinview_u AS ON UPDATE TO joinview DO INSTEAD + UPDATE foo SET f1 = new.f1, f3 = new.f3 + FROM joinme WHERE f2 = f2j AND f2 = old.f2 + RETURNING foo.*, other; + +UPDATE joinview SET f1 = f1 + 1 WHERE f3 = 57 RETURNING *, other + 1; + +SELECT * FROM joinview; + +SELECT * FROM foo; + +SELECT * FROM voo; + +INSERT INTO foo AS bar DEFAULT VALUES RETURNING *; + +INSERT INTO foo AS bar DEFAULT VALUES RETURNING foo.*; + +INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.*; + +INSERT INTO foo AS bar DEFAULT VALUES RETURNING bar.f3; + +TRUNCATE foo; + +INSERT INTO foo VALUES (1, 'xxx', 10, 20), (2, 'more', 42, 141), (3, 'zoo2', 57, 99); + +INSERT INTO foo VALUES (4) + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +INSERT INTO foo VALUES (4) + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +CREATE UNIQUE INDEX foo_f1_idx ON foo (f1); + +UPDATE foo SET f4 = 100 WHERE f1 = 5 + RETURNING old.tableoid::regclass, old.ctid, old.*, old, + new.tableoid::regclass, new.ctid, new.*, new, + old.f4::text||'->'||new.f4::text AS change; + +UPDATE foo SET f4 = 100 WHERE f1 = 5 + RETURNING old.tableoid::regclass, old.ctid, old.*, old, + new.tableoid::regclass, new.ctid, new.*, new, + old.f4::text||'->'||new.f4::text AS change; + +DELETE FROM foo WHERE f1 = 5 + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +DELETE FROM foo WHERE f1 = 5 + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +INSERT INTO foo VALUES (5, 'subquery test') + RETURNING (SELECT max(old.f4 + x) FROM generate_series(1, 10) x) old_max, + (SELECT max(new.f4 + x) FROM generate_series(1, 10) x) new_max; + +INSERT INTO foo VALUES (5, 'subquery test') + RETURNING (SELECT max(old.f4 + x) FROM generate_series(1, 10) x) old_max, + (SELECT max(new.f4 + x) FROM generate_series(1, 10) x) new_max; + +UPDATE foo SET f4 = 100 WHERE f1 = 5 + RETURNING (SELECT old.f4 = new.f4), + (SELECT max(old.f4 + x) FROM generate_series(1, 10) x) old_max, + (SELECT max(new.f4 + x) FROM generate_series(1, 10) x) new_max; + +UPDATE foo SET f4 = 100 WHERE f1 = 5 + RETURNING (SELECT old.f4 = new.f4), + (SELECT max(old.f4 + x) FROM generate_series(1, 10) x) old_max, + (SELECT max(new.f4 + x) FROM generate_series(1, 10) x) new_max; + +DELETE FROM foo WHERE f1 = 5 + RETURNING (SELECT max(old.f4 + x) FROM generate_series(1, 10) x) old_max, + (SELECT max(new.f4 + x) FROM generate_series(1, 10) x) new_max; + +DELETE FROM foo WHERE f1 = 5 + RETURNING (SELECT max(old.f4 + x) FROM generate_series(1, 10) x) old_max, + (SELECT max(new.f4 + x) FROM generate_series(1, 10) x) new_max; + +CREATE RULE foo_del_rule AS ON DELETE TO foo DO INSTEAD + UPDATE foo SET f2 = f2||' (deleted)', f3 = -1, f4 = -1 WHERE f1 = OLD.f1 + RETURNING *; + +DELETE FROM foo WHERE f1 = 4 RETURNING old.*,new.*, *; + +DELETE FROM foo WHERE f1 = 4 RETURNING old.*,new.*, *; + +UPDATE joinview SET f3 = f3 + 1 WHERE f3 = 57 + RETURNING old.*, new.*, *, new.f3 - old.f3 AS delta_f3; + +UPDATE joinview SET f3 = f3 + 1 WHERE f3 = 57 + RETURNING old.*, new.*, *, new.f3 - old.f3 AS delta_f3; + +CREATE FUNCTION joinview_upd_trig_fn() RETURNS trigger +LANGUAGE plpgsql AS +$$ +BEGIN + RAISE NOTICE 'UPDATE: % -> %', old, new; + UPDATE foo SET f1 = new.f1, f3 = new.f3, f4 = new.f4 * 10 + FROM joinme WHERE f2 = f2j AND f2 = old.f2 + RETURNING new.f1, new.f4 INTO new.f1, new.f4; -- should fail + RETURN NEW; +END; +$$; + +CREATE TRIGGER joinview_upd_trig INSTEAD OF UPDATE ON joinview + FOR EACH ROW EXECUTE FUNCTION joinview_upd_trig_fn(); + +DROP RULE joinview_u ON joinview; + +UPDATE joinview SET f3 = f3 + 1, f4 = 7 WHERE f3 = 58 + RETURNING old.*, new.*, *, new.f3 - old.f3 AS delta_f3; + +CREATE OR REPLACE FUNCTION joinview_upd_trig_fn() RETURNS trigger +LANGUAGE plpgsql AS +$$ +BEGIN + RAISE NOTICE 'UPDATE: % -> %', old, new; + UPDATE foo SET f1 = new.f1, f3 = new.f3, f4 = new.f4 * 10 + FROM joinme WHERE f2 = f2j AND f2 = old.f2 + RETURNING WITH (new AS n) new.f1, n.f4 INTO new.f1, new.f4; -- now ok + RETURN NEW; +END; +$$; + +UPDATE joinview SET f3 = f3 + 1, f4 = 7 WHERE f3 = 58 + RETURNING old.*, new.*, *, new.f3 - old.f3 AS delta_f3; + +UPDATE joinview SET f3 = f3 + 1, f4 = 7 WHERE f3 = 58 + RETURNING old.*, new.*, *, new.f3 - old.f3 AS delta_f3; + +ALTER TABLE foo DROP COLUMN f3 CASCADE; + +UPDATE foo SET f4 = f4 + 1 RETURNING old.f3; + +UPDATE foo SET f4 = f4 + 1 RETURNING old, new; + +CREATE TABLE zerocol(); + +INSERT INTO zerocol SELECT RETURNING old.*, new.*, *; + +INSERT INTO zerocol SELECT + RETURNING old.tableoid::regclass, old.ctid, + new.tableoid::regclass, new.ctid, ctid, *; + +DELETE FROM zerocol + RETURNING old.tableoid::regclass, old.ctid, + new.tableoid::regclass, new.ctid, ctid, *; + +DROP TABLE zerocol; + +CREATE TABLE public.tt(a int, b int); + +INSERT INTO public.tt VALUES (1, 10); + +UPDATE public.tt SET b = b * 2 RETURNING a, b, old.b, new.b, tt.b, public.tt.b; + +DROP TABLE public.tt; + +CREATE TABLE foo_parted (a int, b float8, c text) PARTITION BY LIST (a); + +CREATE TABLE foo_part_s1 PARTITION OF foo_parted FOR VALUES IN (1); + +CREATE TABLE foo_part_s2 PARTITION OF foo_parted FOR VALUES IN (2); + +CREATE TABLE foo_part_d1 (c text, a int, b float8); + +ALTER TABLE foo_parted ATTACH PARTITION foo_part_d1 FOR VALUES IN (3); + +CREATE TABLE foo_part_d2 (b float8, c text, a int); + +ALTER TABLE foo_parted ATTACH PARTITION foo_part_d2 FOR VALUES IN (4); + +INSERT INTO foo_parted + VALUES (1, 17.1, 'P1'), (2, 17.2, 'P2'), (3, 17.3, 'P3'), (4, 17.4, 'P4') + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +UPDATE foo_parted SET a = 2, b = b + 1, c = c || '->P2' WHERE a = 1 + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +UPDATE foo_parted SET a = 1, b = b + 1, c = c || '->P1' WHERE a = 3 + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +UPDATE foo_parted SET a = 3, b = b + 1, c = c || '->P3' WHERE a = 1 + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +UPDATE foo_parted SET a = 4, b = b + 1, c = c || '->P4' WHERE a = 3 + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +CREATE VIEW foo_parted_v AS SELECT *, 'xxx' AS dummy FROM foo_parted; + +UPDATE foo_parted_v SET a = 1, c = c || '->P1' WHERE a = 2 AND c = 'P2' + RETURNING 'P2:'||old.dummy, 'P1:'||new.dummy; + +DELETE FROM foo_parted + RETURNING old.tableoid::regclass, old.ctid, old.*, + new.tableoid::regclass, new.ctid, new.*, *; + +DROP TABLE foo_parted CASCADE; + +END; + +DROP FUNCTION foo_update; diff --git a/crates/pgt_pretty_print/tests/data/multi/roleattributes_60.sql b/crates/pgt_pretty_print/tests/data/multi/roleattributes_60.sql new file mode 100644 index 000000000..bbd557788 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/roleattributes_60.sql @@ -0,0 +1,9 @@ +CREATE ROLE regress_test_def_superuser; + +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_superuser'; + +CREATE ROLE regress_test_superuser WITH SUPERUSER; + +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser'; + +ALTER ROLE regress_test_superuser diff --git a/crates/pgt_pretty_print/tests/data/multi/rowsecurity_60.sql b/crates/pgt_pretty_print/tests/data/multi/rowsecurity_60.sql new file mode 100644 index 000000000..a4ae39bb5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/rowsecurity_60.sql @@ -0,0 +1,926 @@ +SET client_min_messages TO 'warning'; + +DROP USER IF EXISTS regress_rls_alice; + +DROP USER IF EXISTS regress_rls_bob; + +DROP USER IF EXISTS regress_rls_carol; + +DROP USER IF EXISTS regress_rls_dave; + +DROP USER IF EXISTS regress_rls_exempt_user; + +DROP ROLE IF EXISTS regress_rls_group1; + +DROP ROLE IF EXISTS regress_rls_group2; + +DROP SCHEMA IF EXISTS regress_rls_schema CASCADE; + +RESET client_min_messages; + +CREATE USER regress_rls_alice NOLOGIN; + +CREATE USER regress_rls_bob NOLOGIN; + +CREATE USER regress_rls_carol NOLOGIN; + +CREATE USER regress_rls_dave NOLOGIN; + +CREATE USER regress_rls_exempt_user BYPASSRLS NOLOGIN; + +CREATE ROLE regress_rls_group1 NOLOGIN; + +CREATE ROLE regress_rls_group2 NOLOGIN; + +GRANT regress_rls_group1 TO regress_rls_bob; + +GRANT regress_rls_group2 TO regress_rls_carol; + +CREATE SCHEMA regress_rls_schema; + +GRANT ALL ON SCHEMA regress_rls_schema to public; + +SET search_path = regress_rls_schema; + +CREATE OR REPLACE FUNCTION f_leak(text) RETURNS bool + COST 0.0000001 LANGUAGE plpgsql + AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END'; + +GRANT EXECUTE ON FUNCTION f_leak(text) TO public; + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE TABLE uaccount ( + pguser name primary key, + seclv int +); + +GRANT SELECT ON uaccount TO public; + +INSERT INTO uaccount VALUES + ('regress_rls_alice', 99), + ('regress_rls_bob', 1), + ('regress_rls_carol', 2), + ('regress_rls_dave', 3); + +CREATE TABLE category ( + cid int primary key, + cname text +); + +GRANT ALL ON category TO public; + +INSERT INTO category VALUES + (11, 'novel'), + (22, 'science fiction'), + (33, 'technology'), + (44, 'manga'); + +CREATE TABLE document ( + did int primary key, + cid int references category(cid), + dlevel int not null, + dauthor name, + dtitle text +); + +GRANT ALL ON document TO public; + +INSERT INTO document VALUES + ( 1, 11, 1, 'regress_rls_bob', 'my first novel'), + ( 2, 11, 2, 'regress_rls_bob', 'my second novel'), + ( 3, 22, 2, 'regress_rls_bob', 'my science fiction'), + ( 4, 44, 1, 'regress_rls_bob', 'my first manga'), + ( 5, 44, 2, 'regress_rls_bob', 'my second manga'), + ( 6, 22, 1, 'regress_rls_carol', 'great science fiction'), + ( 7, 33, 2, 'regress_rls_carol', 'great technology book'), + ( 8, 44, 1, 'regress_rls_carol', 'great manga'), + ( 9, 22, 1, 'regress_rls_dave', 'awesome science fiction'), + (10, 33, 2, 'regress_rls_dave', 'awesome technology book'); + +ALTER TABLE document ENABLE ROW LEVEL SECURITY; + +CREATE POLICY p1 ON document AS PERMISSIVE + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)); + +CREATE POLICY p2r ON document AS RESTRICTIVE TO regress_rls_dave + USING (cid <> 44 AND cid < 50); + +CREATE POLICY p1r ON document AS RESTRICTIVE TO regress_rls_dave + USING (cid <> 44); + +SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename = 'document' ORDER BY policyname; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SET row_security TO ON; + +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document TABLESAMPLE BERNOULLI(50) REPEATABLE(0) + WHERE f_leak(dtitle) ORDER BY did; + +SET SESSION AUTHORIZATION regress_rls_carol; + +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document TABLESAMPLE BERNOULLI(50) REPEATABLE(0) + WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document WHERE f_leak(dtitle); + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle); + +SET SESSION AUTHORIZATION regress_rls_dave; + +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document WHERE f_leak(dtitle); + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle); + +INSERT INTO document VALUES (100, 44, 1, 'regress_rls_dave', 'testing sorting of policies'); + +INSERT INTO document VALUES (100, 55, 1, 'regress_rls_dave', 'testing sorting of policies'); + +ALTER POLICY p1 ON document USING (true); + +DROP POLICY p1 ON document; + +SET SESSION AUTHORIZATION regress_rls_alice; + +ALTER POLICY p1 ON document USING (dauthor = current_user); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER by did; + +SET SESSION AUTHORIZATION regress_rls_carol; + +SELECT * FROM document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle) ORDER by did; + +SELECT * FROM document WHERE f_leak(dtitle); + +SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle); + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE POLICY p2 ON category + USING (CASE WHEN current_user = 'regress_rls_bob' THEN cid IN (11, 33) + WHEN current_user = 'regress_rls_carol' THEN cid IN (22, 44) + ELSE false END); + +ALTER TABLE category ENABLE ROW LEVEL SECURITY; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM document d FULL OUTER JOIN category c on d.cid = c.cid ORDER BY d.did, c.cid; + +DELETE FROM category WHERE cid = 33; + +SET SESSION AUTHORIZATION regress_rls_carol; + +SELECT * FROM document d FULL OUTER JOIN category c on d.cid = c.cid ORDER BY d.did, c.cid; + +INSERT INTO document VALUES (11, 33, 1, current_user, 'hoge'); + +SET SESSION AUTHORIZATION regress_rls_bob; + +INSERT INTO document VALUES (8, 44, 1, 'regress_rls_bob', 'my third manga'); + +SELECT * FROM document WHERE did = 8; + +INSERT INTO document VALUES (8, 44, 1, 'regress_rls_carol', 'my third manga'); + +UPDATE document SET did = 8, dauthor = 'regress_rls_carol' WHERE did = 5; + +RESET SESSION AUTHORIZATION; + +SET row_security TO ON; + +SELECT * FROM document; + +SELECT * FROM category; + +RESET SESSION AUTHORIZATION; + +SET row_security TO OFF; + +SELECT * FROM document; + +SELECT * FROM category; + +SET SESSION AUTHORIZATION regress_rls_exempt_user; + +SET row_security TO OFF; + +SELECT * FROM document; + +SELECT * FROM category; + +SET SESSION AUTHORIZATION regress_rls_alice; + +SET row_security TO ON; + +SELECT * FROM document; + +SELECT * FROM category; + +SET SESSION AUTHORIZATION regress_rls_alice; + +SET row_security TO OFF; + +SELECT * FROM document; + +SELECT * FROM category; + +SET SESSION AUTHORIZATION regress_rls_alice; + +SET row_security TO ON; + +CREATE TABLE t1 (id int not null primary key, a int, junk1 text, b text); + +ALTER TABLE t1 DROP COLUMN junk1; + +GRANT ALL ON t1 TO public; + +CREATE TABLE t2 (c float) INHERITS (t1); + +GRANT ALL ON t2 TO public; + +CREATE TABLE t3 (id int not null primary key, c text, b text, a int); + +ALTER TABLE t3 INHERIT t1; + +GRANT ALL ON t3 TO public; + +CREATE POLICY p1 ON t1 FOR ALL TO PUBLIC USING (a % 2 = 0); + +CREATE POLICY p2 ON t2 FOR ALL TO PUBLIC USING (a % 2 = 1); + +ALTER TABLE t1 ENABLE ROW LEVEL SECURITY; + +ALTER TABLE t2 ENABLE ROW LEVEL SECURITY; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM t1; + +SELECT * FROM t1; + +SELECT * FROM t1 WHERE f_leak(b); + +SELECT * FROM t1 WHERE f_leak(b); + +SELECT tableoid::regclass, * FROM t1; + +SELECT *, t1 FROM t1; + +SELECT *, t1 FROM t1; + +SELECT *, t1 FROM t1; + +SELECT * FROM t1 FOR SHARE; + +SELECT * FROM t1 FOR SHARE; + +SELECT * FROM t1 WHERE f_leak(b) FOR SHARE; + +SELECT * FROM t1 WHERE f_leak(b) FOR SHARE; + +SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3; + +SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3; + +RESET SESSION AUTHORIZATION; + +SET row_security TO OFF; + +SELECT * FROM t1 WHERE f_leak(b); + +SELECT * FROM t1 WHERE f_leak(b); + +SET SESSION AUTHORIZATION regress_rls_exempt_user; + +SET row_security TO OFF; + +SELECT * FROM t1 WHERE f_leak(b); + +SELECT * FROM t1 WHERE f_leak(b); + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE TABLE part_document ( + did int, + cid int, + dlevel int not null, + dauthor name, + dtitle text +) PARTITION BY RANGE (cid); + +GRANT ALL ON part_document TO public; + +CREATE TABLE part_document_fiction PARTITION OF part_document FOR VALUES FROM (11) to (12); + +CREATE TABLE part_document_satire PARTITION OF part_document FOR VALUES FROM (55) to (56); + +CREATE TABLE part_document_nonfiction PARTITION OF part_document FOR VALUES FROM (99) to (100); + +GRANT ALL ON part_document_fiction TO public; + +GRANT ALL ON part_document_satire TO public; + +GRANT ALL ON part_document_nonfiction TO public; + +INSERT INTO part_document VALUES + ( 1, 11, 1, 'regress_rls_bob', 'my first novel'), + ( 2, 11, 2, 'regress_rls_bob', 'my second novel'), + ( 3, 99, 2, 'regress_rls_bob', 'my science textbook'), + ( 4, 55, 1, 'regress_rls_bob', 'my first satire'), + ( 5, 99, 2, 'regress_rls_bob', 'my history book'), + ( 6, 11, 1, 'regress_rls_carol', 'great science fiction'), + ( 7, 99, 2, 'regress_rls_carol', 'great technology book'), + ( 8, 55, 2, 'regress_rls_carol', 'great satire'), + ( 9, 11, 1, 'regress_rls_dave', 'awesome science fiction'), + (10, 99, 2, 'regress_rls_dave', 'awesome technology book'); + +ALTER TABLE part_document ENABLE ROW LEVEL SECURITY; + +CREATE POLICY pp1 ON part_document AS PERMISSIVE + USING (dlevel <= (SELECT seclv FROM uaccount WHERE pguser = current_user)); + +CREATE POLICY pp1r ON part_document AS RESTRICTIVE TO regress_rls_dave + USING (cid < 55); + +SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename like '%part_document%' ORDER BY policyname; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SET row_security TO ON; + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document WHERE f_leak(dtitle); + +SET SESSION AUTHORIZATION regress_rls_carol; + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document WHERE f_leak(dtitle); + +SET SESSION AUTHORIZATION regress_rls_dave; + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document WHERE f_leak(dtitle); + +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_dave', 'testing pp1'); + +INSERT INTO part_document VALUES (100, 99, 1, 'regress_rls_dave', 'testing pp1r'); + +INSERT INTO part_document VALUES (100, 55, 1, 'regress_rls_dave', 'testing RLS with partitions'); + +INSERT INTO part_document_satire VALUES (100, 55, 1, 'regress_rls_dave', 'testing RLS with partitions'); + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did; + +SET SESSION AUTHORIZATION regress_rls_alice; + +ALTER TABLE part_document_satire ENABLE ROW LEVEL SECURITY; + +CREATE POLICY pp3 ON part_document_satire AS RESTRICTIVE + USING (cid < 55); + +SET SESSION AUTHORIZATION regress_rls_dave; + +INSERT INTO part_document_satire VALUES (101, 55, 1, 'regress_rls_dave', 'testing RLS with partitions'); + +SELECT * FROM part_document_satire WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document WHERE f_leak(dtitle); + +SET SESSION AUTHORIZATION regress_rls_carol; + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document WHERE f_leak(dtitle); + +ALTER POLICY pp1 ON part_document USING (true); + +DROP POLICY pp1 ON part_document; + +SET SESSION AUTHORIZATION regress_rls_alice; + +ALTER POLICY pp1 ON part_document USING (dauthor = current_user); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SET SESSION AUTHORIZATION regress_rls_carol; + +SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did; + +SELECT * FROM part_document WHERE f_leak(dtitle); + +RESET SESSION AUTHORIZATION; + +SET row_security TO ON; + +SELECT * FROM part_document ORDER BY did; + +SELECT * FROM part_document_satire ORDER by did; + +SET SESSION AUTHORIZATION regress_rls_exempt_user; + +SET row_security TO OFF; + +SELECT * FROM part_document ORDER BY did; + +SELECT * FROM part_document_satire ORDER by did; + +SET SESSION AUTHORIZATION regress_rls_alice; + +SET row_security TO ON; + +SELECT * FROM part_document ORDER by did; + +SELECT * FROM part_document_satire ORDER by did; + +SET SESSION AUTHORIZATION regress_rls_dave; + +SET row_security TO OFF; + +SELECT * FROM part_document ORDER by did; + +SELECT * FROM part_document_satire ORDER by did; + +SET SESSION AUTHORIZATION regress_rls_alice; + +SET row_security TO ON; + +CREATE POLICY pp3 ON part_document AS RESTRICTIVE + USING ((SELECT dlevel <= seclv FROM uaccount WHERE pguser = current_user)); + +SET SESSION AUTHORIZATION regress_rls_carol; + +INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_carol', 'testing pp3'); + +SET SESSION AUTHORIZATION regress_rls_alice; + +SET row_security TO ON; + +CREATE TABLE dependee (x integer, y integer); + +CREATE TABLE dependent (x integer, y integer); + +CREATE POLICY d1 ON dependent FOR ALL + TO PUBLIC + USING (x = (SELECT d.x FROM dependee d WHERE d.y = y)); + +DROP TABLE dependee; + +DROP TABLE dependee CASCADE; + +SELECT * FROM dependent; + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE TABLE rec1 (x integer, y integer); + +CREATE POLICY r1 ON rec1 USING (x = (SELECT r.x FROM rec1 r WHERE y = r.y)); + +ALTER TABLE rec1 ENABLE ROW LEVEL SECURITY; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM rec1; + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE TABLE rec2 (a integer, b integer); + +ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2 WHERE b = y)); + +CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1 WHERE y = b)); + +ALTER TABLE rec2 ENABLE ROW LEVEL SECURITY; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM rec1; + +SET SESSION AUTHORIZATION regress_rls_bob; + +CREATE VIEW rec1v AS SELECT * FROM rec1; + +CREATE VIEW rec2v AS SELECT * FROM rec2; + +SET SESSION AUTHORIZATION regress_rls_alice; + +ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y)); + +ALTER POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b)); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM rec1; + +SET SESSION AUTHORIZATION regress_rls_bob; + +DROP VIEW rec1v, rec2v CASCADE; + +CREATE VIEW rec1v WITH (security_barrier) AS SELECT * FROM rec1; + +CREATE VIEW rec2v WITH (security_barrier) AS SELECT * FROM rec2; + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y)); + +CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b)); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM rec1; + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE TABLE s1 (a int, b text); + +INSERT INTO s1 (SELECT x, public.fipshash(x::text) FROM generate_series(-10,10) x); + +CREATE TABLE s2 (x int, y text); + +INSERT INTO s2 (SELECT x, public.fipshash(x::text) FROM generate_series(-6,6) x); + +GRANT SELECT ON s1, s2 TO regress_rls_bob; + +CREATE POLICY p1 ON s1 USING (a in (select x from s2 where y like '%2f%')); + +CREATE POLICY p2 ON s2 USING (x in (select a from s1 where b like '%22%')); + +CREATE POLICY p3 ON s1 FOR INSERT WITH CHECK (a = (SELECT a FROM s1)); + +ALTER TABLE s1 ENABLE ROW LEVEL SECURITY; + +ALTER TABLE s2 ENABLE ROW LEVEL SECURITY; + +SET SESSION AUTHORIZATION regress_rls_bob; + +CREATE VIEW v2 AS SELECT * FROM s2 WHERE y like '%af%'; + +SELECT * FROM s1 WHERE f_leak(b); + +INSERT INTO s1 VALUES (1, 'foo'); + +SET SESSION AUTHORIZATION regress_rls_alice; + +DROP POLICY p3 on s1; + +ALTER POLICY p2 ON s2 USING (x % 2 = 0); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM s1 WHERE f_leak(b); + +SELECT * FROM only s1 WHERE f_leak(b); + +SET SESSION AUTHORIZATION regress_rls_alice; + +ALTER POLICY p1 ON s1 USING (a in (select x from v2)); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM s1 WHERE f_leak(b); + +SELECT * FROM s1 WHERE f_leak(b); + +SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%'; + +SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%'; + +SET SESSION AUTHORIZATION regress_rls_alice; + +ALTER POLICY p2 ON s2 USING (x in (select a from s1 where b like '%d2%')); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM s1 WHERE f_leak(b); + +PREPARE p1(int) AS SELECT * FROM t1 WHERE a <= $1; + +EXECUTE p1(2); + +EXPLAIN (COSTS OFF) EXECUTE p1(2); + +RESET SESSION AUTHORIZATION; + +SET row_security TO OFF; + +SELECT * FROM t1 WHERE f_leak(b); + +SELECT * FROM t1 WHERE f_leak(b); + +EXECUTE p1(2); + +EXPLAIN (COSTS OFF) EXECUTE p1(2); + +PREPARE p2(int) AS SELECT * FROM t1 WHERE a = $1; + +EXECUTE p2(2); + +EXPLAIN (COSTS OFF) EXECUTE p2(2); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SET row_security TO ON; + +EXECUTE p2(2); + +EXPLAIN (COSTS OFF) EXECUTE p2(2); + +SET SESSION AUTHORIZATION regress_rls_bob; + +UPDATE t1 SET b = b || b WHERE f_leak(b); + +UPDATE t1 SET b = b || b WHERE f_leak(b); + +UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b); + +UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b); + +UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; + +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING *; + +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; + +UPDATE t2 SET b=t2.b FROM t3 +WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b); + +UPDATE t2 SET b=t2.b FROM t3 +WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b); + +UPDATE t1 SET b=t1.b FROM t2 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b); + +UPDATE t1 SET b=t1.b FROM t2 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b); + +UPDATE t2 SET b=t2.b FROM t1 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b); + +UPDATE t2 SET b=t2.b FROM t1 +WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b); + +UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 +WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b +AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2; + +UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2 +WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b +AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2; + +UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 +WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b +AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2; + +UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 +WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b +AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2; + +RESET SESSION AUTHORIZATION; + +SET row_security TO OFF; + +SELECT * FROM t1 ORDER BY a,b; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SET row_security TO ON; + +DELETE FROM only t1 WHERE f_leak(b); + +DELETE FROM t1 WHERE f_leak(b); + +DELETE FROM only t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; + +DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE TABLE b1 (a int, b text); + +INSERT INTO b1 (SELECT x, public.fipshash(x::text) FROM generate_series(-10,10) x); + +CREATE POLICY p1 ON b1 USING (a % 2 = 0); + +ALTER TABLE b1 ENABLE ROW LEVEL SECURITY; + +GRANT ALL ON b1 TO regress_rls_bob; + +SET SESSION AUTHORIZATION regress_rls_bob; + +CREATE VIEW bv1 WITH (security_barrier) AS SELECT * FROM b1 WHERE a > 0 WITH CHECK OPTION; + +GRANT ALL ON bv1 TO regress_rls_carol; + +SET SESSION AUTHORIZATION regress_rls_carol; + +SELECT * FROM bv1 WHERE f_leak(b); + +SELECT * FROM bv1 WHERE f_leak(b); + +INSERT INTO bv1 VALUES (-1, 'xxx'); + +INSERT INTO bv1 VALUES (11, 'xxx'); + +INSERT INTO bv1 VALUES (12, 'xxx'); + +UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b); + +UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b); + +DELETE FROM bv1 WHERE a = 6 AND f_leak(b); + +DELETE FROM bv1 WHERE a = 6 AND f_leak(b); + +SET SESSION AUTHORIZATION regress_rls_alice; + +SELECT * FROM b1; + +SET SESSION AUTHORIZATION regress_rls_alice; + +DROP POLICY p1 ON document; + +DROP POLICY p1r ON document; + +CREATE POLICY p1 ON document FOR SELECT USING (true); + +CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user); + +CREATE POLICY p3 ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dauthor = current_user); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM document WHERE did = 2; + +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_carol', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, dauthor = EXCLUDED.dauthor; + +INSERT INTO document VALUES (33, 22, 1, 'regress_rls_bob', 'okay science fiction'); + +INSERT INTO document VALUES (33, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'Some novel, replaces sci-fi') -- takes UPDATE path + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle; + +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING *; + +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING *; + +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING *; + +INSERT INTO document VALUES (78, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'some technology novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33 RETURNING *; + +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING *; + +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING *; + +SET SESSION AUTHORIZATION regress_rls_alice; + +DROP POLICY p1 ON document; + +DROP POLICY p2 ON document; + +DROP POLICY p3 ON document; + +CREATE POLICY p3_with_default ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')); + +SET SESSION AUTHORIZATION regress_rls_bob; + +INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING *; + +INSERT INTO document VALUES (2, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET cid = EXCLUDED.cid, dtitle = EXCLUDED.dtitle RETURNING *; + +SET SESSION AUTHORIZATION regress_rls_alice; + +DROP POLICY p3_with_default ON document; + +CREATE POLICY p3_with_all ON document FOR ALL + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dauthor = current_user); + +SET SESSION AUTHORIZATION regress_rls_bob; + +INSERT INTO document VALUES (80, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_carol', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle, cid = 33; + +INSERT INTO document VALUES (4, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle; + +INSERT INTO document VALUES (1, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') + ON CONFLICT (did) DO UPDATE SET dauthor = 'regress_rls_carol'; + +RESET SESSION AUTHORIZATION; + +DROP POLICY p3_with_all ON document; + +ALTER TABLE document ADD COLUMN dnotes text DEFAULT ''; + +CREATE POLICY p1 ON document FOR SELECT USING (true); + +CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user); + +CREATE POLICY p3 ON document FOR UPDATE + USING (cid = (SELECT cid from category WHERE cname = 'novel')) + WITH CHECK (dlevel > 0); + +CREATE POLICY p4 ON document FOR DELETE + USING (cid = (SELECT cid from category WHERE cname = 'manga')); + +SELECT * FROM document; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM document WHERE did = 4; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_rls_carol; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_rls_bob; + +RESET SESSION AUTHORIZATION; + +DROP POLICY p1 ON document; + +CREATE POLICY p1 ON document FOR SELECT + USING (cid = (SELECT cid from category WHERE cname = 'novel')); + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM document WHERE did = 13; + +RESET SESSION AUTHORIZATION; + +DROP POLICY p1 ON document; + +SELECT * FROM document; + +SET SESSION AUTHORIZATION regress_rls_alice; + +CREATE TABLE z1 (a int, b text); + +CREATE TABLE z2 (a int, b text); + +GRANT SELECT ON z1,z2 TO regress_rls_group1, regress_rls_group2, + regress_rls_bob, regress_rls_carol; + +INSERT INTO z1 VALUES + (1, 'aba'), + (2, 'bbb'), + (3, 'ccc'), + (4, 'dad'); + +CREATE POLICY p1 ON z1 TO regress_rls_group1 USING (a % 2 = 0); + +CREATE POLICY p2 ON z1 TO regress_rls_group2 USING (a % 2 = 1); + +ALTER TABLE z1 ENABLE ROW LEVEL SECURITY; + +SET SESSION AUTHORIZATION regress_rls_bob; + +SELECT * FROM z1 WHERE f_leak(b); + +SELECT * FROM z1 WHERE f_leak(b); + +PREPARE plancache_test AS SELECT * FROM z1 WHERE f_leak(b); + +EXPLAIN (COSTS OFF) EXECUTE plancache_test; diff --git a/crates/pgt_pretty_print/tests/data/multi/rowtypes_60.sql b/crates/pgt_pretty_print/tests/data/multi/rowtypes_60.sql new file mode 100644 index 000000000..dfee14612 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/rowtypes_60.sql @@ -0,0 +1,564 @@ +create type complex as (r float8, i float8); + +create temp table fullname (first text, last text); + +create type quad as (c1 complex, c2 complex); + +select (1.1,2.2)::complex, row((3.3,4.4),(5.5,null))::quad; + +select row('Joe', 'Blow')::fullname, '(Joe,Blow)'::fullname; + +select '(Joe,von Blow)'::fullname, '(Joe,d''Blow)'::fullname; + +select '(Joe,"von""Blow")'::fullname, E'(Joe,d\\\\Blow)'::fullname; + +select '(Joe,"Blow,Jr")'::fullname; + +select '(Joe,)'::fullname; + +select '(Joe)'::fullname; + +select '(Joe,,)'::fullname; + +select '[]'::fullname; + +select ' (Joe,Blow) '::fullname; + +select '(Joe,Blow) /'::fullname; + +SELECT pg_input_is_valid('(1,2)', 'complex'); + +SELECT pg_input_is_valid('(1,2', 'complex'); + +SELECT pg_input_is_valid('(1,zed)', 'complex'); + +SELECT * FROM pg_input_error_info('(1,zed)', 'complex'); + +SELECT * FROM pg_input_error_info('(1,1e400)', 'complex'); + +create temp table quadtable(f1 int, q quad); + +insert into quadtable values (1, ((3.3,4.4),(5.5,6.6))); + +insert into quadtable values (2, ((null,4.4),(5.5,6.6))); + +select * from quadtable; + +select f1, q.c1 from quadtable; + +select f1, (q).c1, (qq.q).c1.i from quadtable qq; + +create temp table people (fn fullname, bd date); + +insert into people values ('(Joe,Blow)', '1984-01-10'); + +select * from people; + +alter table fullname add column suffix text default ''; + +alter table fullname add column suffix text default null; + +select * from people; + +update people set fn.suffix = 'Jr'; + +select * from people; + +insert into quadtable (f1, q.c1.r, q.c2.i) values(44,55,66); + +update quadtable set q.c1.r = 12 where f1 = 2; + +update quadtable set q.c1 = 12; + +select * from quadtable; + +create temp table pp (f1 text); + +insert into pp values (repeat('abcdefghijkl', 100000)); + +insert into people select ('Jim', f1, null)::fullname, current_date from pp; + +select (fn).first, substr((fn).last, 1, 20), length((fn).last) from people; + +update people set fn.first = 'Jack'; + +select (fn).first, substr((fn).last, 1, 20), length((fn).last) from people; + +select ROW(1,2) < ROW(1,3) as true; + +select ROW(1,2) < ROW(1,1) as false; + +select ROW(1,2) < ROW(1,NULL) as null; + +select ROW(1,2,3) < ROW(1,3,NULL) as true; + +select ROW(11,'ABC') < ROW(11,'DEF') as true; + +select ROW(11,'ABC') > ROW(11,'DEF') as false; + +select ROW(12,'ABC') > ROW(11,'DEF') as true; + +select ROW(1,2,3) < ROW(1,NULL,4) as null; + +select ROW(1,2,3) = ROW(1,NULL,4) as false; + +select ROW(1,2,3) <> ROW(1,NULL,4) as true; + +select ROW('ABC','DEF') ~<=~ ROW('DEF','ABC') as true; + +select ROW('ABC','DEF') ~>=~ ROW('DEF','ABC') as false; + +select ROW('ABC','DEF') ~~ ROW('DEF','ABC') as fail; + +select ROW(1,2) = ROW(1,2::int8); + +select ROW(1,2) in (ROW(3,4), ROW(1,2)); + +select ROW(1,2) in (ROW(3,4), ROW(1,2::int8)); + +select unique1, unique2 from tenk1 +where (unique1, unique2) < any (select ten, ten from tenk1 where hundred < 3) + and unique1 <= 20 +order by 1; + +select thousand, tenthous from tenk1 +where (thousand, tenthous) >= (997, 5000) +order by thousand, tenthous; + +select thousand, tenthous from tenk1 +where (thousand, tenthous) >= (997, 5000) +order by thousand, tenthous; + +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous; + +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous; + +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous; + +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous; + +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred; + +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred; + +create temp table test_table (a text, b text); + +insert into test_table values ('a', 'b'); + +insert into test_table select 'a', null from generate_series(1,1000); + +insert into test_table values ('b', 'a'); + +create index on test_table (a,b); + +set enable_sort = off; + +select a,b from test_table where (a,b) > ('a','a') order by a,b; + +select a,b from test_table where (a,b) > ('a','a') order by a,b; + +reset enable_sort; + +select * from int8_tbl i8 where i8 in (row(123,456)); + +select * from int8_tbl i8 +where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)'); + +select * from int8_tbl i8 +where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)'); + +select (row(1, 2.0)).f1; + +select (row(1, 2.0)).f2; + +select (row(1, 2.0)).nosuch; + +select (row(1, 2.0)).*; + +select (r).f1 from (select row(1, 2.0) as r) ss; + +select (r).f3 from (select row(1, 2.0) as r) ss; + +select (r).* from (select row(1, 2.0) as r) ss; + +select ROW(); + +select ROW() IS NULL; + +select ROW() = ROW(); + +select array[ row(1,2), row(3,4), row(5,6) ]; + +select row(1,1.1) = any (array[ row(7,7.7), row(1,1.1), row(0,0.0) ]); + +select row(1,1.1) = any (array[ row(7,7.7), row(1,1.0), row(0,0.0) ]); + +create type cantcompare as (p point, r float8); + +create temp table cc (f1 cantcompare); + +insert into cc values('("(1,2)",3)'); + +insert into cc values('("(4,5)",6)'); + +select * from cc order by f1; + +create type testtype1 as (a int, b int); + +select row(1, 2)::testtype1 < row(1, 3)::testtype1; + +select row(1, 2)::testtype1 <= row(1, 3)::testtype1; + +select row(1, 2)::testtype1 = row(1, 2)::testtype1; + +select row(1, 2)::testtype1 <> row(1, 3)::testtype1; + +select row(1, 3)::testtype1 >= row(1, 2)::testtype1; + +select row(1, 3)::testtype1 > row(1, 2)::testtype1; + +select row(1, -2)::testtype1 < row(1, -3)::testtype1; + +select row(1, -2)::testtype1 <= row(1, -3)::testtype1; + +select row(1, -2)::testtype1 = row(1, -3)::testtype1; + +select row(1, -2)::testtype1 <> row(1, -2)::testtype1; + +select row(1, -3)::testtype1 >= row(1, -2)::testtype1; + +select row(1, -3)::testtype1 > row(1, -2)::testtype1; + +select row(1, -2)::testtype1 < row(1, 3)::testtype1; + +create type testtype3 as (a int, b text); + +select row(1, 2)::testtype1 < row(1, 'abc')::testtype3; + +select row(1, 2)::testtype1 <> row(1, 'abc')::testtype3; + +create type testtype5 as (a int); + +select row(1, 2)::testtype1 < row(1)::testtype5; + +select row(1, 2)::testtype1 <> row(1)::testtype5; + +create type testtype6 as (a int, b point); + +select row(1, '(1,2)')::testtype6 < row(1, '(1,3)')::testtype6; + +select row(1, '(1,2)')::testtype6 <> row(1, '(1,3)')::testtype6; + +drop type testtype1, testtype3, testtype5, testtype6; + +create type testtype1 as (a int, b int); + +select row(1, 2)::testtype1 *< row(1, 3)::testtype1; + +select row(1, 2)::testtype1 *<= row(1, 3)::testtype1; + +select row(1, 2)::testtype1 *= row(1, 2)::testtype1; + +select row(1, 2)::testtype1 *<> row(1, 3)::testtype1; + +select row(1, 3)::testtype1 *>= row(1, 2)::testtype1; + +select row(1, 3)::testtype1 *> row(1, 2)::testtype1; + +select row(1, -2)::testtype1 *< row(1, -3)::testtype1; + +select row(1, -2)::testtype1 *<= row(1, -3)::testtype1; + +select row(1, -2)::testtype1 *= row(1, -3)::testtype1; + +select row(1, -2)::testtype1 *<> row(1, -2)::testtype1; + +select row(1, -3)::testtype1 *>= row(1, -2)::testtype1; + +select row(1, -3)::testtype1 *> row(1, -2)::testtype1; + +select row(1, -2)::testtype1 *< row(1, 3)::testtype1; + +create type testtype2 as (a smallint, b bool); + +select row(1, true)::testtype2 *< row(2, true)::testtype2; + +select row(-2, true)::testtype2 *< row(-1, true)::testtype2; + +select row(0, false)::testtype2 *< row(0, true)::testtype2; + +select row(0, false)::testtype2 *<> row(0, true)::testtype2; + +create type testtype3 as (a int, b text); + +select row(1, 'abc')::testtype3 *< row(1, 'abd')::testtype3; + +select row(1, 'abc')::testtype3 *< row(1, 'abcd')::testtype3; + +select row(1, 'abc')::testtype3 *> row(1, 'abd')::testtype3; + +select row(1, 'abc')::testtype3 *<> row(1, 'abd')::testtype3; + +create type testtype4 as (a int, b point); + +select row(1, '(1,2)')::testtype4 *< row(1, '(1,3)')::testtype4; + +select row(1, '(1,2)')::testtype4 *<> row(1, '(1,3)')::testtype4; + +select row(1, 2)::testtype1 *< row(1, 'abc')::testtype3; + +select row(1, 2)::testtype1 *<> row(1, 'abc')::testtype3; + +create type testtype5 as (a int); + +select row(1, 2)::testtype1 *< row(1)::testtype5; + +select row(1, 2)::testtype1 *<> row(1)::testtype5; + +create type testtype6 as (a int, b point); + +select row(1, '(1,2)')::testtype6 *< row(1, '(1,3)')::testtype6; + +select row(1, '(1,2)')::testtype6 *>= row(1, '(1,3)')::testtype6; + +select row(1, '(1,2)')::testtype6 *<> row(1, '(1,3)')::testtype6; + +select q.a, q.b = row(2), q.c = array[row(3)], q.d = row(row(4)) from + unnest(array[row(1, row(2), array[row(3)], row(row(4))), + row(2, row(3), array[row(4)], row(row(5)))]) + as q(a int, b record, c record[], d record); + +drop type testtype1, testtype2, testtype3, testtype4, testtype5, testtype6; + +BEGIN; + +CREATE TABLE price ( + id SERIAL PRIMARY KEY, + active BOOLEAN NOT NULL, + price NUMERIC +); + +CREATE TYPE price_input AS ( + id INTEGER, + price NUMERIC +); + +CREATE TYPE price_key AS ( + id INTEGER +); + +CREATE FUNCTION price_key_from_table(price) RETURNS price_key AS $$ + SELECT $1.id +$$ LANGUAGE SQL; + +CREATE FUNCTION price_key_from_input(price_input) RETURNS price_key AS $$ + SELECT $1.id +$$ LANGUAGE SQL; + +insert into price values (1,false,42), (10,false,100), (11,true,17.99); + +UPDATE price + SET active = true, price = input_prices.price + FROM unnest(ARRAY[(10, 123.00), (11, 99.99)]::price_input[]) input_prices + WHERE price_key_from_table(price.*) = price_key_from_input(input_prices.*); + +select * from price; + +rollback; + +create temp table compos (f1 int, f2 text); + +create function fcompos1(v compos) returns void as $$ +insert into compos values (v); -- fail +$$ language sql; + +create function fcompos1(v compos) returns void as $$ +insert into compos values (v.*); +$$ language sql; + +create function fcompos2(v compos) returns void as $$ +select fcompos1(v); +$$ language sql; + +create function fcompos3(v compos) returns void as $$ +select fcompos1(fcompos3.v.*); +$$ language sql; + +select fcompos1(row(1,'one')); + +select fcompos2(row(2,'two')); + +select fcompos3(row(3,'three')); + +select * from compos; + +select cast (fullname as text) from fullname; + +select fullname::text from fullname; + +select text(fullname) from fullname; + +select fullname.text from fullname; + +select cast (row('Jim', 'Beam') as text); + +select (row('Jim', 'Beam'))::text; + +select text(row('Jim', 'Beam')); + +select (row('Jim', 'Beam')).text; + +insert into fullname values ('Joe', 'Blow'); + +select f.last from fullname f; + +select last(f) from fullname f; + +create function longname(fullname) returns text language sql +as $$select $1.first || ' ' || $1.last$$; + +select f.longname from fullname f; + +select longname(f) from fullname f; + +alter table fullname add column longname text; + +select f.longname from fullname f; + +select longname(f) from fullname f; + +select row_to_json(i) from int8_tbl i; + +select row_to_json(i) from int8_tbl i(x,y); + +select row_to_json(ss) from + (select q1, q2 from int8_tbl) as ss; + +select row_to_json(ss) from + (select q1, q2 from int8_tbl offset 0) as ss; + +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl) as ss; + +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl offset 0) as ss; + +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl) as ss(x,y); + +select row_to_json(ss) from + (select q1 as a, q2 as b from int8_tbl offset 0) as ss(x,y); + +select row_to_json(q) from + (select thousand, tenthous from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q; + +select row_to_json(q) from + (select thousand, tenthous from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q; + +select row_to_json(q) from + (select thousand as x, tenthous as y from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q; + +select row_to_json(q) from + (select thousand as x, tenthous as y from tenk1 + where thousand = 42 and tenthous < 2000 offset 0) q(a,b); + +create temp table tt1 as select * from int8_tbl limit 2; + +create temp table tt2 () inherits(tt1); + +insert into tt2 values(0,0); + +select row_to_json(r) from (select q2,q1 from tt1 offset 0) r; + +create temp table tt3 () inherits(tt2); + +insert into tt3 values(33,44); + +select row_to_json(tt3::tt2::tt1) from tt3; + +select r, r is null as isnull, r is not null as isnotnull +from (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b); + +select r, r is null as isnull, r is not null as isnotnull +from (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b); + +with r(a,b) as materialized + (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) +select r, r is null as isnull, r is not null as isnotnull from r; + +with r(a,b) as materialized + (values (1,row(1,2)), (1,row(null,null)), (1,null), + (null,row(1,2)), (null,row(null,null)), (null,null) ) +select r, r is null as isnull, r is not null as isnotnull from r; + +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select * from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null; + +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select * from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null; + +select 1 as one from cte2 as t +where (select * from (select c as c1) s + where (select (c1).f1 > 0)) is not null; + +select pg_get_viewdef('composite_v', true); + +drop view composite_v; + +select (ss.a).x, (ss.a).n from + (select information_schema._pg_expandarray(array[1,2]) AS a) ss; + +select (ss.a).x, (ss.a).n from + (select information_schema._pg_expandarray(array[1,2]) AS a) ss +where false; + +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select (c).f1 from cte2 as t; + +with cte(c) as materialized (select row(1, 2)), + cte2(c) as (select * from cte) +select (c).f1 from cte2 as t +where false; + +CREATE TABLE compositetable(a text, b text); + +INSERT INTO compositetable(a, b) VALUES('fa', 'fb'); + +SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s; + +SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s; + +SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s; + +SELECT (NULL::compositetable).nonexistent; + +SELECT (NULL::compositetable).a; + +SELECT (NULL::compositetable).oid; + +DROP TABLE compositetable; diff --git a/crates/pgt_pretty_print/tests/data/multi/rules_60.sql b/crates/pgt_pretty_print/tests/data/multi/rules_60.sql new file mode 100644 index 000000000..bd0f2aba4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/rules_60.sql @@ -0,0 +1,177 @@ +create table rtest_t1 (a int4, b int4); + +create table rtest_t2 (a int4, b int4); + +create table rtest_t3 (a int4, b int4); + +create view rtest_v1 as select * from rtest_t1; + +create rule rtest_v1_ins as on insert to rtest_v1 do instead + insert into rtest_t1 values (new.a, new.b); + +create rule rtest_v1_upd as on update to rtest_v1 do instead + update rtest_t1 set a = new.a, b = new.b + where a = old.a; + +create rule rtest_v1_del as on delete to rtest_v1 do instead + delete from rtest_t1 where a = old.a; + +COMMENT ON RULE rtest_v1_bad ON rtest_v1 IS 'bad rule'; + +COMMENT ON RULE rtest_v1_del ON rtest_v1 IS 'delete rule'; + +COMMENT ON RULE rtest_v1_del ON rtest_v1 IS NULL; + +create table rtest_system (sysname text, sysdesc text); + +create table rtest_interface (sysname text, ifname text); + +create table rtest_person (pname text, pdesc text); + +create table rtest_admin (pname text, sysname text); + +create rule rtest_sys_upd as on update to rtest_system do also ( + update rtest_interface set sysname = new.sysname + where sysname = old.sysname; + update rtest_admin set sysname = new.sysname + where sysname = old.sysname + ); + +create rule rtest_sys_del as on delete to rtest_system do also ( + delete from rtest_interface where sysname = old.sysname; + delete from rtest_admin where sysname = old.sysname; + ); + +create rule rtest_pers_upd as on update to rtest_person do also + update rtest_admin set pname = new.pname where pname = old.pname; + +create rule rtest_pers_del as on delete to rtest_person do also + delete from rtest_admin where pname = old.pname; + +create table rtest_emp (ename char(20), salary numeric); + +create table rtest_emplog (ename char(20), who name, action char(10), newsal numeric, oldsal numeric); + +create table rtest_empmass (ename char(20), salary numeric); + +create rule rtest_emp_ins as on insert to rtest_emp do + insert into rtest_emplog values (new.ename, current_user, + 'hired', new.salary, '0.00'); + +create rule rtest_emp_upd as on update to rtest_emp where new.salary != old.salary do + insert into rtest_emplog values (new.ename, current_user, + 'honored', new.salary, old.salary); + +create rule rtest_emp_del as on delete to rtest_emp do + insert into rtest_emplog values (old.ename, current_user, + 'fired', '0.00', old.salary); + +create table rtest_t4 (a int4, b text); + +create table rtest_t5 (a int4, b text); + +create table rtest_t6 (a int4, b text); + +create table rtest_t7 (a int4, b text); + +create table rtest_t8 (a int4, b text); + +create table rtest_t9 (a int4, b text); + +create rule rtest_t4_ins1 as on insert to rtest_t4 + where new.a >= 10 and new.a < 20 do instead + insert into rtest_t5 values (new.a, new.b); + +create rule rtest_t4_ins2 as on insert to rtest_t4 + where new.a >= 20 and new.a < 30 do + insert into rtest_t6 values (new.a, new.b); + +create rule rtest_t5_ins as on insert to rtest_t5 + where new.a > 15 do + insert into rtest_t7 values (new.a, new.b); + +create rule rtest_t6_ins as on insert to rtest_t6 + where new.a > 25 do instead + insert into rtest_t8 values (new.a, new.b); + +create table rtest_order1 (a int4); + +create table rtest_order2 (a int4, b int4, c text); + +create sequence rtest_seq; + +create rule rtest_order_r3 as on insert to rtest_order1 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 3 - this should run 3rd'); + +create rule rtest_order_r4 as on insert to rtest_order1 + where a < 100 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 4 - this should run 4th'); + +create rule rtest_order_r2 as on insert to rtest_order1 do + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 2 - this should run 2nd'); + +create rule rtest_order_r1 as on insert to rtest_order1 do instead + insert into rtest_order2 values (new.a, nextval('rtest_seq'), + 'rule 1 - this should run 1st'); + +create table rtest_nothn1 (a int4, b text); + +create table rtest_nothn2 (a int4, b text); + +create table rtest_nothn3 (a int4, b text); + +create table rtest_nothn4 (a int4, b text); + +create rule rtest_nothn_r1 as on insert to rtest_nothn1 + where new.a >= 10 and new.a < 20 do instead nothing; + +create rule rtest_nothn_r2 as on insert to rtest_nothn1 + where new.a >= 30 and new.a < 40 do instead nothing; + +create rule rtest_nothn_r3 as on insert to rtest_nothn2 + where new.a >= 100 do instead + insert into rtest_nothn3 values (new.a, new.b); + +create rule rtest_nothn_r4 as on insert to rtest_nothn2 + do instead nothing; + +insert into rtest_t2 values (1, 21); + +insert into rtest_t2 values (2, 22); + +insert into rtest_t2 values (3, 23); + +insert into rtest_t3 values (1, 31); + +insert into rtest_t3 values (2, 32); + +insert into rtest_t3 values (3, 33); + +insert into rtest_t3 values (4, 34); + +insert into rtest_t3 values (5, 35); + +insert into rtest_v1 values (1, 11); + +insert into rtest_v1 values (2, 12); + +select * from rtest_v1; + +delete from rtest_v1 where a = 1; + +select * from rtest_v1; + +insert into rtest_v1 values (1, 11); + +delete from rtest_v1 where b = 12; + +select * from rtest_v1; + +insert into rtest_v1 values (2, 12); + +insert into rtest_v1 values (2, 13); + +select * from rtest_v1; diff --git a/crates/pgt_pretty_print/tests/data/multi/sanity_check_60.sql b/crates/pgt_pretty_print/tests/data/multi/sanity_check_60.sql new file mode 100644 index 000000000..31a02cd4f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/sanity_check_60.sql @@ -0,0 +1,14 @@ +VACUUM; + +SELECT relname, nspname + FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a ON (attrelid = c.oid AND attname = 'oid') + WHERE relkind = 'r' and c.oid < 16384 + AND ((nspname ~ '^pg_') IS NOT FALSE) + AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid + AND indkey[0] = a.attnum AND indnatts = 1 + AND indisunique AND indimmediate); + +SELECT relname, relkind + FROM pg_class + WHERE relkind IN ('v', 'c', 'f', 'p', 'I') + AND relfilenode <> 0; diff --git a/crates/pgt_pretty_print/tests/data/multi/security_label_60.sql b/crates/pgt_pretty_print/tests/data/multi/security_label_60.sql new file mode 100644 index 000000000..e661b54a4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/security_label_60.sql @@ -0,0 +1,55 @@ +SET client_min_messages TO 'warning'; + +DROP ROLE IF EXISTS regress_seclabel_user1; + +DROP ROLE IF EXISTS regress_seclabel_user2; + +RESET client_min_messages; + +CREATE USER regress_seclabel_user1 WITH CREATEROLE; + +CREATE USER regress_seclabel_user2; + +CREATE TABLE seclabel_tbl1 (a int, b text); + +CREATE TABLE seclabel_tbl2 (x int, y text); + +CREATE VIEW seclabel_view1 AS SELECT * FROM seclabel_tbl2; + +CREATE FUNCTION seclabel_four() RETURNS integer AS $$SELECT 4$$ language sql; + +CREATE DOMAIN seclabel_domain AS text; + +ALTER TABLE seclabel_tbl1 OWNER TO regress_seclabel_user1; + +ALTER TABLE seclabel_tbl2 OWNER TO regress_seclabel_user2; + +SECURITY LABEL ON TABLE seclabel_tbl1 IS 'classified'; + +SECURITY LABEL FOR 'dummy' ON TABLE seclabel_tbl1 IS 'classified'; + +SECURITY LABEL ON TABLE seclabel_tbl1 IS '...invalid label...'; + +SECURITY LABEL ON TABLE seclabel_tbl3 IS 'unclassified'; + +SECURITY LABEL ON ROLE regress_seclabel_user1 IS 'classified'; + +SECURITY LABEL FOR 'dummy' ON ROLE regress_seclabel_user1 IS 'classified'; + +SECURITY LABEL ON ROLE regress_seclabel_user1 IS '...invalid label...'; + +SECURITY LABEL ON ROLE regress_seclabel_user3 IS 'unclassified'; + +DROP FUNCTION seclabel_four(); + +DROP DOMAIN seclabel_domain; + +DROP VIEW seclabel_view1; + +DROP TABLE seclabel_tbl1; + +DROP TABLE seclabel_tbl2; + +DROP USER regress_seclabel_user1; + +DROP USER regress_seclabel_user2; diff --git a/crates/pgt_pretty_print/tests/data/multi/select_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_60.sql new file mode 100644 index 000000000..f3cf6a335 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_60.sql @@ -0,0 +1,207 @@ +SELECT * FROM onek + WHERE onek.unique1 < 10 + ORDER BY onek.unique1; + +SELECT onek.unique1, onek.stringu1 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using >; + +SELECT onek.unique1, onek.stringu1 FROM onek + WHERE onek.unique1 > 980 + ORDER BY stringu1 using <; + +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 > 980 + ORDER BY string4 using <, unique1 using >; + +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 > 980 + ORDER BY string4 using >, unique1 using <; + +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using >, string4 using <; + +SELECT onek.unique1, onek.string4 FROM onek + WHERE onek.unique1 < 20 + ORDER BY unique1 using <, string4 using >; + +ANALYZE onek2; + +SET enable_seqscan TO off; + +SET enable_bitmapscan TO off; + +SET enable_sort TO off; + +SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10; + +SELECT onek2.unique1, onek2.stringu1 FROM onek2 + WHERE onek2.unique1 < 20 + ORDER BY unique1 using >; + +SELECT onek2.unique1, onek2.stringu1 FROM onek2 + WHERE onek2.unique1 > 980; + +RESET enable_seqscan; + +RESET enable_bitmapscan; + +RESET enable_sort; + +SELECT p.name, p.age FROM person* p; + +SELECT p.name, p.age FROM person* p ORDER BY age using >, name; + +select foo from (select 1 offset 0) as foo; + +select foo from (select null offset 0) as foo; + +select foo from (select 'xyzzy',1,null offset 0) as foo; + +select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) + WHERE onek.unique1 = v.i and onek.stringu1 = v.j; + +select * from onek, + (values ((select i from + (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i) + order by i asc limit 1))) bar (i) + where onek.unique1 = bar.i; + +select * from onek + where (unique1,ten) in (values (1,1), (20,0), (99,9), (17,99)) + order by unique1; + +VALUES (1,2), (3,4+4), (7,77.7); + +VALUES (1,2), (3,4+4), (7,77.7) +UNION ALL +SELECT 2+2, 57 +UNION ALL +TABLE int8_tbl; + +CREATE TEMP TABLE nocols(); + +INSERT INTO nocols DEFAULT VALUES; + +SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v; + +CREATE TEMP TABLE foo (f1 int); + +INSERT INTO foo VALUES (42),(3),(10),(7),(null),(null),(1); + +SELECT * FROM foo ORDER BY f1; + +SELECT * FROM foo ORDER BY f1 ASC; + +SELECT * FROM foo ORDER BY f1 NULLS FIRST; + +SELECT * FROM foo ORDER BY f1 DESC; + +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; + +CREATE INDEX fooi ON foo (f1); + +SET enable_sort = false; + +SELECT * FROM foo ORDER BY f1; + +SELECT * FROM foo ORDER BY f1 NULLS FIRST; + +SELECT * FROM foo ORDER BY f1 DESC; + +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; + +DROP INDEX fooi; + +CREATE INDEX fooi ON foo (f1 DESC); + +SELECT * FROM foo ORDER BY f1; + +SELECT * FROM foo ORDER BY f1 NULLS FIRST; + +SELECT * FROM foo ORDER BY f1 DESC; + +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; + +DROP INDEX fooi; + +CREATE INDEX fooi ON foo (f1 DESC NULLS LAST); + +SELECT * FROM foo ORDER BY f1; + +SELECT * FROM foo ORDER BY f1 NULLS FIRST; + +SELECT * FROM foo ORDER BY f1 DESC; + +SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; + +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; + +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; + +select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; + +select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; + +select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; + +select * from onek2 where unique2 = 11 and stringu1 < 'B'; + +select * from onek2 where unique2 = 11 and stringu1 < 'B'; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; + +SET enable_indexscan TO off; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; + +select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; + +RESET enable_indexscan; + +select unique1, unique2 from onek2 + where (unique2 = 11 or unique1 = 0) and stringu1 < 'B'; + +select unique1, unique2 from onek2 + where (unique2 = 11 or unique1 = 0) and stringu1 < 'B'; + +select unique1, unique2 from onek2 + where (unique2 = 11 and stringu1 < 'B') or unique1 = 0; + +select unique1, unique2 from onek2 + where (unique2 = 11 and stringu1 < 'B') or unique1 = 0; + +SELECT 1 AS x ORDER BY x; + +create function sillysrf(int) returns setof int as + 'values (1),(10),(2),($1)' language sql immutable; + +select sillysrf(42); + +select sillysrf(-1) order by 1; + +drop function sillysrf(int); + +select * from (values (2),(null),(1)) v(k) where k = k order by k; + +select * from (values (2),(null),(1)) v(k) where k = k; + +create table list_parted_tbl (a int,b int) partition by list (a); + +create table list_parted_tbl1 partition of list_parted_tbl + for values in (1) partition by list(b); + +select * from list_parted_tbl; + +drop table list_parted_tbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/select_distinct_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_distinct_60.sql new file mode 100644 index 000000000..775cb6bd1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_distinct_60.sql @@ -0,0 +1,221 @@ +SELECT DISTINCT two FROM onek ORDER BY 1; + +SELECT DISTINCT ten FROM onek ORDER BY 1; + +SELECT DISTINCT string4 FROM onek ORDER BY 1; + +SELECT DISTINCT two, string4, ten + FROM onek + ORDER BY two using <, string4 using <, ten using <; + +SELECT DISTINCT p.age FROM person* p ORDER BY age using >; + +SELECT count(*) FROM + (SELECT DISTINCT two, four, two FROM tenk1) ss; + +SELECT count(*) FROM + (SELECT DISTINCT two, four, two FROM tenk1) ss; + +SET work_mem='64kB'; + +SET enable_hashagg=FALSE; + +SET jit_above_cost=0; + +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; + +CREATE TABLE distinct_group_1 AS +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; + +SET jit_above_cost TO DEFAULT; + +CREATE TABLE distinct_group_2 AS +SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g; + +SET enable_seqscan = 0; + +SELECT DISTINCT hundred, two FROM tenk1; + +RESET enable_seqscan; + +SET enable_hashagg=TRUE; + +SET enable_sort=FALSE; + +SET jit_above_cost=0; + +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; + +CREATE TABLE distinct_hash_1 AS +SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; + +SET jit_above_cost TO DEFAULT; + +CREATE TABLE distinct_hash_2 AS +SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g; + +SET enable_sort=TRUE; + +SET work_mem TO DEFAULT; + +(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) + UNION ALL +(SELECT * FROM distinct_group_1 EXCEPT SELECT * FROM distinct_hash_1); + +(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) + UNION ALL +(SELECT * FROM distinct_group_1 EXCEPT SELECT * FROM distinct_hash_1); + +DROP TABLE distinct_hash_1; + +DROP TABLE distinct_hash_2; + +DROP TABLE distinct_group_1; + +DROP TABLE distinct_group_2; + +SET parallel_tuple_cost=0; + +SET parallel_setup_cost=0; + +SET min_parallel_table_scan_size=0; + +SET max_parallel_workers_per_gather=2; + +SELECT DISTINCT four FROM tenk1; + +SELECT DISTINCT four FROM tenk1; + +CREATE OR REPLACE FUNCTION distinct_func(a INT) RETURNS INT AS $$ + BEGIN + RETURN a; + END; +$$ LANGUAGE plpgsql PARALLEL UNSAFE; + +SELECT DISTINCT distinct_func(1) FROM tenk1; + +CREATE OR REPLACE FUNCTION distinct_func(a INT) RETURNS INT AS $$ + BEGIN + RETURN a; + END; +$$ LANGUAGE plpgsql PARALLEL SAFE; + +SELECT DISTINCT distinct_func(1) FROM tenk1; + +RESET max_parallel_workers_per_gather; + +RESET min_parallel_table_scan_size; + +RESET parallel_setup_cost; + +RESET parallel_tuple_cost; + +SELECT DISTINCT four FROM tenk1 WHERE four = 0; + +SELECT DISTINCT four FROM tenk1 WHERE four = 0; + +SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0; + +SELECT DISTINCT four FROM tenk1 WHERE four = 0 AND two <> 0; + +SELECT DISTINCT four,1,2,3 FROM tenk1 WHERE four = 0; + +SELECT DISTINCT four,1,2,3 FROM tenk1 WHERE four = 0; + +SET parallel_setup_cost=0; + +SET min_parallel_table_scan_size=0; + +SET max_parallel_workers_per_gather=2; + +SELECT DISTINCT four FROM tenk1 WHERE four = 10; + +RESET max_parallel_workers_per_gather; + +RESET min_parallel_table_scan_size; + +RESET parallel_setup_cost; + +CREATE TEMP TABLE disttable (f1 integer); + +INSERT INTO DISTTABLE VALUES(1); + +INSERT INTO DISTTABLE VALUES(2); + +INSERT INTO DISTTABLE VALUES(3); + +INSERT INTO DISTTABLE VALUES(NULL); + +SELECT f1, f1 IS DISTINCT FROM 2 as "not 2" FROM disttable; + +SELECT f1, f1 IS DISTINCT FROM NULL as "not null" FROM disttable; + +SELECT f1, f1 IS DISTINCT FROM f1 as "false" FROM disttable; + +SELECT f1, f1 IS DISTINCT FROM f1+1 as "not null" FROM disttable; + +SELECT 1 IS DISTINCT FROM 2 as "yes"; + +SELECT 2 IS DISTINCT FROM 2 as "no"; + +SELECT 2 IS DISTINCT FROM null as "yes"; + +SELECT null IS DISTINCT FROM null as "no"; + +SELECT 1 IS NOT DISTINCT FROM 2 as "no"; + +SELECT 2 IS NOT DISTINCT FROM 2 as "yes"; + +SELECT 2 IS NOT DISTINCT FROM null as "no"; + +SELECT null IS NOT DISTINCT FROM null as "yes"; + +CREATE TABLE distinct_tbl (x int, y int); + +INSERT INTO distinct_tbl SELECT i%10, i%10 FROM generate_series(1, 1000) AS i; + +CREATE INDEX distinct_tbl_x_y_idx ON distinct_tbl (x, y); + +ANALYZE distinct_tbl; + +SET enable_hashagg TO OFF; + +SELECT DISTINCT y, x FROM distinct_tbl; + +SELECT DISTINCT y, x FROM distinct_tbl; + +SELECT DISTINCT y, x FROM (SELECT * FROM distinct_tbl ORDER BY x) s; + +SELECT DISTINCT y, x FROM (SELECT * FROM distinct_tbl ORDER BY x) s; + +SET parallel_tuple_cost=0; + +SET parallel_setup_cost=0; + +SET min_parallel_table_scan_size=0; + +SET min_parallel_index_scan_size=0; + +SET max_parallel_workers_per_gather=2; + +SELECT DISTINCT y, x FROM distinct_tbl limit 10; + +SELECT DISTINCT y, x FROM distinct_tbl limit 10; + +RESET max_parallel_workers_per_gather; + +RESET min_parallel_index_scan_size; + +RESET min_parallel_table_scan_size; + +RESET parallel_setup_cost; + +RESET parallel_tuple_cost; + +SELECT DISTINCT y, x FROM distinct_tbl ORDER BY y; + +SELECT DISTINCT y, x FROM distinct_tbl ORDER BY y; + +RESET enable_hashagg; + +DROP TABLE distinct_tbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/select_distinct_on_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_distinct_on_60.sql new file mode 100644 index 000000000..50d22fc54 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_distinct_on_60.sql @@ -0,0 +1,55 @@ +SELECT DISTINCT ON (string4) string4, two, ten + FROM onek + ORDER BY string4 using <, two using >, ten using <; + +SELECT DISTINCT ON (string4, ten) string4, two, ten + FROM onek + ORDER BY string4 using <, two using <, ten using <; + +SELECT DISTINCT ON (string4, ten) string4, ten, two + FROM onek + ORDER BY string4 using <, ten using >, two using <; + +select distinct on (1) floor(random()) as r, f1 from int4_tbl order by 1,2; + +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1; + +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1; + +SELECT DISTINCT ON (four) four,two + FROM tenk1 WHERE four = 0 ORDER BY 1,2; + +SELECT DISTINCT ON (four) four,hundred + FROM tenk1 WHERE four = 0 ORDER BY 1,2; + +CREATE TABLE distinct_on_tbl (x int, y int, z int); + +INSERT INTO distinct_on_tbl SELECT i%10, i%10, i%10 FROM generate_series(1, 1000) AS i; + +CREATE INDEX distinct_on_tbl_x_y_idx ON distinct_on_tbl (x, y); + +ANALYZE distinct_on_tbl; + +SET enable_hashagg TO OFF; + +SELECT DISTINCT ON (y, x) x, y FROM distinct_on_tbl; + +SELECT DISTINCT ON (y, x) x, y FROM distinct_on_tbl; + +SELECT DISTINCT ON (y, x) x, y FROM (SELECT * FROM distinct_on_tbl ORDER BY x) s; + +SELECT DISTINCT ON (y, x) x, y FROM (SELECT * FROM distinct_on_tbl ORDER BY x) s; + +SELECT DISTINCT ON (y, x) x, y FROM distinct_on_tbl ORDER BY y; + +SELECT DISTINCT ON (y, x) x, y FROM distinct_on_tbl ORDER BY y; + +SELECT DISTINCT ON (y, x) x, y FROM (select * from distinct_on_tbl order by x, z, y) s ORDER BY y, x, z; + +SELECT DISTINCT ON (y, x) x, y FROM (select * from distinct_on_tbl order by x, z, y) s ORDER BY y, x, z; + +RESET enable_hashagg; + +DROP TABLE distinct_on_tbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/select_having_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_having_60.sql new file mode 100644 index 000000000..ba945931f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_having_60.sql @@ -0,0 +1,51 @@ +CREATE TABLE test_having (a int, b int, c char(8), d char); + +INSERT INTO test_having VALUES (0, 1, 'XXXX', 'A'); + +INSERT INTO test_having VALUES (1, 2, 'AAAA', 'b'); + +INSERT INTO test_having VALUES (2, 2, 'AAAA', 'c'); + +INSERT INTO test_having VALUES (3, 3, 'BBBB', 'D'); + +INSERT INTO test_having VALUES (4, 3, 'BBBB', 'e'); + +INSERT INTO test_having VALUES (5, 3, 'bbbb', 'F'); + +INSERT INTO test_having VALUES (6, 4, 'cccc', 'g'); + +INSERT INTO test_having VALUES (7, 4, 'cccc', 'h'); + +INSERT INTO test_having VALUES (8, 4, 'CCCC', 'I'); + +INSERT INTO test_having VALUES (9, 4, 'CCCC', 'j'); + +SELECT b, c FROM test_having + GROUP BY b, c HAVING count(*) = 1 ORDER BY b, c; + +SELECT b, c FROM test_having + GROUP BY b, c HAVING b = 3 ORDER BY b, c; + +SELECT lower(c), count(c) FROM test_having + GROUP BY lower(c) HAVING count(*) > 2 OR min(a) = max(a) + ORDER BY lower(c); + +SELECT c, max(a) FROM test_having + GROUP BY c HAVING count(*) > 2 OR min(a) = max(a) + ORDER BY c; + +SELECT min(a), max(a) FROM test_having HAVING min(a) = max(a); + +SELECT min(a), max(a) FROM test_having HAVING min(a) < max(a); + +SELECT a FROM test_having HAVING min(a) < max(a); + +SELECT 1 AS one FROM test_having HAVING a > 1; + +SELECT 1 AS one FROM test_having HAVING 1 > 2; + +SELECT 1 AS one FROM test_having HAVING 1 < 2; + +SELECT 1 AS one FROM test_having WHERE 1/a = 1 HAVING 1 < 2; + +DROP TABLE test_having; diff --git a/crates/pgt_pretty_print/tests/data/multi/select_implicit_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_implicit_60.sql new file mode 100644 index 000000000..4c417d591 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_implicit_60.sql @@ -0,0 +1,117 @@ +CREATE TABLE test_missing_target (a int, b int, c char(8), d char); + +INSERT INTO test_missing_target VALUES (0, 1, 'XXXX', 'A'); + +INSERT INTO test_missing_target VALUES (1, 2, 'ABAB', 'b'); + +INSERT INTO test_missing_target VALUES (2, 2, 'ABAB', 'c'); + +INSERT INTO test_missing_target VALUES (3, 3, 'BBBB', 'D'); + +INSERT INTO test_missing_target VALUES (4, 3, 'BBBB', 'e'); + +INSERT INTO test_missing_target VALUES (5, 3, 'bbbb', 'F'); + +INSERT INTO test_missing_target VALUES (6, 4, 'cccc', 'g'); + +INSERT INTO test_missing_target VALUES (7, 4, 'cccc', 'h'); + +INSERT INTO test_missing_target VALUES (8, 4, 'CCCC', 'I'); + +INSERT INTO test_missing_target VALUES (9, 4, 'CCCC', 'j'); + +SELECT c, count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c; + +SELECT count(*) FROM test_missing_target GROUP BY test_missing_target.c ORDER BY c; + +SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b; + +SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b; + +SELECT test_missing_target.b, count(*) + FROM test_missing_target GROUP BY b ORDER BY b; + +SELECT c FROM test_missing_target ORDER BY a; + +SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b desc; + +SELECT count(*) FROM test_missing_target ORDER BY 1 desc; + +SELECT c, count(*) FROM test_missing_target GROUP BY 1 ORDER BY 1; + +SELECT c, count(*) FROM test_missing_target GROUP BY 3; + +SELECT count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY b ORDER BY b; + +SELECT a, a FROM test_missing_target + ORDER BY a; + +SELECT a/2, a/2 FROM test_missing_target + ORDER BY a/2; + +SELECT a/2, a/2 FROM test_missing_target + GROUP BY a/2 ORDER BY a/2; + +SELECT x.b, count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b; + +SELECT count(*) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b; + +CREATE TABLE test_missing_target2 AS +SELECT count(*) +FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b ORDER BY x.b; + +SELECT * FROM test_missing_target2; + +SELECT a%2, count(b) FROM test_missing_target +GROUP BY test_missing_target.a%2 +ORDER BY test_missing_target.a%2; + +SELECT count(c) FROM test_missing_target +GROUP BY lower(test_missing_target.c) +ORDER BY lower(test_missing_target.c); + +SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b; + +SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2; + +SELECT lower(test_missing_target.c), count(c) + FROM test_missing_target GROUP BY lower(c) ORDER BY lower(c); + +SELECT a FROM test_missing_target ORDER BY upper(d); + +SELECT count(b) FROM test_missing_target + GROUP BY (b + 1) / 2 ORDER BY (b + 1) / 2 desc; + +SELECT count(x.a) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY b/2 ORDER BY b/2; + +SELECT x.b/2, count(x.b) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 ORDER BY x.b/2; + +SELECT count(b) FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2; + +CREATE TABLE test_missing_target3 AS +SELECT count(x.b) +FROM test_missing_target x, test_missing_target y + WHERE x.a = y.a + GROUP BY x.b/2 ORDER BY x.b/2; + +SELECT * FROM test_missing_target3; + +DROP TABLE test_missing_target; + +DROP TABLE test_missing_target2; + +DROP TABLE test_missing_target3; diff --git a/crates/pgt_pretty_print/tests/data/multi/select_into_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_into_60.sql new file mode 100644 index 000000000..9267bdd25 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_into_60.sql @@ -0,0 +1,156 @@ +SELECT * + INTO TABLE sitmp1 + FROM onek + WHERE onek.unique1 < 2; + +DROP TABLE sitmp1; + +SELECT * + INTO TABLE sitmp1 + FROM onek2 + WHERE onek2.unique1 < 2; + +DROP TABLE sitmp1; + +CREATE SCHEMA selinto_schema; + +CREATE USER regress_selinto_user; + +ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + REVOKE INSERT ON TABLES FROM regress_selinto_user; + +GRANT ALL ON SCHEMA selinto_schema TO public; + +SET SESSION AUTHORIZATION regress_selinto_user; + +CREATE TABLE selinto_schema.tbl_withdata1 (a) + AS SELECT generate_series(1,3) WITH DATA; + +INSERT INTO selinto_schema.tbl_withdata1 VALUES (4); + +CREATE TABLE selinto_schema.tbl_withdata2 (a) AS + SELECT generate_series(1,3) WITH DATA; + +CREATE TABLE selinto_schema.tbl_nodata1 (a) AS + SELECT generate_series(1,3) WITH NO DATA; + +CREATE TABLE selinto_schema.tbl_nodata2 (a) AS + SELECT generate_series(1,3) WITH NO DATA; + +PREPARE data_sel AS SELECT generate_series(1,3); + +CREATE TABLE selinto_schema.tbl_withdata3 (a) AS + EXECUTE data_sel WITH DATA; + +CREATE TABLE selinto_schema.tbl_withdata4 (a) AS + EXECUTE data_sel WITH DATA; + +CREATE TABLE selinto_schema.tbl_nodata3 (a) AS + EXECUTE data_sel WITH NO DATA; + +CREATE TABLE selinto_schema.tbl_nodata4 (a) AS + EXECUTE data_sel WITH NO DATA; + +RESET SESSION AUTHORIZATION; + +ALTER DEFAULT PRIVILEGES FOR ROLE regress_selinto_user + GRANT INSERT ON TABLES TO regress_selinto_user; + +SET SESSION AUTHORIZATION regress_selinto_user; + +RESET SESSION AUTHORIZATION; + +DEALLOCATE data_sel; + +DROP SCHEMA selinto_schema CASCADE; + +DROP USER regress_selinto_user; + +CREATE TABLE ctas_base (i int, j int); + +INSERT INTO ctas_base VALUES (1, 2); + +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base; + +CREATE TABLE ctas_nodata (ii, jj, kk) AS SELECT i, j FROM ctas_base WITH NO DATA; + +CREATE TABLE ctas_nodata (ii, jj) AS SELECT i, j FROM ctas_base; + +CREATE TABLE ctas_nodata_2 (ii, jj) AS SELECT i, j FROM ctas_base WITH NO DATA; + +CREATE TABLE ctas_nodata_3 (ii) AS SELECT i, j FROM ctas_base; + +CREATE TABLE ctas_nodata_4 (ii) AS SELECT i, j FROM ctas_base WITH NO DATA; + +SELECT * FROM ctas_nodata; + +SELECT * FROM ctas_nodata_2; + +SELECT * FROM ctas_nodata_3; + +SELECT * FROM ctas_nodata_4; + +DROP TABLE ctas_base; + +DROP TABLE ctas_nodata; + +DROP TABLE ctas_nodata_2; + +DROP TABLE ctas_nodata_3; + +DROP TABLE ctas_nodata_4; + +CREATE FUNCTION make_table() RETURNS VOID +AS $$ + CREATE TABLE created_table AS SELECT * FROM int8_tbl; +$$ LANGUAGE SQL; + +SELECT make_table(); + +SELECT * FROM created_table; + +DO $$ +BEGIN + EXECUTE 'EXPLAIN ANALYZE SELECT * INTO TABLE easi FROM int8_tbl'; + EXECUTE 'EXPLAIN ANALYZE CREATE TABLE easi2 AS SELECT * FROM int8_tbl WITH NO DATA'; +END$$; + +DROP TABLE created_table; + +DROP TABLE easi, easi2; + +DECLARE foo CURSOR FOR SELECT 1 INTO int4_tbl; + +COPY (SELECT 1 INTO frak UNION SELECT 2) TO 'blob'; + +SELECT * FROM (SELECT 1 INTO f) bar; + +CREATE VIEW foo AS SELECT 1 INTO int4_tbl; + +INSERT INTO int4_tbl SELECT 1 INTO f; + +CREATE TABLE ctas_ine_tbl AS SELECT 1; + +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0; + +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0; + +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA; + +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA; + +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0; + +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0; + +CREATE TABLE ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA; + +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS SELECT 1 / 0 WITH NO DATA; + +PREPARE ctas_ine_query AS SELECT 1 / 0; + +CREATE TABLE ctas_ine_tbl AS EXECUTE ctas_ine_query; + +CREATE TABLE IF NOT EXISTS ctas_ine_tbl AS EXECUTE ctas_ine_query; + +DROP TABLE ctas_ine_tbl; diff --git a/crates/pgt_pretty_print/tests/data/multi/select_parallel_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_parallel_60.sql new file mode 100644 index 000000000..ffb3e9c29 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_parallel_60.sql @@ -0,0 +1,621 @@ +select pg_stat_force_next_flush(); + +select parallel_workers_to_launch as parallel_workers_to_launch_before, + parallel_workers_launched as parallel_workers_launched_before + from pg_stat_database + where datname = current_database() ; + +create function sp_parallel_restricted(int) returns int as + $$begin return $1; end$$ language plpgsql parallel restricted; + +begin; + +set parallel_setup_cost=0; + +set parallel_tuple_cost=0; + +set min_parallel_table_scan_size=0; + +set max_parallel_workers_per_gather=4; + +select round(avg(aa)), sum(aa) from a_star; + +select round(avg(aa)), sum(aa) from a_star a1; + +alter table c_star set (parallel_workers = 0); + +alter table d_star set (parallel_workers = 0); + +select round(avg(aa)), sum(aa) from a_star; + +select round(avg(aa)), sum(aa) from a_star a2; + +alter table a_star set (parallel_workers = 0); + +alter table b_star set (parallel_workers = 0); + +alter table e_star set (parallel_workers = 0); + +alter table f_star set (parallel_workers = 0); + +select round(avg(aa)), sum(aa) from a_star; + +select round(avg(aa)), sum(aa) from a_star a3; + +alter table a_star reset (parallel_workers); + +alter table b_star reset (parallel_workers); + +alter table c_star reset (parallel_workers); + +alter table d_star reset (parallel_workers); + +alter table e_star reset (parallel_workers); + +alter table f_star reset (parallel_workers); + +set enable_parallel_append to off; + +select round(avg(aa)), sum(aa) from a_star; + +select round(avg(aa)), sum(aa) from a_star a4; + +reset enable_parallel_append; + +create function sp_test_func() returns setof text as +$$ select 'foo'::varchar union all select 'bar'::varchar $$ +language sql stable; + +select sp_test_func() order by 1; + +create table part_pa_test(a int, b int) partition by range(a); + +create table part_pa_test_p1 partition of part_pa_test for values from (minvalue) to (0); + +create table part_pa_test_p2 partition of part_pa_test for values from (0) to (maxvalue); + +select (select max((select pa1.b from part_pa_test pa1 where pa1.a = pa2.a))) + from part_pa_test pa2; + +drop table part_pa_test; + +set parallel_leader_participation = off; + +select count(*) from tenk1 where stringu1 = 'GRAAAA'; + +select count(*) from tenk1 where stringu1 = 'GRAAAA'; + +set max_parallel_workers = 0; + +select count(*) from tenk1 where stringu1 = 'GRAAAA'; + +select count(*) from tenk1 where stringu1 = 'GRAAAA'; + +reset max_parallel_workers; + +reset parallel_leader_participation; + +alter table tenk1 set (parallel_workers = 4); + +select sp_parallel_restricted(unique1) from tenk1 + where stringu1 = 'GRAAAA' order by 1; + +select length(stringu1) from tenk1 group by length(stringu1); + +select length(stringu1) from tenk1 group by length(stringu1); + +select stringu1, count(*) from tenk1 group by stringu1 order by stringu1; + +select sum(sp_parallel_restricted(unique1)) from tenk1 + group by(sp_parallel_restricted(unique1)); + +prepare tenk1_count(integer) As select count((unique1)) from tenk1 where hundred > $1; + +explain (costs off) execute tenk1_count(1); + +execute tenk1_count(1); + +deallocate tenk1_count; + +alter table tenk2 set (parallel_workers = 0); + +select count(*) from tenk1 where (two, four) not in + (select hundred, thousand from tenk2 where thousand > 100); + +select count(*) from tenk1 where (two, four) not in + (select hundred, thousand from tenk2 where thousand > 100); + +select * from tenk1 where (unique1 + random())::integer not in + (select ten from tenk2); + +alter table tenk2 reset (parallel_workers); + +set enable_indexscan = off; + +set enable_indexonlyscan = off; + +set enable_bitmapscan = off; + +alter table tenk2 set (parallel_workers = 2); + +select count(*) from tenk1 + where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2); + +select count(*) from tenk1 + where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2); + +reset enable_indexscan; + +reset enable_indexonlyscan; + +reset enable_bitmapscan; + +alter table tenk2 reset (parallel_workers); + +set enable_seqscan to off; + +set enable_bitmapscan to off; + +set random_page_cost = 2; + +select count((unique1)) from tenk1 where hundred > 1; + +select count((unique1)) from tenk1 where hundred > 1; + +select count((unique1)) from tenk1 + where hundred = any ((select array_agg(i) from generate_series(1, 100, 15) i)::int[]); + +select count((unique1)) from tenk1 +where hundred = any ((select array_agg(i) from generate_series(1, 100, 15) i)::int[]); + +select count(*) from tenk1 where thousand > 95; + +select count(*) from tenk1 where thousand > 95; + +set enable_material = false; + +select * from + (select count(unique1) from tenk1 where hundred > 10) ss + right join (values (1),(2),(3)) v(x) on true; + +select * from + (select count(unique1) from tenk1 where hundred > 10) ss + right join (values (1),(2),(3)) v(x) on true; + +select * from + (select count(*) from tenk1 where thousand > 99) ss + right join (values (1),(2),(3)) v(x) on true; + +select * from + (select count(*) from tenk1 where thousand > 99) ss + right join (values (1),(2),(3)) v(x) on true; + +reset enable_seqscan; + +set enable_indexonlyscan to off; + +set enable_indexscan to off; + +alter table tenk1 set (parallel_workers = 0); + +alter table tenk2 set (parallel_workers = 1); + +select count(*) from tenk1 + left join (select tenk2.unique1 from tenk2 order by 1 limit 1000) ss + on tenk1.unique1 < ss.unique1 + 1 + where tenk1.unique1 < 2; + +select count(*) from tenk1 + left join (select tenk2.unique1 from tenk2 order by 1 limit 1000) ss + on tenk1.unique1 < ss.unique1 + 1 + where tenk1.unique1 < 2; + +alter table tenk1 set (parallel_workers = 4); + +alter table tenk2 reset (parallel_workers); + +reset enable_material; + +reset enable_bitmapscan; + +reset enable_indexonlyscan; + +reset enable_indexscan; + +set enable_seqscan to off; + +set enable_indexscan to off; + +set enable_hashjoin to off; + +set enable_mergejoin to off; + +set enable_material to off; + +DO $$ +BEGIN + SET effective_io_concurrency = 50; +EXCEPTION WHEN invalid_parameter_value THEN +END $$; + +set work_mem='64kB'; + +select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; + +select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; + +create table bmscantest (a int, t text); + +insert into bmscantest select r, 'fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' FROM generate_series(1,100000) r; + +create index i_bmtest ON bmscantest(a); + +select count(*) from bmscantest where a>1; + +reset enable_seqscan; + +alter table tenk2 set (parallel_workers = 0); + +select count(*) from tenk1, tenk2 where tenk1.hundred > 1 + and tenk2.thousand=0; + +alter table tenk2 reset (parallel_workers); + +reset work_mem; + +create function explain_parallel_sort_stats() returns setof text +language plpgsql as +$$ +declare ln text; +begin + for ln in + explain (analyze, timing off, summary off, costs off, buffers off) + select * from + (select ten from tenk1 where ten < 100 order by ten) ss + right join (values (1),(2),(3)) v(x) on true + loop + ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx'); + return next ln; + end loop; +end; +$$; + +select * from explain_parallel_sort_stats(); + +reset enable_indexscan; + +reset enable_hashjoin; + +reset enable_mergejoin; + +reset enable_material; + +reset effective_io_concurrency; + +drop table bmscantest; + +drop function explain_parallel_sort_stats(); + +set enable_hashjoin to off; + +set enable_nestloop to off; + +select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1; + +select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1; + +reset enable_hashjoin; + +reset enable_nestloop; + +alter table tenk2 set (parallel_workers = 0); + +select * from tenk1 t1, tenk2 t2 where t1.two > t2.two; + +select * from tenk1 t1 + left join lateral + (select t1.unique1 as x, * from tenk2 t2 order by 1) t2 + on true +where t1.two > t2.two; + +alter table tenk2 reset (parallel_workers); + +set enable_hashagg = false; + +select count(*) from tenk1 group by twenty; + +select count(*) from tenk1 group by twenty; + +create function sp_simple_func(var1 integer) returns integer +as $$ +begin + return var1 + 10; +end; +$$ language plpgsql PARALLEL SAFE; + +select ten, sp_simple_func(ten) from tenk1 where ten < 100 order by ten; + +drop function sp_simple_func(integer); + +select count(*), generate_series(1,2) from tenk1 group by twenty; + +select count(*), generate_series(1,2) from tenk1 group by twenty; + +set parallel_leader_participation = off; + +select count(*) from tenk1 group by twenty; + +select count(*) from tenk1 group by twenty; + +reset parallel_leader_participation; + +set enable_material = false; + +select * from + (select string4, count(unique2) + from tenk1 group by string4 order by string4) ss + right join (values (1),(2),(3)) v(x) on true; + +select * from + (select string4, count(unique2) + from tenk1 group by string4 order by string4) ss + right join (values (1),(2),(3)) v(x) on true; + +reset enable_material; + +reset enable_hashagg; + +select avg(unique1::int8) from tenk1; + +select avg(unique1::int8) from tenk1; + +select fivethous from tenk1 order by fivethous limit 4; + +select fivethous from tenk1 order by fivethous limit 4; + +set max_parallel_workers = 0; + +select string4 from tenk1 order by string4 limit 5; + +select string4 from tenk1 order by string4 limit 5; + +set parallel_leader_participation = off; + +select string4 from tenk1 order by string4 limit 5; + +select string4 from tenk1 order by string4 limit 5; + +reset parallel_leader_participation; + +reset max_parallel_workers; + +create function parallel_safe_volatile(a int) returns int as + $$ begin return a; end; $$ parallel safe volatile language plpgsql; + +select * from tenk1 where four = 2 +order by four, hundred, parallel_safe_volatile(thousand); + +set min_parallel_index_scan_size = 0; + +set enable_seqscan = off; + +select * from tenk1 where four = 2 +order by four, hundred, parallel_safe_volatile(thousand); + +reset min_parallel_index_scan_size; + +reset enable_seqscan; + +select count(*) from tenk1 +group by twenty, parallel_safe_volatile(two); + +drop function parallel_safe_volatile(int); + +SAVEPOINT settings; + +SET LOCAL debug_parallel_query = 1; + +select stringu1::int2 from tenk1 where unique1 = 1; + +ROLLBACK TO SAVEPOINT settings; + +CREATE FUNCTION make_record(n int) + RETURNS RECORD LANGUAGE plpgsql PARALLEL SAFE AS +$$ +BEGIN + RETURN CASE n + WHEN 1 THEN ROW(1) + WHEN 2 THEN ROW(1, 2) + WHEN 3 THEN ROW(1, 2, 3) + WHEN 4 THEN ROW(1, 2, 3, 4) + ELSE ROW(1, 2, 3, 4, 5) + END; +END; +$$; + +SAVEPOINT settings; + +SET LOCAL debug_parallel_query = 1; + +SELECT make_record(x) FROM (SELECT generate_series(1, 5) x) ss ORDER BY x; + +ROLLBACK TO SAVEPOINT settings; + +DROP function make_record(n int); + +drop role if exists regress_parallel_worker; + +create role regress_parallel_worker; + +set role regress_parallel_worker; + +reset session authorization; + +drop role regress_parallel_worker; + +set debug_parallel_query = 1; + +select count(*) from tenk1; + +reset debug_parallel_query; + +reset role; + +select count(*) from tenk1 a where (unique1, two) in + (select unique1, row_number() over() from tenk1 b); + +select * from tenk1 a where two in + (select two from tenk1 b where stringu1 like '%AAAA' limit 3); + +SAVEPOINT settings; + +SET LOCAL debug_parallel_query = 1; + +SELECT * FROM tenk1; + +ROLLBACK TO SAVEPOINT settings; + +SAVEPOINT settings; + +SET LOCAL debug_parallel_query = 1; + +select (stringu1 || repeat('abcd', 5000))::int2 from tenk1 where unique1 = 1; + +ROLLBACK TO SAVEPOINT settings; + +SAVEPOINT settings; + +SET LOCAL parallel_setup_cost = 10; + +SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1 +UNION ALL +SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1; + +ROLLBACK TO SAVEPOINT settings; + +SELECT unique1 FROM tenk1 WHERE fivethous = + (SELECT unique1 FROM tenk1 WHERE fivethous = 1 LIMIT 1) +UNION ALL +SELECT unique1 FROM tenk1 WHERE fivethous = + (SELECT unique2 FROM tenk1 WHERE fivethous = 1 LIMIT 1) +ORDER BY 1; + +SELECT * FROM information_schema.foreign_data_wrapper_options +ORDER BY 1, 2, 3; + +SELECT generate_series(1, two), array(select generate_series(1, two)) + FROM tenk1 ORDER BY tenthous; + +SELECT unnest(ARRAY[]::integer[]) + 1 AS pathkey + FROM tenk1 t1 JOIN tenk1 t2 ON TRUE + ORDER BY pathkey; + +CREATE FUNCTION make_some_array(int,int) returns int[] as +$$declare x int[]; + begin + x[1] := $1; + x[2] := $2; + return x; + end$$ language plpgsql parallel safe; + +CREATE TABLE fooarr(f1 text, f2 int[], f3 text); + +INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one'); + +PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2; + +EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2)); + +EXECUTE pstmt('1', make_some_array(1,2)); + +DEALLOCATE pstmt; + +CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1; + +SELECT 1 FROM tenk1_vw_sec + WHERE (SELECT sum(f1) FROM int4_tbl WHERE f1 < unique1) < 100; + +rollback; + +begin; + +create role regress_parallel_worker; + +set session authorization regress_parallel_worker; + +select current_setting('session_authorization'); + +set debug_parallel_query = 1; + +select current_setting('session_authorization'); + +rollback; + +create role regress_parallel_worker; + +create function set_and_report_role() returns text as + $$ select current_setting('role') $$ language sql parallel safe + set role = regress_parallel_worker; + +create function set_role_and_error(int) returns int as + $$ select 1 / $1 $$ language sql parallel safe + set role = regress_parallel_worker; + +set debug_parallel_query = 0; + +select set_and_report_role(); + +select set_role_and_error(0); + +set debug_parallel_query = 1; + +select set_and_report_role(); + +select set_role_and_error(0); + +reset debug_parallel_query; + +drop function set_and_report_role(); + +drop function set_role_and_error(int); + +drop role regress_parallel_worker; + +BEGIN; + +CREATE FUNCTION my_cmp (int4, int4) +RETURNS int LANGUAGE sql AS +$$ + SELECT + CASE WHEN $1 < $2 THEN -1 + WHEN $1 > $2 THEN 1 + ELSE 0 + END; +$$; + +CREATE TABLE parallel_hang (i int4); + +INSERT INTO parallel_hang + (SELECT * FROM generate_series(1, 400) gs); + +CREATE OPERATOR CLASS int4_custom_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4, int4), OPERATOR 2 <= (int4, int4), + OPERATOR 3 = (int4, int4), OPERATOR 4 >= (int4, int4), + OPERATOR 5 > (int4, int4), FUNCTION 1 my_cmp(int4, int4); + +CREATE UNIQUE INDEX parallel_hang_idx + ON parallel_hang + USING btree (i int4_custom_ops); + +SET debug_parallel_query = on; + +DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420; + +ROLLBACK; + +select pg_stat_force_next_flush(); + +select parallel_workers_to_launch > 'parallel_workers_to_launch_before' AS wrk_to_launch, + parallel_workers_launched > 'parallel_workers_launched_before' AS wrk_launched + from pg_stat_database + where datname = current_database(); diff --git a/crates/pgt_pretty_print/tests/data/multi/select_views_60.sql b/crates/pgt_pretty_print/tests/data/multi/select_views_60.sql new file mode 100644 index 000000000..0ec17b696 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/select_views_60.sql @@ -0,0 +1,149 @@ +SELECT * FROM street; + +SELECT name, #thepath FROM iexit ORDER BY name COLLATE "C", 2; + +SELECT * FROM toyemp WHERE name = 'sharon'; + +CREATE ROLE regress_alice; + +CREATE FUNCTION f_leak (text) + RETURNS bool LANGUAGE 'plpgsql' COST 0.0000001 + AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END'; + +CREATE TABLE customer ( + cid int primary key, + name text not null, + tel text, + passwd text +); + +CREATE TABLE credit_card ( + cid int references customer(cid), + cnum text, + climit int +); + +CREATE TABLE credit_usage ( + cid int references customer(cid), + ymd date, + usage int +); + +INSERT INTO customer + VALUES (101, 'regress_alice', '+81-12-3456-7890', 'passwd123'), + (102, 'regress_bob', '+01-234-567-8901', 'beafsteak'), + (103, 'regress_eve', '+49-8765-43210', 'hamburger'); + +INSERT INTO credit_card + VALUES (101, '1111-2222-3333-4444', 4000), + (102, '5555-6666-7777-8888', 3000), + (103, '9801-2345-6789-0123', 2000); + +INSERT INTO credit_usage + VALUES (101, '2011-09-15', 120), + (101, '2011-10-05', 90), + (101, '2011-10-18', 110), + (101, '2011-10-21', 200), + (101, '2011-11-10', 80), + (102, '2011-09-22', 300), + (102, '2011-10-12', 120), + (102, '2011-10-28', 200), + (103, '2011-10-15', 480); + +CREATE VIEW my_property_normal AS + SELECT * FROM customer WHERE name = current_user; + +CREATE VIEW my_property_secure WITH (security_barrier) AS + SELECT * FROM customer WHERE name = current_user; + +CREATE VIEW my_credit_card_normal AS + SELECT * FROM customer l NATURAL JOIN credit_card r + WHERE l.name = current_user; + +CREATE VIEW my_credit_card_secure WITH (security_barrier) AS + SELECT * FROM customer l NATURAL JOIN credit_card r + WHERE l.name = current_user; + +CREATE VIEW my_credit_card_usage_normal AS + SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r; + +CREATE VIEW my_credit_card_usage_secure WITH (security_barrier) AS + SELECT * FROM my_credit_card_secure l NATURAL JOIN credit_usage r; + +GRANT SELECT ON my_property_normal TO public; + +GRANT SELECT ON my_property_secure TO public; + +GRANT SELECT ON my_credit_card_normal TO public; + +GRANT SELECT ON my_credit_card_secure TO public; + +GRANT SELECT ON my_credit_card_usage_normal TO public; + +GRANT SELECT ON my_credit_card_usage_secure TO public; + +SET SESSION AUTHORIZATION regress_alice; + +SELECT * FROM my_property_normal WHERE f_leak(passwd); + +SELECT * FROM my_property_normal WHERE f_leak(passwd); + +SELECT * FROM my_property_secure WHERE f_leak(passwd); + +SELECT * FROM my_property_secure WHERE f_leak(passwd); + +SELECT * FROM my_property_normal v + WHERE f_leak('passwd') AND f_leak(passwd); + +SELECT * FROM my_property_normal v + WHERE f_leak('passwd') AND f_leak(passwd); + +SELECT * FROM my_property_secure v + WHERE f_leak('passwd') AND f_leak(passwd); + +SELECT * FROM my_property_secure v + WHERE f_leak('passwd') AND f_leak(passwd); + +SELECT * FROM my_credit_card_normal WHERE f_leak(cnum); + +SELECT * FROM my_credit_card_normal WHERE f_leak(cnum); + +SELECT * FROM my_credit_card_secure WHERE f_leak(cnum); + +SELECT * FROM my_credit_card_secure WHERE f_leak(cnum); + +SELECT * FROM my_credit_card_usage_normal + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01'; + +SELECT * FROM my_credit_card_usage_normal + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01'; + +SELECT * FROM my_credit_card_usage_secure + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01'; + +SELECT * FROM my_credit_card_usage_secure + WHERE f_leak(cnum) AND ymd >= '2011-10-01' AND ymd < '2011-11-01'; + +PREPARE p1 AS SELECT * FROM my_property_normal WHERE f_leak(passwd); + +PREPARE p2 AS SELECT * FROM my_property_secure WHERE f_leak(passwd); + +EXECUTE p1; + +EXECUTE p2; + +RESET SESSION AUTHORIZATION; + +ALTER VIEW my_property_normal SET (security_barrier=true); + +ALTER VIEW my_property_secure SET (security_barrier=false); + +SET SESSION AUTHORIZATION regress_alice; + +EXECUTE p1; + +EXECUTE p2; + +RESET SESSION AUTHORIZATION; + +DROP ROLE regress_alice; diff --git a/crates/pgt_pretty_print/tests/data/multi/sequence_60.sql b/crates/pgt_pretty_print/tests/data/multi/sequence_60.sql new file mode 100644 index 000000000..24578c029 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/sequence_60.sql @@ -0,0 +1,211 @@ +CREATE SEQUENCE sequence_testx INCREMENT BY 0; + +CREATE SEQUENCE sequence_testx INCREMENT BY -1 MINVALUE 20; + +CREATE SEQUENCE sequence_testx INCREMENT BY 1 MAXVALUE -20; + +CREATE SEQUENCE sequence_testx INCREMENT BY -1 START 10; + +CREATE SEQUENCE sequence_testx INCREMENT BY 1 START -10; + +CREATE SEQUENCE sequence_testx CACHE 0; + +CREATE SEQUENCE sequence_testx OWNED BY nobody; + +CREATE SEQUENCE sequence_testx OWNED BY pg_class_oid_index.oid; + +CREATE SEQUENCE sequence_testx OWNED BY pg_class.relname; + +CREATE TABLE sequence_test_table (a int); + +CREATE SEQUENCE sequence_testx OWNED BY sequence_test_table.b; + +DROP TABLE sequence_test_table; + +CREATE SEQUENCE sequence_test5 AS integer; + +CREATE SEQUENCE sequence_test6 AS smallint; + +CREATE SEQUENCE sequence_test7 AS bigint; + +CREATE SEQUENCE sequence_test8 AS integer MAXVALUE 100000; + +CREATE SEQUENCE sequence_test9 AS integer INCREMENT BY -1; + +CREATE SEQUENCE sequence_test10 AS integer MINVALUE -100000 START 1; + +CREATE SEQUENCE sequence_test11 AS smallint; + +CREATE SEQUENCE sequence_test12 AS smallint INCREMENT -1; + +CREATE SEQUENCE sequence_test13 AS smallint MINVALUE -32768; + +CREATE SEQUENCE sequence_test14 AS smallint MAXVALUE 32767 INCREMENT -1; + +CREATE SEQUENCE sequence_testx AS text; + +CREATE SEQUENCE sequence_testx AS nosuchtype; + +CREATE SEQUENCE sequence_testx AS smallint MAXVALUE 100000; + +CREATE SEQUENCE sequence_testx AS smallint MINVALUE -100000; + +ALTER SEQUENCE sequence_test5 AS smallint; + +ALTER SEQUENCE sequence_test8 AS smallint; + +ALTER SEQUENCE sequence_test8 AS smallint MAXVALUE 20000; + +ALTER SEQUENCE sequence_test9 AS smallint; + +ALTER SEQUENCE sequence_test10 AS smallint; + +ALTER SEQUENCE sequence_test10 AS smallint MINVALUE -20000; + +ALTER SEQUENCE sequence_test11 AS int; + +ALTER SEQUENCE sequence_test12 AS int; + +ALTER SEQUENCE sequence_test13 AS int; + +ALTER SEQUENCE sequence_test14 AS int; + +CREATE TABLE serialTest1 (f1 text, f2 serial); + +INSERT INTO serialTest1 VALUES ('foo'); + +INSERT INTO serialTest1 VALUES ('bar'); + +INSERT INTO serialTest1 VALUES ('force', 100); + +INSERT INTO serialTest1 VALUES ('wrong', NULL); + +SELECT * FROM serialTest1; + +SELECT pg_get_serial_sequence('serialTest1', 'f2'); + +CREATE TABLE serialTest2 (f1 text, f2 serial, f3 smallserial, f4 serial2, + f5 bigserial, f6 serial8); + +INSERT INTO serialTest2 (f1) + VALUES ('test_defaults'); + +INSERT INTO serialTest2 (f1, f2, f3, f4, f5, f6) + VALUES ('test_max_vals', 2147483647, 32767, 32767, 9223372036854775807, + 9223372036854775807), + ('test_min_vals', -2147483648, -32768, -32768, -9223372036854775808, + -9223372036854775808); + +INSERT INTO serialTest2 (f1, f3) + VALUES ('bogus', -32769); + +INSERT INTO serialTest2 (f1, f4) + VALUES ('bogus', -32769); + +INSERT INTO serialTest2 (f1, f3) + VALUES ('bogus', 32768); + +INSERT INTO serialTest2 (f1, f4) + VALUES ('bogus', 32768); + +INSERT INTO serialTest2 (f1, f5) + VALUES ('bogus', -9223372036854775809); + +INSERT INTO serialTest2 (f1, f6) + VALUES ('bogus', -9223372036854775809); + +INSERT INTO serialTest2 (f1, f5) + VALUES ('bogus', 9223372036854775808); + +INSERT INTO serialTest2 (f1, f6) + VALUES ('bogus', 9223372036854775808); + +SELECT * FROM serialTest2 ORDER BY f2 ASC; + +SELECT nextval('serialTest2_f2_seq'); + +SELECT nextval('serialTest2_f3_seq'); + +SELECT nextval('serialTest2_f4_seq'); + +SELECT nextval('serialTest2_f5_seq'); + +SELECT nextval('serialTest2_f6_seq'); + +CREATE SEQUENCE sequence_test; + +CREATE SEQUENCE IF NOT EXISTS sequence_test; + +SELECT nextval('sequence_test'::text); + +SELECT nextval('sequence_test'::regclass); + +SELECT currval('sequence_test'::text); + +SELECT currval('sequence_test'::regclass); + +SELECT setval('sequence_test'::text, 32); + +SELECT nextval('sequence_test'::regclass); + +SELECT setval('sequence_test'::text, 99, false); + +SELECT nextval('sequence_test'::regclass); + +SELECT setval('sequence_test'::regclass, 32); + +SELECT nextval('sequence_test'::text); + +SELECT setval('sequence_test'::regclass, 99, false); + +SELECT nextval('sequence_test'::text); + +DISCARD SEQUENCES; + +SELECT currval('sequence_test'::regclass); + +DROP SEQUENCE sequence_test; + +CREATE SEQUENCE foo_seq; + +ALTER TABLE foo_seq RENAME TO foo_seq_new; + +SELECT * FROM foo_seq_new; + +SELECT nextval('foo_seq_new'); + +SELECT nextval('foo_seq_new'); + +SELECT last_value, log_cnt IN (31, 32) AS log_cnt_ok, is_called FROM foo_seq_new; + +DROP SEQUENCE foo_seq_new; + +ALTER TABLE serialtest1_f2_seq RENAME TO serialtest1_f2_foo; + +INSERT INTO serialTest1 VALUES ('more'); + +SELECT * FROM serialTest1; + +CREATE TEMP SEQUENCE myseq2; + +CREATE TEMP SEQUENCE myseq3; + +CREATE TEMP TABLE t1 ( + f1 serial, + f2 int DEFAULT nextval('myseq2'), + f3 int DEFAULT nextval('myseq3'::text) +); + +DROP SEQUENCE t1_f1_seq; + +DROP SEQUENCE myseq2; + +DROP SEQUENCE myseq3; + +DROP TABLE t1; + +DROP SEQUENCE t1_f1_seq; + +DROP SEQUENCE myseq2; + +ALTER SEQUENCE IF EXISTS sequence_test2 RESTART diff --git a/crates/pgt_pretty_print/tests/data/multi/spgist_60.sql b/crates/pgt_pretty_print/tests/data/multi/spgist_60.sql new file mode 100644 index 000000000..65f025311 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/spgist_60.sql @@ -0,0 +1,77 @@ +create table spgist_point_tbl(id int4, p point); + +create index spgist_point_idx on spgist_point_tbl using spgist(p) with (fillfactor = 75); + +insert into spgist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10) g; + +delete from spgist_point_tbl where id < 5; + +vacuum spgist_point_tbl; + +insert into spgist_point_tbl (id, p) +select g, point(g*10, g*10) from generate_series(1, 10000) g; + +insert into spgist_point_tbl (id, p) +select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g; + +delete from spgist_point_tbl where id % 2 = 1; + +delete from spgist_point_tbl where id < 10000; + +vacuum spgist_point_tbl; + +create table spgist_box_tbl(id serial, b box); + +insert into spgist_box_tbl(b) +select box(point(i,j),point(i+s,j+s)) + from generate_series(1,100,5) i, + generate_series(1,100,5) j, + generate_series(1,10) s; + +create index spgist_box_idx on spgist_box_tbl using spgist (b); + +select count(*) + from (values (point(5,5)),(point(8,8)),(point(12,12))) v(p) + where exists(select * from spgist_box_tbl b where b.b && box(v.p,v.p)); + +create table spgist_text_tbl(id int4, t text); + +create index spgist_text_idx on spgist_text_tbl using spgist(t); + +insert into spgist_text_tbl (id, t) +select g, 'f' || repeat('o', 100) || g from generate_series(1, 10000) g +union all +select g, 'baaaaaaaaaaaaaar' || g from generate_series(1, 1000) g; + +insert into spgist_text_tbl (id, t) +select -g, 'f' || repeat('o', 100-g) || 'surprise' from generate_series(1, 100) g; + +create index spgist_point_idx2 on spgist_point_tbl using spgist(p) with (fillfactor = 9); + +create index spgist_point_idx2 on spgist_point_tbl using spgist(p) with (fillfactor = 101); + +alter index spgist_point_idx set (fillfactor = 90); + +reindex index spgist_point_idx; + +create domain spgist_text as varchar; + +create table spgist_domain_tbl (f1 spgist_text); + +create index spgist_domain_idx on spgist_domain_tbl using spgist(f1); + +insert into spgist_domain_tbl values('fee'), ('fi'), ('fo'), ('fum'); + +select * from spgist_domain_tbl where f1 = 'fo'; + +select * from spgist_domain_tbl where f1 = 'fo'; + +create unlogged table spgist_unlogged_tbl(id serial, b box); + +create index spgist_unlogged_idx on spgist_unlogged_tbl using spgist (b); + +insert into spgist_unlogged_tbl(b) +select box(point(i,j)) + from generate_series(1,100,5) i, + generate_series(1,10,5) j; diff --git a/crates/pgt_pretty_print/tests/data/multi/sqljson_60.sql b/crates/pgt_pretty_print/tests/data/multi/sqljson_60.sql new file mode 100644 index 000000000..d5f7e183f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/sqljson_60.sql @@ -0,0 +1,487 @@ +SELECT JSON(NULL); + +SELECT JSON('{ "a" : 1 } '); + +SELECT JSON('{ "a" : 1 } ' FORMAT JSON); + +SELECT JSON('{ "a" : 1 } ' FORMAT JSON ENCODING UTF8); + +SELECT JSON('{ "a" : 1 } '::bytea FORMAT JSON ENCODING UTF8); + +SELECT pg_typeof(JSON('{ "a" : 1 } ')); + +SELECT JSON(' 1 '::json); + +SELECT JSON(' 1 '::jsonb); + +SELECT JSON(' 1 '::json WITH UNIQUE KEYS); + +SELECT JSON(123); + +SELECT JSON('{"a": 1, "a": 2}'); + +SELECT JSON('{"a": 1, "a": 2}' WITH UNIQUE KEYS); + +SELECT JSON('{"a": 1, "a": 2}' WITHOUT UNIQUE KEYS); + +SELECT JSON('123'); + +SELECT JSON('123' FORMAT JSON); + +SELECT JSON('123'::bytea FORMAT JSON); + +SELECT JSON('123'::bytea FORMAT JSON ENCODING UTF8); + +SELECT JSON('123' WITH UNIQUE KEYS); + +SELECT JSON('123' WITHOUT UNIQUE KEYS); + +SELECT JSON('123'); + +SELECT pg_typeof(JSON('123')); + +SELECT JSON_SCALAR(NULL); + +SELECT JSON_SCALAR(NULL::int); + +SELECT JSON_SCALAR(123); + +SELECT JSON_SCALAR(123.45); + +SELECT JSON_SCALAR(123.45::numeric); + +SELECT JSON_SCALAR(true); + +SELECT JSON_SCALAR(false); + +SELECT JSON_SCALAR(' 123.45'); + +SELECT JSON_SCALAR('2020-06-07'::date); + +SELECT JSON_SCALAR('2020-06-07 01:02:03'::timestamp); + +SELECT JSON_SCALAR('{}'::json); + +SELECT JSON_SCALAR('{}'::jsonb); + +SELECT JSON_SCALAR(123); + +SELECT JSON_SCALAR('123'); + +SELECT JSON_SERIALIZE(NULL); + +SELECT JSON_SERIALIZE(JSON('{ "a" : 1 } ')); + +SELECT JSON_SERIALIZE('{ "a" : 1 } '); + +SELECT JSON_SERIALIZE('1'); + +SELECT JSON_SERIALIZE('1' FORMAT JSON); + +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING bytea); + +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING varchar); + +SELECT pg_typeof(JSON_SERIALIZE(NULL)); + +SELECT JSON_SERIALIZE('{ "a" : 1 } ' RETURNING jsonb); + +SELECT JSON_SERIALIZE('{}'); + +SELECT JSON_SERIALIZE('{}' RETURNING bytea); + +SELECT JSON_OBJECT(); + +SELECT JSON_OBJECT(RETURNING json); + +SELECT JSON_OBJECT(RETURNING json FORMAT JSON); + +SELECT JSON_OBJECT(RETURNING jsonb); + +SELECT JSON_OBJECT(RETURNING jsonb FORMAT JSON); + +SELECT JSON_OBJECT(RETURNING text); + +SELECT JSON_OBJECT(RETURNING text FORMAT JSON); + +SELECT JSON_OBJECT(RETURNING text FORMAT JSON ENCODING UTF8); + +SELECT JSON_OBJECT(RETURNING bytea); + +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON); + +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF8); + +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF16); + +SELECT JSON_OBJECT(RETURNING bytea FORMAT JSON ENCODING UTF32); + +SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON); + +SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON ENCODING UTF8); + +SELECT JSON_OBJECT('foo': NULL::json FORMAT JSON); + +SELECT JSON_OBJECT('foo': NULL::json FORMAT JSON ENCODING UTF8); + +SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON); + +SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON ENCODING UTF8); + +SELECT JSON_OBJECT(NULL: 1); + +SELECT JSON_OBJECT('a': 2 + 3); + +SELECT JSON_OBJECT('a' VALUE 2 + 3); + +SELECT JSON_OBJECT('a' || 2: 1); + +SELECT JSON_OBJECT(('a' || 2) VALUE 1); + +SELECT JSON_OBJECT('a': 2::text); + +SELECT JSON_OBJECT('a' VALUE 2::text); + +SELECT JSON_OBJECT(1::text: 2); + +SELECT JSON_OBJECT((1::text) VALUE 2); + +SELECT JSON_OBJECT(json '[1]': 123); + +SELECT JSON_OBJECT(ARRAY[1,2,3]: 'aaa'); + +SELECT JSON_OBJECT( + 'a': '123', + 1.23: 123, + 'c': json '[ 1,true,{ } ]', + 'd': jsonb '{ "x" : 123.45 }' +); + +SELECT JSON_OBJECT( + 'a': '123', + 1.23: 123, + 'c': json '[ 1,true,{ } ]', + 'd': jsonb '{ "x" : 123.45 }' + RETURNING jsonb +); + +SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa')); + +SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa' RETURNING jsonb)); + +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text)); + +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text) FORMAT JSON); + +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea)); + +SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING bytea) FORMAT JSON); + +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2); + +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2 NULL ON NULL); + +SELECT JSON_OBJECT('a': '1', 'b': NULL, 'c': 2 ABSENT ON NULL); + +SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, repeat('x', 1000): 1, 2: repeat('a', 100) WITH UNIQUE); + +SELECT JSON_OBJECT(1: 1, '1': NULL WITH UNIQUE); + +SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE); + +SELECT JSON_OBJECT(1: 1, '1': NULL NULL ON NULL WITH UNIQUE RETURNING jsonb); + +SELECT JSON_OBJECT(1: 1, '1': NULL ABSENT ON NULL WITH UNIQUE RETURNING jsonb); + +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 NULL ON NULL WITH UNIQUE); + +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE); + +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITHOUT UNIQUE); + +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITH UNIQUE RETURNING jsonb); + +SELECT JSON_OBJECT(1: 1, '2': NULL, '1': 1 ABSENT ON NULL WITHOUT UNIQUE RETURNING jsonb); + +SELECT JSON_OBJECT(1: 1, '2': NULL, '3': 1, 4: NULL, '5': 'a' ABSENT ON NULL WITH UNIQUE RETURNING jsonb); + +CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral'); + +CREATE FUNCTION mood_to_json(mood) RETURNS json AS $$ + SELECT to_json($1::text); +$$ LANGUAGE sql IMMUTABLE; + +CREATE CAST (mood AS json) WITH FUNCTION mood_to_json(mood) AS IMPLICIT; + +SELECT JSON_OBJECT('happy'::mood: '123'::jsonb); + +DROP CAST (mood AS json); + +DROP FUNCTION mood_to_json; + +DROP TYPE mood; + +SELECT JSON_ARRAY(); + +SELECT JSON_ARRAY(RETURNING json); + +SELECT JSON_ARRAY(RETURNING json FORMAT JSON); + +SELECT JSON_ARRAY(RETURNING jsonb); + +SELECT JSON_ARRAY(RETURNING jsonb FORMAT JSON); + +SELECT JSON_ARRAY(RETURNING text); + +SELECT JSON_ARRAY(RETURNING text FORMAT JSON); + +SELECT JSON_ARRAY(RETURNING text FORMAT JSON ENCODING UTF8); + +SELECT JSON_ARRAY(RETURNING bytea); + +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON); + +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF8); + +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF16); + +SELECT JSON_ARRAY(RETURNING bytea FORMAT JSON ENCODING UTF32); + +SELECT JSON_ARRAY('aaa', 111, true, array[1,2,3], NULL, json '{"a": [1]}', jsonb '["a",3]'); + +SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL); + +SELECT JSON_ARRAY('a', NULL, 'b' ABSENT ON NULL); + +SELECT JSON_ARRAY(NULL, NULL, 'b' ABSENT ON NULL); + +SELECT JSON_ARRAY('a', NULL, 'b' NULL ON NULL RETURNING jsonb); + +SELECT JSON_ARRAY('a', NULL, 'b' ABSENT ON NULL RETURNING jsonb); + +SELECT JSON_ARRAY(NULL, NULL, 'b' ABSENT ON NULL RETURNING jsonb); + +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' RETURNING text)); + +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' FORMAT JSON RETURNING text)); + +SELECT JSON_ARRAY(JSON_ARRAY('{ "a" : 123 }' FORMAT JSON RETURNING text) FORMAT JSON); + +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i)); + +SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i)); + +SELECT JSON_ARRAY(SELECT i FROM (VALUES (NULL::int[]), ('{1,2}'), (NULL), (NULL), ('{3,4}'), (NULL)) foo(i) RETURNING jsonb); + +SELECT JSON_ARRAY(SELECT i FROM (VALUES (3), (1), (NULL), (2)) foo(i) ORDER BY i); + +SELECT JSON_ARRAY(WITH x AS (SELECT 1) VALUES (TRUE)); + +SELECT JSON_ARRAY(SELECT FROM (VALUES (1)) foo(i)); + +SELECT JSON_ARRAY(SELECT i, i FROM (VALUES (1)) foo(i)); + +SELECT JSON_ARRAY(SELECT * FROM (VALUES (1, 2)) foo(i, j)); + +SELECT JSON_ARRAYAGG(i) IS NULL, + JSON_ARRAYAGG(i RETURNING jsonb) IS NULL +FROM generate_series(1, 0) i; + +SELECT JSON_ARRAYAGG(i), + JSON_ARRAYAGG(i RETURNING jsonb) +FROM generate_series(1, 5) i; + +SELECT JSON_ARRAYAGG(i ORDER BY i DESC) +FROM generate_series(1, 5) i; + +SELECT JSON_ARRAYAGG(i::text::json) +FROM generate_series(1, 5) i; + +SELECT JSON_ARRAYAGG(JSON_ARRAY(i, i + 1 RETURNING text) FORMAT JSON) +FROM generate_series(1, 5) i; + +SELECT JSON_ARRAYAGG(NULL), + JSON_ARRAYAGG(NULL RETURNING jsonb) +FROM generate_series(1, 5); + +SELECT JSON_ARRAYAGG(NULL NULL ON NULL), + JSON_ARRAYAGG(NULL NULL ON NULL RETURNING jsonb) +FROM generate_series(1, 5); + +SELECT + JSON_ARRAYAGG(bar) as no_options, + JSON_ARRAYAGG(bar RETURNING jsonb) as returning_jsonb, + JSON_ARRAYAGG(bar ABSENT ON NULL) as absent_on_null, + JSON_ARRAYAGG(bar ABSENT ON NULL RETURNING jsonb) as absentonnull_returning_jsonb, + JSON_ARRAYAGG(bar NULL ON NULL) as null_on_null, + JSON_ARRAYAGG(bar NULL ON NULL RETURNING jsonb) as nullonnull_returning_jsonb, + JSON_ARRAYAGG(foo) as row_no_options, + JSON_ARRAYAGG(foo RETURNING jsonb) as row_returning_jsonb, + JSON_ARRAYAGG(foo ORDER BY bar) FILTER (WHERE bar > 2) as row_filtered_agg, + JSON_ARRAYAGG(foo ORDER BY bar RETURNING jsonb) FILTER (WHERE bar > 2) as row_filtered_agg_returning_jsonb +FROM + (VALUES (NULL), (3), (1), (NULL), (NULL), (5), (2), (4), (NULL)) foo(bar); + +SELECT + bar, JSON_ARRAYAGG(bar) FILTER (WHERE bar > 2) OVER (PARTITION BY foo.bar % 2) +FROM + (VALUES (NULL), (3), (1), (NULL), (NULL), (5), (2), (4), (NULL), (5), (4)) foo(bar); + +SELECT JSON_OBJECTAGG('key': 1) IS NULL, + JSON_OBJECTAGG('key': 1 RETURNING jsonb) IS NULL +WHERE FALSE; + +SELECT JSON_OBJECTAGG(NULL: 1); + +SELECT JSON_OBJECTAGG(NULL: 1 RETURNING jsonb); + +SELECT + JSON_OBJECTAGG(i: i), +-- JSON_OBJECTAGG(i VALUE i), +-- JSON_OBJECTAGG(KEY i VALUE i), + JSON_OBJECTAGG(i: i RETURNING jsonb) +FROM + generate_series(1, 5) i; + +SELECT + JSON_OBJECTAGG(k: v), + JSON_OBJECTAGG(k: v NULL ON NULL), + JSON_OBJECTAGG(k: v ABSENT ON NULL), + JSON_OBJECTAGG(k: v RETURNING jsonb), + JSON_OBJECTAGG(k: v NULL ON NULL RETURNING jsonb), + JSON_OBJECTAGG(k: v ABSENT ON NULL RETURNING jsonb) +FROM + (VALUES (1, 1), (1, NULL), (2, NULL), (3, 3)) foo(k, v); + +SELECT JSON_OBJECTAGG(k: v WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v); + +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v); + +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS) +FROM (VALUES (1, 1), (0, NULL), (3, NULL), (2, 2), (4, NULL)) foo(k, v); + +SELECT JSON_OBJECTAGG(k: v WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v); + +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (1, NULL), (2, 2)) foo(k, v); + +SELECT JSON_OBJECTAGG(k: v ABSENT ON NULL WITH UNIQUE KEYS RETURNING jsonb) +FROM (VALUES (1, 1), (0, NULL),(4, null), (5, null),(6, null),(2, 2)) foo(k, v); + +SELECT JSON_OBJECTAGG(mod(i,100): (i)::text FORMAT JSON WITH UNIQUE) +FROM generate_series(0, 199) i; + +SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json); + +CREATE VIEW json_object_view AS +SELECT JSON_OBJECT('foo' : '1' FORMAT JSON, 'bar' : 'baz' RETURNING json); + +DROP VIEW json_object_view; + +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v WITH UNIQUE KEYS) OVER (ORDER BY k) +FROM (VALUES (1,1), (2,2)) a(k,v); + +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v WITH UNIQUE KEYS) OVER (ORDER BY k) +FROM (VALUES (1,1), (1,2), (2,2)) a(k,v); + +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL WITH UNIQUE KEYS) + OVER (ORDER BY k) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v); + +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL) +OVER (ORDER BY k) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v); + +SELECT to_json(a) AS a, JSON_OBJECTAGG(k : v ABSENT ON NULL) +OVER (ORDER BY k RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM (VALUES (1,1), (1,null), (2,2)) a(k,v); + +SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING json); + +CREATE VIEW json_array_view AS +SELECT JSON_ARRAY('1' FORMAT JSON, 2 RETURNING json); + +DROP VIEW json_array_view; + +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i; + +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) OVER (PARTITION BY i % 2) +FROM generate_series(1,5) i; + +CREATE VIEW json_objectagg_view AS +SELECT JSON_OBJECTAGG(i: ('111' || i)::bytea FORMAT JSON WITH UNIQUE RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i; + +DROP VIEW json_objectagg_view; + +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i; + +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) OVER (PARTITION BY i % 2) +FROM generate_series(1,5) i; + +CREATE VIEW json_arrayagg_view AS +SELECT JSON_ARRAYAGG(('111' || i)::bytea FORMAT JSON NULL ON NULL RETURNING text) FILTER (WHERE i > 3) +FROM generate_series(1,5) i; + +DROP VIEW json_arrayagg_view; + +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING jsonb); + +CREATE VIEW json_array_subquery_view AS +SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING jsonb); + +DROP VIEW json_array_subquery_view; + +SELECT NULL IS JSON; + +SELECT NULL IS NOT JSON; + +SELECT NULL::json IS JSON; + +SELECT NULL::jsonb IS JSON; + +SELECT NULL::text IS JSON; + +SELECT NULL::bytea IS JSON; + +SELECT NULL::int IS JSON; + +SELECT '' IS JSON; + +SELECT bytea '\x00' IS JSON; + +CREATE TABLE test_is_json (js text); + +INSERT INTO test_is_json VALUES + (NULL), + (''), + ('123'), + ('"aaa "'), + ('true'), + ('null'), + ('[]'), + ('[1, "2", {}]'), + ('{}'), + ('{ "a": 1, "b": null }'), + ('{ "a": 1, "a": null }'), + ('{ "a": 1, "b": [{ "a": 1 }, { "a": 2 }] }'), + ('{ "a": 1, "b": [{ "a": 1, "b": 0, "a": 2 }] }'), + ('aaa'), + ('{a:1}'), + ('["a",]'); + +SELECT + js, + js IS JSON "IS JSON", + js IS NOT JSON "IS NOT JSON", + js IS JSON VALUE "IS VALUE", + js IS JSON OBJECT "IS OBJECT", + js IS JSON ARRAY "IS ARRAY", + js IS JSON SCALAR "IS SCALAR", + js IS JSON WITHOUT UNIQUE KEYS "WITHOUT UNIQUE", + js IS JSON diff --git a/crates/pgt_pretty_print/tests/data/multi/sqljson_jsontable_60.sql b/crates/pgt_pretty_print/tests/data/multi/sqljson_jsontable_60.sql new file mode 100644 index 000000000..fb74e60fd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/sqljson_jsontable_60.sql @@ -0,0 +1,537 @@ +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') DEFAULT 1 ON ERROR); + +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') NULL ON ERROR); + +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') EMPTY ON ERROR); + +SELECT * FROM JSON_TABLE('[]', 'strict $.a' COLUMNS (js2 int PATH '$') ERROR ON ERROR); + +SELECT * FROM JSON_TABLE(jsonb'"1.23"', '$.a' as js2 COLUMNS (js2 int path '$')); + +SELECT * FROM JSON_TABLE (NULL::jsonb, '$' COLUMNS (v1 timestamp)) AS f (v1, v2); + +SELECT * FROM JSON_TABLE(jsonb'"1.23"', '$.a' COLUMNS (js2 int path '$', js2 int path '$')); + +create type comp as (a int, b int); + +SELECT * FROM JSON_TABLE(jsonb '{"rec": "(1,2)"}', '$' COLUMNS (id FOR ORDINALITY, comp comp path '$.rec' omit quotes)) jt; + +drop type comp; + +SELECT * FROM JSON_TABLE(NULL::jsonb, '$' COLUMNS (foo int)) bar; + +SELECT * FROM JSON_TABLE(jsonb'"1.23"', 'strict $.a' COLUMNS (js2 int PATH '$')); + +SELECT * FROM JSON_TABLE(jsonb '123', '$' + COLUMNS (item int PATH '$', foo int)) bar; + +CREATE DOMAIN jsonb_test_domain AS text CHECK (value <> 'foo'); + +CREATE TEMP TABLE json_table_test (js) AS + (VALUES + ('1'), + ('[]'), + ('{}'), + ('[1, 1.23, "2", "aaaaaaa", "foo", null, false, true, {"aaa": 123}, "[1,2]", "\"str\""]') + ); + +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$', + "char(4)" char(4) PATH '$', + "bool" bool PATH '$', + "numeric" numeric PATH '$', + "domain" jsonb_test_domain PATH '$', + js json PATH '$', + jb jsonb PATH '$' + ) + ) jt + ON true; + +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + jst text FORMAT JSON PATH '$', + jsc char(4) FORMAT JSON PATH '$', + jsv varchar(4) FORMAT JSON PATH '$', + jsb jsonb FORMAT JSON PATH '$', + jsbq jsonb FORMAT JSON PATH '$' OMIT QUOTES + ) + ) jt + ON true; + +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + exists1 bool EXISTS PATH '$.aaa', + exists2 int EXISTS PATH '$.aaa', + exists3 int EXISTS PATH 'strict $.aaa' UNKNOWN ON ERROR, + exists4 text EXISTS PATH 'strict $.aaa' FALSE ON ERROR + ) + ) jt + ON true; + +SELECT * +FROM json_table_test vals + LEFT OUTER JOIN + JSON_TABLE( + vals.js::jsonb, 'lax $[*]' + COLUMNS ( + id FOR ORDINALITY, + aaa int, -- "aaa" has implicit path '$."aaa"' + aaa1 int PATH '$.aaa', + js2 json PATH '$', + jsb2w jsonb PATH '$' WITH WRAPPER, + jsb2q jsonb PATH '$' OMIT QUOTES, + ia int[] PATH '$', + ta text[] PATH '$', + jba jsonb[] PATH '$' + ) + ) jt + ON true; + +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT '"foo1"'::jsonb::text ON EMPTY)); + +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo'::jsonb_test_domain ON EMPTY)); + +SELECT * FROM JSON_TABLE(jsonb '{"d1": "H"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.a2' DEFAULT 'foo1'::jsonb_test_domain ON EMPTY)); + +SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' + COLUMNS (js1 jsonb_test_domain PATH '$.d1' DEFAULT 'foo2'::jsonb_test_domain ON ERROR)); + +SELECT * FROM JSON_TABLE(jsonb '{"d1": "foo"}', '$' + COLUMNS (js1 oid[] PATH '$.d2' DEFAULT '{1}'::int[]::oid[] ON EMPTY)); + +CREATE VIEW jsonb_table_view2 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + "int" int PATH '$', + "text" text PATH '$', + "char(4)" char(4) PATH '$', + "bool" bool PATH '$', + "numeric" numeric PATH '$', + "domain" jsonb_test_domain PATH '$')); + +CREATE VIEW jsonb_table_view3 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + js json PATH '$', + jb jsonb PATH '$', + jst text FORMAT JSON PATH '$', + jsc char(4) FORMAT JSON PATH '$', + jsv varchar(4) FORMAT JSON PATH '$')); + +CREATE VIEW jsonb_table_view4 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + jsb jsonb FORMAT JSON PATH '$', + jsbq jsonb FORMAT JSON PATH '$' OMIT QUOTES, + aaa int, -- implicit path '$."aaa"', + aaa1 int PATH '$.aaa')); + +CREATE VIEW jsonb_table_view5 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + exists1 bool EXISTS PATH '$.aaa', + exists2 int EXISTS PATH '$.aaa' TRUE ON ERROR, + exists3 text EXISTS PATH 'strict $.aaa' UNKNOWN ON ERROR)); + +CREATE VIEW jsonb_table_view6 AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + js2 json PATH '$', + jsb2w jsonb PATH '$' WITH WRAPPER, + jsb2q jsonb PATH '$' OMIT QUOTES, + ia int[] PATH '$', + ta text[] PATH '$', + jba jsonb[] PATH '$')); + +SELECT * FROM jsonb_table_view2; + +SELECT * FROM jsonb_table_view3; + +SELECT * FROM jsonb_table_view4; + +SELECT * FROM jsonb_table_view5; + +SELECT * FROM jsonb_table_view6; + +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$' + )) json_table_func; + +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + "int" int PATH '$', + "text" text PATH '$' + )) json_table_func; + +DROP VIEW jsonb_table_view2; + +DROP VIEW jsonb_table_view3; + +DROP VIEW jsonb_table_view4; + +DROP VIEW jsonb_table_view5; + +DROP VIEW jsonb_table_view6; + +DROP DOMAIN jsonb_test_domain; + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (id FOR ORDINALITY, id2 FOR ORDINALITY, a int PATH '$.a' ERROR ON EMPTY)) jt; + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (id FOR ORDINALITY, a int PATH '$' ERROR ON EMPTY)) jt; + +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js), + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$')) jt; + +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js) + LEFT OUTER JOIN + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$' ERROR ON ERROR)) jt + ON true; + +SELECT * +FROM + (VALUES ('1'), ('"err"')) vals(js) + LEFT OUTER JOIN + JSON_TABLE(vals.js::jsonb, '$' COLUMNS (a int PATH '$' ERROR ON ERROR)) jt + ON true; + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH '$.a' ERROR ON EMPTY)) jt; + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'strict $.a' ERROR ON ERROR) ERROR ON ERROR) jt; + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int PATH 'lax $.a' ERROR ON EMPTY) ERROR ON ERROR) jt; + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH '$' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt; + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'strict $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt; + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int PATH 'lax $.a' DEFAULT 1 ON EMPTY DEFAULT 2 ON ERROR)) jt; + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$.a' ERROR ON ERROR)); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int4 EXISTS PATH '$' ERROR ON ERROR)); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int2 EXISTS PATH '$.a')); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a int8 EXISTS PATH '$.a')); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a float4 EXISTS PATH '$.a')); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(3) EXISTS PATH '$.a')); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(3) EXISTS PATH '$.a' ERROR ON ERROR)); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a char(5) EXISTS PATH '$.a' ERROR ON ERROR)); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a json EXISTS PATH '$.a')); + +SELECT * FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a jsonb EXISTS PATH '$.a')); + +CREATE DOMAIN dint4 AS int; + +CREATE DOMAIN dint4_0 AS int CHECK (VALUE <> 0 ); + +SELECT a, a::bool FROM JSON_TABLE(jsonb '"a"', '$' COLUMNS (a dint4 EXISTS PATH '$.a' )); + +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b')); + +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' ERROR ON ERROR)); + +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' FALSE ON ERROR)); + +SELECT a, a::bool FROM JSON_TABLE(jsonb '{"a":1}', '$' COLUMNS (a dint4_0 EXISTS PATH '$.b' TRUE ON ERROR)); + +DROP DOMAIN dint4, dint4_0; + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' KEEP QUOTES ON SCALAR STRING)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' OMIT QUOTES ON SCALAR STRING)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' KEEP QUOTES)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' OMIT QUOTES)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITHOUT WRAPPER KEEP QUOTES)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' WITHOUT WRAPPER OMIT QUOTES)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITH WRAPPER)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text PATH '$' WITH WRAPPER OMIT QUOTES)); + +SELECT * FROM JSON_TABLE(jsonb '"world"', '$' COLUMNS (item text FORMAT JSON PATH '$' WITH WRAPPER KEEP QUOTES)); + +SELECT * +FROM JSON_TABLE( + jsonb '[1,2,3]', + '$[*] ? (@ < $x)' + PASSING 3 AS x + COLUMNS (y text FORMAT JSON PATH '$') + ) jt; + +SELECT * +FROM JSON_TABLE( + jsonb '[1,2,3]', + '$[*] ? (@ < $x)' + PASSING 10 AS x, 3 AS y + COLUMNS (a text FORMAT JSON PATH '$ ? (@ < $y)') + ) jt; + +SELECT * FROM JSON_TABLE('{"a": [{"b": "1"}, {"b": "2"}]}', '$' COLUMNS (b json path '$.a[*].b' ERROR ON ERROR)); + +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' AS a + COLUMNS ( + b int, + NESTED PATH '$' AS a + COLUMNS ( + c int + ) + ) +) jt; + +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' AS a + COLUMNS ( + b int, + NESTED PATH '$' AS n_a + COLUMNS ( + c int + ) + ) +) jt; + +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' + COLUMNS ( + b int, + NESTED PATH '$' AS b + COLUMNS ( + c int + ) + ) +) jt; + +SELECT * FROM JSON_TABLE( + jsonb '[]', '$' + COLUMNS ( + NESTED PATH '$' AS a + COLUMNS ( + b int + ), + NESTED PATH '$' + COLUMNS ( + NESTED PATH '$' AS a + COLUMNS ( + c int + ) + ) + ) +) jt; + +CREATE TEMP TABLE jsonb_table_test (js jsonb); + +INSERT INTO jsonb_table_test +VALUES ( + '[ + {"a": 1, "b": [], "c": []}, + {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, + {"a": 3, "b": [1, 2], "c": []}, + {"x": "4", "b": [1, 2], "c": 123} + ]' +); + +select + jt.* +from + jsonb_table_test jtt, + json_table ( + jtt.js,'strict $[*]' as p + columns ( + n for ordinality, + a int path 'lax $.a' default -1 on empty, + nested path 'strict $.b[*]' as pb columns (b_id for ordinality, b int path '$' ), + nested path 'strict $.c[*]' as pc columns (c_id for ordinality, c int path '$' ) + ) + ) jt; + +SELECT * +FROM + generate_series(1, 3) x, + generate_series(1, 3) y, + JSON_TABLE(jsonb + '[[1,2,3],[2,3,4,5],[3,4,5,6]]', + 'strict $[*] ? (@[*] <= $x)' + PASSING x AS x, y AS y + COLUMNS ( + y text FORMAT JSON PATH '$', + NESTED PATH 'strict $[*] ? (@ == $y)' + COLUMNS ( + z int PATH '$' + ) + ) + ) jt; + +CREATE VIEW jsonb_table_view_nested AS +SELECT * FROM + JSON_TABLE( + jsonb 'null', 'lax $[*]' PASSING 1 + 2 AS a, json '"foo"' AS "b c" + COLUMNS ( + id FOR ORDINALITY, + NESTED PATH '$[1]' AS p1 COLUMNS ( + a1 int, + NESTED PATH '$[*]' AS "p1 1" COLUMNS ( + a11 text + ), + b1 text + ), + NESTED PATH '$[2]' AS p2 COLUMNS ( + NESTED PATH '$[*]' AS "p2:1" COLUMNS ( + a21 text + ), + NESTED PATH '$[*]' AS p22 COLUMNS ( + a22 text + ) + ) + ) + ); + +DROP VIEW jsonb_table_view_nested; + +CREATE TABLE s (js jsonb); + +INSERT INTO s VALUES + ('{"a":{"za":[{"z1": [11,2222]},{"z21": [22, 234,2345]},{"z22": [32, 204,145]}]},"c": 3}'), + ('{"a":{"za":[{"z1": [21,4222]},{"z21": [32, 134,1345]}]},"c": 10}'); + +SELECT sub.* FROM s, + JSON_TABLE(js, '$' PASSING 32 AS x, 13 AS y COLUMNS ( + xx int path '$.c', + NESTED PATH '$.a.za[1]' columns (NESTED PATH '$.z21[*]' COLUMNS (z21 int path '$?(@ >= $"x")' ERROR ON ERROR)) + )) sub; + +SELECT sub.* FROM s, + (VALUES (23)) x(x), generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y COLUMNS ( + NESTED PATH '$.a.za[2]' COLUMNS ( + NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$')), + NESTED PATH '$.a.za[1]' columns (d int[] PATH '$.z21'), + NESTED PATH '$.a.za[0]' columns (NESTED PATH '$.z1[*]' as z1 COLUMNS (a int PATH '$')), + xx1 int PATH '$.c', + NESTED PATH '$.a.za[1]' columns (NESTED PATH '$.z21[*]' as z21 COLUMNS (b int PATH '$')), + xx int PATH '$.c' + )) sub; + +SELECT sub.* FROM s, + (VALUES (23)) x(x), generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[0].z1[*]' COLUMNS (NESTED PATH '$ ?(@ >= ($"x" -2))' COLUMNS (a int PATH '$')), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' COLUMNS (b int PATH '$')) + )) sub; + +SELECT sub.* FROM s, + (VALUES (23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[1]' + COLUMNS (NESTED PATH '$.z21[*]' COLUMNS (b int PATH '$')), + NESTED PATH '$.a.za[1] ? (@.z21[*] >= ($"x"-1))' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" + 3))' as z22 COLUMNS (a int PATH '$ ? (@ >= ($"y" + 12))')), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (c int PATH '$ ? (@ > ($"x" +111))')) + )) sub; + +SELECT sub.* FROM s, + (values(23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[2]' COLUMNS (NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$')), + NESTED PATH '$.a.za[1]' COLUMNS (d json PATH '$ ? (@.z21[*] == ($"x" -1))'), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' as z1 COLUMNS (a int PATH '$')), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (b int PATH '$ ? (@ > ($"x" +111))' DEFAULT 0 ON EMPTY)) + )) sub; + +CREATE OR REPLACE VIEW jsonb_table_view7 AS +SELECT sub.* FROM s, + (values(23)) x(x), + generate_series(13, 13) y, + JSON_TABLE(js, '$' AS c1 PASSING x AS x, y AS y + COLUMNS ( + xx1 int PATH '$.c', + NESTED PATH '$.a.za[2]' COLUMNS (NESTED PATH '$.z22[*]' as z22 COLUMNS (c int PATH '$' WITHOUT WRAPPER OMIT QUOTES)), + NESTED PATH '$.a.za[1]' COLUMNS (d json PATH '$ ? (@.z21[*] == ($"x" -1))' WITH WRAPPER), + NESTED PATH '$.a.za[0]' COLUMNS (NESTED PATH '$.z1[*] ? (@ >= ($"x" -2))' as z1 COLUMNS (a int PATH '$' KEEP QUOTES)), + NESTED PATH '$.a.za[1]' COLUMNS + (NESTED PATH '$.z21[*] ? (@ >= ($"y" +121))' as z21 COLUMNS (b int PATH '$ ? (@ > ($"x" +111))' DEFAULT 0 ON EMPTY)) + )) sub; + +DROP VIEW jsonb_table_view7; + +DROP TABLE s; + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int) NULL ON ERROR); + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int true on empty)); + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int omit quotes true on error)); + +SELECT * FROM JSON_TABLE(jsonb '1', '$' COLUMNS (a int exists empty object on error)); + +CREATE VIEW json_table_view8 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$')); + +CREATE VIEW json_table_view9 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') ERROR ON ERROR); + +DROP VIEW json_table_view8, json_table_view9; + +CREATE VIEW json_table_view8 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ON ERROR); + +CREATE VIEW json_table_view9 AS SELECT * from JSON_TABLE('"a"', '$' COLUMNS (a text PATH '$') EMPTY ARRAY ON ERROR); + +DROP VIEW json_table_view8, json_table_view9; diff --git a/crates/pgt_pretty_print/tests/data/multi/sqljson_queryfuncs_60.sql b/crates/pgt_pretty_print/tests/data/multi/sqljson_queryfuncs_60.sql new file mode 100644 index 000000000..4a23a2ca1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/sqljson_queryfuncs_60.sql @@ -0,0 +1,697 @@ +SELECT JSON_EXISTS(NULL::jsonb, '$'); + +SELECT JSON_EXISTS(jsonb '[]', '$'); + +SELECT JSON_EXISTS(JSON_OBJECT(RETURNING jsonb), '$'); + +SELECT JSON_EXISTS(jsonb '1', '$'); + +SELECT JSON_EXISTS(jsonb 'null', '$'); + +SELECT JSON_EXISTS(jsonb '[]', '$'); + +SELECT JSON_EXISTS(jsonb '1', '$.a'); + +SELECT JSON_EXISTS(jsonb '1', 'strict $.a'); + +SELECT JSON_EXISTS(jsonb '1', 'strict $.a' ERROR ON ERROR); + +SELECT JSON_EXISTS(jsonb 'null', '$.a'); + +SELECT JSON_EXISTS(jsonb '[]', '$.a'); + +SELECT JSON_EXISTS(jsonb '[1, "aaa", {"a": 1}]', 'strict $.a'); + +SELECT JSON_EXISTS(jsonb '[1, "aaa", {"a": 1}]', 'lax $.a'); + +SELECT JSON_EXISTS(jsonb '{}', '$.a'); + +SELECT JSON_EXISTS(jsonb '{"b": 1, "a": 2}', '$.a'); + +SELECT JSON_EXISTS(jsonb '1', '$.a.b'); + +SELECT JSON_EXISTS(jsonb '{"a": {"b": 1}}', '$.a.b'); + +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.a.b'); + +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x)' PASSING 1 AS x); + +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x)' PASSING '1' AS x); + +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 2 AS y); + +SELECT JSON_EXISTS(jsonb '{"a": 1, "b": 2}', '$.* ? (@ > $x && @ < $y)' PASSING 0 AS x, 1 AS y); + +SELECT JSON_EXISTS(jsonb '1', '$ > 2'); + +SELECT JSON_EXISTS(jsonb '1', '$.a > 2' ERROR ON ERROR); + +SELECT JSON_VALUE(NULL::jsonb, '$'); + +SELECT JSON_VALUE(jsonb 'null', '$'); + +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING int); + +SELECT JSON_VALUE(jsonb 'true', '$'); + +SELECT JSON_VALUE(jsonb 'true', '$' RETURNING bool); + +SELECT JSON_VALUE(jsonb '123', '$'); + +SELECT JSON_VALUE(jsonb '123', '$' RETURNING int) + 234; + +SELECT JSON_VALUE(jsonb '123', '$' RETURNING text); + +SELECT JSON_VALUE(jsonb '123', '$' RETURNING bytea ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1.23', '$'); + +SELECT JSON_VALUE(jsonb '1.23', '$' RETURNING int); + +SELECT JSON_VALUE(jsonb '"1.23"', '$' RETURNING numeric); + +SELECT JSON_VALUE(jsonb '"1.23"', '$' RETURNING int ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '"aaa"', '$'); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING text); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(5)); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2) ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(2)); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING jsonb); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING json ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING jsonb ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '"\"aaa\""', '$' RETURNING json); + +SELECT JSON_VALUE(jsonb '"\"aaa\""', '$' RETURNING jsonb); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '"aaa"', '$' RETURNING int DEFAULT 111 ON ERROR); + +SELECT JSON_VALUE(jsonb '"123"', '$' RETURNING int) + 234; + +SELECT JSON_VALUE(jsonb '"2017-02-20"', '$' RETURNING date) + 9; + +CREATE DOMAIN sqljsonb_int_not_null AS int NOT NULL; + +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null); + +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb 'null', '$' RETURNING sqljsonb_int_not_null DEFAULT 2 ON EMPTY ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT 2 ON EMPTY ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1', '$.a' RETURNING sqljsonb_int_not_null DEFAULT NULL ON EMPTY ERROR ON ERROR); + +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); + +CREATE DOMAIN rgb AS rainbow CHECK (VALUE IN ('red', 'green', 'blue')); + +SELECT JSON_VALUE('"purple"'::jsonb, 'lax $[*]' RETURNING rgb); + +SELECT JSON_VALUE('"purple"'::jsonb, 'lax $[*]' RETURNING rgb ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '[]', '$'); + +SELECT JSON_VALUE(jsonb '[]', '$' ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '{}', '$'); + +SELECT JSON_VALUE(jsonb '{}', '$' ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1', '$.a'); + +SELECT JSON_VALUE(jsonb '1', 'strict $.a' ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'strict $.a' DEFAULT 'error' ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'strict $.*' DEFAULT 2 ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT 2 ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY); + +SELECT JSON_VALUE(jsonb '1', 'lax $.a' NULL ON EMPTY DEFAULT '2' ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'lax $.a' DEFAULT '2' ON EMPTY DEFAULT '3' ON ERROR); + +SELECT JSON_VALUE(jsonb '1', 'lax $.a' ERROR ON EMPTY DEFAULT '3' ON ERROR); + +SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '[1,2]', '$[*]' DEFAULT '0' ON ERROR); + +SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '[" "]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR); + +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int DEFAULT 2 + 3 ON ERROR); + +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING int FORMAT JSON); + +SELECT JSON_VALUE(jsonb '["1"]', '$[*]' RETURNING record); + +SELECT + x, + JSON_VALUE( + jsonb '{"a": 1, "b": 2}', + '$.* ? (@ > $x)' PASSING x AS x + RETURNING int + DEFAULT -1 ON EMPTY + DEFAULT -2 ON ERROR + ) y +FROM + generate_series(0, 2) x; + +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a); + +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a RETURNING point); + +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING point ' (1, 2 )' AS a RETURNING point ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamptz); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING timestamp); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING date '2018-02-21 12:34:56 +10' AS ts RETURNING date); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING time '2018-02-21 12:34:56 +10' AS ts RETURNING time); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timetz '2018-02-21 12:34:56 +10' AS ts RETURNING timetz); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamp '2018-02-21 12:34:56 +10' AS ts RETURNING timestamp); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING json); + +SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING jsonb); + +select json_value('{"a": 1.234}', '$.a' returning int error on error); + +select json_value('{"a": "1.234"}', '$.a' returning int error on error); + +SELECT JSON_VALUE(NULL::jsonb, '$'); + +SELECT + JSON_QUERY(js, '$') AS "unspec", + JSON_QUERY(js, '$' WITHOUT WRAPPER) AS "without", + JSON_QUERY(js, '$' WITH CONDITIONAL WRAPPER) AS "with cond", + JSON_QUERY(js, '$' WITH UNCONDITIONAL ARRAY WRAPPER) AS "with uncond", + JSON_QUERY(js, '$' WITH ARRAY WRAPPER) AS "with" +FROM + (VALUES + (jsonb 'null'), + ('12.3'), + ('true'), + ('"aaa"'), + ('[1, null, "2"]'), + ('{"a": 1, "b": [2]}') + ) foo(js); + +SELECT + JSON_QUERY(js, 'strict $[*]') AS "unspec", + JSON_QUERY(js, 'strict $[*]' WITHOUT WRAPPER) AS "without", + JSON_QUERY(js, 'strict $[*]' WITH CONDITIONAL WRAPPER) AS "with cond", + JSON_QUERY(js, 'strict $[*]' WITH UNCONDITIONAL ARRAY WRAPPER) AS "with uncond", + JSON_QUERY(js, 'strict $[*]' WITH ARRAY WRAPPER) AS "with" +FROM + (VALUES + (jsonb '1'), + ('[]'), + ('[null]'), + ('[12.3]'), + ('[true]'), + ('["aaa"]'), + ('[[1, 2, 3]]'), + ('[{"a": 1, "b": [2]}]'), + ('[1, "2", null, [3]]') + ) foo(js); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text KEEP QUOTES); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text KEEP QUOTES ON SCALAR STRING); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text OMIT QUOTES); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING text OMIT QUOTES ON SCALAR STRING); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' OMIT QUOTES ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING json OMIT QUOTES ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING bytea FORMAT JSON OMIT QUOTES ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3)); + +SELECT JSON_QUERY(jsonb '"aaa"', '$' RETURNING char(3) OMIT QUOTES ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT 'bb' ON EMPTY); + +SELECT JSON_QUERY(jsonb '"aaa"', '$.a' RETURNING char(2) OMIT QUOTES DEFAULT '"bb"'::jsonb ON EMPTY); + +SELECT JSON_QUERY(jsonb '[1]', '$' WITH WRAPPER OMIT QUOTES); + +SELECT JSON_QUERY(jsonb '[1]', '$' WITH CONDITIONAL WRAPPER OMIT QUOTES); + +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH CONDITIONAL WRAPPER KEEP QUOTES); + +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH UNCONDITIONAL WRAPPER KEEP QUOTES); + +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITH WRAPPER KEEP QUOTES); + +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITHOUT WRAPPER OMIT QUOTES); + +SELECT JSON_QUERY(jsonb '["1"]', '$[*]' WITHOUT WRAPPER KEEP QUOTES); + +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] omit quotes); + +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] keep quotes); + +SELECT JSON_QUERY(jsonb'{"rec": "{1,2,3}"}', '$.rec' returning int[] keep quotes error on error); + +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range omit quotes); + +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes); + +SELECT JSON_QUERY(jsonb'{"rec": "[1,2]"}', '$.rec' returning int4range keep quotes error on error); + +CREATE DOMAIN qf_char_domain AS char(1); + +CREATE DOMAIN qf_jsonb_domain AS jsonb; + +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_char_domain OMIT QUOTES ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '"1"', '$' RETURNING qf_jsonb_domain OMIT QUOTES ERROR ON ERROR); + +DROP DOMAIN qf_char_domain, qf_jsonb_domain; + +SELECT JSON_QUERY(jsonb '[]', '$[*]'); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' NULL ON EMPTY); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ON EMPTY); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY ARRAY ON EMPTY); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' EMPTY OBJECT ON EMPTY); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' DEFAULT '"empty"' ON EMPTY); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY NULL ON ERROR); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY EMPTY ARRAY ON ERROR); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY EMPTY OBJECT ON ERROR); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON EMPTY ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '[]', '$[*]' ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' DEFAULT '"empty"' ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING json); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING json FORMAT JSON); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING jsonb FORMAT JSON); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING char(10)); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING text FORMAT JSON); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea); + +SELECT JSON_QUERY(jsonb '[1,2]', '$' RETURNING bytea FORMAT JSON); + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING bytea EMPTY OBJECT ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING bytea FORMAT JSON EMPTY OBJECT ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING json EMPTY OBJECT ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2]', '$[*]' RETURNING jsonb EMPTY OBJECT ON ERROR); + +SELECT JSON_QUERY(jsonb '[3,4]', '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR); + +SELECT JSON_QUERY(jsonb '"[3,4]"', '$[*]' RETURNING bigint[] EMPTY OBJECT ON ERROR); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int2 error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int4 error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int8 error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING bool error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING numeric error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING real error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING float8 error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING int2 omit quotes error on error); + +SELECT JSON_QUERY(jsonb '"123.1"', '$' RETURNING float8 omit quotes error on error); + +SELECT JSON_QUERY(jsonb '[3,4]', '$[*]' RETURNING anyarray EMPTY OBJECT ON ERROR); + +SELECT + x, y, + JSON_QUERY( + jsonb '[1,2,3,4,5,null]', + '$[*] ? (@ >= $x && @ <= $y)' + PASSING x AS x, y AS y + WITH CONDITIONAL WRAPPER + EMPTY ARRAY ON EMPTY + ) list +FROM + generate_series(0, 4) x, + generate_series(0, 4) y; + +CREATE TYPE comp_abc AS (a text, b int, c timestamp); + +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc omit quotes); + +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc keep quotes); + +SELECT JSON_QUERY(jsonb'{"rec": "(abc,42,01.02.2003)"}', '$.rec' returning comp_abc keep quotes error on error); + +DROP TYPE comp_abc; + +CREATE TYPE sqljsonb_rec AS (a int, t text, js json, jb jsonb, jsa json[]); + +CREATE TYPE sqljsonb_reca AS (reca sqljsonb_rec[]); + +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec); + +SELECT JSON_QUERY(jsonb '[{"a": "a", "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '[{"a": "a", "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING sqljsonb_rec); + +SELECT * FROM unnest((JSON_QUERY(jsonb '{"jsa": [{"a": 1, "b": ["foo"]}, {"a": 2, "c": {}}, 123]}', '$' RETURNING sqljsonb_rec)).jsa); + +SELECT * FROM unnest((JSON_QUERY(jsonb '{"reca": [{"a": 1, "t": ["foo", []]}, {"a": 2, "jb": [{}, true]}]}', '$' RETURNING sqljsonb_reca)).reca); + +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING jsonpath); + +SELECT JSON_QUERY(jsonb '[{"a": 1, "b": "foo", "t": "aaa", "js": [1, "2", {}], "jb": {"x": [1, "2", {}]}}, {"a": 2}]', '$[0]' RETURNING jsonpath ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2,null,"3"]', '$[*]' RETURNING int[] WITH WRAPPER); + +SELECT JSON_QUERY(jsonb '[1,2,null,"a"]', '$[*]' RETURNING int[] WITH WRAPPER ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '[1,2,null,"a"]', '$[*]' RETURNING int[] WITH WRAPPER); + +SELECT * FROM unnest(JSON_QUERY(jsonb '[{"a": 1, "t": ["foo", []]}, {"a": 2, "jb": [{}, true]}]', '$' RETURNING sqljsonb_rec[])); + +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.a' RETURNING sqljsonb_int_not_null); + +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.b' RETURNING sqljsonb_int_not_null); + +SELECT JSON_QUERY(jsonb '{"a": 1}', '$.b' RETURNING sqljsonb_int_not_null ERROR ON EMPTY ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts); + +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING json); + +SELECT JSON_QUERY(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 +10' AS ts RETURNING jsonb); + +CREATE TABLE test_jsonb_constraints ( + js text, + i int, + x jsonb DEFAULT JSON_QUERY(jsonb '[1,2]', '$[*]' WITH WRAPPER) + CONSTRAINT test_jsonb_constraint1 + CHECK (js IS JSON) + CONSTRAINT test_jsonb_constraint2 + CHECK (JSON_EXISTS(js::jsonb, '$.a' PASSING i + 5 AS int, i::text AS "TXT", array[1,2,3] as arr)) + CONSTRAINT test_jsonb_constraint3 + CHECK (JSON_VALUE(js::jsonb, '$.a' RETURNING int DEFAULT '12' ON EMPTY ERROR ON ERROR) > i) + CONSTRAINT test_jsonb_constraint4 + CHECK (JSON_QUERY(js::jsonb, '$.a' WITH CONDITIONAL WRAPPER EMPTY OBJECT ON ERROR) = jsonb '[10]') + CONSTRAINT test_jsonb_constraint5 + CHECK (JSON_QUERY(js::jsonb, '$.a' RETURNING char(5) OMIT QUOTES EMPTY ARRAY ON EMPTY) > 'a' COLLATE "C") +); + +SELECT check_clause +FROM information_schema.check_constraints +WHERE constraint_name LIKE 'test_jsonb_constraint%' +ORDER BY 1; + +SELECT pg_get_expr(adbin, adrelid) +FROM pg_attrdef +WHERE adrelid = 'test_jsonb_constraints'::regclass +ORDER BY 1; + +INSERT INTO test_jsonb_constraints VALUES ('', 1); + +INSERT INTO test_jsonb_constraints VALUES ('1', 1); + +INSERT INTO test_jsonb_constraints VALUES ('[]'); + +INSERT INTO test_jsonb_constraints VALUES ('{"b": 1}', 1); + +INSERT INTO test_jsonb_constraints VALUES ('{"a": 1}', 1); + +INSERT INTO test_jsonb_constraints VALUES ('{"a": 10}', 1); + +DROP TABLE test_jsonb_constraints; + +CREATE TABLE test_jsonb_mutability(js jsonb, b int); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a[0]')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time()')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date()')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.time_tz()')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp()')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.timestamp_tz()')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time_tz())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.time())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.time_tz())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.timestamp_tz())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.timestamp_tz())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.time() < $.datetime("HH:MI TZH"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.date() < $.datetime("HH:MI TZH"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI TZH"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp() < $.datetime("HH:MI"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI TZH"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp_tz() < $.datetime("HH:MI"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '12:34'::timetz AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.date() < $x' PASSING '1234'::int AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.timestamp(2) < $.timestamp(3))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime()')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@ < $.datetime())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime())')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime() < $.datetime("HH:MI TZH"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("HH:MI TZH"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI") < $.datetime("YY-MM-DD HH:MI"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.a ? (@.datetime("HH:MI TZH") < $.datetime("YY-MM-DD HH:MI"))')); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $x' PASSING '12:34'::timetz AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("HH:MI TZH") < $y' PASSING '12:34'::timetz AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '12:34'::timetz AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() < $x' PASSING '1234'::int AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime() ? (@ == $x)' PASSING '12:34'::time AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$.datetime("YY-MM-DD") ? (@ == $x)' PASSING '2020-07-14'::date AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, 0 to $.a ? (@.datetime() == $x)]' PASSING '12:34'::time AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_QUERY(js, '$[1, $.a ? (@.datetime("HH:MI") == $x)]' PASSING '12:34'::time AS x)); + +CREATE INDEX ON test_jsonb_mutability (JSON_VALUE(js, '$' DEFAULT random()::int ON ERROR)); + +CREATE OR REPLACE FUNCTION ret_setint() RETURNS SETOF integer AS +$$ +BEGIN + RETURN QUERY EXECUTE 'select 1 union all select 1'; +END; +$$ +LANGUAGE plpgsql IMMUTABLE; + +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT ret_setint() ON ERROR) FROM test_jsonb_mutability; + +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT b + 1 ON ERROR) FROM test_jsonb_mutability; + +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT sum(1) over() ON ERROR) FROM test_jsonb_mutability; + +SELECT JSON_QUERY(js, '$' RETURNING int DEFAULT (SELECT 1) ON ERROR) FROM test_jsonb_mutability; + +DROP TABLE test_jsonb_mutability; + +DROP FUNCTION ret_setint; + +CREATE DOMAIN queryfuncs_test_domain AS text CHECK (value <> 'foo'); + +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo'::queryfuncs_test_domain ON EMPTY); + +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo1'::queryfuncs_test_domain ON EMPTY); + +SELECT JSON_VALUE(jsonb '{"d1": "H"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT '"foo1"'::jsonb::text ON EMPTY); + +SELECT JSON_VALUE(jsonb '{"d1": "foo"}', '$.a2' RETURNING queryfuncs_test_domain DEFAULT 'foo1'::queryfuncs_test_domain ON EMPTY); + +SELECT JSON_QUERY('"a"', '$.a' RETURNING int DEFAULT (SELECT '"1"')::jsonb ON ERROR); + +SELECT JSON_QUERY('"a"', '$.a' RETURNING queryfuncs_test_domain DEFAULT (select '"1"')::queryfuncs_test_domain ON ERROR); + +SELECT JSON_QUERY('"a"', '$.a' RETURNING int DEFAULT (SELECT 1)::oid::int ON ERROR); + +SELECT JSON_QUERY('"a"', '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::oid[]::int[] ON ERROR); + +SELECT JSON_QUERY('"a"', '$.a' RETURNING int[] DEFAULT (SELECT '{1}')::text COLLATE "C" ON ERROR); + +CREATE TABLE someparent (a int); + +CREATE TABLE somechild () INHERITS (someparent); + +SELECT JSON_QUERY('"a"', '$.a' RETURNING someparent DEFAULT (SELECT '(1)')::somechild::someparent ON ERROR); + +DROP DOMAIN queryfuncs_test_domain; + +DROP TABLE someparent, somechild; + +SELECT JSON_EXISTS(jsonb '{"a": 123}', '$' || '.' || 'a'); + +SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'a'); + +SELECT JSON_VALUE(jsonb '{"a": 123}', '$' || '.' || 'b' DEFAULT 'foo' ON EMPTY); + +SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a'); + +SELECT JSON_QUERY(jsonb '{"a": 123}', '$' || '.' || 'a' WITH WRAPPER); + +SELECT JSON_QUERY(jsonb '{"a": 123}', 'error' || ' ' || 'error'); + +SELECT JSON_EXISTS(json '{"a": 123}', '$' || '.' || 'a'); + +SELECT JSON_QUERY(NULL FORMAT JSON, '$'); + +CREATE TEMP TABLE jsonpaths (path) AS SELECT '$'; + +SELECT json_value('"aaa"', path RETURNING json) FROM jsonpaths; + +SELECT JSON_QUERY(jsonb 'null', '$xyz' PASSING 1 AS xy); + +SELECT JSON_QUERY(jsonb 'null', '$xy' PASSING 1 AS xyz); + +SELECT JSON_QUERY(jsonb 'null', '$xyz' PASSING 1 AS xyz); + +SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS Xyz); + +SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS "Xyz"); + +SELECT JSON_QUERY(jsonb 'null', '$"Xyz"' PASSING 1 AS "Xyz"); + +SELECT JSON_EXISTS(jsonb '1', '$' DEFAULT 1 ON ERROR); + +SELECT JSON_VALUE(jsonb '1', '$' EMPTY ON ERROR); + +SELECT JSON_QUERY(jsonb '1', '$' TRUE ON ERROR); + +CREATE DOMAIN queryfuncs_char2 AS char(2); + +CREATE DOMAIN queryfuncs_char2_chk AS char(2) CHECK (VALUE NOT IN ('12')); + +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT '1' ON ERROR); + +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR); + +SELECT JSON_QUERY(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT '1' ON ERROR); + +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2 DEFAULT 1 ON ERROR); + +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '123', '$' RETURNING queryfuncs_char2_chk DEFAULT 1 ON ERROR); + +DROP DOMAIN queryfuncs_char2, queryfuncs_char2_chk; + +CREATE DOMAIN queryfuncs_d_varbit3 AS varbit(3) CHECK (VALUE <> '01'); + +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '111111' ON ERROR); + +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '010' ON ERROR); + +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING queryfuncs_d_varbit3 DEFAULT '01' ON ERROR); + +SELECT JSON_VALUE(jsonb '"111"', '$' RETURNING bit(2) ERROR ON ERROR); + +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING bit(3) DEFAULT 1 ON ERROR); + +SELECT JSON_VALUE(jsonb '1234', '$' RETURNING bit(3) DEFAULT 1::bit(3) ON ERROR); + +SELECT JSON_VALUE(jsonb '"111"', '$.a' RETURNING bit(3) DEFAULT '1111' ON EMPTY); + +DROP DOMAIN queryfuncs_d_varbit3; diff --git a/crates/pgt_pretty_print/tests/data/multi/stats_60.sql b/crates/pgt_pretty_print/tests/data/multi/stats_60.sql new file mode 100644 index 000000000..d28e7deb2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/stats_60.sql @@ -0,0 +1,1039 @@ +SHOW track_counts; + +SELECT backend_type, object, context FROM pg_stat_io + ORDER BY backend_type COLLATE "C", object COLLATE "C", context COLLATE "C"; + +SET enable_seqscan TO on; + +SET enable_indexscan TO on; + +SET enable_indexonlyscan TO off; + +SET track_functions TO 'all'; + +SELECT oid AS dboid from pg_database where datname = current_database() ; + +BEGIN; + +SET LOCAL stats_fetch_consistency = snapshot; + +CREATE TABLE prevstats AS +SELECT t.seq_scan, t.seq_tup_read, t.idx_scan, t.idx_tup_fetch, + (b.heap_blks_read + b.heap_blks_hit) AS heap_blks, + (b.idx_blks_read + b.idx_blks_hit) AS idx_blks, + pg_stat_get_snapshot_timestamp() as snap_ts + FROM pg_catalog.pg_stat_user_tables AS t, + pg_catalog.pg_statio_user_tables AS b + WHERE t.relname='tenk2' AND b.relname='tenk2'; + +COMMIT; + +CREATE TABLE trunc_stats_test(id serial); + +CREATE TABLE trunc_stats_test1(id serial, stuff text); + +CREATE TABLE trunc_stats_test2(id serial); + +CREATE TABLE trunc_stats_test3(id serial, stuff text); + +CREATE TABLE trunc_stats_test4(id serial); + +INSERT INTO trunc_stats_test DEFAULT VALUES; + +INSERT INTO trunc_stats_test DEFAULT VALUES; + +INSERT INTO trunc_stats_test DEFAULT VALUES; + +TRUNCATE trunc_stats_test; + +INSERT INTO trunc_stats_test1 DEFAULT VALUES; + +INSERT INTO trunc_stats_test1 DEFAULT VALUES; + +INSERT INTO trunc_stats_test1 DEFAULT VALUES; + +UPDATE trunc_stats_test1 SET id = id + 10 WHERE id IN (1, 2); + +DELETE FROM trunc_stats_test1 WHERE id = 3; + +BEGIN; + +UPDATE trunc_stats_test1 SET id = id + 100; + +TRUNCATE trunc_stats_test1; + +INSERT INTO trunc_stats_test1 DEFAULT VALUES; + +COMMIT; + +BEGIN; + +INSERT INTO trunc_stats_test2 DEFAULT VALUES; + +INSERT INTO trunc_stats_test2 DEFAULT VALUES; + +SAVEPOINT p1; + +INSERT INTO trunc_stats_test2 DEFAULT VALUES; + +TRUNCATE trunc_stats_test2; + +INSERT INTO trunc_stats_test2 DEFAULT VALUES; + +RELEASE SAVEPOINT p1; + +COMMIT; + +BEGIN; + +INSERT INTO trunc_stats_test3 DEFAULT VALUES; + +INSERT INTO trunc_stats_test3 DEFAULT VALUES; + +SAVEPOINT p1; + +INSERT INTO trunc_stats_test3 DEFAULT VALUES; + +INSERT INTO trunc_stats_test3 DEFAULT VALUES; + +TRUNCATE trunc_stats_test3; + +INSERT INTO trunc_stats_test3 DEFAULT VALUES; + +ROLLBACK TO SAVEPOINT p1; + +COMMIT; + +BEGIN; + +INSERT INTO trunc_stats_test4 DEFAULT VALUES; + +INSERT INTO trunc_stats_test4 DEFAULT VALUES; + +TRUNCATE trunc_stats_test4; + +INSERT INTO trunc_stats_test4 DEFAULT VALUES; + +ROLLBACK; + +SELECT count(*) FROM tenk2; + +SET enable_bitmapscan TO off; + +SELECT count(*) FROM tenk2 WHERE unique1 = 1; + +RESET enable_bitmapscan; + +SELECT pg_stat_force_next_flush(); + +BEGIN; + +SET LOCAL stats_fetch_consistency = snapshot; + +SELECT relname, n_tup_ins, n_tup_upd, n_tup_del, n_live_tup, n_dead_tup + FROM pg_stat_user_tables + WHERE relname like 'trunc_stats_test%' order by relname; + +SELECT st.seq_scan >= pr.seq_scan + 1, + st.seq_tup_read >= pr.seq_tup_read + cl.reltuples, + st.idx_scan >= pr.idx_scan + 1, + st.idx_tup_fetch >= pr.idx_tup_fetch + 1 + FROM pg_stat_user_tables AS st, pg_class AS cl, prevstats AS pr + WHERE st.relname='tenk2' AND cl.relname='tenk2'; + +SELECT st.heap_blks_read + st.heap_blks_hit >= pr.heap_blks + cl.relpages, + st.idx_blks_read + st.idx_blks_hit >= pr.idx_blks + 1 + FROM pg_statio_user_tables AS st, pg_class AS cl, prevstats AS pr + WHERE st.relname='tenk2' AND cl.relname='tenk2'; + +SELECT pr.snap_ts < pg_stat_get_snapshot_timestamp() as snapshot_newer +FROM prevstats AS pr; + +COMMIT; + +CREATE FUNCTION stats_test_func1() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$; + +SELECT 'stats_test_func1()'::regprocedure::oid AS stats_test_func1_oid ; + +CREATE FUNCTION stats_test_func2() RETURNS VOID LANGUAGE plpgsql AS $$BEGIN END;$$; + +SELECT 'stats_test_func2()'::regprocedure::oid AS stats_test_func2_oid ; + +BEGIN; + +SET LOCAL stats_fetch_consistency = none; + +SELECT pg_stat_get_function_calls('stats_test_func1_oid'); + +SELECT pg_stat_get_xact_function_calls('stats_test_func1_oid'); + +SELECT stats_test_func1(); + +SELECT pg_stat_get_xact_function_calls('stats_test_func1_oid'); + +SELECT stats_test_func1(); + +SELECT pg_stat_get_xact_function_calls('stats_test_func1_oid'); + +SELECT pg_stat_get_function_calls('stats_test_func1_oid'); + +COMMIT; + +BEGIN; + +SELECT stats_test_func2(); + +SAVEPOINT foo; + +SELECT stats_test_func2(); + +ROLLBACK TO SAVEPOINT foo; + +SELECT pg_stat_get_xact_function_calls('stats_test_func2_oid'); + +SELECT stats_test_func2(); + +COMMIT; + +BEGIN; + +SELECT stats_test_func2(); + +ROLLBACK; + +SELECT pg_stat_force_next_flush(); + +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = 'stats_test_func1_oid'; + +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = 'stats_test_func2_oid'; + +BEGIN; + +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = 'stats_test_func1_oid'; + +DROP FUNCTION stats_test_func1(); + +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = 'stats_test_func1_oid'; + +SELECT pg_stat_get_function_calls('stats_test_func1_oid'); + +ROLLBACK; + +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = 'stats_test_func1_oid'; + +SELECT pg_stat_get_function_calls('stats_test_func1_oid'); + +BEGIN; + +DROP FUNCTION stats_test_func1(); + +COMMIT; + +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = 'stats_test_func1_oid'; + +SELECT pg_stat_get_function_calls('stats_test_func1_oid'); + +BEGIN; + +SELECT stats_test_func2(); + +SAVEPOINT a; + +SELECT stats_test_func2(); + +SAVEPOINT b; + +DROP FUNCTION stats_test_func2(); + +COMMIT; + +SELECT funcname, calls FROM pg_stat_user_functions WHERE funcid = 'stats_test_func2_oid'; + +SELECT pg_stat_get_function_calls('stats_test_func2_oid'); + +CREATE TABLE drop_stats_test(); + +INSERT INTO drop_stats_test DEFAULT VALUES; + +SELECT 'drop_stats_test'::regclass::oid AS drop_stats_test_oid ; + +CREATE TABLE drop_stats_test_xact(); + +INSERT INTO drop_stats_test_xact DEFAULT VALUES; + +SELECT 'drop_stats_test_xact'::regclass::oid AS drop_stats_test_xact_oid ; + +CREATE TABLE drop_stats_test_subxact(); + +INSERT INTO drop_stats_test_subxact DEFAULT VALUES; + +SELECT 'drop_stats_test_subxact'::regclass::oid AS drop_stats_test_subxact_oid ; + +SELECT pg_stat_force_next_flush(); + +SELECT pg_stat_get_live_tuples('drop_stats_test_oid'); + +DROP TABLE drop_stats_test; + +SELECT pg_stat_get_live_tuples('drop_stats_test_oid'); + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_oid'); + +SELECT pg_stat_get_live_tuples('drop_stats_test_xact_oid'); + +SELECT pg_stat_get_tuples_inserted('drop_stats_test_xact_oid'); + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_xact_oid'); + +BEGIN; + +INSERT INTO drop_stats_test_xact DEFAULT VALUES; + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_xact_oid'); + +DROP TABLE drop_stats_test_xact; + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_xact_oid'); + +ROLLBACK; + +SELECT pg_stat_force_next_flush(); + +SELECT pg_stat_get_live_tuples('drop_stats_test_xact_oid'); + +SELECT pg_stat_get_tuples_inserted('drop_stats_test_xact_oid'); + +SELECT pg_stat_get_live_tuples('drop_stats_test_xact_oid'); + +SELECT pg_stat_get_tuples_inserted('drop_stats_test_xact_oid'); + +BEGIN; + +INSERT INTO drop_stats_test_xact DEFAULT VALUES; + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_xact_oid'); + +DROP TABLE drop_stats_test_xact; + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_xact_oid'); + +COMMIT; + +SELECT pg_stat_force_next_flush(); + +SELECT pg_stat_get_live_tuples('drop_stats_test_xact_oid'); + +SELECT pg_stat_get_tuples_inserted('drop_stats_test_xact_oid'); + +SELECT pg_stat_get_live_tuples('drop_stats_test_subxact_oid'); + +BEGIN; + +INSERT INTO drop_stats_test_subxact DEFAULT VALUES; + +SAVEPOINT sp1; + +INSERT INTO drop_stats_test_subxact DEFAULT VALUES; + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_subxact_oid'); + +SAVEPOINT sp2; + +DROP TABLE drop_stats_test_subxact; + +ROLLBACK TO SAVEPOINT sp2; + +SELECT pg_stat_get_xact_tuples_inserted('drop_stats_test_subxact_oid'); + +COMMIT; + +SELECT pg_stat_force_next_flush(); + +SELECT pg_stat_get_live_tuples('drop_stats_test_subxact_oid'); + +SELECT pg_stat_get_live_tuples('drop_stats_test_subxact_oid'); + +BEGIN; + +SAVEPOINT sp1; + +DROP TABLE drop_stats_test_subxact; + +SAVEPOINT sp2; + +ROLLBACK TO SAVEPOINT sp1; + +COMMIT; + +SELECT pg_stat_get_live_tuples('drop_stats_test_subxact_oid'); + +SELECT pg_stat_get_live_tuples('drop_stats_test_subxact_oid'); + +BEGIN; + +SAVEPOINT sp1; + +DROP TABLE drop_stats_test_subxact; + +SAVEPOINT sp2; + +RELEASE SAVEPOINT sp1; + +COMMIT; + +SELECT pg_stat_get_live_tuples('drop_stats_test_subxact_oid'); + +DROP TABLE trunc_stats_test, trunc_stats_test1, trunc_stats_test2, trunc_stats_test3, trunc_stats_test4; + +DROP TABLE prevstats; + +BEGIN; + +CREATE TEMPORARY TABLE test_last_scan(idx_col int primary key, noidx_col int); + +INSERT INTO test_last_scan(idx_col, noidx_col) VALUES(1, 1); + +SELECT pg_stat_force_next_flush(); + +SELECT last_seq_scan, last_idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass; + +COMMIT; + +SELECT pg_stat_reset_single_table_counters('test_last_scan'::regclass); + +SELECT seq_scan, idx_scan FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass; + +BEGIN; + +SET LOCAL enable_seqscan TO on; + +SET LOCAL enable_indexscan TO on; + +SET LOCAL enable_bitmapscan TO off; + +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1; + +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1; + +SET LOCAL enable_seqscan TO off; + +SELECT count(*) FROM test_last_scan WHERE idx_col = 1; + +SELECT count(*) FROM test_last_scan WHERE idx_col = 1; + +SELECT pg_stat_force_next_flush(); + +COMMIT; + +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass ; + +SELECT pg_sleep(0.1); + +BEGIN; + +SET LOCAL enable_seqscan TO on; + +SET LOCAL enable_indexscan TO off; + +SET LOCAL enable_bitmapscan TO off; + +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1; + +SELECT count(*) FROM test_last_scan WHERE noidx_col = 1; + +SELECT pg_stat_force_next_flush(); + +COMMIT; + +SELECT seq_scan, 'test_last_seq' < last_seq_scan AS seq_ok, idx_scan, 'test_last_idx' = last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass; + +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass ; + +SELECT pg_sleep(0.1); + +BEGIN; + +SET LOCAL enable_seqscan TO off; + +SET LOCAL enable_indexscan TO on; + +SET LOCAL enable_bitmapscan TO off; + +SELECT count(*) FROM test_last_scan WHERE idx_col = 1; + +SELECT count(*) FROM test_last_scan WHERE idx_col = 1; + +SELECT pg_stat_force_next_flush(); + +COMMIT; + +SELECT seq_scan, 'test_last_seq' = last_seq_scan AS seq_ok, idx_scan, 'test_last_idx' < last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass; + +SELECT last_seq_scan AS test_last_seq, last_idx_scan AS test_last_idx +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass ; + +SELECT pg_sleep(0.1); + +BEGIN; + +SET LOCAL enable_seqscan TO off; + +SET LOCAL enable_indexscan TO off; + +SET LOCAL enable_bitmapscan TO on; + +SELECT count(*) FROM test_last_scan WHERE idx_col = 1; + +SELECT count(*) FROM test_last_scan WHERE idx_col = 1; + +SELECT pg_stat_force_next_flush(); + +COMMIT; + +SELECT seq_scan, 'test_last_seq' = last_seq_scan AS seq_ok, idx_scan, 'test_last_idx' < last_idx_scan AS idx_ok +FROM pg_stat_all_tables WHERE relid = 'test_last_scan'::regclass; + +SELECT shobj_description(d.oid, 'pg_database') as description_before + FROM pg_database d WHERE datname = current_database() ; + +BEGIN; + +SELECT current_database() as datname ; + +SELECT pg_stat_force_next_flush(); + +COMMIT; + +SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables + WHERE relid = 'pg_shdescription'::regclass; + +SELECT pg_stat_reset_single_table_counters('pg_shdescription'::regclass); + +SELECT (n_tup_ins + n_tup_upd) > 0 AS has_data FROM pg_stat_all_tables + WHERE relid = 'pg_shdescription'::regclass; + +SELECT sessions AS db_stat_sessions FROM pg_stat_database WHERE datname = (SELECT current_database()) ; + +SELECT pg_stat_force_next_flush(); + +SELECT sessions > 'db_stat_sessions' FROM pg_stat_database WHERE datname = (SELECT current_database()); + +SELECT num_requested AS rqst_ckpts_before FROM pg_stat_checkpointer ; + +SELECT wal_bytes AS wal_bytes_before FROM pg_stat_wal ; + +SELECT wal_bytes AS backend_wal_bytes_before from pg_stat_get_backend_wal(pg_backend_pid()) ; + +CREATE TEMP TABLE test_stats_temp AS SELECT 17; + +DROP TABLE test_stats_temp; + +SELECT num_requested > 'rqst_ckpts_before' FROM pg_stat_checkpointer; + +SELECT wal_bytes > 'wal_bytes_before' FROM pg_stat_wal; + +SELECT pg_stat_force_next_flush(); + +SELECT wal_bytes > 'backend_wal_bytes_before' FROM pg_stat_get_backend_wal(pg_backend_pid()); + +SELECT (current_schemas(true))[1] = ('pg_temp_' || beid::text) AS match +FROM pg_stat_get_backend_idset() beid +WHERE pg_stat_get_backend_pid(beid) = pg_backend_pid(); + +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' ; + +SELECT stats_reset AS slru_notify_reset_ts FROM pg_stat_slru WHERE name = 'notify' ; + +SELECT pg_stat_reset_slru('commit_timestamp'); + +SELECT stats_reset > 'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'commit_timestamp'; + +SELECT stats_reset AS slru_commit_ts_reset_ts FROM pg_stat_slru WHERE name = 'commit_timestamp' ; + +SELECT pg_stat_reset_slru(); + +SELECT stats_reset > 'slru_commit_ts_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'commit_timestamp'; + +SELECT stats_reset > 'slru_notify_reset_ts'::timestamptz FROM pg_stat_slru WHERE name = 'notify'; + +SELECT stats_reset AS archiver_reset_ts FROM pg_stat_archiver ; + +SELECT pg_stat_reset_shared('archiver'); + +SELECT stats_reset > 'archiver_reset_ts'::timestamptz FROM pg_stat_archiver; + +SELECT stats_reset AS bgwriter_reset_ts FROM pg_stat_bgwriter ; + +SELECT pg_stat_reset_shared('bgwriter'); + +SELECT stats_reset > 'bgwriter_reset_ts'::timestamptz FROM pg_stat_bgwriter; + +SELECT stats_reset AS checkpointer_reset_ts FROM pg_stat_checkpointer ; + +SELECT pg_stat_reset_shared('checkpointer'); + +SELECT stats_reset > 'checkpointer_reset_ts'::timestamptz FROM pg_stat_checkpointer; + +SELECT stats_reset AS recovery_prefetch_reset_ts FROM pg_stat_recovery_prefetch ; + +SELECT pg_stat_reset_shared('recovery_prefetch'); + +SELECT stats_reset > 'recovery_prefetch_reset_ts'::timestamptz FROM pg_stat_recovery_prefetch; + +SELECT max(stats_reset) AS slru_reset_ts FROM pg_stat_slru ; + +SELECT pg_stat_reset_shared('slru'); + +SELECT max(stats_reset) > 'slru_reset_ts'::timestamptz FROM pg_stat_slru; + +SELECT stats_reset AS wal_reset_ts FROM pg_stat_wal ; + +SELECT pg_stat_reset_shared('wal'); + +SELECT stats_reset > 'wal_reset_ts'::timestamptz FROM pg_stat_wal; + +SELECT pg_stat_reset_shared('unknown'); + +SELECT pg_stat_reset(); + +SELECT stats_reset AS db_reset_ts FROM pg_stat_database WHERE datname = (SELECT current_database()) ; + +SELECT pg_stat_reset(); + +SELECT stats_reset > 'db_reset_ts'::timestamptz FROM pg_stat_database WHERE datname = (SELECT current_database()); + +BEGIN; + +SET LOCAL stats_fetch_consistency = snapshot; + +SELECT pg_stat_get_snapshot_timestamp(); + +SELECT pg_stat_get_function_calls(0); + +SELECT pg_stat_get_snapshot_timestamp() >= NOW(); + +SELECT pg_stat_clear_snapshot(); + +SELECT pg_stat_get_snapshot_timestamp(); + +COMMIT; + +BEGIN; + +SET LOCAL stats_fetch_consistency = cache; + +SELECT pg_stat_get_function_calls(0); + +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok; + +SET LOCAL stats_fetch_consistency = snapshot; + +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok; + +SELECT pg_stat_get_function_calls(0); + +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok; + +SET LOCAL stats_fetch_consistency = none; + +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok; + +SELECT pg_stat_get_function_calls(0); + +SELECT pg_stat_get_snapshot_timestamp() IS NOT NULL AS snapshot_ok; + +ROLLBACK; + +SELECT pg_stat_have_stats('bgwriter', 0, 0); + +SELECT pg_stat_have_stats('zaphod', 0, 0); + +SELECT pg_stat_have_stats('database', 'dboid', 1); + +SELECT pg_stat_have_stats('database', 'dboid', 0); + +CREATE table stats_test_tab1 as select generate_series(1,10) a; + +CREATE index stats_test_idx1 on stats_test_tab1(a); + +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid ; + +SET enable_seqscan TO off; + +select a from stats_test_tab1 where a = 3; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +DROP index stats_test_idx1; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +BEGIN; + +CREATE index stats_test_idx1 on stats_test_tab1(a); + +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid ; + +select a from stats_test_tab1 where a = 3; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +ROLLBACK; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +CREATE index stats_test_idx1 on stats_test_tab1(a); + +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid ; + +select a from stats_test_tab1 where a = 3; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +REINDEX index CONCURRENTLY stats_test_idx1; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +SELECT 'stats_test_idx1'::regclass::oid AS stats_test_idx1_oid ; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +BEGIN; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +DROP index stats_test_idx1; + +ROLLBACK; + +SELECT pg_stat_have_stats('relation', 'dboid', 'stats_test_idx1_oid'); + +SET enable_seqscan TO on; + +SELECT pg_stat_get_replication_slot(NULL); + +SELECT pg_stat_get_subscription_stats(NULL); + +SELECT pid AS checkpointer_pid FROM pg_stat_activity + WHERE backend_type = 'checkpointer' ; + +SELECT sum(extends) AS io_sum_shared_before_extends + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' ; + +SELECT sum(extends) AS my_io_sum_shared_before_extends + FROM pg_stat_get_backend_io(pg_backend_pid()) + WHERE context = 'normal' AND object = 'relation' ; + +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE object = 'relation' ; + +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_get_backend_io(pg_backend_pid()) + WHERE object = 'relation' ; + +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE context = 'normal' AND object = 'wal' ; + +CREATE TABLE test_io_shared(a int); + +INSERT INTO test_io_shared SELECT i FROM generate_series(1,100)i; + +SELECT pg_stat_force_next_flush(); + +SELECT sum(extends) AS io_sum_shared_after_extends + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' ; + +SELECT 'io_sum_shared_after_extends' > 'io_sum_shared_before_extends'; + +SELECT sum(extends) AS my_io_sum_shared_after_extends + FROM pg_stat_get_backend_io(pg_backend_pid()) + WHERE context = 'normal' AND object = 'relation' ; + +SELECT 'my_io_sum_shared_after_extends' > 'my_io_sum_shared_before_extends'; + +CHECKPOINT; + +CHECKPOINT; + +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE object = 'relation' ; + +SELECT 'io_sum_shared_after_writes' > 'io_sum_shared_before_writes'; + +SELECT current_setting('fsync') = 'off' + OR 'io_sum_shared_after_fsyncs' > 'io_sum_shared_before_fsyncs'; + +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_get_backend_io(pg_backend_pid()) + WHERE object = 'relation' ; + +SELECT 'my_io_sum_shared_after_writes' >= 'my_io_sum_shared_before_writes'; + +SELECT current_setting('fsync') = 'off' + OR 'my_io_sum_shared_after_fsyncs' >= 'my_io_sum_shared_before_fsyncs'; + +SELECT sum(writes) AS writes, sum(fsyncs) AS fsyncs + FROM pg_stat_io + WHERE context = 'normal' AND object = 'wal' ; + +SELECT current_setting('synchronous_commit') = 'on'; + +SELECT 'io_sum_wal_normal_after_writes' > 'io_sum_wal_normal_before_writes'; + +SELECT current_setting('fsync') = 'off' + OR current_setting('wal_sync_method') IN ('open_sync', 'open_datasync') + OR 'io_sum_wal_normal_after_fsyncs' > 'io_sum_wal_normal_before_fsyncs'; + +SELECT sum(reads) AS io_sum_shared_before_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' ; + +BEGIN; + +ALTER TABLE test_io_shared SET TABLESPACE regress_tblspace; + +SELECT COUNT(*) FROM test_io_shared; + +COMMIT; + +SELECT pg_stat_force_next_flush(); + +SELECT sum(reads) AS io_sum_shared_after_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' ; + +SELECT 'io_sum_shared_after_reads' > 'io_sum_shared_before_reads'; + +SELECT sum(hits) AS io_sum_shared_before_hits + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' ; + +BEGIN; + +SET LOCAL enable_nestloop TO on; + +SET LOCAL enable_mergejoin TO off; + +SET LOCAL enable_hashjoin TO off; + +SET LOCAL enable_material TO off; + +SELECT COUNT(*) FROM test_io_shared t1 INNER JOIN test_io_shared t2 USING (a); + +SELECT COUNT(*) FROM test_io_shared t1 INNER JOIN test_io_shared t2 USING (a); + +COMMIT; + +SELECT pg_stat_force_next_flush(); + +SELECT sum(hits) AS io_sum_shared_after_hits + FROM pg_stat_io WHERE context = 'normal' AND object = 'relation' ; + +SELECT 'io_sum_shared_after_hits' > 'io_sum_shared_before_hits'; + +DROP TABLE test_io_shared; + +SET temp_buffers TO 100; + +CREATE TEMPORARY TABLE test_io_local(a int, b TEXT); + +SELECT sum(extends) AS extends, sum(evictions) AS evictions, sum(writes) AS writes + FROM pg_stat_io + WHERE context = 'normal' AND object = 'temp relation' ; + +INSERT INTO test_io_local SELECT generate_series(1, 5000) as id, repeat('a', 200); + +SELECT pg_relation_size('test_io_local') / current_setting('block_size')::int8 > 100; + +SELECT sum(reads) AS io_sum_local_before_reads + FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation' ; + +SELECT COUNT(*) FROM test_io_local; + +SELECT pg_stat_force_next_flush(); + +SELECT sum(evictions) AS evictions, + sum(reads) AS reads, + sum(writes) AS writes, + sum(extends) AS extends + FROM pg_stat_io + WHERE context = 'normal' AND object = 'temp relation' ; + +SELECT 'io_sum_local_after_evictions' > 'io_sum_local_before_evictions', + 'io_sum_local_after_reads' > 'io_sum_local_before_reads', + 'io_sum_local_after_writes' > 'io_sum_local_before_writes', + 'io_sum_local_after_extends' > 'io_sum_local_before_extends'; + +ALTER TABLE test_io_local SET TABLESPACE regress_tblspace; + +SELECT pg_stat_force_next_flush(); + +SELECT sum(writes) AS io_sum_local_new_tblspc_writes + FROM pg_stat_io WHERE context = 'normal' AND object = 'temp relation' ; + +SELECT 'io_sum_local_new_tblspc_writes' > 'io_sum_local_after_writes'; + +RESET temp_buffers; + +SET wal_skip_threshold = '1 kB'; + +SELECT sum(reuses) AS reuses, sum(reads) AS reads, sum(evictions) AS evictions + FROM pg_stat_io WHERE context = 'vacuum' ; + +CREATE TABLE test_io_vac_strategy(a int, b int) WITH (autovacuum_enabled = 'false'); + +INSERT INTO test_io_vac_strategy SELECT i, i from generate_series(1, 4500)i; + +VACUUM (FULL) test_io_vac_strategy; + +VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) test_io_vac_strategy; + +SELECT pg_stat_force_next_flush(); + +SELECT sum(reuses) AS reuses, sum(reads) AS reads, sum(evictions) AS evictions + FROM pg_stat_io WHERE context = 'vacuum' ; + +SELECT 'io_sum_vac_strategy_after_reads' > 'io_sum_vac_strategy_before_reads'; + +SELECT ('io_sum_vac_strategy_after_reuses' + 'io_sum_vac_strategy_after_evictions') > + ('io_sum_vac_strategy_before_reuses' + 'io_sum_vac_strategy_before_evictions'); + +RESET wal_skip_threshold; + +SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_before + FROM pg_stat_io WHERE context = 'bulkwrite' ; + +CREATE TABLE test_io_bulkwrite_strategy AS SELECT i FROM generate_series(1,100)i; + +SELECT pg_stat_force_next_flush(); + +SELECT sum(extends) AS io_sum_bulkwrite_strategy_extends_after + FROM pg_stat_io WHERE context = 'bulkwrite' ; + +SELECT 'io_sum_bulkwrite_strategy_extends_after' > 'io_sum_bulkwrite_strategy_extends_before'; + +SELECT pg_stat_have_stats('io', 0, 0); + +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS io_stats_pre_reset + FROM pg_stat_io ; + +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS my_io_stats_pre_reset + FROM pg_stat_get_backend_io(pg_backend_pid()) ; + +SELECT pg_stat_reset_shared('io'); + +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS io_stats_post_reset + FROM pg_stat_io ; + +SELECT 'io_stats_post_reset' < 'io_stats_pre_reset'; + +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS my_io_stats_post_reset + FROM pg_stat_get_backend_io(pg_backend_pid()) ; + +SELECT 'my_io_stats_pre_reset' <= 'my_io_stats_post_reset'; + +SELECT pg_stat_reset_backend_stats(pg_backend_pid()); + +SELECT sum(evictions) + sum(reuses) + sum(extends) + sum(fsyncs) + sum(reads) + sum(writes) + sum(writebacks) + sum(hits) AS my_io_stats_post_backend_reset + FROM pg_stat_get_backend_io(pg_backend_pid()) ; + +SELECT 'my_io_stats_pre_reset' > 'my_io_stats_post_backend_reset'; + +SELECT pg_stat_get_backend_io(NULL); + +SELECT pg_stat_get_backend_io(0); + +SELECT pg_stat_get_backend_io('checkpointer_pid'); + +CREATE TABLE brin_hot ( + id integer PRIMARY KEY, + val integer NOT NULL +) WITH (autovacuum_enabled = off, fillfactor = 70); + +INSERT INTO brin_hot SELECT *, 0 FROM generate_series(1, 235); + +CREATE INDEX val_brin ON brin_hot using brin(val); + +CREATE FUNCTION wait_for_hot_stats() RETURNS void AS $$ +DECLARE + start_time timestamptz := clock_timestamp(); + updated bool; +BEGIN + -- we don't want to wait forever; loop will exit after 30 seconds + FOR i IN 1 .. 300 LOOP + SELECT (pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid) > 0) INTO updated; + EXIT WHEN updated; + + -- wait a little + PERFORM pg_sleep_for('100 milliseconds'); + -- reset stats snapshot so we can test again + PERFORM pg_stat_clear_snapshot(); + END LOOP; + -- report time waited in postmaster log (where it won't change test output) + RAISE log 'wait_for_hot_stats delayed % seconds', + EXTRACT(epoch FROM clock_timestamp() - start_time); +END +$$ LANGUAGE plpgsql; + +UPDATE brin_hot SET val = -3 WHERE id = 42; + +SELECT wait_for_hot_stats(); + +SELECT pg_stat_get_tuples_hot_updated('brin_hot'::regclass::oid); + +DROP TABLE brin_hot; + +DROP FUNCTION wait_for_hot_stats(); + +CREATE TABLE brin_hot_2 (a int, b int); + +INSERT INTO brin_hot_2 VALUES (1, 100); + +CREATE INDEX ON brin_hot_2 USING brin (b) WHERE a = 2; + +UPDATE brin_hot_2 SET a = 2; + +SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100; + +SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100; + +SET enable_seqscan = off; + +SELECT * FROM brin_hot_2 WHERE a = 2 AND b = 100; + +SELECT COUNT(*) FROM brin_hot_2 WHERE a = 2 AND b = 100; + +DROP TABLE brin_hot_2; + +CREATE TABLE brin_hot_3 (a int, filler text) WITH (fillfactor = 10); + +INSERT INTO brin_hot_3 SELECT 1, repeat(' ', 500) FROM generate_series(1, 20); + +CREATE INDEX ON brin_hot_3 USING brin (a) WITH (pages_per_range = 1); + +UPDATE brin_hot_3 SET a = 2; + +SELECT * FROM brin_hot_3 WHERE a = 2; + +SELECT COUNT(*) FROM brin_hot_3 WHERE a = 2; + +DROP TABLE brin_hot_3; + +SET enable_seqscan = on; + +CREATE TABLE table_fillfactor ( + n char(1000) +) with (fillfactor=10, autovacuum_enabled=off); + +INSERT INTO table_fillfactor +SELECT 'x' FROM generate_series(1,1000); + +SELECT * FROM check_estimated_rows('SELECT * FROM table_fillfactor'); + +DROP TABLE table_fillfactor; diff --git a/crates/pgt_pretty_print/tests/data/multi/stats_ext_60.sql b/crates/pgt_pretty_print/tests/data/multi/stats_ext_60.sql new file mode 100644 index 000000000..c464ce0c3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/stats_ext_60.sql @@ -0,0 +1,1865 @@ +create function check_estimated_rows(text) returns table (estimated int, actual int) +language plpgsql as +$$ +declare + ln text; + tmp text[]; + first_row bool := true; +begin + for ln in + execute format('explain analyze %s', $1) + loop + if first_row then + first_row := false; + tmp := regexp_match(ln, 'rows=(\d*) .* rows=(\d*)'); + return query select tmp[1]::int, tmp[2]::int; + end if; + end loop; +end; +$$; + +CREATE TABLE ext_stats_test (x text, y int, z int); + +CREATE STATISTICS tst ON a, b FROM nonexistent; + +CREATE STATISTICS tst ON a, b FROM ext_stats_test; + +CREATE STATISTICS tst ON x, x, y FROM ext_stats_test; + +CREATE STATISTICS tst ON x, x, y, x, x, y, x, x, y FROM ext_stats_test; + +CREATE STATISTICS tst ON x, x, y, x, x, (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1) FROM ext_stats_test; + +CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1), (x || 'x'), (x || 'x'), (y + 1) FROM ext_stats_test; + +CREATE STATISTICS tst ON (x || 'x'), (x || 'x'), y FROM ext_stats_test; + +CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test; + +CREATE STATISTICS tst ON a FROM (VALUES (x)) AS foo; + +CREATE STATISTICS tst ON a FROM foo NATURAL JOIN bar; + +CREATE STATISTICS tst ON a FROM (SELECT * FROM ext_stats_test) AS foo; + +CREATE STATISTICS tst ON a FROM ext_stats_test s TABLESAMPLE system (x); + +CREATE STATISTICS tst ON a FROM XMLTABLE('foo' PASSING 'bar' COLUMNS a text); + +CREATE STATISTICS tst ON a FROM JSON_TABLE(jsonb '123', '$' COLUMNS (item int)); + +CREATE FUNCTION tftest(int) returns table(a int, b int) as $$ +SELECT $1, $1+i FROM generate_series(1,5) g(i); +$$ LANGUAGE sql IMMUTABLE STRICT; + +CREATE STATISTICS alt_stat2 ON a FROM tftest(1); + +DROP FUNCTION tftest; + +CREATE STATISTICS tst ON (y) FROM ext_stats_test; + +DROP TABLE ext_stats_test; + +CREATE STATISTICS tst on z from ext_stats_test1; + +CREATE STATISTICS tst on (z) from ext_stats_test1; + +CREATE STATISTICS tst on (z+1) from ext_stats_test1; + +CREATE STATISTICS tst (ndistinct) ON z from ext_stats_test1; + +CREATE STATISTICS tst on tableoid from ext_stats_test1; + +CREATE STATISTICS tst on (tableoid) from ext_stats_test1; + +CREATE STATISTICS tst on (tableoid::int+1) from ext_stats_test1; + +CREATE STATISTICS tst (ndistinct) ON xmin from ext_stats_test1; + +CREATE STATISTICS tst (ndistinct) ON w from ext_stats_test1; + +DROP TABLE ext_stats_test1; + +CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER); + +CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1; + +COMMENT ON STATISTICS ab1_a_b_stats IS 'new comment'; + +CREATE ROLE regress_stats_ext; + +SET SESSION AUTHORIZATION regress_stats_ext; + +COMMENT ON STATISTICS ab1_a_b_stats IS 'changed comment'; + +DROP STATISTICS ab1_a_b_stats; + +ALTER STATISTICS ab1_a_b_stats RENAME TO ab1_a_b_stats_new; + +RESET SESSION AUTHORIZATION; + +DROP ROLE regress_stats_ext; + +CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1; + +DROP STATISTICS ab1_a_b_stats; + +CREATE SCHEMA regress_schema_2; + +CREATE STATISTICS regress_schema_2.ab1_a_b_stats ON a, b FROM ab1; + +SELECT pg_get_statisticsobjdef(oid) FROM pg_statistic_ext WHERE stxname = 'ab1_a_b_stats'; + +DROP STATISTICS regress_schema_2.ab1_a_b_stats; + +CREATE STATISTICS ab1_b_c_stats ON b, c FROM ab1; + +CREATE STATISTICS ab1_a_b_c_stats ON a, b, c FROM ab1; + +CREATE STATISTICS ab1_b_a_stats ON b, a FROM ab1; + +ALTER TABLE ab1 DROP COLUMN a; + +SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%'; + +DROP TABLE ab1; + +SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%'; + +CREATE TABLE ab1 (a INTEGER, b INTEGER); + +ALTER TABLE ab1 ALTER a SET STATISTICS 0; + +INSERT INTO ab1 SELECT a, a%23 FROM generate_series(1, 1000) a; + +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1; + +ANALYZE ab1; + +ALTER TABLE ab1 ALTER a SET STATISTICS -1; + +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0; + +ANALYZE ab1; + +SELECT stxname, stxdndistinct, stxddependencies, stxdmcv, stxdinherit + FROM pg_statistic_ext s LEFT JOIN pg_statistic_ext_data d ON (d.stxoid = s.oid) + WHERE s.stxname = 'ab1_a_b_stats'; + +ALTER STATISTICS ab1_a_b_stats SET STATISTICS -1; + +ANALYZE ab1 (a); + +ANALYZE ab1; + +DROP TABLE ab1; + +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0; + +ALTER STATISTICS IF EXISTS ab1_a_b_stats SET STATISTICS 0; + +CREATE TABLE ab1 (a INTEGER, b INTEGER); + +CREATE TABLE ab1c () INHERITS (ab1); + +INSERT INTO ab1 VALUES (1,1); + +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1; + +ANALYZE ab1; + +DROP TABLE ab1 CASCADE; + +CREATE TABLE stxdinh(a int, b int); + +CREATE TABLE stxdinh1() INHERITS(stxdinh); + +CREATE TABLE stxdinh2() INHERITS(stxdinh); + +INSERT INTO stxdinh SELECT mod(a,50), mod(a,100) FROM generate_series(0, 1999) a; + +INSERT INTO stxdinh1 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a; + +INSERT INTO stxdinh2 SELECT mod(a,100), mod(a,100) FROM generate_series(0, 999) a; + +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2; + +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2'); + +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0'); + +CREATE STATISTICS stxdinh ON a, b FROM stxdinh; + +VACUUM ANALYZE stxdinh, stxdinh1, stxdinh2; + +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* GROUP BY 1, 2'); + +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinh* WHERE a = 0 AND b = 0'); + +SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh GROUP BY 1, 2'); + +SELECT * FROM check_estimated_rows('SELECT a, b FROM ONLY stxdinh WHERE a = 0 AND b = 0'); + +DROP TABLE stxdinh, stxdinh1, stxdinh2; + +CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i); + +CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100); + +INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a; + +CREATE STATISTICS stxdinp ON (a + 1), a, b FROM stxdinp; + +VACUUM ANALYZE stxdinp; + +SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass; + +SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2'); + +SELECT * FROM check_estimated_rows('SELECT a + 1, b FROM ONLY stxdinp GROUP BY 1, 2'); + +DROP TABLE stxdinp; + +CREATE TABLE ab1 (a INTEGER, b INTEGER, c TIMESTAMP, d TIMESTAMPTZ); + +CREATE STATISTICS ab1_exprstat_1 ON (a+b) FROM ab1; + +CREATE STATISTICS ab1_exprstat_2 ON (a+b) FROM ab1; + +SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_2'; + +CREATE STATISTICS ab1_exprstat_3 ON (a+b), a FROM ab1; + +SELECT stxkind FROM pg_statistic_ext WHERE stxname = 'ab1_exprstat_3'; + +CREATE STATISTICS ab1_exprstat_4 ON date_trunc('day', d) FROM ab1; + +CREATE STATISTICS ab1_exprstat_5 ON date_trunc('day', c) FROM ab1; + +CREATE STATISTICS ab1_exprstat_6 ON + (case a when 1 then true else false end), b FROM ab1; + +INSERT INTO ab1 +SELECT x / 10, x / 3, + '2020-10-01'::timestamp + x * interval '1 day', + '2020-10-01'::timestamptz + x * interval '1 day' +FROM generate_series(1, 100) x; + +ANALYZE ab1; + +SELECT * FROM check_estimated_rows('SELECT * FROM ab1 WHERE (case a when 1 then true else false end) AND b=2'); + +DROP TABLE ab1; + +CREATE schema tststats; + +CREATE TABLE tststats.t (a int, b int, c text); + +CREATE INDEX ti ON tststats.t (a, b); + +CREATE SEQUENCE tststats.s; + +CREATE VIEW tststats.v AS SELECT * FROM tststats.t; + +CREATE MATERIALIZED VIEW tststats.mv AS SELECT * FROM tststats.t; + +CREATE TYPE tststats.ty AS (a int, b int, c text); + +CREATE FOREIGN DATA WRAPPER extstats_dummy_fdw; + +CREATE SERVER extstats_dummy_srv FOREIGN DATA WRAPPER extstats_dummy_fdw; + +CREATE FOREIGN TABLE tststats.f (a int, b int, c text) SERVER extstats_dummy_srv; + +CREATE TABLE tststats.pt (a int, b int, c text) PARTITION BY RANGE (a, b); + +CREATE TABLE tststats.pt1 PARTITION OF tststats.pt FOR VALUES FROM (-10, -10) TO (10, 10); + +CREATE STATISTICS tststats.s1 ON a, b FROM tststats.t; + +CREATE STATISTICS tststats.s2 ON a, b FROM tststats.ti; + +CREATE STATISTICS tststats.s3 ON a, b FROM tststats.s; + +CREATE STATISTICS tststats.s4 ON a, b FROM tststats.v; + +CREATE STATISTICS tststats.s5 ON a, b FROM tststats.mv; + +CREATE STATISTICS tststats.s6 ON a, b FROM tststats.ty; + +CREATE STATISTICS tststats.s7 ON a, b FROM tststats.f; + +CREATE STATISTICS tststats.s8 ON a, b FROM tststats.pt; + +CREATE STATISTICS tststats.s9 ON a, b FROM tststats.pt1; + +DO $$ +DECLARE + relname text := reltoastrelid::regclass FROM pg_class WHERE oid = 'tststats.t'::regclass; +BEGIN + EXECUTE 'CREATE STATISTICS tststats.s10 ON a, b FROM ' || relname; +EXCEPTION WHEN wrong_object_type THEN + RAISE NOTICE 'stats on toast table not created'; +END; +$$; + +DROP SCHEMA tststats CASCADE; + +DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE; + +CREATE TABLE ndistinct ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b INT, + filler3 DATE, + c INT, + d INT +) +WITH (autovacuum_enabled = off); + +INSERT INTO ndistinct (a, b, c, filler1) + SELECT i/100, i/100, i/100, (i/100) || ' dollars and zero cents' + FROM generate_series(1,1000) s(i); + +ANALYZE ndistinct; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)'); + +CREATE STATISTICS s10 ON a, b, c FROM ndistinct; + +ANALYZE ndistinct; + +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + +TRUNCATE TABLE ndistinct; + +INSERT INTO ndistinct (a, b, c, filler1) + SELECT mod(i,13), mod(i,17), mod(i,19), + mod(i,23) || ' dollars and zero cents' + FROM generate_series(1,1000) s(i); + +ANALYZE ndistinct; + +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)'); + +DROP STATISTICS s10; + +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (a+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)'); + +CREATE STATISTICS s10 (ndistinct) ON (a+1), (b+100), (2*c) FROM ndistinct; + +ANALYZE ndistinct; + +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a+1), (b+100), (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (a+1), (b+100)'); + +DROP STATISTICS s10; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)'); + +CREATE STATISTICS s10 (ndistinct) ON a, b, (2*c) FROM ndistinct; + +ANALYZE ndistinct; + +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (2*c)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (2*c)'); + +DROP STATISTICS s10; + +TRUNCATE ndistinct; + +INSERT INTO ndistinct (a, b, c, d) + SELECT mod(i,3), mod(i,9), mod(i,5), mod(i,20) + FROM generate_series(1,1000) s(i); + +ANALYZE ndistinct; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)'); + +CREATE STATISTICS s11 (ndistinct) ON a, b FROM ndistinct; + +CREATE STATISTICS s12 (ndistinct) ON c, d FROM ndistinct; + +ANALYZE ndistinct; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)'); + +DROP STATISTICS s12; + +CREATE STATISTICS s12 (ndistinct) ON (c * 10), (d - 1) FROM ndistinct; + +ANALYZE ndistinct; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)'); + +DROP STATISTICS s12; + +CREATE STATISTICS s12 (ndistinct) ON c, d, (c * 10), (d - 1) FROM ndistinct; + +ANALYZE ndistinct; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)'); + +DROP STATISTICS s11; + +CREATE STATISTICS s11 (ndistinct) ON a, b, (a*5), (b+1) FROM ndistinct; + +ANALYZE ndistinct; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)'); + +DROP STATISTICS s11; + +DROP STATISTICS s12; + +CREATE STATISTICS s11 (ndistinct) ON a, b, (a*5), (b+1) FROM ndistinct; + +CREATE STATISTICS s12 (ndistinct) ON a, (b+1), (c * 10) FROM ndistinct; + +ANALYZE ndistinct; + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), b'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY (a*5), (b+1), c'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, (c*10)'); + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, (b+1), c, (d - 1)'); + +DROP STATISTICS s11; + +DROP STATISTICS s12; + +CREATE TABLE functional_dependencies ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b TEXT, + filler3 DATE, + c INT, + d TEXT +) +WITH (autovacuum_enabled = off); + +CREATE INDEX fdeps_ab_idx ON functional_dependencies (a, b); + +CREATE INDEX fdeps_abc_idx ON functional_dependencies (a, b, c); + +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT mod(i, 5), mod(i, 7), mod(i, 11), i FROM generate_series(1,1000) s(i); + +ANALYZE functional_dependencies; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + +CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies; + +ANALYZE functional_dependencies; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + +TRUNCATE functional_dependencies; + +DROP STATISTICS func_deps_stat; + +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,5000) s(i); + +ANALYZE functional_dependencies; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1 AND mod(c, 7) = 1'); + +CREATE STATISTICS func_deps_stat (dependencies) ON (mod(a,11)), (mod(b::int, 13)), (mod(c, 7)) FROM functional_dependencies; + +ANALYZE functional_dependencies; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE mod(a, 11) = 1 AND mod(b::int, 13) = 1 AND mod(c, 7) = 1'); + +TRUNCATE functional_dependencies; + +DROP STATISTICS func_deps_stat; + +INSERT INTO functional_dependencies (a, b, c, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), i FROM generate_series(1,5000) s(i); + +ANALYZE functional_dependencies; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c IN (1)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 27, 51, 52, 76, 77) AND b IN (''1'', ''2'', ''26'', ''27'') AND c IN (1, 2)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1'') AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = ANY (ARRAY[1])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 26, 27, 51, 52, 76, 77]) AND b = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND c = ANY (ARRAY[1, 2])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1, 51]) AND b > ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1, 51]) AND b <= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1, 2, 51, 52]) AND b >= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ALL (ARRAY[''1'', ''2''])'); + +CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies; + +ANALYZE functional_dependencies; + +SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat'; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 26, 51, 76) AND b IN (''1'', ''26'') AND c IN (1)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 26, 27, 51, 52, 76, 77) AND b IN (''1'', ''2'', ''26'', ''27'') AND c IN (1, 2)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 51) AND (b = ''1'' OR b = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR a = 2 OR a = 51 OR a = 52) AND (b = ''1'' OR b = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a = 1 OR b = ''1'') AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 51]) AND b = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 26, 51, 76]) AND b = ANY (ARRAY[''1'', ''26'']) AND c = ANY (ARRAY[1])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = ANY (ARRAY[1, 2, 26, 27, 51, 52, 76, 77]) AND b = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND c = ANY (ARRAY[1, 2])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a < ANY (ARRAY[1, 51]) AND b > ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a >= ANY (ARRAY[1, 51]) AND b <= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a <= ANY (ARRAY[1, 2, 51, 52]) AND b >= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 51) AND b = ALL (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a IN (1, 2, 51, 52) AND b = ALL (ARRAY[''1'', ''2''])'); + +ALTER TABLE functional_dependencies ALTER COLUMN c TYPE numeric; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + +ANALYZE functional_dependencies; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + +DROP STATISTICS func_deps_stat; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'' AND (c + 1) = 2'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) = 2'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) IN (2)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 52, 54, 102, 104, 152, 154) AND upper(b) IN (''1'', ''2'', ''26'', ''27'') AND (c + 1) IN (2, 3)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND (upper(b) = ''1'' OR upper(b) = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 4 OR (a * 2) = 102 OR (a * 2) = 104) AND (upper(b) = ''1'' OR upper(b) = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR upper(b) = ''1'') AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 102, 104]) AND upper(b) = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = 2'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = ANY (ARRAY[2])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 52, 54, 102, 104, 152, 154]) AND upper(b) = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND (c + 1) = ANY (ARRAY[2, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (ARRAY[2, 102]) AND upper(b) > ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (ARRAY[2, 102]) AND upper(b) <= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (ARRAY[2, 4, 102, 104]) AND upper(b) >= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ALL (ARRAY[''1'', ''2''])'); + +CREATE STATISTICS func_deps_stat (dependencies) ON (a * 2), upper(b), (c + 1) FROM functional_dependencies; + +ANALYZE functional_dependencies; + +SELECT dependencies FROM pg_stats_ext WHERE statistics_name = 'func_deps_stat'; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = 2 AND upper(b) = ''1'' AND (c + 1) = 2'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) IN (''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) = 2'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 52, 102, 152) AND upper(b) IN (''1'', ''26'') AND (c + 1) IN (2)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 52, 54, 102, 104, 152, 154) AND upper(b) IN (''1'', ''2'', ''26'', ''27'') AND (c + 1) IN (2, 3)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 102) AND (upper(b) = ''1'' OR upper(b) = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR (a * 2) = 4 OR (a * 2) = 102 OR (a * 2) = 104) AND (upper(b) = ''1'' OR upper(b) = ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE ((a * 2) = 2 OR upper(b) = ''1'') AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 102]) AND upper(b) = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 102, 104]) AND upper(b) = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = 2'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 52, 102, 152]) AND upper(b) = ANY (ARRAY[''1'', ''26'']) AND (c + 1) = ANY (ARRAY[2])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) = ANY (ARRAY[2, 4, 52, 54, 102, 104, 152, 154]) AND upper(b) = ANY (ARRAY[''1'', ''2'', ''26'', ''27'']) AND (c + 1) = ANY (ARRAY[2, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) < ANY (ARRAY[2, 102]) AND upper(b) > ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) >= ANY (ARRAY[2, 102]) AND upper(b) <= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) <= ANY (ARRAY[2, 4, 102, 104]) AND upper(b) >= ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 102) AND upper(b) = ALL (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE (a * 2) IN (2, 4, 102, 104) AND upper(b) = ALL (ARRAY[''1'', ''2''])'); + +CREATE TABLE functional_dependencies_multi ( + a INTEGER, + b INTEGER, + c INTEGER, + d INTEGER +) +WITH (autovacuum_enabled = off); + +INSERT INTO functional_dependencies_multi (a, b, c, d) + SELECT + mod(i,7), + mod(i,7), + mod(i,11), + mod(i,11) + FROM generate_series(1,5000) s(i); + +ANALYZE functional_dependencies_multi; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0 = b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b = 0 AND 0 = c AND d = 0'); + +CREATE STATISTICS functional_dependencies_multi_1 (dependencies) ON a, b FROM functional_dependencies_multi; + +CREATE STATISTICS functional_dependencies_multi_2 (dependencies) ON c, d FROM functional_dependencies_multi; + +ANALYZE functional_dependencies_multi; + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND 0 = b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies_multi WHERE 0 = a AND b = 0 AND 0 = c AND d = 0'); + +DROP TABLE functional_dependencies_multi; + +CREATE TABLE mcv_lists ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b VARCHAR, + filler3 DATE, + c INT, + d TEXT, + ia INT[] +) +WITH (autovacuum_enabled = off); + +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT mod(i,37), mod(i,41), mod(i,43), mod(i,47) FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +TRUNCATE mcv_lists; + +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,1000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1 AND mod(c,13) = 1'); + +CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a,7)), (mod(b::int,11)), (mod(c,13)) FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,7) = 1 AND mod(b::int,11) = 1 AND mod(c,13) = 1'); + +TRUNCATE mcv_lists; + +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, ia, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), array[mod(i,25)], i + FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b IN ( ''1'', ''2'', NULL)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2'', NULL])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3]) AND b IN (''1'', ''2'', NULL, ''3'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3, NULL])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', NULL, ''3'') AND c > ANY (ARRAY[1, 2, NULL, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)'); + +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c, ia FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = a AND ''1'' = b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > a AND ''1'' > b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 0 >= a AND ''0'' >= b'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND ''1'' > b AND 5 > c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 4 >= a AND ''0'' >= b AND 4 >= c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''1'' OR c = 1 OR d IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52) AND b IN ( ''1'', ''2'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (1, 2, 51, 52, NULL) AND b IN ( ''1'', ''2'', NULL)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2''])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[NULL, 1, 2, 51, 52]) AND b = ANY (ARRAY[''1'', ''2'', NULL])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, 2, 3]) AND b IN (''1'', ''2'', ''3'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= ANY (ARRAY[1, NULL, 2, 3]) AND b IN (''1'', ''2'', NULL, ''3'')'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND c > ANY (ARRAY[1, 2, 3, NULL])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', ''3'') AND c > ANY (ARRAY[1, 2, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < ALL (ARRAY[4, 5]) AND b IN (''1'', ''2'', NULL, ''3'') AND c > ANY (ARRAY[1, 2, NULL, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = ANY (ARRAY[4,5]) AND 4 = ANY(ia)'); + +ALTER TABLE mcv_lists ALTER COLUMN d TYPE VARCHAR(64); + +SELECT d.stxdmcv IS NOT NULL + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid; + +ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +TRUNCATE mcv_lists; + +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT i, i, i, i FROM generate_series(1,1000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])'); + +CREATE STATISTICS mcv_lists_stats_1 ON (mod(a,20)) FROM mcv_lists; + +CREATE STATISTICS mcv_lists_stats_2 ON (mod(b::int,10)) FROM mcv_lists; + +CREATE STATISTICS mcv_lists_stats_3 ON (mod(c,5)) FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])'); + +DROP STATISTICS mcv_lists_stats_1; + +DROP STATISTICS mcv_lists_stats_2; + +DROP STATISTICS mcv_lists_stats_3; + +CREATE STATISTICS mcv_lists_stats (mcv) ON (mod(a,20)), (mod(b::int,10)), (mod(c,5)) FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 = mod(a,20) AND 1 = mod(b::int,10)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < 1 AND mod(b::int,10) < 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE 1 > mod(a,20) AND 1 > mod(b::int,10)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 AND mod(b::int,10) = 1 AND mod(c,5) = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,25) = 1 OR d IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) IN (1, 2, 51, 52, NULL) AND mod(b::int,10) IN ( 1, 2, NULL)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = ANY (ARRAY[1, 2, 51, 52]) AND mod(b::int,10) = ANY (ARRAY[1, 2])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) <= ANY (ARRAY[1, NULL, 2, 3]) AND mod(b::int,10) IN (1, 2, NULL, 3)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) < ALL (ARRAY[4, 5]) AND mod(b::int,10) IN (1, 2, 3) AND mod(c,5) > ANY (ARRAY[1, 2, 3])'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE mod(a,20) = 1 OR mod(b::int,10) = 1 OR mod(c,5) = 1 OR d IS NOT NULL'); + +TRUNCATE mcv_lists; + +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT + (CASE WHEN mod(i,100) = 1 THEN NULL ELSE mod(i,100) END), + (CASE WHEN mod(i,50) = 1 THEN NULL ELSE mod(i,50) END), + (CASE WHEN mod(i,25) = 1 THEN NULL ELSE mod(i,25) END), + i + FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND c IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''1'')'); + +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NOT NULL AND b IS NULL AND c IS NOT NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IN (0, 1) AND b IN (''0'', ''1'')'); + +TRUNCATE mcv_lists; + +INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1,1000) s(i); + +ANALYZE mcv_lists; + +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid; + +TRUNCATE mcv_lists; + +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, d) + SELECT + NULL, -- always NULL + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 0 END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END) + FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d = ''x'')'); + +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, d FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 OR b = ''x'' OR d = ''x'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND (b = ''x'' OR d = ''x'')'); + +CREATE TABLE mcv_lists_uuid ( + a UUID, + b UUID, + c UUID +) +WITH (autovacuum_enabled = off); + +INSERT INTO mcv_lists_uuid (a, b, c) + SELECT + fipshash(mod(i,100)::text)::uuid, + fipshash(mod(i,50)::text)::uuid, + fipshash(mod(i,25)::text)::uuid + FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists_uuid; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND c = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'''); + +CREATE STATISTICS mcv_lists_uuid_stats (mcv) ON a, b, c + FROM mcv_lists_uuid; + +ANALYZE mcv_lists_uuid; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_uuid WHERE a = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND b = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'' AND c = ''e7f6c011-776e-8db7-cd33-0b54174fd76f'''); + +DROP TABLE mcv_lists_uuid; + +CREATE TABLE mcv_lists_arrays ( + a TEXT[], + b NUMERIC[], + c INT[] +) +WITH (autovacuum_enabled = off); + +INSERT INTO mcv_lists_arrays (a, b, c) + SELECT + ARRAY[fipshash((i/100)::text), fipshash((i/100-1)::text), fipshash((i/100+1)::text)], + ARRAY[(i/100-1)::numeric/1000, (i/100)::numeric/1000, (i/100+1)::numeric/1000], + ARRAY[(i/100-1), i/100, (i/100+1)] + FROM generate_series(1,5000) s(i); + +CREATE STATISTICS mcv_lists_arrays_stats (mcv) ON a, b, c + FROM mcv_lists_arrays; + +ANALYZE mcv_lists_arrays; + +CREATE TABLE mcv_lists_bool ( + a BOOL, + b BOOL, + c BOOL +) +WITH (autovacuum_enabled = off); + +INSERT INTO mcv_lists_bool (a, b, c) + SELECT + (mod(i,2) = 0), (mod(i,4) = 0), (mod(i,8) = 0) + FROM generate_series(1,10000) s(i); + +ANALYZE mcv_lists_bool; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c'); + +CREATE STATISTICS mcv_lists_bool_stats (mcv) ON a, b, c + FROM mcv_lists_bool; + +ANALYZE mcv_lists_bool; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c'); + +CREATE TABLE mcv_lists_partial ( + a INT, + b INT, + c INT +); + +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + mod(i,10), + mod(i,10), + mod(i,10) + FROM generate_series(0,999) s(i); + +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + i, + i, + i + FROM generate_series(0,99) s(i); + +INSERT INTO mcv_lists_partial (a, b, c) + SELECT + i, + i, + i + FROM generate_series(0,3999) s(i); + +ANALYZE mcv_lists_partial; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)'); + +CREATE STATISTICS mcv_lists_partial_stats (mcv) ON a, b, c + FROM mcv_lists_partial; + +ANALYZE mcv_lists_partial; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 AND b = 10 AND c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 10 OR b = 10 OR c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 AND b = 0 AND c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE a = 0 OR b = 0 OR c = 10'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0 AND c = 0) OR (a = 1 AND b = 1 AND c = 1) OR (a = 2 AND b = 2 AND c = 2)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_partial WHERE (a = 0 AND b = 0) OR (a = 0 AND c = 0) OR (b = 0 AND c = 0)'); + +DROP TABLE mcv_lists_partial; + +CREATE TABLE mcv_lists_multi ( + a INTEGER, + b INTEGER, + c INTEGER, + d INTEGER +) +WITH (autovacuum_enabled = off); + +INSERT INTO mcv_lists_multi (a, b, c, d) + SELECT + mod(i,5), + mod(i,5), + mod(i,7), + mod(i,7) + FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists_multi; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c = 0 AND d = 0)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 OR d = 0'); + +CREATE STATISTICS mcv_lists_multi_1 (mcv) ON a, b FROM mcv_lists_multi; + +CREATE STATISTICS mcv_lists_multi_2 (mcv) ON c, d FROM mcv_lists_multi; + +ANALYZE mcv_lists_multi; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 AND c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE b = 0 OR c = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 AND b = 0 AND c = 0 AND d = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE (a = 0 AND b = 0) OR (c = 0 AND d = 0)'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 OR d = 0'); + +DROP TABLE mcv_lists_multi; + +CREATE TABLE expr_stats (a int, b int, c int); + +INSERT INTO expr_stats SELECT mod(i,10), mod(i,10), mod(i,10) FROM generate_series(1,1000) s(i); + +ANALYZE expr_stats; + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0'); + +CREATE STATISTICS expr_stats_1 (mcv) ON (a+b), (a-b), (2*a), (3*b) FROM expr_stats; + +ANALYZE expr_stats; + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (2*a) = 0 AND (3*b) = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE (a+b) = 0 AND (a-b) = 0'); + +DROP STATISTICS expr_stats_1; + +DROP TABLE expr_stats; + +CREATE TABLE expr_stats (a int, b int, c int); + +INSERT INTO expr_stats SELECT mod(i,10), mod(i,10), mod(i,10) FROM generate_series(1,1000) s(i); + +ANALYZE expr_stats; + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0'); + +CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (2*a), (3*b), (a+b), (a-b) FROM expr_stats; + +ANALYZE expr_stats; + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (2*a) = 0 AND (3*b) = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 3 AND b = 3 AND (a-b) = 0'); + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND b = 1 AND (a-b) = 0'); + +DROP TABLE expr_stats; + +CREATE TABLE expr_stats (a int, b name, c text); + +INSERT INTO expr_stats SELECT mod(i,10), fipshash(mod(i,10)::text), fipshash(mod(i,10)::text) FROM generate_series(1,1000) s(i); + +ANALYZE expr_stats; + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AND (c || b) >= ''0'''); + +CREATE STATISTICS expr_stats_1 (mcv) ON a, b, (b || c), (c || b) FROM expr_stats; + +ANALYZE expr_stats; + +SELECT * FROM check_estimated_rows('SELECT * FROM expr_stats WHERE a = 0 AND (b || c) <= ''z'' AND (c || b) >= ''0'''); + +DROP TABLE expr_stats; + +CREATE TABLE expr_stats_incompatible_test ( + c0 double precision, + c1 boolean NOT NULL +); + +CREATE STATISTICS expr_stat_comp_1 ON c0, c1 FROM expr_stats_incompatible_test; + +INSERT INTO expr_stats_incompatible_test VALUES (1234,false), (5678,true); + +ANALYZE expr_stats_incompatible_test; + +SELECT c0 FROM ONLY expr_stats_incompatible_test WHERE +( + upper('x') LIKE ('x'||('[0,1]'::int4range)) + AND + (c0 IN (0, 1) OR c1) +); + +DROP TABLE expr_stats_incompatible_test; + +CREATE SCHEMA tststats; + +CREATE TABLE tststats.priv_test_tbl ( + a int, + b int +); + +INSERT INTO tststats.priv_test_tbl + SELECT mod(i,5), mod(i,10) FROM generate_series(1,100) s(i); + +CREATE STATISTICS tststats.priv_test_stats (mcv) ON a, b + FROM tststats.priv_test_tbl; + +ANALYZE tststats.priv_test_tbl; + +create table stts_t1 (a int, b int); + +create statistics (ndistinct) on a, b from stts_t1; + +create statistics (ndistinct, dependencies) on a, b from stts_t1; + +create statistics (ndistinct, dependencies, mcv) on a, b from stts_t1; + +create table stts_t2 (a int, b int, c int); + +create statistics on b, c from stts_t2; + +create table stts_t3 (col1 int, col2 int, col3 int); + +create statistics stts_hoge on col1, col2, col3 from stts_t3; + +create schema stts_s1; + +create schema stts_s2; + +create statistics stts_s1.stts_foo on col1, col2 from stts_t3; + +create statistics stts_s2.stts_yama (dependencies, mcv) on col1, col3 from stts_t3; + +insert into stts_t1 select i,i from generate_series(1,100) i; + +analyze stts_t1; + +set search_path to public, stts_s1, stts_s2, tststats; + +create statistics (mcv) ON a, b, (a+b), (a-b) FROM stts_t1; + +create statistics (mcv) ON a, b, (a+b), (a-b) FROM stts_t1; + +create statistics (mcv) ON (a+b), (a-b) FROM stts_t1; + +drop statistics stts_t1_a_b_expr_expr_stat; + +drop statistics stts_t1_a_b_expr_expr_stat1; + +drop statistics stts_t1_expr_expr_stat; + +set search_path to public, stts_s1; + +create role regress_stats_ext nosuperuser; + +set role regress_stats_ext; + +reset role; + +drop table stts_t1, stts_t2, stts_t3; + +drop schema stts_s1, stts_s2 cascade; + +drop user regress_stats_ext; + +reset search_path; + +CREATE USER regress_stats_user1; + +GRANT USAGE ON SCHEMA tststats TO regress_stats_user1; + +SET SESSION AUTHORIZATION regress_stats_user1; + +SELECT * FROM tststats.priv_test_tbl; + +SELECT * FROM tststats.priv_test_tbl + WHERE a = 1 and tststats.priv_test_tbl.* > (1, 1) is not null; + +CREATE FUNCTION op_leak(int, int) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql; + +CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, + restrict = scalarltsel); + +CREATE FUNCTION op_leak(record, record) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql; + +CREATE OPERATOR <<< (procedure = op_leak, leftarg = record, rightarg = record, + restrict = scalarltsel); + +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; + +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 OR b <<< 0; + +SELECT * FROM tststats.priv_test_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL); + +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; + +RESET SESSION AUTHORIZATION; + +CREATE VIEW tststats.priv_test_view WITH (security_barrier=true) + AS SELECT * FROM tststats.priv_test_tbl WHERE false; + +GRANT SELECT, DELETE ON tststats.priv_test_view TO regress_stats_user1; + +SET SESSION AUTHORIZATION regress_stats_user1; + +SELECT * FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0; + +SELECT * FROM tststats.priv_test_view WHERE a <<< 0 OR b <<< 0; + +SELECT * FROM tststats.priv_test_view t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL); + +DELETE FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0; + +RESET SESSION AUTHORIZATION; + +ALTER TABLE tststats.priv_test_tbl ENABLE ROW LEVEL SECURITY; + +CREATE POLICY priv_test_tbl_pol ON tststats.priv_test_tbl USING (2 * a < 0); + +GRANT SELECT, DELETE ON tststats.priv_test_tbl TO regress_stats_user1; + +SET SESSION AUTHORIZATION regress_stats_user1; + +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; + +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 OR b <<< 0; + +SELECT * FROM tststats.priv_test_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL); + +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; + +RESET SESSION AUTHORIZATION; + +CREATE TABLE tststats.priv_test_parent_tbl (a int, b int); + +ALTER TABLE tststats.priv_test_tbl INHERIT tststats.priv_test_parent_tbl; + +SET SESSION AUTHORIZATION regress_stats_user1; + +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0; + +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 OR b <<< 0; + +SELECT * FROM tststats.priv_test_parent_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL); + +DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0; + +RESET SESSION AUTHORIZATION; + +ALTER TABLE tststats.priv_test_parent_tbl ENABLE ROW LEVEL SECURITY; + +CREATE POLICY priv_test_parent_tbl_pol ON tststats.priv_test_parent_tbl USING (2 * a < 0); + +GRANT SELECT, DELETE ON tststats.priv_test_parent_tbl TO regress_stats_user1; + +SET SESSION AUTHORIZATION regress_stats_user1; + +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0; + +SELECT * FROM tststats.priv_test_parent_tbl WHERE a <<< 0 OR b <<< 0; + +SELECT * FROM tststats.priv_test_parent_tbl t + WHERE a <<< 0 AND (b <<< 0 OR t.* <<< (1, 1) IS NOT NULL); + +DELETE FROM tststats.priv_test_parent_tbl WHERE a <<< 0 AND b <<< 0; + +RESET SESSION AUTHORIZATION; + +CREATE TABLE stats_ext_tbl (id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, col TEXT); + +INSERT INTO stats_ext_tbl (col) VALUES ('secret'), ('secret'), ('very secret'); + +CREATE STATISTICS s_col ON id, col FROM stats_ext_tbl; + +CREATE STATISTICS s_expr ON mod(id, 2), lower(col) FROM stats_ext_tbl; + +ANALYZE stats_ext_tbl; + +SET SESSION AUTHORIZATION regress_stats_user1; + +SELECT statistics_name, most_common_vals FROM pg_stats_ext x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*); + +SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*); + +RESET SESSION AUTHORIZATION; + +ALTER TABLE stats_ext_tbl OWNER TO regress_stats_user1; + +SET SESSION AUTHORIZATION regress_stats_user1; + +SELECT statistics_name, most_common_vals FROM pg_stats_ext x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*); + +SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x + WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*); + +DROP OPERATOR <<< (int, int); + +DROP FUNCTION op_leak(int, int); + +DROP OPERATOR <<< (record, record); + +DROP FUNCTION op_leak(record, record); + +RESET SESSION AUTHORIZATION; + +DROP TABLE stats_ext_tbl; + +DROP SCHEMA tststats CASCADE; + +DROP USER regress_stats_user1; + +CREATE TABLE grouping_unique (x integer); + +INSERT INTO grouping_unique (x) SELECT gs FROM generate_series(1,1000) AS gs; + +ANALYZE grouping_unique; + +SELECT * FROM check_estimated_rows(' + SELECT * FROM generate_series(1, 1) t1 LEFT JOIN ( + SELECT x FROM grouping_unique t2 GROUP BY x) AS q1 + ON t1.t1 = q1.x; +'); + +DROP TABLE grouping_unique; + +CREATE TABLE sb_1 AS + SELECT gs % 10 AS x, gs % 10 AS y, gs % 10 AS z + FROM generate_series(1, 1e4) AS gs; + +CREATE TABLE sb_2 AS + SELECT gs % 49 AS x, gs % 51 AS y, gs % 73 AS z, 'abc' || gs AS payload + FROM generate_series(1, 1e4) AS gs; + +ANALYZE sb_1, sb_2; + +SELECT * FROM sb_1 a, sb_2 b WHERE a.x = b.x AND a.y = b.y AND a.z = b.z; + +CREATE STATISTICS extstat_sb_2 (ndistinct) ON x, y, z FROM sb_2; + +ANALYZE sb_2; + +SELECT * FROM sb_1 a, sb_2 b WHERE a.x = b.x AND a.y = b.y AND a.z = b.z; + +SET enable_nestloop = 'off'; + +SET enable_mergejoin = 'off'; + +SELECT FROM sb_1 LEFT JOIN sb_2 ON (sb_2.x=sb_1.x) AND (sb_1.x=sb_2.x); + +SELECT FROM sb_1 LEFT JOIN sb_2 + ON (sb_2.x=sb_1.x) AND (sb_1.x=sb_2.x) AND (sb_1.y=sb_2.y); + +RESET enable_nestloop; + +RESET enable_mergejoin; + +CREATE FUNCTION extstat_small(x numeric) RETURNS bool +STRICT IMMUTABLE LANGUAGE plpgsql +AS $$ BEGIN RETURN x < 1; END $$; + +SELECT * FROM check_estimated_rows('SELECT * FROM sb_2 WHERE extstat_small(y)'); + +CREATE STATISTICS extstat_sb_2_small ON extstat_small(y) FROM sb_2; + +ANALYZE sb_2; + +SELECT * FROM check_estimated_rows('SELECT * FROM sb_2 WHERE extstat_small(y)'); + +DROP TABLE sb_1, sb_2 CASCADE; + +DROP FUNCTION extstat_small(x numeric); diff --git a/crates/pgt_pretty_print/tests/data/multi/stats_import_60.sql b/crates/pgt_pretty_print/tests/data/multi/stats_import_60.sql new file mode 100644 index 000000000..1bbad65b2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/stats_import_60.sql @@ -0,0 +1,886 @@ +CREATE SCHEMA stats_import; + +CREATE TYPE stats_import.complex_type AS ( + a integer, + b real, + c text, + d date, + e jsonb); + +CREATE TABLE stats_import.test( + id INTEGER PRIMARY KEY, + name text, + comp stats_import.complex_type, + arange int4range, + tags text[] +) WITH (autovacuum_enabled = false); + +SELECT + pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'relpages', 18::integer, + 'reltuples', 21::real, + 'relallvisible', 24::integer, + 'relallfrozen', 27::integer); + +CREATE INDEX test_i ON stats_import.test(id); + +SELECT relname, relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass +ORDER BY relname; + +SELECT pg_clear_relation_stats('stats_import', 'test'); + +SELECT pg_catalog.pg_restore_relation_stats( + 'relname', 'test', + 'relpages', 17::integer); + +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relpages', 17::integer); + +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 3.6::float, + 'relname', 'test', + 'relpages', 17::integer); + +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 0::oid, + 'relpages', 17::integer); + +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'nope', + 'relpages', 17::integer); + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'relallvisible'); + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + NULL, '17'::integer); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test_i'::regclass; + +BEGIN; + +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test_i', + 'relpages', 18::integer); + +SELECT mode FROM pg_locks +WHERE relation = 'stats_import.test'::regclass AND + pid = pg_backend_pid() AND granted; + +SELECT mode FROM pg_locks +WHERE relation = 'stats_import.test_i'::regclass AND + pid = pg_backend_pid() AND granted; + +COMMIT; + +CREATE TABLE stats_import.part_parent ( i integer ) PARTITION BY RANGE(i); + +CREATE TABLE stats_import.part_child_1 + PARTITION OF stats_import.part_parent + FOR VALUES FROM (0) TO (10) + WITH (autovacuum_enabled = false); + +CREATE INDEX part_parent_i ON stats_import.part_parent(i); + +ANALYZE stats_import.part_parent; + +SELECT relpages +FROM pg_class +WHERE oid = 'stats_import.part_parent'::regclass; + +BEGIN; + +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'part_parent_i', + 'relpages', 2::integer); + +SELECT mode FROM pg_locks +WHERE relation = 'stats_import.part_parent'::regclass AND + pid = pg_backend_pid() AND granted; + +SELECT mode FROM pg_locks +WHERE relation = 'stats_import.part_parent_i'::regclass AND + pid = pg_backend_pid() AND granted; + +COMMIT; + +SELECT relpages +FROM pg_class +WHERE oid = 'stats_import.part_parent_i'::regclass; + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'version', 150000::integer, + 'relpages', '-17'::integer, + 'reltuples', 400::real, + 'relallvisible', 4::integer, + 'relallfrozen', 2::integer); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'relpages', '16'::integer); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'reltuples', '500'::real); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'relallvisible', 5::integer); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'version', 150000::integer, + 'relallfrozen', 3::integer); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'relpages', 'nope'::text, + 'reltuples', 400.0::real, + 'relallvisible', 4::integer, + 'relallfrozen', 3::integer); + +SELECT relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +SELECT pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'relpages', '171'::integer, + 'nope', 10::integer); + +SELECT relpages, reltuples, relallvisible +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'test'); + +SELECT relpages, reltuples, relallvisible +FROM pg_class +WHERE oid = 'stats_import.test'::regclass; + +CREATE SEQUENCE stats_import.testseq; + +SELECT pg_catalog.pg_restore_relation_stats( + 'schemaname', 'stats_import', + 'relname', 'testseq'); + +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testseq'); + +CREATE VIEW stats_import.testview AS SELECT * FROM stats_import.test; + +SELECT pg_catalog.pg_clear_relation_stats(schemaname => 'stats_import', relname => 'testview'); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'nope', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'nope', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', NULL, + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', NULL, + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'nope', + 'inherited', false::boolean, + 'null_frac', 0.1::real, + 'avg_width', 2::integer, + 'n_distinct', 0.3::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'attnum', 1::smallint, + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'xmin', + 'inherited', false::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', NULL::boolean, + 'null_frac', 0.1::real); + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'version', 150000::integer, + 'null_frac', 0.2::real, + 'avg_width', 5::integer, + 'n_distinct', 0.6::real); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attnum', 1::smallint, + 'inherited', false::boolean, + 'null_frac', 0.4::real); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.2::real, + 'nope', 0.5::real); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.21::real, + 'most_common_freqs', '{0.1,0.2,0.3}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.21::real, + 'most_common_vals', '{1,2,3}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.22::real, + 'most_common_vals', '{2,1,3}'::text, + 'most_common_freqs', '{0.2,0.1}'::double precision[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.23::real, + 'most_common_vals', '{2,four,3}'::text, + 'most_common_freqs', '{0.3,0.25,0.05}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'most_common_vals', '{2,1,3}'::text, + 'most_common_freqs', '{0.3,0.25,0.05}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.24::real, + 'histogram_bounds', '{1,NULL,3,4}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'histogram_bounds', '{1,2,3,4}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', + 'inherited', false::boolean, + 'null_frac', 0.25::real, + 'elem_count_histogram', '{1,1,NULL,1,1,1,1,1}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'tags'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', + 'inherited', false::boolean, + 'null_frac', 0.26::real, + 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'tags'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.27::real, + 'range_empty_frac', 0.5::real, + 'range_length_histogram', '{399,499,Infinity}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', + 'inherited', false::boolean, + 'null_frac', 0.28::real, + 'range_length_histogram', '{399,499,Infinity}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', + 'inherited', false::boolean, + 'null_frac', 0.29::real, + 'range_empty_frac', 0.5::real + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', + 'inherited', false::boolean, + 'range_empty_frac', 0.5::real, + 'range_length_histogram', '{399,499,Infinity}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.31::real, + 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', + 'inherited', false::boolean, + 'range_bounds_histogram', '{"[-1,1)","[0,4)","[1,4)","[1,100)"}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'arange', + 'inherited', false::boolean, + 'null_frac', 0.32::real, + 'most_common_elems', '{3,1}'::text, + 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.33::real, + 'most_common_elems', '{1,3}'::text, + 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', + 'inherited', false::boolean, + 'null_frac', 0.34::real, + 'most_common_elems', '{one,two}'::text + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'tags'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', + 'inherited', false::boolean, + 'null_frac', 0.35::real, + 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'tags'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'tags', + 'inherited', false::boolean, + 'most_common_elems', '{one,three}'::text, + 'most_common_elem_freqs', '{0.3,0.2,0.2,0.3,0.0}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'tags'; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', 'test', + 'attname', 'id', + 'inherited', false::boolean, + 'null_frac', 0.36::real, + 'elem_count_histogram', '{1,1,1,1,1,1,1,1,1,1}'::real[] + ); + +SELECT * +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'id'; + +INSERT INTO stats_import.test +SELECT 1, 'one', (1, 1.1, 'ONE', '2001-01-01', '{ "xkey": "xval" }')::stats_import.complex_type, int4range(1,4), array['red','green'] +UNION ALL +SELECT 2, 'two', (2, 2.2, 'TWO', '2002-02-02', '[true, 4, "six"]')::stats_import.complex_type, int4range(1,4), array['blue','yellow'] +UNION ALL +SELECT 3, 'tre', (3, 3.3, 'TRE', '2003-03-03', NULL)::stats_import.complex_type, int4range(-1,1), array['"orange"', 'purple', 'cyan'] +UNION ALL +SELECT 4, 'four', NULL, int4range(0,100), NULL; + +CREATE INDEX is_odd ON stats_import.test(((comp).a % 2 = 1)); + +ANALYZE stats_import.test; + +CREATE TABLE stats_import.test_clone ( LIKE stats_import.test ) + WITH (autovacuum_enabled = false); + +CREATE INDEX is_odd_clone ON stats_import.test_clone(((comp).a % 2 = 1)); + +SELECT s.schemaname, s.tablename, s.attname, s.inherited, r.* +FROM pg_catalog.pg_stats AS s +CROSS JOIN LATERAL + pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'stats_import', + 'relname', s.tablename::text || '_clone', + 'attname', s.attname::text, + 'inherited', s.inherited, + 'version', 150000, + 'null_frac', s.null_frac, + 'avg_width', s.avg_width, + 'n_distinct', s.n_distinct, + 'most_common_vals', s.most_common_vals::text, + 'most_common_freqs', s.most_common_freqs, + 'histogram_bounds', s.histogram_bounds::text, + 'correlation', s.correlation, + 'most_common_elems', s.most_common_elems::text, + 'most_common_elem_freqs', s.most_common_elem_freqs, + 'elem_count_histogram', s.elem_count_histogram, + 'range_bounds_histogram', s.range_bounds_histogram::text, + 'range_empty_frac', s.range_empty_frac, + 'range_length_histogram', s.range_length_histogram::text) AS r +WHERE s.schemaname = 'stats_import' +AND s.tablename IN ('test', 'is_odd') +ORDER BY s.tablename, s.attname, s.inherited; + +SELECT c.relname, COUNT(*) AS num_stats +FROM pg_class AS c +JOIN pg_statistic s ON s.starelid = c.oid +WHERE c.relnamespace = 'stats_import'::regnamespace +AND c.relname IN ('test', 'test_clone', 'is_odd', 'is_odd_clone') +GROUP BY c.relname +ORDER BY c.relname; + +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'test' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.test'::regclass +EXCEPT +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'test' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.test_clone'::regclass; + +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'test_clone' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.test_clone'::regclass +EXCEPT +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'test_clone' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.test'::regclass; + +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'is_odd' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.is_odd'::regclass +EXCEPT +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'is_odd' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.is_odd_clone'::regclass; + +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'is_odd_clone' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.is_odd_clone'::regclass +EXCEPT +SELECT + a.attname, s.stainherit, s.stanullfrac, s.stawidth, s.stadistinct, + s.stakind1, s.stakind2, s.stakind3, s.stakind4, s.stakind5, + s.staop1, s.staop2, s.staop3, s.staop4, s.staop5, + s.stacoll1, s.stacoll2, s.stacoll3, s.stacoll4, s.stacoll5, + s.stanumbers1, s.stanumbers2, s.stanumbers3, s.stanumbers4, s.stanumbers5, + s.stavalues1::text AS sv1, s.stavalues2::text AS sv2, + s.stavalues3::text AS sv3, s.stavalues4::text AS sv4, + s.stavalues5::text AS sv5, 'is_odd_clone' AS direction +FROM pg_statistic s +JOIN pg_attribute a ON a.attrelid = s.starelid AND a.attnum = s.staattnum +WHERE s.starelid = 'stats_import.is_odd'::regclass; + +SELECT COUNT(*) +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + +SELECT pg_catalog.pg_clear_attribute_stats( + schemaname => 'stats_import', + relname => 'test', + attname => 'arange', + inherited => false); + +SELECT COUNT(*) +FROM pg_stats +WHERE schemaname = 'stats_import' +AND tablename = 'test' +AND inherited = false +AND attname = 'arange'; + +CREATE TEMP TABLE stats_temp(i int); + +SELECT pg_restore_relation_stats( + 'schemaname', 'pg_temp', + 'relname', 'stats_temp', + 'relpages', '-19'::integer, + 'reltuples', 401::real, + 'relallvisible', 5::integer, + 'relallfrozen', 3::integer); + +SELECT relname, relpages, reltuples, relallvisible, relallfrozen +FROM pg_class +WHERE oid = 'pg_temp.stats_temp'::regclass +ORDER BY relname; + +SELECT pg_catalog.pg_restore_attribute_stats( + 'schemaname', 'pg_temp', + 'relname', 'stats_temp', + 'attname', 'i', + 'inherited', false::boolean, + 'null_frac', 0.0123::real + ); + +SELECT tablename, null_frac +FROM pg_stats +WHERE schemaname like 'pg_temp%' +AND tablename = 'stats_temp' +AND inherited = false +AND attname = 'i'; + +DROP TABLE stats_temp; + +DROP SCHEMA stats_import CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/strings_60.sql b/crates/pgt_pretty_print/tests/data/multi/strings_60.sql new file mode 100644 index 000000000..5fb119740 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/strings_60.sql @@ -0,0 +1,1036 @@ +SELECT 'first line' +' - next line' + ' - third line' + AS "Three lines to one"; + +SET standard_conforming_strings TO on; + +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; + +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; + +SELECT U&'a\\b' AS "a\b"; + +SELECT U&' \' UESCAPE '!' AS "tricky"; + +SELECT 'tricky' AS U&"\" UESCAPE '!'; + +SELECT E'd\u0061t\U00000061' AS "data"; + +SELECT E'a\\b' AS "a\b"; + +SET standard_conforming_strings TO off; + +SELECT U&'d\0061t\+000061' AS U&"d\0061t\+000061"; + +SELECT U&'d!0061t\+000061' UESCAPE '!' AS U&"d*0061t\+000061" UESCAPE '*'; + +SELECT U&' \' UESCAPE '!' AS "tricky"; + +SELECT 'tricky' AS U&"\" UESCAPE '!'; + +RESET standard_conforming_strings; + +SET bytea_output TO hex; + +SELECT E'\\xDeAdBeEf'::bytea; + +SELECT E'\\x De Ad Be Ef '::bytea; + +SELECT E'\\xDeAdBeE'::bytea; + +SELECT E'\\xDeAdBeEx'::bytea; + +SELECT E'\\xDe00BeEf'::bytea; + +SELECT E'DeAdBeEf'::bytea; + +SELECT E'De\\000dBeEf'::bytea; + +SELECT E'De\123dBeEf'::bytea; + +SELECT E'De\\123dBeEf'::bytea; + +SELECT E'De\\678dBeEf'::bytea; + +SELECT E'DeAd\\\\BeEf'::bytea; + +SELECT reverse(''::bytea); + +SELECT reverse('\xaa'::bytea); + +SELECT reverse('\xabcd'::bytea); + +SET bytea_output TO escape; + +SELECT E'\\xDeAdBeEf'::bytea; + +SELECT E'\\x De Ad Be Ef '::bytea; + +SELECT E'\\xDe00BeEf'::bytea; + +SELECT E'DeAdBeEf'::bytea; + +SELECT E'De\\000dBeEf'::bytea; + +SELECT E'De\\123dBeEf'::bytea; + +SELECT E'DeAd\\\\BeEf'::bytea; + +SELECT pg_input_is_valid(E'\\xDeAdBeE', 'bytea'); + +SELECT * FROM pg_input_error_info(E'\\xDeAdBeE', 'bytea'); + +SELECT * FROM pg_input_error_info(E'\\xDeAdBeEx', 'bytea'); + +SELECT * FROM pg_input_error_info(E'foo\\99bar', 'bytea'); + +SELECT CAST(f1 AS text) AS "text(char)" FROM CHAR_TBL; + +SELECT CAST(f1 AS text) AS "text(varchar)" FROM VARCHAR_TBL; + +SELECT CAST(name 'namefield' AS text) AS "text(name)"; + +SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; + +SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL; + +SELECT CAST(f1 AS char(10)) AS "char(varchar)" FROM VARCHAR_TBL; + +SELECT CAST(name 'namefield' AS char(10)) AS "char(name)"; + +SELECT CAST(f1 AS varchar) AS "varchar(text)" FROM TEXT_TBL; + +SELECT CAST(f1 AS varchar) AS "varchar(char)" FROM CHAR_TBL; + +SELECT CAST(name 'namefield' AS varchar) AS "varchar(name)"; + +SELECT TRIM(BOTH FROM ' bunch o blanks ') = 'bunch o blanks' AS "bunch o blanks"; + +SELECT TRIM(LEADING FROM ' bunch o blanks ') = 'bunch o blanks ' AS "bunch o blanks "; + +SELECT TRIM(TRAILING FROM ' bunch o blanks ') = ' bunch o blanks' AS " bunch o blanks"; + +SELECT TRIM(BOTH 'x' FROM 'xxxxxsome Xsxxxxx') = 'some Xs' AS "some Xs"; + +SELECT SUBSTRING('1234567890' FROM 3) = '34567890' AS "34567890"; + +SELECT SUBSTRING('1234567890' FROM 4 FOR 3) = '456' AS "456"; + +SELECT SUBSTRING('string' FROM 2 FOR 2147483646) AS "tring"; + +SELECT SUBSTRING('string' FROM -10 FOR 2147483646) AS "string"; + +SELECT SUBSTRING('string' FROM -10 FOR -2147483646) AS "error"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"(b_d)#"%' ESCAPE '#') AS "bcd"; + +SELECT SUBSTRING('abcdefg' FROM 'a#"(b_d)#"%' FOR '#') AS "bcd"; + +SELECT SUBSTRING('abcdefg' SIMILAR '#"(b_d)#"%' ESCAPE '#') IS NULL AS "True"; + +SELECT SUBSTRING('abcdefg' SIMILAR '%' ESCAPE NULL) IS NULL AS "True"; + +SELECT SUBSTRING(NULL SIMILAR '%' ESCAPE '#') IS NULL AS "True"; + +SELECT SUBSTRING('abcdefg' SIMILAR NULL ESCAPE '#') IS NULL AS "True"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%#"g' ESCAPE '#') AS "bcdef"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a*#"%#"g*' ESCAPE '#') AS "abcdefg"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a|b#"%#"g' ESCAPE '#') AS "bcdef"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%#"x|g' ESCAPE '#') AS "bcdef"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%|ab#"g' ESCAPE '#') AS "bcdef"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a*#"%#"g*#"x' ESCAPE '#') AS "error"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a#"%g' ESCAPE '#') AS "bcdefg"; + +SELECT SUBSTRING('abcdefg' SIMILAR 'a%g' ESCAPE '#') AS "abcdefg"; + +SELECT SUBSTRING('abcdefg' FROM 'c.e') AS "cde"; + +SELECT SUBSTRING('abcdefg' FROM 'b(.*)f') AS "cde"; + +SELECT SUBSTRING('foo' FROM 'foo(bar)?') IS NULL AS t; + +SELECT 'abcdefg' SIMILAR TO '_bcd%' AS true; + +SELECT 'abcdefg' SIMILAR TO 'bcd%' AS false; + +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '#' AS false; + +SELECT 'abcd%' SIMILAR TO '_bcd#%' ESCAPE '#' AS true; + +SELECT 'abcdefg' SIMILAR TO '_bcd\%' AS false; + +SELECT 'abcd\efg' SIMILAR TO '_bcd\%' ESCAPE '' AS true; + +SELECT 'abcdefg' SIMILAR TO '_bcd%' ESCAPE NULL AS null; + +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '##' AS error; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '_[_[:alpha:]_]_'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '%[%[:alnum:]%]%'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '.[.[:alnum:].].'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '$[$[:alnum:]$]$'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '()[([:alnum:](]()'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '^[^[:alnum:]^[^^][[^^]][\^][[\^]]\^]^'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[]%][^]%][^%]%'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[^^]^'; + +SELECT * FROM TEXT_TBL WHERE f1 SIMILAR TO '[|a]%' ESCAPE '|'; + +SELECT regexp_replace('1112223333', E'(\\d{3})(\\d{3})(\\d{4})', E'(\\1) \\2-\\3'); + +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\&Y', 'g'); + +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\\\Y', 'g'); + +SELECT regexp_replace('foobarrbazz', E'(.)\\1', E'X\\Y\\1Z\\'); + +SELECT regexp_replace('AAA BBB CCC ', E'\\s+', ' ', 'g'); + +SELECT regexp_replace('AAA', '^|$', 'Z', 'g'); + +SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'gi'); + +SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'z'); + +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 1); + +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 1, 2); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 1, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 2, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 9, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'A|e|i|o|u', 'X', 7, 0, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 1, 'g'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', -1, 0, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, -1, 'i'); + +SELECT regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', '1'); + +SELECT regexp_count('123123123123123', '(12)3'); + +SELECT regexp_count('123123123123', '123', 1); + +SELECT regexp_count('123123123123', '123', 3); + +SELECT regexp_count('123123123123', '123', 33); + +SELECT regexp_count('ABCABCABCABC', 'Abc', 1, ''); + +SELECT regexp_count('ABCABCABCABC', 'Abc', 1, 'i'); + +SELECT regexp_count('123123123123', '123', 0); + +SELECT regexp_count('123123123123', '123', -3); + +SELECT regexp_like('Steven', '^Ste(v|ph)en$'); + +SELECT regexp_like('a'||CHR(10)||'d', 'a.d', 'n'); + +SELECT regexp_like('a'||CHR(10)||'d', 'a.d', 's'); + +SELECT regexp_like('abc', ' a . c ', 'x'); + +SELECT regexp_like('abc', 'a.c', 'g'); + +SELECT regexp_instr('abcdefghi', 'd.f'); + +SELECT regexp_instr('abcdefghi', 'd.q'); + +SELECT regexp_instr('abcabcabc', 'a.c'); + +SELECT regexp_instr('abcabcabc', 'a.c', 2); + +SELECT regexp_instr('abcabcabc', 'a.c', 1, 3); + +SELECT regexp_instr('abcabcabc', 'a.c', 1, 4); + +SELECT regexp_instr('abcabcabc', 'A.C', 1, 2, 0, 'i'); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 0); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 1); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 2); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 3); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 4); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 0, 'i', 5); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 0); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 1); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 2); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 3); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 4); + +SELECT regexp_instr('1234567890', '(123)(4(56)(78))', 1, 1, 1, 'i', 5); + +SELECT regexp_instr('foo', 'foo(bar)?', 1, 1, 0, '', 1); + +SELECT regexp_instr('abcabcabc', 'a.c', 0, 1); + +SELECT regexp_instr('abcabcabc', 'a.c', 1, 0); + +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, -1); + +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 2); + +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, 'g'); + +SELECT regexp_instr('abcabcabc', 'a.c', 1, 1, 0, '', -1); + +SELECT regexp_substr('abcdefghi', 'd.f'); + +SELECT regexp_substr('abcdefghi', 'd.q') IS NULL AS t; + +SELECT regexp_substr('abcabcabc', 'a.c'); + +SELECT regexp_substr('abcabcabc', 'a.c', 2); + +SELECT regexp_substr('abcabcabc', 'a.c', 1, 3); + +SELECT regexp_substr('abcabcabc', 'a.c', 1, 4) IS NULL AS t; + +SELECT regexp_substr('abcabcabc', 'A.C', 1, 2, 'i'); + +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 0); + +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 1); + +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 2); + +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 3); + +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 4); + +SELECT regexp_substr('1234567890', '(123)(4(56)(78))', 1, 1, 'i', 5) IS NULL AS t; + +SELECT regexp_substr('foo', 'foo(bar)?', 1, 1, '', 1) IS NULL AS t; + +SELECT regexp_substr('abcabcabc', 'a.c', 0, 1); + +SELECT regexp_substr('abcabcabc', 'a.c', 1, 0); + +SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, 'g'); + +SELECT regexp_substr('abcabcabc', 'a.c', 1, 1, '', -1); + +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$); + +SELECT regexp_matches('foObARbEqUEbAz', $re$(bar)(beque)$re$, 'i'); + +SELECT regexp_matches('foobarbequebazilbarfbonk', $re$(b[^b]+)(b[^b]+)$re$, 'g'); + +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.*)(beque)$re$); + +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.+)(beque)$re$); + +SELECT regexp_matches('foobarbequebaz', $re$(bar)(.+)?(beque)$re$); + +SELECT regexp_matches('foobarbequebaz', $re$barbeque$re$); + +SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '^', 'mg'); + +SELECT regexp_matches('foo' || chr(10) || 'bar' || chr(10) || 'bequq' || chr(10) || 'baz', '$', 'mg'); + +SELECT regexp_matches('1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '^.?', 'mg'); + +SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4' || chr(10), '.?$', 'mg'); + +SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr(10) || '4', '.?$', 'mg'); + +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$, 'gz'); + +SELECT regexp_matches('foobarbequebaz', $re$(barbeque$re$); + +SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque){2,1}$re$); + +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', $re$\s+$re$) AS foo; + +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', $re$\s+$re$); + +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', $re$\s*$re$) AS foo; + +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', $re$\s*$re$); + +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '') AS foo; + +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', ''); + +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'i') AS foo; + +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'i'); + +SELECT foo, length(foo) FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', 'nomatch') AS foo; + +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', 'nomatch'); + +SELECT regexp_split_to_array('123456','1'); + +SELECT regexp_split_to_array('123456','6'); + +SELECT regexp_split_to_array('123456','.'); + +SELECT regexp_split_to_array('123456',''); + +SELECT regexp_split_to_array('123456','(?:)'); + +SELECT regexp_split_to_array('1',''); + +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'zippy') AS foo; + +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'iz'); + +SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g') AS foo; + +SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g'); + +SELECT POSITION('4' IN '1234567890') = '4' AS "4"; + +SELECT POSITION('5' IN '1234567890') = '5' AS "5"; + +SELECT POSITION('\x11'::bytea IN ''::bytea) = 0 AS "0"; + +SELECT POSITION('\x33'::bytea IN '\x1122'::bytea) = 0 AS "0"; + +SELECT POSITION(''::bytea IN '\x1122'::bytea) = 1 AS "1"; + +SELECT POSITION('\x22'::bytea IN '\x1122'::bytea) = 2 AS "2"; + +SELECT POSITION('\x5678'::bytea IN '\x1234567890'::bytea) = 3 AS "3"; + +SELECT OVERLAY('abcdef' PLACING '45' FROM 4) AS "abc45f"; + +SELECT OVERLAY('yabadoo' PLACING 'daba' FROM 5) AS "yabadaba"; + +SELECT OVERLAY('yabadoo' PLACING 'daba' FROM 5 FOR 0) AS "yabadabadoo"; + +SELECT OVERLAY('babosa' PLACING 'ubb' FROM 2 FOR 4) AS "bubba"; + +SELECT 'hawkeye' LIKE 'h%' AS "true"; + +SELECT 'hawkeye' NOT LIKE 'h%' AS "false"; + +SELECT 'hawkeye' LIKE 'H%' AS "false"; + +SELECT 'hawkeye' NOT LIKE 'H%' AS "true"; + +SELECT 'hawkeye' LIKE 'indio%' AS "false"; + +SELECT 'hawkeye' NOT LIKE 'indio%' AS "true"; + +SELECT 'hawkeye' LIKE 'h%eye' AS "true"; + +SELECT 'hawkeye' NOT LIKE 'h%eye' AS "false"; + +SELECT 'indio' LIKE '_ndio' AS "true"; + +SELECT 'indio' NOT LIKE '_ndio' AS "false"; + +SELECT 'indio' LIKE 'in__o' AS "true"; + +SELECT 'indio' NOT LIKE 'in__o' AS "false"; + +SELECT 'indio' LIKE 'in_o' AS "false"; + +SELECT 'indio' NOT LIKE 'in_o' AS "true"; + +SELECT 'abc'::name LIKE '_b_' AS "true"; + +SELECT 'abc'::name NOT LIKE '_b_' AS "false"; + +SELECT 'abc'::bytea LIKE '_b_'::bytea AS "true"; + +SELECT 'abc'::bytea NOT LIKE '_b_'::bytea AS "false"; + +SELECT 'hawkeye' LIKE 'h%' ESCAPE '#' AS "true"; + +SELECT 'hawkeye' NOT LIKE 'h%' ESCAPE '#' AS "false"; + +SELECT 'indio' LIKE 'ind_o' ESCAPE '$' AS "true"; + +SELECT 'indio' NOT LIKE 'ind_o' ESCAPE '$' AS "false"; + +SELECT 'h%' LIKE 'h#%' ESCAPE '#' AS "true"; + +SELECT 'h%' NOT LIKE 'h#%' ESCAPE '#' AS "false"; + +SELECT 'h%wkeye' LIKE 'h#%' ESCAPE '#' AS "false"; + +SELECT 'h%wkeye' NOT LIKE 'h#%' ESCAPE '#' AS "true"; + +SELECT 'h%wkeye' LIKE 'h#%%' ESCAPE '#' AS "true"; + +SELECT 'h%wkeye' NOT LIKE 'h#%%' ESCAPE '#' AS "false"; + +SELECT 'h%awkeye' LIKE 'h#%a%k%e' ESCAPE '#' AS "true"; + +SELECT 'h%awkeye' NOT LIKE 'h#%a%k%e' ESCAPE '#' AS "false"; + +SELECT 'indio' LIKE '_ndio' ESCAPE '$' AS "true"; + +SELECT 'indio' NOT LIKE '_ndio' ESCAPE '$' AS "false"; + +SELECT 'i_dio' LIKE 'i$_d_o' ESCAPE '$' AS "true"; + +SELECT 'i_dio' NOT LIKE 'i$_d_o' ESCAPE '$' AS "false"; + +SELECT 'i_dio' LIKE 'i$_nd_o' ESCAPE '$' AS "false"; + +SELECT 'i_dio' NOT LIKE 'i$_nd_o' ESCAPE '$' AS "true"; + +SELECT 'i_dio' LIKE 'i$_d%o' ESCAPE '$' AS "true"; + +SELECT 'i_dio' NOT LIKE 'i$_d%o' ESCAPE '$' AS "false"; + +SELECT 'a_c'::bytea LIKE 'a$__'::bytea ESCAPE '$'::bytea AS "true"; + +SELECT 'a_c'::bytea NOT LIKE 'a$__'::bytea ESCAPE '$'::bytea AS "false"; + +SELECT 'maca' LIKE 'm%aca' ESCAPE '%' AS "true"; + +SELECT 'maca' NOT LIKE 'm%aca' ESCAPE '%' AS "false"; + +SELECT 'ma%a' LIKE 'm%a%%a' ESCAPE '%' AS "true"; + +SELECT 'ma%a' NOT LIKE 'm%a%%a' ESCAPE '%' AS "false"; + +SELECT 'bear' LIKE 'b_ear' ESCAPE '_' AS "true"; + +SELECT 'bear' NOT LIKE 'b_ear' ESCAPE '_' AS "false"; + +SELECT 'be_r' LIKE 'b_e__r' ESCAPE '_' AS "true"; + +SELECT 'be_r' NOT LIKE 'b_e__r' ESCAPE '_' AS "false"; + +SELECT 'be_r' LIKE '__e__r' ESCAPE '_' AS "false"; + +SELECT 'be_r' NOT LIKE '__e__r' ESCAPE '_' AS "true"; + +SELECT 'hawkeye' ILIKE 'h%' AS "true"; + +SELECT 'hawkeye' NOT ILIKE 'h%' AS "false"; + +SELECT 'hawkeye' ILIKE 'H%' AS "true"; + +SELECT 'hawkeye' NOT ILIKE 'H%' AS "false"; + +SELECT 'hawkeye' ILIKE 'H%Eye' AS "true"; + +SELECT 'hawkeye' NOT ILIKE 'H%Eye' AS "false"; + +SELECT 'Hawkeye' ILIKE 'h%' AS "true"; + +SELECT 'Hawkeye' NOT ILIKE 'h%' AS "false"; + +SELECT 'ABC'::name ILIKE '_b_' AS "true"; + +SELECT 'ABC'::name NOT ILIKE '_b_' AS "false"; + +SELECT 'foo' LIKE '_%' as t, 'f' LIKE '_%' as t, '' LIKE '_%' as f; + +SELECT 'foo' LIKE '%_' as t, 'f' LIKE '%_' as t, '' LIKE '%_' as f; + +SELECT 'foo' LIKE '__%' as t, 'foo' LIKE '___%' as t, 'foo' LIKE '____%' as f; + +SELECT 'foo' LIKE '%__' as t, 'foo' LIKE '%___' as t, 'foo' LIKE '%____' as f; + +SELECT 'jack' LIKE '%____%' AS t; + +CREATE TABLE texttest (a text PRIMARY KEY, b int); + +SELECT * FROM texttest WHERE a LIKE '%1%'; + +CREATE TABLE byteatest (a bytea PRIMARY KEY, b int); + +SELECT * FROM byteatest WHERE a LIKE '%1%'; + +DROP TABLE texttest, byteatest; + +SELECT 'unknown' || ' and unknown' AS "Concat unknown types"; + +SELECT text 'text' || ' and unknown' AS "Concat text to unknown type"; + +SELECT char(20) 'characters' || ' and text' AS "Concat char to unknown type"; + +SELECT text 'text' || char(20) ' and characters' AS "Concat text to char"; + +SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar"; + +CREATE TABLE toasttest(f1 text); + +insert into toasttest values(repeat('1234567890',10000)); + +insert into toasttest values(repeat('1234567890',10000)); + +alter table toasttest alter column f1 set storage external; + +insert into toasttest values(repeat('1234567890',10000)); + +insert into toasttest values(repeat('1234567890',10000)); + +SELECT substr(f1, -1, 5) from toasttest; + +SELECT substr(f1, 5, -1) from toasttest; + +SELECT substr(f1, 99995) from toasttest; + +SELECT substr(f1, 99995, 10) from toasttest; + +TRUNCATE TABLE toasttest; + +INSERT INTO toasttest values (repeat('1234567890',300)); + +INSERT INTO toasttest values (repeat('1234567890',300)); + +INSERT INTO toasttest values (repeat('1234567890',300)); + +INSERT INTO toasttest values (repeat('1234567890',300)); + +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + +TRUNCATE TABLE toasttest; + +ALTER TABLE toasttest set (toast_tuple_target = 4080); + +INSERT INTO toasttest values (repeat('1234567890',300)); + +INSERT INTO toasttest values (repeat('1234567890',300)); + +INSERT INTO toasttest values (repeat('1234567890',300)); + +INSERT INTO toasttest values (repeat('1234567890',300)); + +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + +DROP TABLE toasttest; + +CREATE TABLE toasttest(f1 bytea); + +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +alter table toasttest alter column f1 set storage external; + +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +insert into toasttest values(decode(repeat('1234567890',10000),'escape')); + +SELECT substr(f1, -1, 5) from toasttest; + +SELECT substr(f1, 5, -1) from toasttest; + +SELECT substr(f1, 99995) from toasttest; + +SELECT substr(f1, 99995, 10) from toasttest; + +DROP TABLE toasttest; + +CREATE TABLE toasttest (c char(4096)); + +INSERT INTO toasttest VALUES('x'); + +SELECT length(c), c::text FROM toasttest; + +SELECT c FROM toasttest; + +DROP TABLE toasttest; + +CREATE TABLE toasttest (f1 text, f2 text); + +ALTER TABLE toasttest SET (toast_tuple_target = 128); + +ALTER TABLE toasttest ALTER COLUMN f1 SET STORAGE EXTERNAL; + +ALTER TABLE toasttest ALTER COLUMN f2 SET STORAGE EXTERNAL; + +INSERT INTO toasttest values(repeat('1234', 1000), repeat('5678', 30)); + +SELECT reltoastrelid::regclass AS reltoastname FROM pg_class + WHERE oid = 'toasttest'::regclass ; + +SELECT substr(f1, 5, 10) AS f1_data, substr(f2, 5, 10) AS f2_data + FROM toasttest; + +SELECT pg_column_compression(f1) AS f1_comp, pg_column_compression(f2) AS f2_comp + FROM toasttest; + +DROP TABLE toasttest; + +SELECT length('abcdef') AS "length_6"; + +SELECT strpos('abcdef', 'cd') AS "pos_3"; + +SELECT strpos('abcdef', 'xy') AS "pos_0"; + +SELECT strpos('abcdef', '') AS "pos_1"; + +SELECT strpos('', 'xy') AS "pos_0"; + +SELECT strpos('', '') AS "pos_1"; + +SELECT replace('abcdef', 'de', '45') AS "abc45f"; + +SELECT replace('yabadabadoo', 'ba', '123') AS "ya123da123doo"; + +SELECT replace('yabadoo', 'bad', '') AS "yaoo"; + +select split_part('','@',1) AS "empty string"; + +select split_part('','@',-1) AS "empty string"; + +select split_part('joeuser@mydatabase','',1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','',2) AS "empty string"; + +select split_part('joeuser@mydatabase','',-1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','',-2) AS "empty string"; + +select split_part('joeuser@mydatabase','@',0) AS "an error"; + +select split_part('joeuser@mydatabase','@@',1) AS "joeuser@mydatabase"; + +select split_part('joeuser@mydatabase','@@',2) AS "empty string"; + +select split_part('joeuser@mydatabase','@',1) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',2) AS "mydatabase"; + +select split_part('joeuser@mydatabase','@',3) AS "empty string"; + +select split_part('@joeuser@mydatabase@','@',2) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',-1) AS "mydatabase"; + +select split_part('joeuser@mydatabase','@',-2) AS "joeuser"; + +select split_part('joeuser@mydatabase','@',-3) AS "empty string"; + +select split_part('@joeuser@mydatabase@','@',-2) AS "mydatabase"; + +select to_bin(-1234) AS "11111111111111111111101100101110"; + +select to_bin(-1234::bigint); + +select to_bin(256*256*256 - 1) AS "111111111111111111111111"; + +select to_bin(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "11111111111111111111111111111111"; + +select to_oct(-1234) AS "37777775456"; + +select to_oct(-1234::bigint) AS "1777777777777777775456"; + +select to_oct(256*256*256 - 1) AS "77777777"; + +select to_oct(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "37777777777"; + +select to_hex(-1234) AS "fffffb2e"; + +select to_hex(-1234::bigint) AS "fffffffffffffb2e"; + +select to_hex(256*256*256 - 1) AS "ffffff"; + +select to_hex(256::bigint*256::bigint*256::bigint*256::bigint - 1) AS "ffffffff"; + +SET bytea_output TO hex; + +SELECT sha224(''); + +SELECT sha224('The quick brown fox jumps over the lazy dog.'); + +SELECT sha256(''); + +SELECT sha256('The quick brown fox jumps over the lazy dog.'); + +SELECT sha384(''); + +SELECT sha384('The quick brown fox jumps over the lazy dog.'); + +SELECT sha512(''); + +SELECT sha512('The quick brown fox jumps over the lazy dog.'); + +SELECT crc32(''); + +SELECT crc32('The quick brown fox jumps over the lazy dog.'); + +SELECT crc32c(''); + +SELECT crc32c('The quick brown fox jumps over the lazy dog.'); + +SELECT crc32c(repeat('A', 127)::bytea); + +SELECT crc32c(repeat('A', 128)::bytea); + +SELECT crc32c(repeat('A', 129)::bytea); + +SELECT crc32c(repeat('A', 800)::bytea); + +SELECT encode('\x1234567890abcdef00', 'hex'); + +SELECT decode('1234567890abcdef00', 'hex'); + +SELECT encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea, 'base64'); + +SELECT decode(encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea, + 'base64'), 'base64'); + +SELECT encode('\x1234567890abcdef00', 'escape'); + +SELECT decode(encode('\x1234567890abcdef00', 'escape'), 'escape'); + +SET bytea_output TO hex; + +SELECT encode('\x69b73eff', 'base64url'); + +SELECT decode('abc-_w', 'base64url'); + +SELECT decode(encode('\x1234567890abcdef00', 'base64url'), 'base64url'); + +SELECT encode('', 'base64url'); + +SELECT decode('', 'base64url'); + +SELECT encode('\x01', 'base64url'); + +SELECT decode('AQ', 'base64url'); + +SELECT encode('\x0102'::bytea, 'base64url'); + +SELECT decode('AQI', 'base64url'); + +SELECT encode('\x010203'::bytea, 'base64url'); + +SELECT decode('AQID', 'base64url'); + +SELECT encode('\xdeadbeef'::bytea, 'base64url'); + +SELECT decode('3q2-7w', 'base64url'); + +SELECT encode(decode(encode(E'\\x', 'base64url'), 'base64url'), 'base64url'); + +SELECT encode(decode(encode(E'\\x00', 'base64url'), 'base64url'), 'base64url'); + +SELECT encode(decode(encode(E'\\x0001', 'base64url'), 'base64url'), 'base64url'); + +SELECT encode(decode(encode(E'\\x000102', 'base64url'), 'base64url'), 'base64url'); + +SELECT encode(decode(encode(E'\\x00010203', 'base64url'), 'base64url'), 'base64url'); + +SELECT decode('QQ@=', 'base64url'); + +SELECT decode('QQ', 'base64url'); + +SELECT decode('QQI', 'base64url'); + +SELECT decode('QQIDQ', 'base64url'); + +SELECT decode('=QQQ', 'base64url'); + +SELECT decode('abc-_w==', 'base64url'); + +SELECT get_bit('\x1234567890abcdef00'::bytea, 43); + +SELECT get_bit('\x1234567890abcdef00'::bytea, 99); + +SELECT set_bit('\x1234567890abcdef00'::bytea, 43, 0); + +SELECT set_bit('\x1234567890abcdef00'::bytea, 99, 0); + +SELECT get_byte('\x1234567890abcdef00'::bytea, 3); + +SELECT get_byte('\x1234567890abcdef00'::bytea, 99); + +SELECT set_byte('\x1234567890abcdef00'::bytea, 7, 11); + +SELECT set_byte('\x1234567890abcdef00'::bytea, 99, 11); + +SELECT 0x1234::int2::bytea AS "\x1234", (-0x1234)::int2::bytea AS "\xedcc"; + +SELECT 0x12345678::int4::bytea AS "\x12345678", (-0x12345678)::int4::bytea AS "\xedcba988"; + +SELECT 0x1122334455667788::int8::bytea AS "\x1122334455667788", + (-0x1122334455667788)::int8::bytea AS "\xeeddccbbaa998878"; + +SELECT ''::bytea::int2 AS "0"; + +SELECT '\x12'::bytea::int2 AS "18"; + +SELECT '\x1234'::bytea::int2 AS "4460"; + +SELECT '\x123456'::bytea::int2; + +SELECT ''::bytea::int4 AS "0"; + +SELECT '\x12'::bytea::int4 AS "18"; + +SELECT '\x12345678'::bytea::int4 AS "305419896"; + +SELECT '\x123456789A'::bytea::int4; + +SELECT ''::bytea::int8 AS "0"; + +SELECT '\x12'::bytea::int8 AS "18"; + +SELECT '\x1122334455667788'::bytea::int8 AS "1234605616436508552"; + +SELECT '\x112233445566778899'::bytea::int8; + +SELECT '\x8000'::bytea::int2 AS "-32768", '\x7FFF'::bytea::int2 AS "32767"; + +SELECT '\x80000000'::bytea::int4 AS "-2147483648", '\x7FFFFFFF'::bytea::int4 AS "2147483647"; + +SELECT '\x8000000000000000'::bytea::int8 AS "-9223372036854775808", + '\x7FFFFFFFFFFFFFFF'::bytea::int8 AS "9223372036854775807"; + +set escape_string_warning = off; + +set standard_conforming_strings = off; + +show escape_string_warning; + +show standard_conforming_strings; + +set escape_string_warning = on; + +set standard_conforming_strings = on; + +show escape_string_warning; + +show standard_conforming_strings; + +select 'a\bcd' as f1, 'a\b''cd' as f2, 'a\b''''cd' as f3, 'abcd\' as f4, 'ab\''cd' as f5, '\\' as f6; + +set standard_conforming_strings = off; + +reset standard_conforming_strings; + +SET bytea_output TO escape; + +SELECT initcap('hi THOMAS'); + +SELECT lpad('hi', 5, 'xy'); + +SELECT lpad('hi', 5); + +SELECT lpad('hi', -5, 'xy'); + +SELECT lpad('hello', 2); + +SELECT lpad('hi', 5, ''); + +SELECT rpad('hi', 5, 'xy'); + +SELECT rpad('hi', 5); + +SELECT rpad('hi', -5, 'xy'); + +SELECT rpad('hello', 2); + +SELECT rpad('hi', 5, ''); + +SELECT ltrim('zzzytrim', 'xyz'); + +SELECT translate('', '14', 'ax'); + +SELECT translate('12345', '14', 'ax'); + +SELECT translate('12345', '134', 'a'); + +SELECT ascii('x'); + +SELECT ascii(''); + +SELECT chr(65); + +SELECT chr(0); + +SELECT repeat('Pg', 4); + +SELECT repeat('Pg', -4); + +SELECT SUBSTRING('1234567890'::bytea FROM 3) "34567890"; + +SELECT SUBSTRING('1234567890'::bytea FROM 4 FOR 3) AS "456"; + +SELECT SUBSTRING('string'::bytea FROM 2 FOR 2147483646) AS "tring"; + +SELECT SUBSTRING('string'::bytea FROM -10 FOR 2147483646) AS "string"; + +SELECT SUBSTRING('string'::bytea FROM -10 FOR -2147483646) AS "error"; + +SELECT trim(E'\\000'::bytea from E'\\000Tom\\000'::bytea); + +SELECT trim(leading E'\\000'::bytea from E'\\000Tom\\000'::bytea); + +SELECT trim(trailing E'\\000'::bytea from E'\\000Tom\\000'::bytea); + +SELECT btrim(E'\\000trim\\000'::bytea, E'\\000'::bytea); + +SELECT btrim(''::bytea, E'\\000'::bytea); + +SELECT btrim(E'\\000trim\\000'::bytea, ''::bytea); + +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'Th\\001omas'::bytea from 2),'escape'); + +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 8),'escape'); + +SELECT encode(overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 5 for 3),'escape'); + +SELECT bit_count('\x1234567890'::bytea); + +SELECT unistr('\0064at\+0000610'); + +SELECT unistr('d\u0061t\U000000610'); + +SELECT unistr('a\\b'); + +SELECT unistr('wrong: \db99'); + +SELECT unistr('wrong: \db99\0061'); + +SELECT unistr('wrong: \+00db99\+000061'); + +SELECT unistr('wrong: \+2FFFFF'); + +SELECT unistr('wrong: \udb99\u0061'); + +SELECT unistr('wrong: \U0000db99\U00000061'); + +SELECT unistr('wrong: \U002FFFFF'); + +SELECT unistr('wrong: \xyz'); diff --git a/crates/pgt_pretty_print/tests/data/multi/subscription_60.sql b/crates/pgt_pretty_print/tests/data/multi/subscription_60.sql new file mode 100644 index 000000000..56bd679d2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/subscription_60.sql @@ -0,0 +1,331 @@ +CREATE ROLE regress_subscription_user LOGIN SUPERUSER; + +CREATE ROLE regress_subscription_user2; + +CREATE ROLE regress_subscription_user3 IN ROLE pg_create_subscription; + +CREATE ROLE regress_subscription_user_dummy LOGIN NOSUPERUSER; + +SET SESSION AUTHORIZATION 'regress_subscription_user'; + +BEGIN; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); + +COMMIT; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false); + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); + +COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'; + +SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; + +SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub'; + +SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub'; + +SELECT subname, stats_reset IS NULL stats_reset_is_null FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub'; + +SELECT stats_reset as prev_stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub' ; + +SELECT pg_stat_reset_subscription_stats(oid) FROM pg_subscription WHERE subname = 'regress_testsub'; + +SELECT 'prev_stats_reset' < stats_reset FROM pg_stat_subscription_stats WHERE subname = 'regress_testsub'; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); + +SET SESSION AUTHORIZATION 'regress_subscription_user2'; + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WITH (connect = false); + +SET SESSION AUTHORIZATION 'regress_subscription_user'; + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true); + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true); + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true); + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true); + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false, create_slot = true); + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false); + +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false); + +CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); + +ALTER SUBSCRIPTION regress_testsub3 ENABLE; + +ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION; + +CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = foo); + +CREATE SUBSCRIPTION regress_testsub4 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false, origin = none); + +ALTER SUBSCRIPTION regress_testsub4 SET (origin = any); + +DROP SUBSCRIPTION regress_testsub3; + +DROP SUBSCRIPTION regress_testsub4; + +CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'i_dont_exist=param' PUBLICATION testpub; + +CREATE SUBSCRIPTION regress_testsub5 CONNECTION 'port=-1' PUBLICATION testpub; + +ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; + +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 + +ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'; + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname'); + +ALTER SUBSCRIPTION regress_testsub SET (password_required = false); + +ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = true); + +ALTER SUBSCRIPTION regress_testsub SET (password_required = true); + +ALTER SUBSCRIPTION regress_testsub SET (run_as_owner = false); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = ''); + +ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2'; + +ALTER SUBSCRIPTION regress_testsub SET (create_slot = false); + +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/12345'); + +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = NONE); + +ALTER SUBSCRIPTION regress_testsub SKIP (lsn = '0/0'); + +BEGIN; + +ALTER SUBSCRIPTION regress_testsub ENABLE; + +ALTER SUBSCRIPTION regress_testsub DISABLE; + +COMMIT; + +SET ROLE regress_subscription_user_dummy; + +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy; + +RESET ROLE; + +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo; + +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local); + +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar); + +ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub; + +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; + +BEGIN; + +DROP SUBSCRIPTION regress_testsub; + +COMMIT; + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +BEGIN; + +DROP SUBSCRIPTION regress_testsub; + +COMMIT; + +DROP SUBSCRIPTION IF EXISTS regress_testsub; + +DROP SUBSCRIPTION regress_testsub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = foo); + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, binary = true); + +ALTER SUBSCRIPTION regress_testsub SET (binary = false); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = foo); + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true); + +ALTER SUBSCRIPTION regress_testsub SET (streaming = parallel); + +ALTER SUBSCRIPTION regress_testsub SET (streaming = false); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub + +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub1 + +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 + +ALTER SUBSCRIPTION regress_testsub ADD PUBLICATION testpub1, testpub2 + +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub1 + +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub, testpub1, testpub2 + +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub3 + +ALTER SUBSCRIPTION regress_testsub DROP PUBLICATION testpub1, testpub2 + +DROP SUBSCRIPTION regress_testsub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION mypub + WITH (connect = false, create_slot = false, copy_data = false); + +ALTER SUBSCRIPTION regress_testsub ENABLE; + +BEGIN; + +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub + +END; + +BEGIN; + +ALTER SUBSCRIPTION regress_testsub REFRESH PUBLICATION; + +END; + +CREATE FUNCTION func() RETURNS VOID AS +$$ ALTER SUBSCRIPTION regress_testsub SET PUBLICATION mypub WITH (refresh = true) $$ LANGUAGE SQL; + +SELECT func(); + +ALTER SUBSCRIPTION regress_testsub DISABLE; + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +DROP FUNCTION func; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = foo); + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, two_phase = true); + +ALTER SUBSCRIPTION regress_testsub SET (streaming = true); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, streaming = true, two_phase = true); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = foo); + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, disable_on_error = false); + +ALTER SUBSCRIPTION regress_testsub SET (disable_on_error = true); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, retain_dead_tuples = foo); + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, retain_dead_tuples = false); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, max_retention_duration = foo); + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, max_retention_duration = 1000); + +ALTER SUBSCRIPTION regress_testsub SET (max_retention_duration = 0); + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +SET SESSION AUTHORIZATION regress_subscription_user3; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); + +RESET SESSION AUTHORIZATION; + +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3; + +SET SESSION AUTHORIZATION regress_subscription_user3; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); + +RESET SESSION AUTHORIZATION; + +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3; + +SET SESSION AUTHORIZATION regress_subscription_user3; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, password_required = false); + +RESET SESSION AUTHORIZATION; + +GRANT CREATE ON DATABASE REGRESSION TO regress_subscription_user3; + +SET SESSION AUTHORIZATION regress_subscription_user3; + +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist password=regress_fakepassword' PUBLICATION testpub WITH (connect = false); + +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user; + +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2; + +RESET SESSION AUTHORIZATION; + +REVOKE pg_create_subscription FROM regress_subscription_user3; + +SET SESSION AUTHORIZATION regress_subscription_user3; + +ALTER SUBSCRIPTION regress_testsub2 RENAME TO regress_testsub; + +RESET SESSION AUTHORIZATION; + +REVOKE CREATE ON DATABASE REGRESSION FROM regress_subscription_user3; + +SET SESSION AUTHORIZATION regress_subscription_user3; + +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub2; + +BEGIN; + +ALTER SUBSCRIPTION regress_testsub SET (failover); + +COMMIT; + +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); + +DROP SUBSCRIPTION regress_testsub; + +RESET SESSION AUTHORIZATION; + +DROP ROLE regress_subscription_user; + +DROP ROLE regress_subscription_user2; + +DROP ROLE regress_subscription_user3; + +DROP ROLE regress_subscription_user_dummy; diff --git a/crates/pgt_pretty_print/tests/data/multi/subselect_60.sql b/crates/pgt_pretty_print/tests/data/multi/subselect_60.sql new file mode 100644 index 000000000..ba4e18f47 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/subselect_60.sql @@ -0,0 +1,991 @@ +SELECT 1 AS one WHERE 1 IN (SELECT 1); + +SELECT 1 AS zero WHERE 1 NOT IN (SELECT 1); + +SELECT 1 AS zero WHERE 1 IN (SELECT 2); + +SELECT * FROM (SELECT 1 AS x) ss; + +SELECT * FROM ((SELECT 1 AS x)) ss; + +SELECT * FROM ((SELECT 1 AS x)), ((SELECT * FROM ((SELECT 2 AS y)))); + +(SELECT 2) UNION SELECT 2; + +((SELECT 2)) UNION SELECT 2; + +SELECT ((SELECT 2) UNION SELECT 2); + +SELECT (((SELECT 2)) UNION SELECT 2); + +SELECT (SELECT ARRAY[1,2,3])[1]; + +SELECT ((SELECT ARRAY[1,2,3]))[2]; + +SELECT (((SELECT ARRAY[1,2,3])))[3]; + +CREATE TABLE SUBSELECT_TBL ( + f1 integer, + f2 integer, + f3 float +); + +INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3); + +INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4); + +INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5); + +INSERT INTO SUBSELECT_TBL VALUES (1, 1, 1); + +INSERT INTO SUBSELECT_TBL VALUES (2, 2, 2); + +INSERT INTO SUBSELECT_TBL VALUES (3, 3, 3); + +INSERT INTO SUBSELECT_TBL VALUES (6, 7, 8); + +INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL); + +SELECT * FROM SUBSELECT_TBL; + +SELECT f1 AS "Constant Select" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT 1); + +SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL); + +SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE + f2 IN (SELECT f1 FROM SUBSELECT_TBL)); + +SELECT f1, f2 + FROM SUBSELECT_TBL + WHERE (f1, f2) NOT IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL + WHERE f3 IS NOT NULL); + +SELECT f1 AS "Correlated Field", f2 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1); + +SELECT f1 AS "Correlated Field", f3 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f1 IN + (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3); + +SELECT f1 AS "Correlated Field", f3 AS "Second Field" + FROM SUBSELECT_TBL upper + WHERE f3 IN (SELECT upper.f1 + f2 FROM SUBSELECT_TBL + WHERE f2 = CAST(f3 AS integer)); + +SELECT f1 AS "Correlated Field" + FROM SUBSELECT_TBL + WHERE (f1, f2) IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL + WHERE f3 IS NOT NULL); + +SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM SUBSELECT_TBL; + +SELECT ROW(1, 2) = (SELECT f1, f2) AS eq FROM SUBSELECT_TBL; + +SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM SUBSELECT_TBL; + +SELECT ROW(1, 2) = (SELECT 3, 4) AS eq FROM SUBSELECT_TBL; + +SELECT ROW(1, 2) = (SELECT f1, f2 FROM SUBSELECT_TBL); + +SELECT count FROM (SELECT COUNT(DISTINCT name) FROM road); + +SELECT COUNT(*) FROM (SELECT DISTINCT name FROM road); + +SELECT * FROM (SELECT * FROM int4_tbl), (VALUES (123456)) WHERE f1 = column1; + +CREATE VIEW view_unnamed_ss AS +SELECT * FROM (SELECT * FROM (SELECT abs(f1) AS a1 FROM int4_tbl)), + (SELECT * FROM int8_tbl) + WHERE a1 < 10 AND q1 > a1 ORDER BY q1, q2; + +SELECT * FROM view_unnamed_ss; + +DROP VIEW view_unnamed_ss; + +CREATE VIEW view_unnamed_ss_locking AS +SELECT * FROM (SELECT * FROM int4_tbl), int8_tbl AS unnamed_subquery + WHERE f1 = q1 + FOR UPDATE OF unnamed_subquery; + +DROP VIEW view_unnamed_ss_locking; + +SELECT ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" + FROM SUBSELECT_TBL ss + WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL + WHERE f1 != ss.f1 AND f1 < 2147483647); + +select q1, float8(count(*)) / (select count(*) from int8_tbl) +from int8_tbl group by q1 order by q1; + +SELECT *, pg_typeof(f1) FROM + (SELECT 'foo' AS f1 FROM generate_series(1,3)) ss ORDER BY 1; + +select '42' union all select '43'; + +select '42' union all select 43; + +select 1 = all (select (select 1)); + +select 1 = all (select (select 1)); + +select * from int4_tbl o where exists + (select 1 from int4_tbl i where i.f1=o.f1 limit null); + +select * from int4_tbl o where not exists + (select 1 from int4_tbl i where i.f1=o.f1 limit 1); + +select * from int4_tbl o where exists + (select 1 from int4_tbl i where i.f1=o.f1 limit 0); + +select count(*) from + (select 1 from tenk1 a + where unique1 IN (select hundred from tenk1 b)) ss; + +select count(distinct ss.ten) from + (select ten from tenk1 a + where unique1 IN (select hundred from tenk1 b)) ss; + +select count(*) from + (select 1 from tenk1 a + where unique1 IN (select distinct hundred from tenk1 b)) ss; + +select count(distinct ss.ten) from + (select ten from tenk1 a + where unique1 IN (select distinct hundred from tenk1 b)) ss; + +CREATE TEMP TABLE foo (id integer); + +CREATE TEMP TABLE bar (id1 integer, id2 integer); + +INSERT INTO foo VALUES (1); + +INSERT INTO bar VALUES (1, 1); + +INSERT INTO bar VALUES (2, 2); + +INSERT INTO bar VALUES (3, 1); + +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT DISTINCT id1, id2 FROM bar) AS s); + +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id1,id2 FROM bar GROUP BY id1,id2) AS s); + +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id1, id2 FROM bar UNION + SELECT id1, id2 FROM bar) AS s); + +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT DISTINCT ON (id2) id1, id2 FROM bar) AS s); + +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id2 FROM bar GROUP BY id2) AS s); + +SELECT * FROM foo WHERE id IN + (SELECT id2 FROM (SELECT id2 FROM bar UNION + SELECT id2 FROM bar) AS s); + +CREATE TABLE orderstest ( + approver_ref integer, + po_ref integer, + ordercanceled boolean +); + +INSERT INTO orderstest VALUES (1, 1, false); + +INSERT INTO orderstest VALUES (66, 5, false); + +INSERT INTO orderstest VALUES (66, 6, false); + +INSERT INTO orderstest VALUES (66, 7, false); + +INSERT INTO orderstest VALUES (66, 1, true); + +INSERT INTO orderstest VALUES (66, 8, false); + +INSERT INTO orderstest VALUES (66, 1, false); + +INSERT INTO orderstest VALUES (77, 1, false); + +INSERT INTO orderstest VALUES (1, 1, false); + +INSERT INTO orderstest VALUES (66, 1, false); + +INSERT INTO orderstest VALUES (1, 1, false); + +CREATE VIEW orders_view AS +SELECT *, +(SELECT CASE + WHEN ord.approver_ref=1 THEN '---' ELSE 'Approved' + END) AS "Approved", +(SELECT CASE + WHEN ord.ordercanceled + THEN 'Canceled' + ELSE + (SELECT CASE + WHEN ord.po_ref=1 + THEN + (SELECT CASE + WHEN ord.approver_ref=1 + THEN '---' + ELSE 'Approved' + END) + ELSE 'PO' + END) +END) AS "Status", +(CASE + WHEN ord.ordercanceled + THEN 'Canceled' + ELSE + (CASE + WHEN ord.po_ref=1 + THEN + (CASE + WHEN ord.approver_ref=1 + THEN '---' + ELSE 'Approved' + END) + ELSE 'PO' + END) +END) AS "Status_OK" +FROM orderstest ord; + +SELECT * FROM orders_view; + +DROP TABLE orderstest cascade; + +create temp table parts ( + partnum text, + cost float8 +); + +create temp table shipped ( + ttype char(2), + ordnum int4, + partnum text, + value float8 +); + +create temp view shipped_view as + select * from shipped where ttype = 'wt'; + +create rule shipped_view_insert as on insert to shipped_view do instead + insert into shipped values('wt', new.ordnum, new.partnum, new.value); + +insert into parts (partnum, cost) values (1, 1234.56); + +insert into shipped_view (ordnum, partnum, value) + values (0, 1, (select cost from parts where partnum = '1')); + +select * from shipped_view; + +create rule shipped_view_update as on update to shipped_view do instead + update shipped set partnum = new.partnum, value = new.value + where ttype = new.ttype and ordnum = new.ordnum; + +update shipped_view set value = 11 + from int4_tbl a join int4_tbl b + on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)) + where ordnum = a.f1; + +select * from shipped_view; + +select f1, ss1 as relabel from + (select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1 + from int4_tbl a) ss; + +select * from ( + select max(unique1) from tenk1 as a + where exists (select 1 from tenk1 as b where b.thousand = a.unique2) +) ss; + +select * from ( + select min(unique1) from tenk1 as a + where not exists (select 1 from tenk1 as b where b.unique2 = 10000) +) ss; + +create temp table numeric_table (num_col numeric); + +insert into numeric_table values (1), (1.000000000000000000001), (2), (3); + +create temp table float_table (float_col float8); + +insert into float_table values (1), (2), (3); + +select * from float_table + where float_col in (select num_col from numeric_table); + +select * from numeric_table + where num_col in (select float_col from float_table); + +create table semijoin_unique_tbl (a int, b int); + +insert into semijoin_unique_tbl select i%10, i%10 from generate_series(1,1000)i; + +create index on semijoin_unique_tbl(a, b); + +analyze semijoin_unique_tbl; + +select * from semijoin_unique_tbl t1, semijoin_unique_tbl t2 +where (t1.a, t2.a) in (select a, b from semijoin_unique_tbl t3) +order by t1.a, t2.a; + +select * from semijoin_unique_tbl t1, semijoin_unique_tbl t2 +where (t1.a, t2.a) in (select a+1, b+1 from semijoin_unique_tbl t3) +order by t1.a, t2.a; + +set parallel_setup_cost=0; + +set parallel_tuple_cost=0; + +set min_parallel_table_scan_size=0; + +set max_parallel_workers_per_gather=4; + +set enable_indexscan to off; + +select * from semijoin_unique_tbl t1, semijoin_unique_tbl t2 +where (t1.a, t2.a) in (select a, b from semijoin_unique_tbl t3) +order by t1.a, t2.a; + +reset enable_indexscan; + +reset max_parallel_workers_per_gather; + +reset min_parallel_table_scan_size; + +reset parallel_tuple_cost; + +reset parallel_setup_cost; + +drop table semijoin_unique_tbl; + +create table unique_tbl_p (a int, b int) partition by range(a); + +create table unique_tbl_p1 partition of unique_tbl_p for values from (0) to (5); + +create table unique_tbl_p2 partition of unique_tbl_p for values from (5) to (10); + +create table unique_tbl_p3 partition of unique_tbl_p for values from (10) to (20); + +insert into unique_tbl_p select i%12, i from generate_series(0, 1000)i; + +create index on unique_tbl_p1(a); + +create index on unique_tbl_p2(a); + +create index on unique_tbl_p3(a); + +analyze unique_tbl_p; + +set enable_partitionwise_join to on; + +select * from unique_tbl_p t1, unique_tbl_p t2 +where (t1.a, t2.a) in (select a, a from unique_tbl_p t3) +order by t1.a, t2.a; + +reset enable_partitionwise_join; + +drop table unique_tbl_p; + +create temp table ta (id int primary key, val int); + +insert into ta values(1,1); + +insert into ta values(2,2); + +create temp table tb (id int primary key, aval int); + +insert into tb values(1,1); + +insert into tb values(2,1); + +insert into tb values(3,2); + +insert into tb values(4,2); + +create temp table tc (id int primary key, aid int); + +insert into tc values(1,1); + +insert into tc values(2,2); + +select + ( select min(tb.id) from tb + where tb.aval = (select ta.val from ta where ta.id = tc.aid) ) as min_tb_id +from tc; + +create temp table t1 (f1 numeric(14,0), f2 varchar(30)); + +select * from + (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs + from t1 up) ss +group by f1,f2,fs; + +create temp table table_a(id integer); + +insert into table_a values (42); + +create temp view view_a as select * from table_a; + +select view_a from view_a; + +select (select view_a) from view_a; + +select (select (select view_a)) from view_a; + +select (select (a.*)::text) from view_a a; + +select (1 = any(array_agg(f1))) = any (select false) from int4_tbl; + +select (1 = any(array_agg(f1))) = any (select false) from int4_tbl; + +select q from (select max(f1) from int4_tbl group by f1 order by f1) q; + +with q as (select max(f1) from int4_tbl group by f1 order by f1) + select q from q; + +begin; + +delete from road +where exists ( + select 1 + from + int4_tbl cross join + ( select f1, array(select q1 from int8_tbl) as arr + from text_tbl ) ss + where road.name = ss.f1 ); + +rollback; + +select + (select sq1) as qq1 +from + (select exists(select 1 from int4_tbl where f1 = q2) as sq1, 42 as dummy + from int8_tbl) sq0 + join + int4_tbl i4 on dummy = i4.f1; + +create temp table upsert(key int4 primary key, val text); + +insert into upsert values(1, 'val') on conflict (key) do update set val = 'not seen'; + +insert into upsert values(1, 'val') on conflict (key) do update set val = 'seen with subselect ' || (select f1 from int4_tbl where f1 != 0 limit 1)::text; + +select * from upsert; + +with aa as (select 'int4_tbl' u from int4_tbl limit 1) +insert into upsert values (1, 'x'), (999, 'y') +on conflict (key) do update set val = (select u from aa) +returning *; + +create temp table outer_7597 (f1 int4, f2 int4); + +insert into outer_7597 values (0, 0); + +insert into outer_7597 values (1, 0); + +insert into outer_7597 values (0, null); + +insert into outer_7597 values (1, null); + +create temp table inner_7597(c1 int8, c2 int8); + +insert into inner_7597 values(0, null); + +select * from outer_7597 where (f1, f2) not in (select * from inner_7597); + +create temp table outer_text (f1 text, f2 text); + +insert into outer_text values ('a', 'a'); + +insert into outer_text values ('b', 'a'); + +insert into outer_text values ('a', null); + +insert into outer_text values ('b', null); + +create temp table inner_text (c1 text, c2 text); + +insert into inner_text values ('a', null); + +insert into inner_text values ('123', '456'); + +select * from outer_text where (f1, f2) not in (select * from inner_text); + +select 'foo'::text in (select 'bar'::name union all select 'bar'::name); + +select 'foo'::text in (select 'bar'::name union all select 'bar'::name); + +select row(row(row(1))) = any (select row(row(1))); + +select row(row(row(1))) = any (select row(row(1))); + +select '1'::text in (select '1'::name union all select '1'::name); + +select * from int8_tbl where q1 in (select c1 from inner_text); + +begin; + +create function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $1::text = $2'; + +create operator = (procedure=bogus_int8_text_eq, leftarg=int8, rightarg=text); + +select * from int8_tbl where q1 in (select c1 from inner_text); + +select * from int8_tbl where q1 in (select c1 from inner_text); + +create or replace function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $1::text = $2 and $1::text = $2'; + +select * from int8_tbl where q1 in (select c1 from inner_text); + +select * from int8_tbl where q1 in (select c1 from inner_text); + +create or replace function bogus_int8_text_eq(int8, text) returns boolean +language sql as 'select $2 = $1::text'; + +select * from int8_tbl where q1 in (select c1 from inner_text); + +select * from int8_tbl where q1 in (select c1 from inner_text); + +rollback; + +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); + +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); + +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) + and thousand = 1; + +select count(*) from tenk1 t +where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) + and thousand = 1; + +create temp table exists_tbl (c1 int, c2 int, c3 int) partition by list (c1); + +create temp table exists_tbl_null partition of exists_tbl for values in (null); + +create temp table exists_tbl_def partition of exists_tbl default; + +insert into exists_tbl select x, x/2, x+1 from generate_series(0,10) x; + +analyze exists_tbl; + +select * from exists_tbl t1 + where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0); + +select * from exists_tbl t1 + where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0); + +select a.thousand from tenk1 a, tenk1 b +where a.thousand = b.thousand + and exists ( select 1 from tenk1 c where b.hundred = c.hundred + and not exists ( select 1 from tenk1 d + where a.thousand = d.thousand ) ); + +select x, x from + (select (select now()) as x from (values(1),(2)) v(y)) ss; + +select x, x from + (select (select random()) as x from (values(1),(2)) v(y)) ss; + +select x, x from + (select (select now() where y=y) as x from (values(1),(2)) v(y)) ss; + +select x, x from + (select (select random() where y=y) as x from (values(1),(2)) v(y)) ss; + +select sum(ss.tst::int) from + onek o cross join lateral ( + select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, + random() as r + from onek i where i.unique1 = o.unique1 ) ss +where o.ten = 0; + +select sum(ss.tst::int) from + onek o cross join lateral ( + select i.ten in (select f1 from int4_tbl where f1 <= o.hundred) as tst, + random() as r + from onek i where i.unique1 = o.unique1 ) ss +where o.ten = 0; + +begin; + +set local enable_sort = off; + +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1; + +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1; + +rollback; + +begin; + +set local enable_hashagg = off; + +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1; + +select count(*) from + onek o cross join lateral ( + select * from onek i1 where i1.unique1 = o.unique1 + except + select * from onek i2 where i2.unique1 = o.unique2 + ) ss +where o.ten = 1; + +rollback; + +select sum(o.four), sum(ss.a) from + onek o cross join lateral ( + with recursive x(a) as + (select o.four as a + union + select a + 1 from x + where a < 10) + select * from x + ) ss +where o.ten = 1; + +select sum(o.four), sum(ss.a) from + onek o cross join lateral ( + with recursive x(a) as + (select o.four as a + union + select a + 1 from x + where a < 10) + select * from x + ) ss +where o.ten = 1; + +create temp table notinouter (a int); + +create temp table notininner (b int not null); + +insert into notinouter values (null), (1); + +select * from notinouter where a not in (select b from notininner); + +create temp table nocolumns(); + +select exists(select * from nocolumns); + +select val.x + from generate_series(1,10) as s(i), + lateral ( + values ((select s.i + 1)), (s.i + 101) + ) as val(x) +where s.i < 10 and (select val.x) < 110; + +select * from +(values + (3 not in (select * from (values (1), (2)) ss1)), + (false) +) ss; + +select * from +(values + (3 not in (select * from (values (1), (2)) ss1)), + (false) +) ss; + +select * from int4_tbl where + (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in + (select ten from tenk1 b); + +select * from int4_tbl where + (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in + (select ten from tenk1 b); + +select * from int4_tbl o where (f1, f1) in + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); + +select * from int4_tbl o where (f1, f1) in + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); + +select (select q from + (select 1,2,3 where f1 > 0 + union all + select 4,5,6.0 where f1 <= 0 + ) q ) +from int4_tbl; + +select * from + int4_tbl i4, + lateral ( + select i4.f1 > 1 as b, 1 as id + from (select random() order by 1) as t1 + union all + select true as b, 2 as id + ) as t2 +where b and f1 >= 0; + +select * from + int4_tbl i4, + lateral ( + select i4.f1 > 1 as b, 1 as id + from (select random() order by 1) as t1 + union all + select true as b, 2 as id + ) as t2 +where b and f1 >= 0; + +create temp sequence ts1; + +select * from + (select distinct ten from tenk1) ss + where ten < 10 + nextval('ts1') + order by 1; + +select nextval('ts1'); + +create function tattle(x int, y int) returns bool +volatile language plpgsql as $$ +begin + raise notice 'x = %, y = %', x, y; + return x > y; +end$$; + +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8); + +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8); + +alter function tattle(x int, y int) stable; + +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8); + +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, 8); + +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, u); + +select * from + (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss + where tattle(x, u); + +drop function tattle(x int, y int); + +create table sq_limit (pk int primary key, c1 int, c2 int); + +insert into sq_limit values + (1, 1, 1), + (2, 2, 2), + (3, 3, 3), + (4, 4, 4), + (5, 1, 1), + (6, 2, 2), + (7, 3, 3), + (8, 4, 4); + +create function explain_sq_limit() returns setof text language plpgsql as +$$ +declare ln text; +begin + for ln in + explain (analyze, summary off, timing off, costs off, buffers off) + select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3 + loop + ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx'); + return next ln; + end loop; +end; +$$; + +select * from explain_sq_limit(); + +select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3; + +drop function explain_sq_limit(); + +drop table sq_limit; + +begin; + +declare c1 scroll cursor for + select * from generate_series(1,4) i + where i <> all (values (2),(3)); + +move forward all in c1; + +fetch backward all in c1; + +commit; + +begin; + +create temp table json_tab (a int); + +insert into json_tab values (1); + +select * from json_tab t1 left join (select json_array(1, a) from json_tab t2) s on false; + +select * from json_tab t1 left join (select json_array(1, a) from json_tab t2) s on false; + +rollback; + +select tname, attname from ( +select relname::information_schema.sql_identifier as tname, * from + (select * from pg_class c) ss1) ss2 + right join pg_attribute a on a.attrelid = ss2.oid +where tname = 'tenk1' and attnum = 1; + +select tname, attname from ( +select relname::information_schema.sql_identifier as tname, * from + (select * from pg_class c) ss1) ss2 + right join pg_attribute a on a.attrelid = ss2.oid +where tname = 'tenk1' and attnum = 1; + +select t1.ten, sum(x) from + tenk1 t1 left join lateral ( + select t1.ten + t2.ten as x, t2.fivethous from tenk1 t2 + ) ss on t1.unique1 = ss.fivethous +group by t1.ten +order by t1.ten; + +select t1.ten, sum(x) from + tenk1 t1 left join lateral ( + select t1.ten + t2.ten as x, t2.fivethous from tenk1 t2 + ) ss on t1.unique1 = ss.fivethous +group by t1.ten +order by t1.ten; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 inner join + lateral (select t2.q1+1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 inner join + lateral (select t2.q1+1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q1+1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) + on t1.q2 = t2.q2 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 inner join + lateral (select t2.q2 as x, * from int8_tbl t3) ss on t2.q2 = ss.q1) + on t1.q1 = t2.q1 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 inner join + lateral (select t2.q2 as x, * from int8_tbl t3) ss on t2.q2 = ss.q1) + on t1.q1 = t2.q1 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q2 as x, * from int8_tbl t3) ss on t2.q2 = ss.q1) + on t1.q1 = t2.q1 +order by 1, 2; + +select t1.q1, x from + int8_tbl t1 left join + (int8_tbl t2 left join + lateral (select t2.q2 as x, * from int8_tbl t3) ss on t2.q2 = ss.q1) + on t1.q1 = t2.q1 +order by 1, 2; + +select ss2.* from + int8_tbl t1 left join + (int8_tbl t2 left join + (select coalesce(q1, q1) as x, * from int8_tbl t3) ss1 on t2.q1 = ss1.q2 inner join + lateral (select ss1.x as y, * from int8_tbl t4) ss2 on t2.q2 = ss2.q1) + on t1.q2 = ss2.q1 +order by 1, 2, 3; + +select ss2.* from + int8_tbl t1 left join + (int8_tbl t2 left join + (select coalesce(q1, q1) as x, * from int8_tbl t3) ss1 on t2.q1 = ss1.q2 inner join + lateral (select ss1.x as y, * from int8_tbl t4) ss2 on t2.q2 = ss2.q1) + on t1.q2 = ss2.q1 +order by 1, 2, 3; + +select ss2.* from + int8_tbl t1 left join + (int8_tbl t2 left join + (select coalesce(q1, q1) as x, * from int8_tbl t3) ss1 on t2.q1 = ss1.q2 left join + lateral (select ss1.x as y, * from int8_tbl t4) ss2 on t2.q2 = ss2.q1) + on t1.q2 = ss2.q1 +order by 1, 2, 3; + +select ss2.* from + int8_tbl t1 left join + (int8_tbl t2 left join + (select coalesce(q1, q1) as x, * from int8_tbl t3) ss1 on t2.q1 = ss1.q2 left join + lateral (select ss1.x as y, * from int8_tbl t4) ss2 on t2.q2 = ss2.q1) + on t1.q2 = ss2.q1 +order by 1, 2, 3; + +with x as (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1; diff --git a/crates/pgt_pretty_print/tests/data/multi/sysviews_60.sql b/crates/pgt_pretty_print/tests/data/multi/sysviews_60.sql new file mode 100644 index 000000000..b6fde340a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/sysviews_60.sql @@ -0,0 +1,70 @@ +select count(*) >= 0 as ok from pg_available_extension_versions; + +select count(*) >= 0 as ok from pg_available_extensions; + +select type, name, ident, level, total_bytes >= free_bytes + from pg_backend_memory_contexts where level = 1; + +begin; + +declare cur cursor for select left(a,10), b + from (values(repeat('a', 512 * 1024),1),(repeat('b', 512),2)) v(a,b) + order by v.a desc; + +fetch 1 from cur; + +select type, name, total_bytes > 0, total_nblocks, free_bytes > 0, free_chunks +from pg_backend_memory_contexts where name = 'Caller tuples'; + +rollback; + +with contexts as ( + select * from pg_backend_memory_contexts +) +select count(*) > 1 +from contexts c1, contexts c2 +where c2.name = 'CacheMemoryContext' +and c1.path[c2.level] = c2.path[c2.level]; + +select count(*) > 20 as ok from pg_config; + +select count(*) = 0 as ok from pg_cursors; + +select count(*) >= 0 as ok from pg_file_settings; + +select count(*) > 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err + from pg_hba_file_rules; + +select count(*) >= 0 as ok, count(*) FILTER (WHERE error IS NOT NULL) = 0 AS no_err + from pg_ident_file_mappings; + +select count(*) > 0 as ok from pg_locks; + +select count(*) = 0 as ok from pg_prepared_statements; + +select count(*) >= 0 as ok from pg_prepared_xacts; + +select count(*) > 0 as ok from pg_stat_slru; + +select count(*) = 1 as ok from pg_stat_wal; + +select count(*) = 0 as ok from pg_stat_wal_receiver; + +select name, setting from pg_settings where name like 'enable%'; + +select type, count(*) > 0 as ok FROM pg_wait_events + where type <> 'InjectionPoint' group by type order by type COLLATE "C"; + +select count(distinct utc_offset) >= 24 as ok from pg_timezone_names; + +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs; + +set timezone_abbreviations = 'Australia'; + +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs; + +set timezone_abbreviations = 'India'; + +select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs; + +select * from pg_timezone_abbrevs where abbrev = 'LMT'; diff --git a/crates/pgt_pretty_print/tests/data/multi/tablesample_60.sql b/crates/pgt_pretty_print/tests/data/multi/tablesample_60.sql new file mode 100644 index 000000000..58dcebe02 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tablesample_60.sql @@ -0,0 +1,127 @@ +CREATE TABLE test_tablesample (id int, name text) WITH (fillfactor=10); + +INSERT INTO test_tablesample + SELECT i, repeat(i::text, 200) FROM generate_series(0, 9) s(i); + +SELECT t.id FROM test_tablesample AS t TABLESAMPLE SYSTEM (50) REPEATABLE (0); + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (100.0/11) REPEATABLE (0); + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0); + +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (50) REPEATABLE (0); + +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (5.5) REPEATABLE (0); + +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100); + +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (1+2); + +SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (0.4); + +CREATE VIEW test_tablesample_v1 AS + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (10*2) REPEATABLE (2); + +CREATE VIEW test_tablesample_v2 AS + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (99); + +BEGIN; + +DECLARE tablesample_cur SCROLL CURSOR FOR + SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0); + +FETCH FIRST FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0); + +FETCH NEXT FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +FETCH FIRST FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +FETCH NEXT FROM tablesample_cur; + +CLOSE tablesample_cur; + +END; + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (2); + +SELECT * FROM test_tablesample_v1; + +select count(*) from person tablesample bernoulli (100); + +select count(*) from person tablesample bernoulli (100); + +select count(*) from person; + +SELECT count(*) FROM test_tablesample TABLESAMPLE bernoulli (('1'::text < '0'::text)::int); + +select * from + (values (0),(100)) v(pct), + lateral (select count(*) from tenk1 tablesample bernoulli (pct)) ss; + +select * from + (values (0),(100)) v(pct), + lateral (select count(*) from tenk1 tablesample system (pct)) ss; + +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample bernoulli (pct)) ss + group by pct; + +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample bernoulli (pct)) ss + group by pct; + +select pct, count(unique1) from + (values (0),(100)) v(pct), + lateral (select * from tenk1 tablesample system (pct)) ss + group by pct; + +SELECT id FROM test_tablesample TABLESAMPLE FOOBAR (1); + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (NULL); + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (NULL); + +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (-1); + +SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (200); + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (-1); + +SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (200); + +SELECT id FROM test_tablesample_v1 TABLESAMPLE BERNOULLI (1); + +INSERT INTO test_tablesample_v1 VALUES(1); + +WITH query_select AS (SELECT * FROM test_tablesample) +SELECT * FROM query_select TABLESAMPLE BERNOULLI (5.5) REPEATABLE (1); + +create table parted_sample (a int) partition by list (a); + +create table parted_sample_1 partition of parted_sample for values in (1); + +create table parted_sample_2 partition of parted_sample for values in (2); + +select * from parted_sample tablesample bernoulli (100); + +drop table parted_sample, parted_sample_1, parted_sample_2; diff --git a/crates/pgt_pretty_print/tests/data/multi/tablespace_60.sql b/crates/pgt_pretty_print/tests/data/multi/tablespace_60.sql new file mode 100644 index 000000000..95dd4b684 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tablespace_60.sql @@ -0,0 +1,463 @@ +CREATE TABLESPACE regress_tblspace LOCATION 'relative'; + +CREATE TABLESPACE regress_tblspace LOCATION ''; + +SET allow_in_place_tablespaces = true; + +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (some_nonexistent_parameter = true); + +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (random_page_cost = 3.0); + +SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; + +DROP TABLESPACE regress_tblspacewith; + +SELECT regexp_replace(pg_tablespace_location(oid), '(pg_tblspc)/(\d+)', '\1/NNN') + FROM pg_tablespace WHERE spcname = 'regress_tblspace'; + +ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1); + +ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true); + +ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0); + +ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency); + +REINDEX (TABLESPACE regress_tblspace) TABLE pg_am; + +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_am; + +REINDEX (TABLESPACE regress_tblspace) TABLE pg_authid; + +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_authid; + +REINDEX (TABLESPACE regress_tblspace) INDEX pg_toast.pg_toast_1262_index; + +REINDEX (TABLESPACE regress_tblspace) INDEX CONCURRENTLY pg_toast.pg_toast_1262_index; + +REINDEX (TABLESPACE regress_tblspace) TABLE pg_toast.pg_toast_1262; + +REINDEX (TABLESPACE regress_tblspace) TABLE CONCURRENTLY pg_toast.pg_toast_1262; + +REINDEX (TABLESPACE pg_global) TABLE pg_authid; + +REINDEX (TABLESPACE pg_global) TABLE CONCURRENTLY pg_authid; + +CREATE TABLE regress_tblspace_test_tbl (num1 bigint, num2 double precision, t text); + +INSERT INTO regress_tblspace_test_tbl (num1, num2, t) + SELECT round(random()*100), random(), 'text' + FROM generate_series(1, 10) s(i); + +CREATE INDEX regress_tblspace_test_tbl_idx ON regress_tblspace_test_tbl (num1); + +REINDEX (TABLESPACE pg_global) INDEX regress_tblspace_test_tbl_idx; + +REINDEX (TABLESPACE pg_global) INDEX CONCURRENTLY regress_tblspace_test_tbl_idx; + +BEGIN; + +REINDEX (TABLESPACE regress_tblspace) INDEX regress_tblspace_test_tbl_idx; + +REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl; + +ROLLBACK; + +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace'; + +SELECT relfilenode as main_filenode FROM pg_class + WHERE relname = 'regress_tblspace_test_tbl_idx' ; + +SELECT relfilenode as toast_filenode FROM pg_class + WHERE oid = + (SELECT i.indexrelid + FROM pg_class c, + pg_index i + WHERE i.indrelid = c.reltoastrelid AND + c.relname = 'regress_tblspace_test_tbl') ; + +REINDEX (TABLESPACE regress_tblspace) TABLE regress_tblspace_test_tbl; + +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname; + +ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE regress_tblspace; + +ALTER TABLE regress_tblspace_test_tbl SET TABLESPACE pg_default; + +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname; + +ALTER INDEX regress_tblspace_test_tbl_idx SET TABLESPACE pg_default; + +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname; + +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE regress_tblspace_test_tbl; + +SELECT c.relname FROM pg_class c, pg_tablespace s + WHERE c.reltablespace = s.oid AND s.spcname = 'regress_tblspace' + ORDER BY c.relname; + +SELECT relfilenode = 'main_filenode' AS main_same FROM pg_class + WHERE relname = 'regress_tblspace_test_tbl_idx'; + +SELECT relfilenode = 'toast_filenode' as toast_same FROM pg_class + WHERE oid = + (SELECT i.indexrelid + FROM pg_class c, + pg_index i + WHERE i.indrelid = c.reltoastrelid AND + c.relname = 'regress_tblspace_test_tbl'); + +DROP TABLE regress_tblspace_test_tbl; + +CREATE TABLE tbspace_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1); + +CREATE TABLE tbspace_reindex_part_0 PARTITION OF tbspace_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2); + +CREATE TABLE tbspace_reindex_part_0_1 PARTITION OF tbspace_reindex_part_0 + FOR VALUES IN (1); + +CREATE TABLE tbspace_reindex_part_0_2 PARTITION OF tbspace_reindex_part_0 + FOR VALUES IN (2); + +CREATE TABLE tbspace_reindex_part_10 PARTITION OF tbspace_reindex_part + FOR VALUES FROM (10) TO (20) PARTITION BY list (c2); + +CREATE INDEX tbspace_reindex_part_index ON ONLY tbspace_reindex_part (c1); + +CREATE INDEX tbspace_reindex_part_index_0 ON ONLY tbspace_reindex_part_0 (c1); + +ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_0; + +CREATE INDEX tbspace_reindex_part_index_10 ON ONLY tbspace_reindex_part_10 (c1); + +ALTER INDEX tbspace_reindex_part_index ATTACH PARTITION tbspace_reindex_part_index_10; + +CREATE INDEX tbspace_reindex_part_index_0_1 ON ONLY tbspace_reindex_part_0_1 (c1); + +ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_1; + +CREATE INDEX tbspace_reindex_part_index_0_2 ON ONLY tbspace_reindex_part_0_2 (c1); + +ALTER INDEX tbspace_reindex_part_index_0 ATTACH PARTITION tbspace_reindex_part_index_0_2; + +SELECT relid, parentrelid, level FROM pg_partition_tree('tbspace_reindex_part_index') + ORDER BY relid, level; + +CREATE TEMP TABLE reindex_temp_before AS + SELECT oid, relname, relfilenode, reltablespace + FROM pg_class + WHERE relname ~ 'tbspace_reindex_part_index'; + +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tbspace_reindex_part; + +SELECT b.relname, + CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' + ELSE 'relfilenode has changed' END AS filenode, + CASE WHEN a.reltablespace = b.reltablespace THEN 'reltablespace is unchanged' + ELSE 'reltablespace has changed' END AS tbspace + FROM reindex_temp_before b JOIN pg_class a ON b.relname = a.relname + ORDER BY 1; + +DROP TABLE tbspace_reindex_part; + +CREATE SCHEMA testschema; + +CREATE TABLE testschema.foo (i int) TABLESPACE regress_tblspace; + +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'foo'; + +INSERT INTO testschema.foo VALUES(1); + +INSERT INTO testschema.foo VALUES(2); + +CREATE TABLE testschema.asselect TABLESPACE regress_tblspace AS SELECT 1; + +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'asselect'; + +PREPARE selectsource(int) AS SELECT $1; + +CREATE TABLE testschema.asexecute TABLESPACE regress_tblspace + AS EXECUTE selectsource(2); + +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'asexecute'; + +CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE regress_tblspace; + +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname = 'foo_idx'; + +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); + +SET default_tablespace TO pg_global; + +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); + +RESET default_tablespace; + +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); + +SET default_tablespace TO regress_tblspace; + +CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2); + +SET default_tablespace TO pg_global; + +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); + +ALTER TABLE testschema.part SET TABLESPACE regress_tblspace; + +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); + +CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) + TABLESPACE pg_default; + +CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) + PARTITION BY LIST (a); + +ALTER TABLE testschema.part SET TABLESPACE pg_default; + +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); + +CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) + PARTITION BY LIST (a) TABLESPACE regress_tblspace; + +RESET default_tablespace; + +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); + +SELECT relname, spcname FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) + LEFT JOIN pg_catalog.pg_tablespace t ON c.reltablespace = t.oid + where c.relname LIKE 'part%' AND n.nspname = 'testschema' order by relname; + +RESET default_tablespace; + +DROP TABLE testschema.part; + +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); + +CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1); + +CREATE INDEX part_a_idx ON testschema.part (a) TABLESPACE regress_tblspace; + +CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2); + +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname LIKE 'part%_idx' ORDER BY relname; + +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE pg_default; + +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE pg_default) PARTITION BY LIST (a); + +SET default_tablespace TO 'pg_default'; + +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE regress_tblspace; + +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a); + +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a) TABLESPACE regress_tblspace; + +SET default_tablespace TO ''; + +CREATE TABLE testschema.dflt2 (a int PRIMARY KEY) PARTITION BY LIST (a); + +DROP TABLE testschema.dflt, testschema.dflt2; + +CREATE TABLE testschema.test_default_tab(id bigint) TABLESPACE regress_tblspace; + +INSERT INTO testschema.test_default_tab VALUES (1); + +CREATE INDEX test_index1 on testschema.test_default_tab (id); + +CREATE INDEX test_index2 on testschema.test_default_tab (id) TABLESPACE regress_tblspace; + +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index3 PRIMARY KEY (id); + +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace; + +SET default_tablespace TO regress_tblspace; + +ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint; + +SELECT * FROM testschema.test_default_tab; + +ALTER TABLE testschema.test_default_tab ALTER id TYPE int; + +SELECT * FROM testschema.test_default_tab; + +SET default_tablespace TO ''; + +ALTER TABLE testschema.test_default_tab ALTER id TYPE int; + +ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint; + +DROP TABLE testschema.test_default_tab; + +CREATE TABLE testschema.test_default_tab_p(id bigint, val bigint) + PARTITION BY LIST (id) TABLESPACE regress_tblspace; + +CREATE TABLE testschema.test_default_tab_p1 PARTITION OF testschema.test_default_tab_p + FOR VALUES IN (1); + +INSERT INTO testschema.test_default_tab_p VALUES (1); + +CREATE INDEX test_index1 on testschema.test_default_tab_p (val); + +CREATE INDEX test_index2 on testschema.test_default_tab_p (val) TABLESPACE regress_tblspace; + +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index3 PRIMARY KEY (id); + +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace; + +SET default_tablespace TO regress_tblspace; + +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint; + +SELECT * FROM testschema.test_default_tab_p; + +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int; + +SELECT * FROM testschema.test_default_tab_p; + +SET default_tablespace TO ''; + +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int; + +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint; + +DROP TABLE testschema.test_default_tab_p; + +CREATE TABLE testschema.test_tab(id int) TABLESPACE regress_tblspace; + +INSERT INTO testschema.test_tab VALUES (1); + +SET default_tablespace TO regress_tblspace; + +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (id); + +SET default_tablespace TO ''; + +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_pkey PRIMARY KEY (id); + +SELECT * FROM testschema.test_tab; + +DROP TABLE testschema.test_tab; + +CREATE TABLE testschema.test_tab(a int, b int, c int); + +SET default_tablespace TO regress_tblspace; + +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (a); + +CREATE INDEX test_tab_a_idx ON testschema.test_tab (a); + +SET default_tablespace TO ''; + +CREATE INDEX test_tab_b_idx ON testschema.test_tab (b); + +ALTER TABLE testschema.test_tab ALTER b TYPE bigint, ADD UNIQUE (c); + +DROP TABLE testschema.test_tab; + +CREATE TABLE testschema.atable AS VALUES (1), (2); + +CREATE UNIQUE INDEX anindex ON testschema.atable(column1); + +ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace; + +ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace; + +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_global; + +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default; + +ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace; + +INSERT INTO testschema.atable VALUES(3); + +INSERT INTO testschema.atable VALUES(1); + +SELECT COUNT(*) FROM testschema.atable; + +CREATE MATERIALIZED VIEW testschema.amv AS SELECT * FROM testschema.atable; + +ALTER MATERIALIZED VIEW testschema.amv SET TABLESPACE regress_tblspace; + +REFRESH MATERIALIZED VIEW testschema.amv; + +SELECT COUNT(*) FROM testschema.amv; + +CREATE TABLESPACE regress_badspace LOCATION '/no/such/location'; + +CREATE TABLE bar (i int) TABLESPACE regress_nosuchspace; + +DROP TABLESPACE regress_tblspace; + +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default; + +DROP TABLESPACE regress_tblspace; + +BEGIN; + +GRANT ALL ON TABLESPACE regress_tblspace TO PUBLIC; + +ROLLBACK; + +CREATE ROLE regress_tablespace_user1 login; + +CREATE ROLE regress_tablespace_user2 login; + +GRANT USAGE ON SCHEMA testschema TO regress_tablespace_user2; + +ALTER TABLESPACE regress_tblspace OWNER TO regress_tablespace_user1; + +CREATE TABLE testschema.tablespace_acl (c int); + +CREATE INDEX k ON testschema.tablespace_acl (c) TABLESPACE regress_tblspace; + +ALTER TABLE testschema.tablespace_acl OWNER TO regress_tablespace_user2; + +SET SESSION ROLE regress_tablespace_user2; + +CREATE TABLE tablespace_table (i int) TABLESPACE regress_tblspace; + +ALTER TABLE testschema.tablespace_acl ALTER c TYPE bigint; + +REINDEX (TABLESPACE regress_tblspace) TABLE tablespace_table; + +REINDEX (TABLESPACE regress_tblspace, CONCURRENTLY) TABLE tablespace_table; + +RESET ROLE; + +ALTER TABLESPACE regress_tblspace RENAME TO regress_tblspace_renamed; + +ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default; + +ALTER INDEX ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default; + +ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default; + +ALTER TABLE ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default; + +ALTER MATERIALIZED VIEW ALL IN TABLESPACE regress_tblspace_renamed SET TABLESPACE pg_default; + +DROP TABLESPACE regress_tblspace_renamed; + +DROP SCHEMA testschema CASCADE; + +DROP ROLE regress_tablespace_user1; + +DROP ROLE regress_tablespace_user2; diff --git a/crates/pgt_pretty_print/tests/data/multi/temp_60.sql b/crates/pgt_pretty_print/tests/data/multi/temp_60.sql new file mode 100644 index 000000000..404d8063e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/temp_60.sql @@ -0,0 +1,426 @@ +CREATE TABLE temptest(col int); + +CREATE INDEX i_temptest ON temptest(col); + +CREATE TEMP TABLE temptest(tcol int); + +CREATE INDEX i_temptest ON temptest(tcol); + +SELECT * FROM temptest; + +DROP INDEX i_temptest; + +DROP TABLE temptest; + +SELECT * FROM temptest; + +DROP INDEX i_temptest; + +DROP TABLE temptest; + +CREATE TABLE temptest(col int); + +INSERT INTO temptest VALUES (1); + +CREATE TEMP TABLE temptest(tcol float); + +INSERT INTO temptest VALUES (2.1); + +SELECT * FROM temptest; + +DROP TABLE temptest; + +SELECT * FROM temptest; + +DROP TABLE temptest; + +CREATE TEMP TABLE temptest(col int); + +SELECT * FROM temptest; + +CREATE INDEX ON temptest(bit_length('')); + +BEGIN; + +INSERT INTO temptest VALUES (1); + +INSERT INTO temptest VALUES (2); + +SELECT * FROM temptest; + +COMMIT; + +SELECT * FROM temptest; + +DROP TABLE temptest; + +BEGIN; + +SELECT * FROM temptest; + +COMMIT; + +SELECT * FROM temptest; + +DROP TABLE temptest; + +BEGIN; + +CREATE TEMP TABLE temptest(col int) ON COMMIT DROP; + +INSERT INTO temptest VALUES (1); + +INSERT INTO temptest VALUES (2); + +SELECT * FROM temptest; + +COMMIT; + +SELECT * FROM temptest; + +BEGIN; + +CREATE TEMP TABLE temptest(col) ON COMMIT DROP AS SELECT 1; + +SELECT * FROM temptest; + +COMMIT; + +SELECT * FROM temptest; + +BEGIN; + +do $$ +begin + execute format($cmd$ + CREATE TEMP TABLE temptest (col text CHECK (col < %L)) ON COMMIT DROP + $cmd$, + (SELECT string_agg(g.i::text || ':' || random()::text, '|') + FROM generate_series(1, 100) g(i))); +end$$; + +SELECT * FROM temptest; + +COMMIT; + +SELECT * FROM temptest; + +BEGIN; + +CREATE TEMP TABLE temptest1(col int PRIMARY KEY); + +INSERT INTO temptest1 VALUES (1); + +INSERT INTO temptest2 VALUES (1); + +COMMIT; + +SELECT * FROM temptest1; + +SELECT * FROM temptest2; + +BEGIN; + +CREATE TEMP TABLE temptest4(col int REFERENCES temptest3); + +COMMIT; + +create table public.whereami (f1 text); + +insert into public.whereami values ('public'); + +create temp table whereami (f1 text); + +insert into whereami values ('temp'); + +create function public.whoami() returns text + as $$select 'public'::text$$ language sql; + +create function pg_temp.whoami() returns text + as $$select 'temp'::text$$ language sql; + +select * from whereami; + +select whoami(); + +set search_path = pg_temp, public; + +select * from whereami; + +select whoami(); + +set search_path = public, pg_temp; + +select * from whereami; + +select whoami(); + +select pg_temp.whoami(); + +drop table public.whereami; + +set search_path = pg_temp, public; + +create domain pg_temp.nonempty as text check (value <> ''); + +select nonempty(''); + +select pg_temp.nonempty(''); + +select ''::nonempty; + +reset search_path; + +begin; + +insert into temp_parted_oncommit values (1); + +commit; + +select * from temp_parted_oncommit; + +drop table temp_parted_oncommit; + +begin; + +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit drop; + +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop; + +insert into temp_parted_oncommit_test values (1), (2); + +commit; + +select relname from pg_class where relname ~ '^temp_parted_oncommit_test'; + +begin; + +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit preserve rows; + +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop; + +insert into temp_parted_oncommit_test values (1), (2); + +commit; + +select * from temp_parted_oncommit_test; + +select relname from pg_class where relname ~ '^temp_parted_oncommit_test' + order by relname; + +drop table temp_parted_oncommit_test; + +begin; + +create temp table temp_inh_oncommit_test (a int) on commit drop; + +insert into temp_inh_oncommit_test1 values (1); + +commit; + +select relname from pg_class where relname ~ '^temp_inh_oncommit_test'; + +begin; + +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit drop; + +insert into temp_inh_oncommit_test1 values (1); + +insert into temp_inh_oncommit_test values (1); + +commit; + +select * from temp_inh_oncommit_test; + +select relname from pg_class where relname ~ '^temp_inh_oncommit_test'; + +drop table temp_inh_oncommit_test; + +begin; + +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql; + +prepare transaction 'twophase_func'; + +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql; + +begin; + +drop function pg_temp.twophase_func(); + +prepare transaction 'twophase_func'; + +begin; + +create operator pg_temp.@@ (leftarg = int4, rightarg = int4, procedure = int4mi); + +prepare transaction 'twophase_operator'; + +begin; + +create type pg_temp.twophase_type as (a int); + +prepare transaction 'twophase_type'; + +begin; + +create view pg_temp.twophase_view as select 1; + +prepare transaction 'twophase_view'; + +begin; + +create sequence pg_temp.twophase_seq; + +prepare transaction 'twophase_sequence'; + +create temp table twophase_tab (a int); + +begin; + +select a from twophase_tab; + +prepare transaction 'twophase_tab'; + +begin; + +insert into twophase_tab values (1); + +prepare transaction 'twophase_tab'; + +begin; + +lock twophase_tab in access exclusive mode; + +prepare transaction 'twophase_tab'; + +begin; + +drop table twophase_tab; + +prepare transaction 'twophase_tab'; + +SET search_path TO 'pg_temp'; + +BEGIN; + +SELECT current_schema() ~ 'pg_temp' AS is_temp_schema; + +PREPARE TRANSACTION 'twophase_search'; + +SET temp_buffers = 100; + +CREATE TEMPORARY TABLE test_temp(a int not null unique, b TEXT not null, cnt int not null); + +INSERT INTO test_temp SELECT generate_series(1, 10000) as id, repeat('a', 200), 0; + +SELECT pg_relation_size('test_temp') / current_setting('block_size')::int8 > 200; + +CREATE FUNCTION test_temp_pin(p_start int, p_end int) +RETURNS void +LANGUAGE plpgsql +AS $f$ + DECLARE + cursorname text; + query text; + BEGIN + FOR i IN p_start..p_end LOOP + cursorname = 'c_'||i; + query = format($q$DECLARE %I CURSOR FOR SELECT ctid FROM test_temp WHERE ctid >= '( %s, 1)'::tid $q$, cursorname, i); + EXECUTE query; + EXECUTE 'FETCH NEXT FROM '||cursorname; + -- for test development + -- RAISE NOTICE '%: %', cursorname, query; + END LOOP; + END; +$f$; + +BEGIN; + +SELECT test_temp_pin(0, 9); + +SELECT test_temp_pin(10, 105); + +ROLLBACK; + +BEGIN; + +SELECT test_temp_pin(0, 9); + +FETCH NEXT FROM c_3; + +SAVEPOINT rescue_me; + +SELECT test_temp_pin(10, 105); + +ROLLBACK TO SAVEPOINT rescue_me; + +FETCH NEXT FROM c_3; + +SELECT test_temp_pin(10, 94); + +SELECT count(*), max(a) max_a, min(a) min_a, max(cnt) max_cnt FROM test_temp; + +ROLLBACK; + +BEGIN; + +SELECT test_temp_pin(0, 1); + +DROP TABLE test_temp; + +COMMIT; + +BEGIN; + +SELECT test_temp_pin(0, 1); + +TRUNCATE test_temp; + +COMMIT; + +SELECT count(*), max(a) max_a, min(a) min_a, max(cnt) max_cnt FROM test_temp; + +INSERT INTO test_temp(a, b, cnt) VALUES (-1, '', 0); + +BEGIN; + +INSERT INTO test_temp(a, b, cnt) VALUES (-2, '', 0); + +DROP TABLE test_temp; + +ROLLBACK; + +SELECT count(*), max(a) max_a, min(a) min_a, max(cnt) max_cnt FROM test_temp; + +UPDATE test_temp SET cnt = cnt + 1 WHERE a = -1; + +BEGIN; + +DROP TABLE test_temp; + +ROLLBACK; + +SELECT count(*), max(a) max_a, min(a) min_a, max(cnt) max_cnt FROM test_temp; + +UPDATE test_temp SET cnt = cnt + 1 WHERE a = -1; + +BEGIN; + +TRUNCATE test_temp; + +ROLLBACK; + +SELECT count(*), max(a) max_a, min(a) min_a, max(cnt) max_cnt FROM test_temp; + +DROP FUNCTION test_temp_pin(int, int); diff --git a/crates/pgt_pretty_print/tests/data/multi/test_setup_60.sql b/crates/pgt_pretty_print/tests/data/multi/test_setup_60.sql new file mode 100644 index 000000000..eef50aa38 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/test_setup_60.sql @@ -0,0 +1,250 @@ +SET synchronous_commit = on; + +GRANT ALL ON SCHEMA public TO public; + +SET allow_in_place_tablespaces = true; + +CREATE TABLESPACE regress_tblspace LOCATION ''; + +CREATE TABLE CHAR_TBL(f1 char(4)); + +INSERT INTO CHAR_TBL (f1) VALUES + ('a'), + ('ab'), + ('abcd'), + ('abcd '); + +VACUUM CHAR_TBL; + +CREATE TABLE FLOAT8_TBL(f1 float8); + +INSERT INTO FLOAT8_TBL(f1) VALUES + ('0.0'), + ('-34.84'), + ('-1004.30'), + ('-1.2345678901234e+200'), + ('-1.2345678901234e-200'); + +VACUUM FLOAT8_TBL; + +CREATE TABLE INT2_TBL(f1 int2); + +INSERT INTO INT2_TBL(f1) VALUES + ('0 '), + (' 1234 '), + (' -1234'), + ('32767'), -- largest and smallest values + ('-32767'); + +VACUUM INT2_TBL; + +CREATE TABLE INT4_TBL(f1 int4); + +INSERT INTO INT4_TBL(f1) VALUES + (' 0 '), + ('123456 '), + (' -123456'), + ('2147483647'), -- largest and smallest values + ('-2147483647'); + +VACUUM INT4_TBL; + +CREATE TABLE INT8_TBL(q1 int8, q2 int8); + +INSERT INTO INT8_TBL VALUES + (' 123 ',' 456'), + ('123 ','4567890123456789'), + ('4567890123456789','123'), + (+4567890123456789,'4567890123456789'), + ('+4567890123456789','-4567890123456789'); + +VACUUM INT8_TBL; + +CREATE TABLE POINT_TBL(f1 point); + +INSERT INTO POINT_TBL(f1) VALUES + ('(0.0,0.0)'), + ('(-10.0,0.0)'), + ('(-3.0,4.0)'), + ('(5.1, 34.5)'), + ('(-5.0,-12.0)'), + ('(1e-300,-1e-300)'), -- To underflow + ('(1e+300,Inf)'), -- To overflow + ('(Inf,1e+300)'), -- Transposed + (' ( Nan , NaN ) '), + ('10.0,10.0'); + +CREATE TABLE TEXT_TBL (f1 text); + +INSERT INTO TEXT_TBL VALUES + ('doh!'), + ('hi de ho neighbor'); + +VACUUM TEXT_TBL; + +CREATE TABLE VARCHAR_TBL(f1 varchar(4)); + +INSERT INTO VARCHAR_TBL (f1) VALUES + ('a'), + ('ab'), + ('abcd'), + ('abcd '); + +VACUUM VARCHAR_TBL; + +CREATE TABLE onek ( + unique1 int4, + unique2 int4, + two int4, + four int4, + ten int4, + twenty int4, + hundred int4, + thousand int4, + twothousand int4, + fivethous int4, + tenthous int4, + odd int4, + even int4, + stringu1 name, + stringu2 name, + string4 name +); + +COPY onek FROM 'filename'; + +VACUUM ANALYZE onek; + +CREATE TABLE onek2 AS SELECT * FROM onek; + +VACUUM ANALYZE onek2; + +CREATE TABLE tenk1 ( + unique1 int4, + unique2 int4, + two int4, + four int4, + ten int4, + twenty int4, + hundred int4, + thousand int4, + twothousand int4, + fivethous int4, + tenthous int4, + odd int4, + even int4, + stringu1 name, + stringu2 name, + string4 name +); + +COPY tenk1 FROM 'filename'; + +VACUUM ANALYZE tenk1; + +CREATE TABLE tenk2 AS SELECT * FROM tenk1; + +VACUUM ANALYZE tenk2; + +CREATE TABLE person ( + name text, + age int4, + location point +); + +COPY person FROM 'filename'; + +VACUUM ANALYZE person; + +CREATE TABLE emp ( + salary int4, + manager name +) INHERITS (person); + +COPY emp FROM 'filename'; + +VACUUM ANALYZE emp; + +CREATE TABLE student ( + gpa float8 +) INHERITS (person); + +COPY student FROM 'filename'; + +VACUUM ANALYZE student; + +CREATE TABLE stud_emp ( + percent int4 +) INHERITS (emp, student); + +COPY stud_emp FROM 'filename'; + +VACUUM ANALYZE stud_emp; + +CREATE TABLE road ( + name text, + thepath path +); + +COPY road FROM 'filename'; + +VACUUM ANALYZE road; + +CREATE TABLE ihighway () INHERITS (road); + +INSERT INTO ihighway + SELECT * + FROM ONLY road + WHERE name ~ 'I- .*'; + +VACUUM ANALYZE ihighway; + +CREATE TABLE shighway ( + surface text +) INHERITS (road); + +INSERT INTO shighway + SELECT *, 'asphalt' + FROM ONLY road + WHERE name ~ 'State Hwy.*'; + +VACUUM ANALYZE shighway; + +create type stoplight as enum ('red', 'yellow', 'green'); + +create type float8range as range (subtype = float8, subtype_diff = float8mi); + +create type textrange as range (subtype = text, collation = "C"); + +CREATE FUNCTION binary_coercible(oid, oid) + RETURNS bool + AS 'regresslib', 'binary_coercible' + LANGUAGE C STRICT STABLE PARALLEL SAFE; + +create function part_hashint4_noop(value int4, seed int8) + returns int8 as $$ + select value + seed; + $$ language sql strict immutable parallel safe; + +create operator class part_test_int4_ops for type int4 using hash as + operator 1 =, + function 2 part_hashint4_noop(int4, int8); + +create function part_hashtext_length(value text, seed int8) + returns int8 as $$ + select length(coalesce(value, ''))::int8 + $$ language sql strict immutable parallel safe; + +create operator class part_test_text_ops for type text using hash as + operator 1 =, + function 2 part_hashtext_length(text, int8); + +create function fipshash(bytea) + returns text + strict immutable parallel safe leakproof + return substr(encode(sha256($1), 'hex'), 1, 32); + +create function fipshash(text) + returns text + strict immutable parallel safe leakproof + return substr(encode(sha256($1::bytea), 'hex'), 1, 32); diff --git a/crates/pgt_pretty_print/tests/data/multi/text_60.sql b/crates/pgt_pretty_print/tests/data/multi/text_60.sql new file mode 100644 index 000000000..48cd9cbb5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/text_60.sql @@ -0,0 +1,146 @@ +SELECT text 'this is a text string' = text 'this is a text string' AS true; + +SELECT text 'this is a text string' = text 'this is a text strin' AS false; + +SELECT * FROM TEXT_TBL; + +select length(42); + +select 'four: '::text || 2+2; + +select 'four: ' || 2+2; + +select 3 || 4.0; + +select concat('one'); + +select concat(1,2,3,'hello',true, false, to_date('20100309','YYYYMMDD')); + +select concat_ws('#','one'); + +select concat_ws('#',1,2,3,'hello',true, false, to_date('20100309','YYYYMMDD')); + +select concat_ws(',',10,20,null,30); + +select concat_ws('',10,20,null,30); + +select concat_ws(NULL,10,20,null,30) is null; + +select reverse('abcde'); + +select i, left('ahoj', i), right('ahoj', i) from generate_series(-5, 5) t(i) order by i; + +select quote_literal(''); + +select quote_literal('abc'''); + +select quote_literal(e'\\'); + +select concat(variadic array[1,2,3]); + +select concat_ws(',', variadic array[1,2,3]); + +select concat_ws(',', variadic NULL::int[]); + +select concat(variadic NULL::int[]) is NULL; + +select concat(variadic '{}'::int[]) = ''; + +select concat_ws(',', variadic 10); + +select format(NULL); + +select format('Hello'); + +select format('Hello %s', 'World'); + +select format('Hello %%'); + +select format('Hello %%%%'); + +select format('Hello %s %s', 'World'); + +select format('Hello %s'); + +select format('Hello %x', 20); + +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, 'Hello'); + +select format('%s%s%s','Hello', NULL,'World'); + +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', 10, NULL); + +select format('INSERT INTO %I VALUES(%L,%L)', 'mytab', NULL, 'Hello'); + +select format('INSERT INTO %I VALUES(%L,%L)', NULL, 10, 'Hello'); + +select format('%1$s %3$s', 1, 2, 3); + +select format('%1$s %12$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); + +select format('%1$s %4$s', 1, 2, 3); + +select format('%1$s %13$s', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); + +select format('%0$s', 'Hello'); + +select format('%*0$s', 'Hello'); + +select format('%1$', 1); + +select format('%1$1', 1); + +select format('Hello %s %1$s %s', 'World', 'Hello again'); + +select format('Hello %s %s, %2$s %2$s', 'World', 'Hello again'); + +select format('%s, %s', variadic array['Hello','World']); + +select format('%s, %s', variadic array[1, 2]); + +select format('%s, %s', variadic array[true, false]); + +select format('%s, %s', variadic array[true, false]::text[]); + +select format('%2$s, %1$s', variadic array['first', 'second']); + +select format('%2$s, %1$s', variadic array[1, 2]); + +select format('Hello', variadic NULL::int[]); + +select format(string_agg('%s',','), variadic array_agg(i)) +from generate_series(1,200) g(i); + +select format('>>%10s<<', 'Hello'); + +select format('>>%10s<<', NULL); + +select format('>>%10s<<', ''); + +select format('>>%-10s<<', ''); + +select format('>>%-10s<<', 'Hello'); + +select format('>>%-10s<<', NULL); + +select format('>>%1$10s<<', 'Hello'); + +select format('>>%1$-10I<<', 'Hello'); + +select format('>>%2$*1$L<<', 10, 'Hello'); + +select format('>>%2$*1$L<<', 10, NULL); + +select format('>>%2$*1$L<<', -10, NULL); + +select format('>>%*s<<', 10, 'Hello'); + +select format('>>%*1$s<<', 10, 'Hello'); + +select format('>>%-s<<', 'Hello'); + +select format('>>%10L<<', NULL); + +select format('>>%2$*1$L<<', NULL, 'Hello'); + +select format('>>%2$*1$L<<', 0, 'Hello'); diff --git a/crates/pgt_pretty_print/tests/data/multi/tid_60.sql b/crates/pgt_pretty_print/tests/data/multi/tid_60.sql new file mode 100644 index 000000000..118e52c4f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tid_60.sql @@ -0,0 +1,85 @@ +SELECT + '(0,0)'::tid as tid00, + '(0,1)'::tid as tid01, + '(-1,0)'::tid as tidm10, + '(4294967295,65535)'::tid as tidmax; + +SELECT '(4294967296,1)'::tid; + +SELECT '(1,65536)'::tid; + +SELECT pg_input_is_valid('(0)', 'tid'); + +SELECT * FROM pg_input_error_info('(0)', 'tid'); + +SELECT pg_input_is_valid('(0,-1)', 'tid'); + +SELECT * FROM pg_input_error_info('(0,-1)', 'tid'); + +CREATE TABLE tid_tab (a int); + +INSERT INTO tid_tab VALUES (1), (2); + +SELECT min(ctid) FROM tid_tab; + +SELECT max(ctid) FROM tid_tab; + +TRUNCATE tid_tab; + +CREATE MATERIALIZED VIEW tid_matview AS SELECT a FROM tid_tab; + +SELECT currtid2('tid_matview'::text, '(0,1)'::tid); + +INSERT INTO tid_tab VALUES (1); + +REFRESH MATERIALIZED VIEW tid_matview; + +SELECT currtid2('tid_matview'::text, '(0,1)'::tid); + +DROP MATERIALIZED VIEW tid_matview; + +TRUNCATE tid_tab; + +CREATE SEQUENCE tid_seq; + +SELECT currtid2('tid_seq'::text, '(0,1)'::tid); + +DROP SEQUENCE tid_seq; + +CREATE INDEX tid_ind ON tid_tab(a); + +SELECT currtid2('tid_ind'::text, '(0,1)'::tid); + +DROP INDEX tid_ind; + +CREATE TABLE tid_part (a int) PARTITION BY RANGE (a); + +SELECT currtid2('tid_part'::text, '(0,1)'::tid); + +DROP TABLE tid_part; + +CREATE VIEW tid_view_no_ctid AS SELECT a FROM tid_tab; + +SELECT currtid2('tid_view_no_ctid'::text, '(0,1)'::tid); + +DROP VIEW tid_view_no_ctid; + +CREATE VIEW tid_view_with_ctid AS SELECT ctid, a FROM tid_tab; + +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); + +INSERT INTO tid_tab VALUES (1); + +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); + +DROP VIEW tid_view_with_ctid; + +TRUNCATE tid_tab; + +CREATE VIEW tid_view_fake_ctid AS SELECT 1 AS ctid, 2 AS a; + +SELECT currtid2('tid_view_fake_ctid'::text, '(0,1)'::tid); + +DROP VIEW tid_view_fake_ctid; + +DROP TABLE tid_tab CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/tidrangescan_60.sql b/crates/pgt_pretty_print/tests/data/multi/tidrangescan_60.sql new file mode 100644 index 000000000..9d0ef3ae9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tidrangescan_60.sql @@ -0,0 +1,95 @@ +SET enable_seqscan TO off; + +CREATE TABLE tidrangescan(id integer, data text); + +SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)'; + +SELECT ctid FROM tidrangescan WHERE ctid < '(1, 0)'; + +SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)'; + +SELECT ctid FROM tidrangescan WHERE ctid > '(9, 0)'; + +INSERT INTO tidrangescan SELECT i,repeat('x', 100) FROM generate_series(1,200) AS s(i); + +DELETE FROM tidrangescan +WHERE substring(ctid::text FROM ',(\d+)\)')::integer > 10 OR substring(ctid::text FROM '\((\d+),')::integer > 2; + +VACUUM tidrangescan; + +SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'; + +SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'; + +SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)'; + +SELECT ctid FROM tidrangescan WHERE ctid <= '(1,5)'; + +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)'; + +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)'; + +SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)'; + +SELECT ctid FROM tidrangescan WHERE ctid > '(2,8)'; + +SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid; + +SELECT ctid FROM tidrangescan WHERE '(2,8)' < ctid; + +SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)'; + +SELECT ctid FROM tidrangescan WHERE ctid >= '(2,8)'; + +SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)'; + +SELECT ctid FROM tidrangescan WHERE ctid >= '(100,0)'; + +SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid; + +SELECT ctid FROM tidrangescan WHERE ctid > '(1,4)' AND '(1,7)' >= ctid; + +SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)'; + +SELECT ctid FROM tidrangescan WHERE '(1,7)' >= ctid AND ctid > '(1,4)'; + +SELECT ctid FROM tidrangescan WHERE ctid > '(0,65535)' AND ctid < '(1,0)' LIMIT 1; + +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)' LIMIT 1; + +SELECT ctid FROM tidrangescan WHERE ctid > '(4294967295,65535)'; + +SELECT ctid FROM tidrangescan WHERE ctid < '(0,0)'; + +SELECT ctid FROM tidrangescan WHERE ctid >= (SELECT NULL::tid); + +SELECT t.ctid,t2.c FROM tidrangescan t, +LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2 +WHERE t.ctid < '(1,0)'; + +SELECT t.ctid,t2.c FROM tidrangescan t, +LATERAL (SELECT count(*) c FROM tidrangescan t2 WHERE t2.ctid <= t.ctid) t2 +WHERE t.ctid < '(1,0)'; + +EXPLAIN (COSTS OFF) +DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'; + +BEGIN; + +DECLARE c SCROLL CURSOR FOR SELECT ctid FROM tidrangescan WHERE ctid < '(1,0)'; + +FETCH NEXT c; + +FETCH NEXT c; + +FETCH PRIOR c; + +FETCH FIRST c; + +FETCH LAST c; + +COMMIT; + +DROP TABLE tidrangescan; + +RESET enable_seqscan; diff --git a/crates/pgt_pretty_print/tests/data/multi/tidscan_60.sql b/crates/pgt_pretty_print/tests/data/multi/tidscan_60.sql new file mode 100644 index 000000000..6ec2983d0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tidscan_60.sql @@ -0,0 +1,104 @@ +CREATE TABLE tidscan(id integer); + +INSERT INTO tidscan VALUES (1), (2), (3); + +SELECT ctid, * FROM tidscan; + +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)'; + +SELECT ctid, * FROM tidscan WHERE ctid = '(0,1)'; + +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid; + +SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid; + +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; + +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; + +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + +SELECT ctid, * FROM tidscan WHERE ctid != ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1); + +SELECT ctid, * FROM tidscan +WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1); + +SET enable_hashjoin TO off; + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + +RESET enable_hashjoin; + +BEGIN; + +DECLARE c CURSOR FOR +SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); + +FETCH ALL FROM c; + +FETCH BACKWARD 1 FROM c; + +FETCH FIRST FROM c; + +ROLLBACK; + +BEGIN; + +DECLARE c CURSOR FOR SELECT ctid, * FROM tidscan; + +FETCH NEXT FROM c; + +FETCH NEXT FROM c; + +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; + +FETCH NEXT FROM c; + +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; + +SELECT * FROM tidscan; + +FETCH NEXT FROM c; + +UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; + +ROLLBACK; + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + +SET enable_hashjoin TO off; + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + +RESET enable_hashjoin; + +BEGIN ISOLATION LEVEL SERIALIZABLE; + +SELECT * FROM tidscan WHERE ctid = '(0,1)'; + +SELECT locktype, mode FROM pg_locks WHERE pid = pg_backend_pid() AND mode = 'SIReadLock'; + +ROLLBACK; + +DROP TABLE tidscan; diff --git a/crates/pgt_pretty_print/tests/data/multi/time_60.sql b/crates/pgt_pretty_print/tests/data/multi/time_60.sql new file mode 100644 index 000000000..f249ca544 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/time_60.sql @@ -0,0 +1,87 @@ +CREATE TABLE TIME_TBL (f1 time(2)); + +INSERT INTO TIME_TBL VALUES ('00:00'); + +INSERT INTO TIME_TBL VALUES ('01:00'); + +INSERT INTO TIME_TBL VALUES ('02:03 PST'); + +INSERT INTO TIME_TBL VALUES ('11:59 EDT'); + +INSERT INTO TIME_TBL VALUES ('12:00'); + +INSERT INTO TIME_TBL VALUES ('12:01'); + +INSERT INTO TIME_TBL VALUES ('23:59'); + +INSERT INTO TIME_TBL VALUES ('11:59:59.99 PM'); + +INSERT INTO TIME_TBL VALUES ('2003-03-07 15:36:39 America/New_York'); + +INSERT INTO TIME_TBL VALUES ('2003-07-07 15:36:39 America/New_York'); + +INSERT INTO TIME_TBL VALUES ('15:36:39 America/New_York'); + +SELECT f1 AS "Time" FROM TIME_TBL; + +SELECT f1 AS "Three" FROM TIME_TBL WHERE f1 < '05:06:07'; + +SELECT f1 AS "Five" FROM TIME_TBL WHERE f1 > '05:06:07'; + +SELECT f1 AS "None" FROM TIME_TBL WHERE f1 < '00:00'; + +SELECT f1 AS "Eight" FROM TIME_TBL WHERE f1 >= '00:00'; + +SELECT '23:59:59.999999'::time; + +SELECT '23:59:59.9999999'::time; + +SELECT '23:59:60'::time; + +SELECT '24:00:00'::time; + +SELECT '24:00:00.01'::time; + +SELECT '23:59:60.01'::time; + +SELECT '24:01:00'::time; + +SELECT '25:00:00'::time; + +SELECT pg_input_is_valid('12:00:00', 'time'); + +SELECT pg_input_is_valid('25:00:00', 'time'); + +SELECT pg_input_is_valid('15:36:39 America/New_York', 'time'); + +SELECT * FROM pg_input_error_info('25:00:00', 'time'); + +SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'time'); + +SELECT f1 + time '00:01' AS "Illegal" FROM TIME_TBL; + +SELECT EXTRACT(MICROSECOND FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(MILLISECOND FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(SECOND FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(MINUTE FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(HOUR FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(DAY FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(FORTNIGHT FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(TIMEZONE FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT EXTRACT(EPOCH FROM TIME '2020-05-26 13:30:25.575401'); + +SELECT date_part('microsecond', TIME '2020-05-26 13:30:25.575401'); + +SELECT date_part('millisecond', TIME '2020-05-26 13:30:25.575401'); + +SELECT date_part('second', TIME '2020-05-26 13:30:25.575401'); + +SELECT date_part('epoch', TIME '2020-05-26 13:30:25.575401'); diff --git a/crates/pgt_pretty_print/tests/data/multi/timestamp_60.sql b/crates/pgt_pretty_print/tests/data/multi/timestamp_60.sql new file mode 100644 index 000000000..2ef105530 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/timestamp_60.sql @@ -0,0 +1,484 @@ +CREATE TABLE TIMESTAMP_TBL (d1 timestamp(2) without time zone); + +BEGIN; + +INSERT INTO TIMESTAMP_TBL VALUES ('today'); + +INSERT INTO TIMESTAMP_TBL VALUES ('yesterday'); + +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow'); + +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow EST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('tomorrow zulu'); + +SELECT count(*) AS One FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'today'; + +SELECT count(*) AS Three FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'tomorrow'; + +SELECT count(*) AS One FROM TIMESTAMP_TBL WHERE d1 = timestamp without time zone 'yesterday'; + +COMMIT; + +DELETE FROM TIMESTAMP_TBL; + +INSERT INTO TIMESTAMP_TBL VALUES ('now'); + +SELECT pg_sleep(0.1); + +BEGIN; + +INSERT INTO TIMESTAMP_TBL VALUES ('now'); + +SELECT pg_sleep(0.1); + +INSERT INTO TIMESTAMP_TBL VALUES ('now'); + +SELECT pg_sleep(0.1); + +SELECT count(*) AS two FROM TIMESTAMP_TBL WHERE d1 = timestamp(2) without time zone 'now'; + +SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM TIMESTAMP_TBL; + +COMMIT; + +TRUNCATE TIMESTAMP_TBL; + +INSERT INTO TIMESTAMP_TBL VALUES ('-infinity'); + +INSERT INTO TIMESTAMP_TBL VALUES ('infinity'); + +INSERT INTO TIMESTAMP_TBL VALUES ('epoch'); + +SELECT timestamp 'infinity' = timestamp '+infinity' AS t; + +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.4 1997 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.5 1997 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.6 1997 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-01-02'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-01-02 03:04:05'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01-08'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01-0800'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01 -08:00'); + +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 -0800'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 17:32:01 -07:00'); + +INSERT INTO TIMESTAMP_TBL VALUES ('2001-09-22T18:19:20'); + +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 08:14:01 GMT+8'); + +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 13:14:02 GMT-1'); + +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 12:14:03 GMT-2'); + +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 03:14:04 PST+8'); + +INSERT INTO TIMESTAMP_TBL VALUES ('2000-03-15 02:14:05 MST+7:00'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997 -0800'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 5:32PM 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997/02/10 17:32:01-0800'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-02-10 17:32:01 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb-10-1997 17:32:01 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('02-10-1997 17:32:01 PST'); + +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 PST'); + +set datestyle to ymd; + +INSERT INTO TIMESTAMP_TBL VALUES ('97FEB10 5:32:01PM UTC'); + +INSERT INTO TIMESTAMP_TBL VALUES ('97/02/10 17:32:01 UTC'); + +reset datestyle; + +INSERT INTO TIMESTAMP_TBL VALUES ('1997.041 17:32:01 UTC'); + +INSERT INTO TIMESTAMP_TBL VALUES ('19970210 173201 America/New_York'); + +INSERT INTO TIMESTAMP_TBL VALUES ('19970710 173201 America/Does_not_exist'); + +SELECT pg_input_is_valid('now', 'timestamp'); + +SELECT pg_input_is_valid('garbage', 'timestamp'); + +SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp'); + +SELECT * FROM pg_input_error_info('garbage', 'timestamp'); + +SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamp'); + +INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 18:32:01 PDT'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 11 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 12 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 13 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 14 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 15 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0097 BC'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0097'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 0597'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1097'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1697'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1797'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1897'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 2097'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1996'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1996'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1996'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1996'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1996'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1997'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1999'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2000'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 2000'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Jan 01 17:32:01 2001'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 -0097'); + +INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 5097 BC'); + +SELECT d1 FROM TIMESTAMP_TBL; + +SELECT '4714-11-24 00:00:00 BC'::timestamp; + +SELECT '4714-11-23 23:59:59 BC'::timestamp; + +SELECT '294276-12-31 23:59:59'::timestamp; + +SELECT '294277-01-01 00:00:00'::timestamp; + +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 > timestamp without time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 < timestamp without time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 = timestamp without time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 != timestamp without time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 <= timestamp without time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMP_TBL + WHERE d1 >= timestamp without time zone '1997-01-02'; + +SELECT d1 - timestamp without time zone '1997-01-02' AS diff + FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; + +SELECT date_trunc( 'week', timestamp '2004-02-29 15:44:17.71393' ) AS week_trunc; + +SELECT date_trunc( 'week', timestamp 'infinity' ) AS inf_trunc; + +SELECT date_trunc( 'timezone', timestamp '2004-02-29 15:44:17.71393' ) AS notsupp_trunc; + +SELECT date_trunc( 'timezone', timestamp 'infinity' ) AS notsupp_inf_trunc; + +SELECT date_trunc( 'ago', timestamp 'infinity' ) AS invalid_trunc; + +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2001-01-01') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '2020-02-29 15:44:17.71393')) ts (ts); + +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2000-01-01 BC') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '0055-6-10 15:44:17.71393 BC')) ts (ts); + +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '2020-03-02') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '2020-02-29 15:44:17.71393')) ts (ts); + +SELECT + str, + interval, + date_trunc(str, ts) = date_bin(interval::interval, ts, timestamp '0055-06-17 BC') AS equal +FROM ( + VALUES + ('week', '7 d'), + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamp '0055-6-10 15:44:17.71393 BC')) ts (ts); + +SELECT + interval, + ts, + origin, + date_bin(interval::interval, ts, origin) +FROM ( + VALUES + ('15 days'), + ('2 hours'), + ('1 hour 30 minutes'), + ('15 minutes'), + ('10 seconds'), + ('100 milliseconds'), + ('250 microseconds') +) intervals (interval), +(VALUES (timestamp '2020-02-11 15:44:17.71393')) ts (ts), +(VALUES (timestamp '2001-01-01')) origin (origin); + +SELECT date_bin('5 min'::interval, timestamp '2020-02-01 01:01:01', timestamp '2020-02-01 00:02:30'); + +SELECT date_bin('30 minutes'::interval, timestamp '2024-02-01 15:00:00', timestamp '2024-02-01 17:00:00'); + +SELECT date_bin('5 months'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01'); + +SELECT date_bin('5 years'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01'); + +SELECT date_bin('0 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00'); + +SELECT date_bin('-2 days'::interval, timestamp '1970-01-01 01:00:00' , timestamp '1970-01-01 00:00:00'); + +select date_bin('15 minutes'::interval, timestamp '294276-12-30', timestamp '4000-12-20 BC'); + +select date_bin('200000000 days'::interval, '2024-02-01'::timestamp, '2024-01-01'::timestamp); + +select date_bin('365000 days'::interval, '4400-01-01 BC'::timestamp, '4000-01-01 BC'::timestamp); + +SELECT d1 - timestamp without time zone '1997-01-02' AS diff + FROM TIMESTAMP_TBL + WHERE d1 BETWEEN timestamp without time zone '1902-01-01' + AND timestamp without time zone '2038-01-01'; + +SELECT d1 as "timestamp", + date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, + date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, + date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second + FROM TIMESTAMP_TBL; + +SELECT d1 as "timestamp", + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMP_TBL; + +SELECT d1 as "timestamp", + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow, + date_part( 'doy', d1) AS doy + FROM TIMESTAMP_TBL; + +SELECT d1 as "timestamp", + date_part( 'decade', d1) AS decade, + date_part( 'century', d1) AS century, + date_part( 'millennium', d1) AS millennium, + round(date_part( 'julian', d1)) AS julian, + date_part( 'epoch', d1) AS epoch + FROM TIMESTAMP_TBL; + +SELECT d1 as "timestamp", + extract(microseconds from d1) AS microseconds, + extract(milliseconds from d1) AS milliseconds, + extract(seconds from d1) AS seconds, + round(extract(julian from d1)) AS julian, + extract(epoch from d1) AS epoch + FROM TIMESTAMP_TBL; + +SELECT date_part('epoch', '294270-01-01 00:00:00'::timestamp); + +SELECT extract(epoch from '294270-01-01 00:00:00'::timestamp); + +SELECT extract(epoch from '5000-01-01 00:00:00'::timestamp); + +SELECT timestamp '294276-12-31 23:59:59' - timestamp '1999-12-23 19:59:04.224193' AS ok; + +SELECT timestamp '294276-12-31 23:59:59' - timestamp '1999-12-23 19:59:04.224192' AS overflows; + +SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM FMWW FMDDD FMDD FMD FMJ') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'HH24--text--MI--text--SS') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'YYYYTH YYYYth Jth') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') + FROM TIMESTAMP_TBL; + +SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') + FROM TIMESTAMP_TBL; + +SELECT to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamp), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d); + +SELECT i, + to_char(i * interval '1mon', 'rm'), + to_char(i * interval '1mon', 'RM') + FROM generate_series(-13, 13) i; + +SELECT make_timestamp(2014, 12, 28, 6, 30, 45.887); + +SELECT make_timestamp(-44, 3, 15, 12, 30, 15); + +select make_timestamp(0, 7, 15, 12, 30, 15); + +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '1 hour'::interval); + +select generate_series('2022-01-01 00:00'::timestamp, + 'infinity'::timestamp, + '1 month'::interval) limit 10; + +select * from generate_series('2020-01-01 00:00'::timestamp, + '2020-01-02 03:00'::timestamp, + '0 hour'::interval); + +select generate_series(timestamp '1995-08-06 12:12:12', timestamp '1996-08-06 12:12:12', interval 'infinity'); + +select generate_series(timestamp '1995-08-06 12:12:12', timestamp '1996-08-06 12:12:12', interval '-infinity'); + +select timestamp 'infinity' - timestamp 'infinity'; + +select timestamp 'infinity' - timestamp '-infinity'; + +select timestamp '-infinity' - timestamp 'infinity'; + +select timestamp '-infinity' - timestamp '-infinity'; + +select timestamp 'infinity' - timestamp '1995-08-06 12:12:12'; + +select timestamp '-infinity' - timestamp '1995-08-06 12:12:12'; + +select age(timestamp 'infinity'); + +select age(timestamp '-infinity'); + +select age(timestamp 'infinity', timestamp 'infinity'); + +select age(timestamp 'infinity', timestamp '-infinity'); + +select age(timestamp '-infinity', timestamp 'infinity'); + +select age(timestamp '-infinity', timestamp '-infinity'); + +select timestamp '1999-12-31 24:00:00'; + +select make_timestamp(1999, 12, 31, 24, 0, 0); diff --git a/crates/pgt_pretty_print/tests/data/multi/timestamptz_60.sql b/crates/pgt_pretty_print/tests/data/multi/timestamptz_60.sql new file mode 100644 index 000000000..cdb0a4471 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/timestamptz_60.sql @@ -0,0 +1,913 @@ +CREATE TABLE TIMESTAMPTZ_TBL (d1 timestamp(2) with time zone); + +BEGIN; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('today'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('yesterday'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow EST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('tomorrow zulu'); + +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'today'; + +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow'; + +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'yesterday'; + +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow EST'; + +SELECT count(*) AS One FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp with time zone 'tomorrow zulu'; + +COMMIT; + +DELETE FROM TIMESTAMPTZ_TBL; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now'); + +SELECT pg_sleep(0.1); + +BEGIN; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now'); + +SELECT pg_sleep(0.1); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('now'); + +SELECT pg_sleep(0.1); + +SELECT count(*) AS two FROM TIMESTAMPTZ_TBL WHERE d1 = timestamp(2) with time zone 'now'; + +SELECT count(d1) AS three, count(DISTINCT d1) AS two FROM TIMESTAMPTZ_TBL; + +COMMIT; + +TRUNCATE TIMESTAMPTZ_TBL; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('-infinity'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('infinity'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('epoch'); + +SELECT timestamptz 'infinity' = timestamptz '+infinity' AS t; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.4 1997 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.5 1997 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.6 1997 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-01-02'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-01-02 03:04:05'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01-08'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01-0800'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01 -08:00'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 -0800'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-06-10 17:32:01 -07:00'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2001-09-22T18:19:20'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 08:14:01 GMT+8'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 13:14:02 GMT-1'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 12:14:03 GMT-2'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 03:14:04 PST+8'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('2000-03-15 02:14:05 MST+7:00'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997 -0800'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 5:32PM 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997/02/10 17:32:01-0800'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-02-10 17:32:01 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb-10-1997 17:32:01 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('02-10-1997 17:32:01 PST'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 PST'); + +set datestyle to ymd; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('97FEB10 5:32:01PM UTC'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('97/02/10 17:32:01 UTC'); + +reset datestyle; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997.041 17:32:01 UTC'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970210 173201 America/New_York'); + +SELECT '19970210 173201' AT TIME ZONE 'America/New_York'; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America/New_York'); + +SELECT '19970710 173201' AT TIME ZONE 'America/New_York'; + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America/Does_not_exist'); + +SELECT '19970710 173201' AT TIME ZONE 'America/Does_not_exist'; + +SELECT '20500710 173201 Europe/Helsinki'::timestamptz; + +SELECT '20500110 173201 Europe/Helsinki'::timestamptz; + +SELECT '205000-07-10 17:32:01 Europe/Helsinki'::timestamptz; + +SELECT '205000-01-10 17:32:01 Europe/Helsinki'::timestamptz; + +SELECT 'Jan 01 00:00:00 1000 LMT'::timestamptz; + +SELECT 'Jan 01 00:00:00 2024 LMT'::timestamptz; + +SET timezone = 'Europe/London'; + +SELECT 'Jan 01 00:00:00 1000 LMT'::timestamptz; + +SELECT 'Jan 01 00:00:00 2024 LMT'::timestamptz; + +SET timezone = 'UTC'; + +SELECT 'Jan 01 00:00:00 2024 LMT'::timestamptz; + +SELECT '1912-01-01 00:00 MMT'::timestamptz; + +SET timezone = 'America/Montevideo'; + +SELECT '1912-01-01 00:00'::timestamptz; + +SELECT '1912-01-01 00:00 MMT'::timestamptz; + +SELECT '1912-01-01 00:00 MMT'::timestamptz AT TIME ZONE 'UTC'; + +RESET timezone; + +SELECT pg_input_is_valid('now', 'timestamptz'); + +SELECT pg_input_is_valid('garbage', 'timestamptz'); + +SELECT pg_input_is_valid('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz'); + +SELECT * FROM pg_input_error_info('garbage', 'timestamptz'); + +SELECT * FROM pg_input_error_info('2001-01-01 00:00 Nehwon/Lankhmar', 'timestamptz'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('1997-06-10 18:32:01 PDT'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 10 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 11 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 12 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 13 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 14 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 15 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0097 BC'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0097'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 0597'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1097'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1697'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1797'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1897'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 2097'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1996'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1996'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1996'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1996'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1996'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1997'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1999'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2000'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 2000'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Jan 01 17:32:01 2001'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097'); + +INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC'); + +SELECT 'Wed Jul 11 10:51:14 America/New_York 2001'::timestamptz; + +SELECT 'Wed Jul 11 10:51:14 GMT-4 2001'::timestamptz; + +SELECT 'Wed Jul 11 10:51:14 GMT+4 2001'::timestamptz; + +SELECT 'Wed Jul 11 10:51:14 PST-03:00 2001'::timestamptz; + +SELECT 'Wed Jul 11 10:51:14 PST+03:00 2001'::timestamptz; + +SELECT d1 FROM TIMESTAMPTZ_TBL; + +SELECT '4714-11-24 00:00:00+00 BC'::timestamptz; + +SELECT '4714-11-23 16:00:00-08 BC'::timestamptz; + +SELECT 'Sun Nov 23 16:00:00 4714 PST BC'::timestamptz; + +SELECT '4714-11-23 23:59:59+00 BC'::timestamptz; + +SELECT '294276-12-31 23:59:59+00'::timestamptz; + +SELECT '294276-12-31 15:59:59-08'::timestamptz; + +SELECT '294277-01-01 00:00:00+00'::timestamptz; + +SELECT '294277-12-31 16:00:00-08'::timestamptz; + +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 > timestamp with time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 < timestamp with time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 = timestamp with time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 != timestamp with time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 <= timestamp with time zone '1997-01-02'; + +SELECT d1 FROM TIMESTAMPTZ_TBL + WHERE d1 >= timestamp with time zone '1997-01-02'; + +SELECT d1 - timestamp with time zone '1997-01-02' AS diff + FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01'; + +SELECT date_trunc( 'week', timestamp with time zone '2004-02-29 15:44:17.71393' ) AS week_trunc; + +SELECT date_trunc( 'week', timestamp with time zone 'infinity' ) AS inf_trunc; + +SELECT date_trunc( 'timezone', timestamp with time zone '2004-02-29 15:44:17.71393' ) AS notsupp_trunc; + +SELECT date_trunc( 'timezone', timestamp with time zone 'infinity' ) AS notsupp_inf_trunc; + +SELECT date_trunc( 'ago', timestamp with time zone 'infinity' ) AS invalid_trunc; + +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'Australia/Sydney') as sydney_trunc; + +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'GMT') as gmt_trunc; + +SELECT date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'VET') as vet_trunc; + +SELECT date_trunc('timezone', timestamp with time zone 'infinity', 'GMT') AS notsupp_zone_trunc; + +SELECT date_trunc( 'week', timestamp with time zone 'infinity', 'GMT') AS inf_zone_trunc; + +SELECT date_trunc('ago', timestamp with time zone 'infinity', 'GMT') AS invalid_zone_trunc; + +SELECT + str, + interval, + date_trunc(str, ts, 'Australia/Sydney') = date_bin(interval::interval, ts, timestamp with time zone '2001-01-01+11') AS equal +FROM ( + VALUES + ('day', '1 d'), + ('hour', '1 h'), + ('minute', '1 m'), + ('second', '1 s'), + ('millisecond', '1 ms'), + ('microsecond', '1 us') +) intervals (str, interval), +(VALUES (timestamptz '2020-02-29 15:44:17.71393+00')) ts (ts); + +SELECT + interval, + ts, + origin, + date_bin(interval::interval, ts, origin) +FROM ( + VALUES + ('15 days'), + ('2 hours'), + ('1 hour 30 minutes'), + ('15 minutes'), + ('10 seconds'), + ('100 milliseconds'), + ('250 microseconds') +) intervals (interval), +(VALUES (timestamptz '2020-02-11 15:44:17.71393')) ts (ts), +(VALUES (timestamptz '2001-01-01')) origin (origin); + +SELECT date_bin('5 min'::interval, timestamptz '2020-02-01 01:01:01+00', timestamptz '2020-02-01 00:02:30+00'); + +SELECT date_bin('30 minutes'::interval, timestamptz '2024-02-01 15:00:00', timestamptz '2024-02-01 17:00:00'); + +SELECT date_bin('5 months'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00'); + +SELECT date_bin('5 years'::interval, timestamp with time zone '2020-02-01 01:01:01+00', timestamp with time zone '2001-01-01+00'); + +SELECT date_bin('0 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00'); + +SELECT date_bin('-2 days'::interval, timestamp with time zone '1970-01-01 01:00:00+00' , timestamp with time zone '1970-01-01 00:00:00+00'); + +select date_bin('15 minutes'::interval, timestamptz '294276-12-30', timestamptz '4000-12-20 BC'); + +select date_bin('200000000 days'::interval, '2024-02-01'::timestamptz, '2024-01-01'::timestamptz); + +select date_bin('365000 days'::interval, '4400-01-01 BC'::timestamptz, '4000-01-01 BC'::timestamptz); + +SELECT d1 - timestamp with time zone '1997-01-02' AS diff + FROM TIMESTAMPTZ_TBL + WHERE d1 BETWEEN timestamp with time zone '1902-01-01' AND timestamp with time zone '2038-01-01'; + +SELECT d1 as timestamptz, + date_part( 'year', d1) AS year, date_part( 'month', d1) AS month, + date_part( 'day', d1) AS day, date_part( 'hour', d1) AS hour, + date_part( 'minute', d1) AS minute, date_part( 'second', d1) AS second + FROM TIMESTAMPTZ_TBL; + +SELECT d1 as timestamptz, + date_part( 'quarter', d1) AS quarter, date_part( 'msec', d1) AS msec, + date_part( 'usec', d1) AS usec + FROM TIMESTAMPTZ_TBL; + +SELECT d1 as timestamptz, + date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week, + date_part( 'isodow', d1) AS isodow, date_part( 'dow', d1) AS dow, + date_part( 'doy', d1) AS doy + FROM TIMESTAMPTZ_TBL; + +SELECT d1 as timestamptz, + date_part( 'decade', d1) AS decade, + date_part( 'century', d1) AS century, + date_part( 'millennium', d1) AS millennium, + round(date_part( 'julian', d1)) AS julian, + date_part( 'epoch', d1) AS epoch + FROM TIMESTAMPTZ_TBL; + +SELECT d1 as timestamptz, + date_part( 'timezone', d1) AS timezone, + date_part( 'timezone_hour', d1) AS timezone_hour, + date_part( 'timezone_minute', d1) AS timezone_minute + FROM TIMESTAMPTZ_TBL; + +SELECT d1 as "timestamp", + extract(microseconds from d1) AS microseconds, + extract(milliseconds from d1) AS milliseconds, + extract(seconds from d1) AS seconds, + round(extract(julian from d1)) AS julian, + extract(epoch from d1) AS epoch + FROM TIMESTAMPTZ_TBL; + +SELECT date_part('epoch', '294270-01-01 00:00:00+00'::timestamptz); + +SELECT extract(epoch from '294270-01-01 00:00:00+00'::timestamptz); + +SELECT extract(epoch from '5000-01-01 00:00:00+00'::timestamptz); + +SELECT timestamptz '294276-12-31 23:59:59 UTC' - timestamptz '1999-12-23 19:59:04.224193 UTC' AS ok; + +SELECT timestamptz '294276-12-31 23:59:59 UTC' - timestamptz '1999-12-23 19:59:04.224192 UTC' AS overflows; + +SELECT to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth FMRM') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM FMWW FMDDD FMDD FMD FMJ') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'HH HH12 HH24 MI SS SSSS') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, E'"HH:MI:SS is" HH:MI:SS "\\"text between quote marks\\""') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'HH24--text--MI--text--SS') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'YYYYTH YYYYth Jth') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'IYYY IYY IY I IW IDDD ID') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') + FROM TIMESTAMPTZ_TBL; + +SELECT to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamptz), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d); + +SET timezone = '00:00'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '+02:00'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '-13:00'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '-00:30'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '00:30'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '-04:30'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '04:30'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '-04:15'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +SET timezone = '04:15'; + +SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; + +RESET timezone; + +SET timezone = '00:00'; + +SELECT to_char(now(), 'of') as "Of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '+02:00'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '-13:00'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '-00:30'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '00:30'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '-04:30'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '04:30'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '-04:15'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +SET timezone = '04:15'; + +SELECT to_char(now(), 'of') as "of", to_char(now(), 'tzh:tzm') as "tzh:tzm"; + +RESET timezone; + +CREATE TABLE TIMESTAMPTZ_TST (a int , b timestamptz); + +INSERT INTO TIMESTAMPTZ_TST VALUES(1, 'Sat Mar 12 23:58:48 1000 IST'); + +INSERT INTO TIMESTAMPTZ_TST VALUES(2, 'Sat Mar 12 23:58:48 10000 IST'); + +INSERT INTO TIMESTAMPTZ_TST VALUES(3, 'Sat Mar 12 23:58:48 100000 IST'); + +INSERT INTO TIMESTAMPTZ_TST VALUES(3, '10000 Mar 12 23:58:48 IST'); + +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '100000312 23:58:48 IST'); + +INSERT INTO TIMESTAMPTZ_TST VALUES(4, '1000000312 23:58:48 IST'); + +SELECT * FROM TIMESTAMPTZ_TST ORDER BY a; + +DROP TABLE TIMESTAMPTZ_TST; + +set TimeZone to 'America/New_York'; + +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33); + +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '+2'); + +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '-2'); + +WITH tzs (tz) AS (VALUES + ('+1'), ('+1:'), ('+1:0'), ('+100'), ('+1:00'), ('+01:00'), + ('+10'), ('+1000'), ('+10:'), ('+10:0'), ('+10:00'), ('+10:00:'), + ('+10:00:1'), ('+10:00:01'), + ('+10:00:10')) + SELECT make_timestamptz(2010, 2, 27, 3, 45, 00, tz), tz FROM tzs; + +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '2'); + +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '+16'); + +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '-16'); + +SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '+2') = '1973-07-15 08:15:55.33+02'::timestamptz; + +SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') = timestamptz '2014-12-10 00:00:00 Europe/Prague'; + +SELECT make_timestamptz(2014, 12, 10, 0, 0, 0, 'Europe/Prague') AT TIME ZONE 'UTC'; + +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Asia/Singapore') AT TIME ZONE 'UTC'; + +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Pacific/Honolulu') AT TIME ZONE 'UTC'; + +SELECT make_timestamptz(1881, 12, 10, 0, 0, 0, 'Europe/Paris') AT TIME ZONE 'UTC'; + +SELECT make_timestamptz(1910, 12, 24, 0, 0, 0, 'Nehwon/Lankhmar'); + +SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EST'); + +SELECT make_timestamptz(2008, 12, 10, 10, 10, 10, 'EDT'); + +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'FOO8BAR'); + +SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, 'PST8PDT,M3.2.0,M11.1.0'); + +RESET TimeZone; + +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '1 hour'::interval); + +select generate_series('2022-01-01 00:00'::timestamptz, + 'infinity'::timestamptz, + '1 month'::interval) limit 10; + +select * from generate_series('2020-01-01 00:00'::timestamptz, + '2020-01-02 03:00'::timestamptz, + '0 hour'::interval); + +select generate_series(timestamptz '1995-08-06 12:12:12', timestamptz '1996-08-06 12:12:12', interval 'infinity'); + +select generate_series(timestamptz '1995-08-06 12:12:12', timestamptz '1996-08-06 12:12:12', interval '-infinity'); + +SET TimeZone to 'UTC'; + +SELECT date_add('2022-10-30 00:00:00+01'::timestamptz, + '1 day'::interval); + +SELECT date_add('2021-10-31 00:00:00+02'::timestamptz, + '1 day'::interval, + 'Europe/Warsaw'); + +SELECT date_subtract('2022-10-30 00:00:00+01'::timestamptz, + '1 day'::interval); + +SELECT date_subtract('2021-10-31 00:00:00+02'::timestamptz, + '1 day'::interval, + 'Europe/Warsaw'); + +SELECT * FROM generate_series('2021-12-31 23:00:00+00'::timestamptz, + '2020-12-31 23:00:00+00'::timestamptz, + '-1 month'::interval, + 'Europe/Warsaw'); + +RESET TimeZone; + +SET TimeZone to 'UTC'; + +SELECT '2011-03-27 00:00:00 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 01:00:00 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 01:59:59 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 02:00:00 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 02:00:01 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 02:59:59 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 03:00:00 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 03:00:01 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 04:00:00 Europe/Moscow'::timestamptz; + +SELECT '2011-03-27 00:00:00 MSK'::timestamptz; + +SELECT '2011-03-27 01:00:00 MSK'::timestamptz; + +SELECT '2011-03-27 01:59:59 MSK'::timestamptz; + +SELECT '2011-03-27 02:00:00 MSK'::timestamptz; + +SELECT '2011-03-27 02:00:01 MSK'::timestamptz; + +SELECT '2011-03-27 02:59:59 MSK'::timestamptz; + +SELECT '2011-03-27 03:00:00 MSK'::timestamptz; + +SELECT '2011-03-27 03:00:01 MSK'::timestamptz; + +SELECT '2011-03-27 04:00:00 MSK'::timestamptz; + +SELECT '2014-10-26 00:00:00 Europe/Moscow'::timestamptz; + +SELECT '2014-10-26 00:59:59 Europe/Moscow'::timestamptz; + +SELECT '2014-10-26 01:00:00 Europe/Moscow'::timestamptz; + +SELECT '2014-10-26 01:00:01 Europe/Moscow'::timestamptz; + +SELECT '2014-10-26 02:00:00 Europe/Moscow'::timestamptz; + +SELECT '2014-10-26 00:00:00 MSK'::timestamptz; + +SELECT '2014-10-26 00:59:59 MSK'::timestamptz; + +SELECT '2014-10-26 01:00:00 MSK'::timestamptz; + +SELECT '2014-10-26 01:00:01 MSK'::timestamptz; + +SELECT '2014-10-26 02:00:00 MSK'::timestamptz; + +SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 00:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 01:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 01:59:59'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 02:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 02:00:01'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 02:59:59'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 03:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 03:00:01'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 04:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-26 00:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2014-10-26 00:59:59'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2014-10-26 01:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2014-10-26 01:00:01'::timestamp AT TIME ZONE 'MSK'; + +SELECT '2014-10-26 02:00:00'::timestamp AT TIME ZONE 'MSK'; + +SELECT make_timestamptz(2014, 10, 26, 0, 0, 0, 'MSK'); + +SELECT make_timestamptz(2014, 10, 26, 1, 0, 0, 'MSK'); + +SELECT to_timestamp( 0); + +SELECT to_timestamp( 946684800); + +SELECT to_timestamp(1262349296.7890123); + +SELECT to_timestamp(-210866803200); + +SELECT to_timestamp(' Infinity'::float); + +SELECT to_timestamp('-Infinity'::float); + +SELECT to_timestamp('NaN'::float); + +SET TimeZone to 'Europe/Moscow'; + +SELECT '2011-03-26 21:00:00 UTC'::timestamptz; + +SELECT '2011-03-26 22:00:00 UTC'::timestamptz; + +SELECT '2011-03-26 22:59:59 UTC'::timestamptz; + +SELECT '2011-03-26 23:00:00 UTC'::timestamptz; + +SELECT '2011-03-26 23:00:01 UTC'::timestamptz; + +SELECT '2011-03-26 23:59:59 UTC'::timestamptz; + +SELECT '2011-03-27 00:00:00 UTC'::timestamptz; + +SELECT '2014-10-25 21:00:00 UTC'::timestamptz; + +SELECT '2014-10-25 21:59:59 UTC'::timestamptz; + +SELECT '2014-10-25 22:00:00 UTC'::timestamptz; + +SELECT '2014-10-25 22:00:01 UTC'::timestamptz; + +SELECT '2014-10-25 23:00:00 UTC'::timestamptz; + +RESET TimeZone; + +SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'Europe/Moscow'; + +SELECT '2011-03-26 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2011-03-26 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2011-03-26 22:59:59 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2011-03-26 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2011-03-26 23:00:01 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2011-03-26 23:59:59 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2011-03-27 00:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2014-10-25 21:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2014-10-25 21:59:59 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2014-10-25 22:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2014-10-25 22:00:01 UTC'::timestamptz AT TIME ZONE 'MSK'; + +SELECT '2014-10-25 23:00:00 UTC'::timestamptz AT TIME ZONE 'MSK'; + +BEGIN; + +SET LOCAL TIME ZONE 'Europe/Paris'; + +VALUES (CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL); + +VALUES (TIMESTAMP '1978-07-07 19:38' AT LOCAL); + +SET LOCAL TIME ZONE 'Australia/Sydney'; + +VALUES (CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL); + +VALUES (TIMESTAMP '1978-07-07 19:38' AT LOCAL); + +SET LOCAL TimeZone TO 'UTC'; + +CREATE VIEW timestamp_local_view AS + SELECT CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE) AT LOCAL AS ttz_at_local, + timezone(CAST('1978-07-07 19:38 America/New_York' AS TIMESTAMP WITH TIME ZONE)) AS ttz_func, + TIMESTAMP '1978-07-07 19:38' AT LOCAL AS t_at_local, + timezone(TIMESTAMP '1978-07-07 19:38') AS t_func; + +SELECT pg_get_viewdef('timestamp_local_view', true); + +TABLE timestamp_local_view; + +DROP VIEW timestamp_local_view; + +COMMIT; + +create temp table tmptz (f1 timestamptz primary key); + +insert into tmptz values ('2017-01-18 00:00+00'); + +select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00'; + +select * from tmptz where f1 at time zone 'utc' = '2017-01-18 00:00'; + +SELECT timestamptz 'infinity' - timestamptz 'infinity'; + +SELECT timestamptz 'infinity' - timestamptz '-infinity'; + +SELECT timestamptz '-infinity' - timestamptz 'infinity'; + +SELECT timestamptz '-infinity' - timestamptz '-infinity'; + +SELECT timestamptz 'infinity' - timestamptz '1995-08-06 12:12:12'; + +SELECT timestamptz '-infinity' - timestamptz '1995-08-06 12:12:12'; + +SELECT age(timestamptz 'infinity'); + +SELECT age(timestamptz '-infinity'); + +SELECT age(timestamptz 'infinity', timestamptz 'infinity'); + +SELECT age(timestamptz 'infinity', timestamptz '-infinity'); + +SELECT age(timestamptz '-infinity', timestamptz 'infinity'); + +SELECT age(timestamptz '-infinity', timestamptz '-infinity'); + +select timestamptz '1999-12-31 24:00:00'; + +select make_timestamptz(1999, 12, 31, 24, 0, 0); diff --git a/crates/pgt_pretty_print/tests/data/multi/timetz_60.sql b/crates/pgt_pretty_print/tests/data/multi/timetz_60.sql new file mode 100644 index 000000000..3c50e89ce --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/timetz_60.sql @@ -0,0 +1,124 @@ +CREATE TABLE TIMETZ_TBL (f1 time(2) with time zone); + +INSERT INTO TIMETZ_TBL VALUES ('00:01 PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('01:00 PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('02:03 PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('07:07 PST'); + +INSERT INTO TIMETZ_TBL VALUES ('08:08 EDT'); + +INSERT INTO TIMETZ_TBL VALUES ('11:59 PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('12:00 PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('12:01 PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('23:59 PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('11:59:59.99 PM PDT'); + +INSERT INTO TIMETZ_TBL VALUES ('2003-03-07 15:36:39 America/New_York'); + +INSERT INTO TIMETZ_TBL VALUES ('2003-07-07 15:36:39 America/New_York'); + +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York'); + +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2'); + +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2'); + +SELECT f1 AS "Time TZ" FROM TIMETZ_TBL; + +SELECT f1 AS "Three" FROM TIMETZ_TBL WHERE f1 < '05:06:07-07'; + +SELECT f1 AS "Seven" FROM TIMETZ_TBL WHERE f1 > '05:06:07-07'; + +SELECT f1 AS "None" FROM TIMETZ_TBL WHERE f1 < '00:00-07'; + +SELECT f1 AS "Ten" FROM TIMETZ_TBL WHERE f1 >= '00:00-07'; + +SELECT '23:59:59.999999 PDT'::timetz; + +SELECT '23:59:59.9999999 PDT'::timetz; + +SELECT '23:59:60 PDT'::timetz; + +SELECT '24:00:00 PDT'::timetz; + +SELECT '24:00:00.01 PDT'::timetz; + +SELECT '23:59:60.01 PDT'::timetz; + +SELECT '24:01:00 PDT'::timetz; + +SELECT '25:00:00 PDT'::timetz; + +SELECT pg_input_is_valid('12:00:00 PDT', 'timetz'); + +SELECT pg_input_is_valid('25:00:00 PDT', 'timetz'); + +SELECT pg_input_is_valid('15:36:39 America/New_York', 'timetz'); + +SELECT * FROM pg_input_error_info('25:00:00 PDT', 'timetz'); + +SELECT * FROM pg_input_error_info('15:36:39 America/New_York', 'timetz'); + +SELECT f1 + time with time zone '00:01' AS "Illegal" FROM TIMETZ_TBL; + +SELECT EXTRACT(MICROSECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT EXTRACT(MILLISECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT EXTRACT(SECOND FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT EXTRACT(MINUTE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT EXTRACT(HOUR FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT EXTRACT(DAY FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT EXTRACT(FORTNIGHT FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT EXTRACT(TIMEZONE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30'); + +SELECT EXTRACT(TIMEZONE_HOUR FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30'); + +SELECT EXTRACT(TIMEZONE_MINUTE FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04:30'); + +SELECT EXTRACT(EPOCH FROM TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT date_part('microsecond', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT date_part('millisecond', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT date_part('second', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +SELECT date_part('epoch', TIME WITH TIME ZONE '2020-05-26 13:30:25.575401-04'); + +BEGIN; + +SET LOCAL TimeZone TO 'UTC'; + +CREATE VIEW timetz_local_view AS + SELECT f1 AS dat, + timezone(f1) AS dat_func, + f1 AT LOCAL AS dat_at_local, + f1 AT TIME ZONE current_setting('TimeZone') AS dat_at_tz, + f1 AT TIME ZONE INTERVAL '00:00' AS dat_at_int + FROM TIMETZ_TBL + ORDER BY f1; + +SELECT pg_get_viewdef('timetz_local_view', true); + +TABLE timetz_local_view; + +SELECT f1 AS dat, + f1 AT TIME ZONE 'UTC+10' AS dat_at_tz, + f1 AT TIME ZONE INTERVAL '-10:00' AS dat_at_int + FROM TIMETZ_TBL + ORDER BY f1; + +ROLLBACK; diff --git a/crates/pgt_pretty_print/tests/data/multi/transactions_60.sql b/crates/pgt_pretty_print/tests/data/multi/transactions_60.sql new file mode 100644 index 000000000..692c08603 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/transactions_60.sql @@ -0,0 +1,890 @@ +BEGIN; + +CREATE TABLE xacttest (a smallint, b real); + +INSERT INTO xacttest VALUES + (56, 7.8), + (100, 99.097), + (0, 0.09561), + (42, 324.78); + +INSERT INTO xacttest (a, b) VALUES (777, 777.777); + +END; + +SELECT a FROM xacttest WHERE a > 100; + +BEGIN; + +CREATE TABLE disappear (a int4); + +DELETE FROM xacttest; + +SELECT * FROM xacttest; + +ABORT; + +SELECT oid FROM pg_class WHERE relname = 'disappear'; + +SELECT * FROM xacttest; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +SELECT COUNT(*) FROM xacttest; + +RESET transaction_isolation; + +END; + +BEGIN TRANSACTION READ ONLY; + +SELECT COUNT(*) FROM xacttest; + +RESET transaction_read_only; + +END; + +BEGIN TRANSACTION DEFERRABLE; + +SELECT COUNT(*) FROM xacttest; + +RESET transaction_deferrable; + +END; + +CREATE FUNCTION errfunc() RETURNS int LANGUAGE SQL AS 'SELECT 1' +SET transaction_read_only = on; + +CREATE TABLE writetest (a int); + +CREATE TEMPORARY TABLE temptest (a int); + +BEGIN; + +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ ONLY, DEFERRABLE; + +SELECT * FROM writetest; + +SET TRANSACTION READ WRITE; + +COMMIT; + +BEGIN; + +SET TRANSACTION READ ONLY; + +SET TRANSACTION READ WRITE; + +SET TRANSACTION READ ONLY; + +SELECT * FROM writetest; + +SAVEPOINT x; + +SET TRANSACTION READ ONLY; + +SELECT * FROM writetest; + +SET TRANSACTION READ ONLY; + +SET TRANSACTION READ WRITE; + +COMMIT; + +BEGIN; + +SET TRANSACTION READ WRITE; + +SAVEPOINT x; + +SET TRANSACTION READ WRITE; + +SET TRANSACTION READ ONLY; + +SELECT * FROM writetest; + +SET TRANSACTION READ ONLY; + +SET TRANSACTION READ WRITE; + +COMMIT; + +BEGIN; + +SET TRANSACTION READ WRITE; + +SAVEPOINT x; + +SET TRANSACTION READ ONLY; + +SELECT * FROM writetest; + +ROLLBACK TO SAVEPOINT x; + +SHOW transaction_read_only; + +SAVEPOINT y; + +SET TRANSACTION READ ONLY; + +SELECT * FROM writetest; + +RELEASE SAVEPOINT y; + +SHOW transaction_read_only; + +COMMIT; + +SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY; + +DROP TABLE writetest; + +INSERT INTO writetest VALUES (1); + +SELECT * FROM writetest; + +DELETE FROM temptest; + +UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a; + +UPDATE writetest SET a = 0; + +EXECUTE test; + +SELECT * FROM writetest, temptest; + +CREATE TABLE test AS SELECT * FROM writetest; + +START TRANSACTION READ WRITE; + +DROP TABLE writetest; + +COMMIT; + +SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE; + +CREATE TABLE trans_foobar (a int); + +BEGIN; + +CREATE TABLE trans_foo (a int); + +SAVEPOINT one; + +DROP TABLE trans_foo; + +CREATE TABLE trans_bar (a int); + +ROLLBACK TO SAVEPOINT one; + +RELEASE SAVEPOINT one; + +SAVEPOINT two; + +CREATE TABLE trans_baz (a int); + +RELEASE SAVEPOINT two; + +drop TABLE trans_foobar; + +CREATE TABLE trans_barbaz (a int); + +COMMIT; + +SELECT * FROM trans_foo; + +SELECT * FROM trans_bar; + +SELECT * FROM trans_barbaz; + +SELECT * FROM trans_baz; + +BEGIN; + +INSERT INTO trans_foo VALUES (1); + +SAVEPOINT one; + +INSERT into trans_bar VALUES (1); + +ROLLBACK TO one; + +RELEASE SAVEPOINT one; + +SAVEPOINT two; + +INSERT into trans_barbaz VALUES (1); + +RELEASE two; + +SAVEPOINT three; + +SAVEPOINT four; + +INSERT INTO trans_foo VALUES (2); + +RELEASE SAVEPOINT four; + +ROLLBACK TO SAVEPOINT three; + +RELEASE SAVEPOINT three; + +INSERT INTO trans_foo VALUES (3); + +COMMIT; + +SELECT * FROM trans_foo; + +SELECT * FROM trans_barbaz; + +BEGIN; + +SAVEPOINT one; + +SELECT trans_foo; + +ROLLBACK TO SAVEPOINT one; + +RELEASE SAVEPOINT one; + +SAVEPOINT two; + +CREATE TABLE savepoints (a int); + +SAVEPOINT three; + +INSERT INTO savepoints VALUES (1); + +SAVEPOINT four; + +INSERT INTO savepoints VALUES (2); + +SAVEPOINT five; + +INSERT INTO savepoints VALUES (3); + +ROLLBACK TO SAVEPOINT five; + +COMMIT; + +COMMIT; + +SELECT * FROM savepoints; + +BEGIN; + +SAVEPOINT one; + +DELETE FROM savepoints WHERE a=1; + +RELEASE SAVEPOINT one; + +SAVEPOINT two; + +DELETE FROM savepoints WHERE a=1; + +SAVEPOINT three; + +DELETE FROM savepoints WHERE a=2; + +ROLLBACK; + +COMMIT; + +SELECT * FROM savepoints; + +BEGIN; + +INSERT INTO savepoints VALUES (4); + +SAVEPOINT one; + +INSERT INTO savepoints VALUES (5); + +SELECT trans_foo; + +COMMIT; + +SELECT * FROM savepoints; + +BEGIN; + +INSERT INTO savepoints VALUES (6); + +SAVEPOINT one; + +INSERT INTO savepoints VALUES (7); + +RELEASE SAVEPOINT one; + +INSERT INTO savepoints VALUES (8); + +COMMIT; + +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=8; + +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=7; + +BEGIN; + +INSERT INTO savepoints VALUES (9); + +SAVEPOINT one; + +INSERT INTO savepoints VALUES (10); + +ROLLBACK TO SAVEPOINT one; + +INSERT INTO savepoints VALUES (11); + +COMMIT; + +SELECT a FROM savepoints WHERE a in (9, 10, 11); + +SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=9 AND b.a=11; + +BEGIN; + +INSERT INTO savepoints VALUES (12); + +SAVEPOINT one; + +INSERT INTO savepoints VALUES (13); + +SAVEPOINT two; + +INSERT INTO savepoints VALUES (14); + +ROLLBACK TO SAVEPOINT one; + +INSERT INTO savepoints VALUES (15); + +SAVEPOINT two; + +INSERT INTO savepoints VALUES (16); + +SAVEPOINT three; + +INSERT INTO savepoints VALUES (17); + +COMMIT; + +SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17; + +BEGIN; + +INSERT INTO savepoints VALUES (18); + +SAVEPOINT one; + +INSERT INTO savepoints VALUES (19); + +SAVEPOINT two; + +INSERT INTO savepoints VALUES (20); + +ROLLBACK TO SAVEPOINT one; + +INSERT INTO savepoints VALUES (21); + +ROLLBACK TO SAVEPOINT one; + +INSERT INTO savepoints VALUES (22); + +COMMIT; + +SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22; + +DROP TABLE savepoints; + +SAVEPOINT one; + +ROLLBACK TO SAVEPOINT one; + +RELEASE SAVEPOINT one; + +BEGIN; + +SAVEPOINT one; + +SELECT 0/0; + +SAVEPOINT two; + +RELEASE SAVEPOINT one; + +ROLLBACK TO SAVEPOINT one; + +SELECT 1; + +COMMIT; + +SELECT 1; + +BEGIN; + +DECLARE c CURSOR FOR SELECT unique2 FROM tenk1 ORDER BY unique2; + +SAVEPOINT one; + +FETCH 10 FROM c; + +ROLLBACK TO SAVEPOINT one; + +FETCH 10 FROM c; + +RELEASE SAVEPOINT one; + +FETCH 10 FROM c; + +CLOSE c; + +DECLARE c CURSOR FOR SELECT unique2/0 FROM tenk1 ORDER BY unique2; + +SAVEPOINT two; + +FETCH 10 FROM c; + +ROLLBACK TO SAVEPOINT two; + +FETCH 10 FROM c; + +ROLLBACK TO SAVEPOINT two; + +RELEASE SAVEPOINT two; + +FETCH 10 FROM c; + +COMMIT; + +select * from xacttest; + +create or replace function max_xacttest() returns smallint language sql as +'select max(a) from xacttest' stable; + +begin; + +update xacttest set a = max_xacttest() + 10 where a > 0; + +select * from xacttest; + +rollback; + +create or replace function max_xacttest() returns smallint language sql as +'select max(a) from xacttest' volatile; + +begin; + +update xacttest set a = max_xacttest() + 10 where a > 0; + +select * from xacttest; + +rollback; + +create or replace function max_xacttest() returns smallint language plpgsql as +'begin return max(a) from xacttest; end' stable; + +begin; + +update xacttest set a = max_xacttest() + 10 where a > 0; + +select * from xacttest; + +rollback; + +create or replace function max_xacttest() returns smallint language plpgsql as +'begin return max(a) from xacttest; end' volatile; + +begin; + +update xacttest set a = max_xacttest() + 10 where a > 0; + +select * from xacttest; + +rollback; + +BEGIN; + +savepoint x; + +CREATE TABLE koju (a INT UNIQUE); + +INSERT INTO koju VALUES (1); + +INSERT INTO koju VALUES (1); + +rollback to x; + +CREATE TABLE koju (a INT UNIQUE); + +INSERT INTO koju VALUES (1); + +INSERT INTO koju VALUES (1); + +ROLLBACK; + +DROP TABLE trans_foo; + +DROP TABLE trans_baz; + +DROP TABLE trans_barbaz; + +create function inverse(int) returns float8 as +$$ +begin + analyze revalidate_bug; + return 1::float8/$1; +exception + when division_by_zero then return 0; +end$$ language plpgsql volatile; + +create table revalidate_bug (c float8 unique); + +insert into revalidate_bug values (1); + +insert into revalidate_bug values (inverse(0)); + +drop table revalidate_bug; + +drop function inverse(int); + +begin; + +savepoint x; + +create table trans_abc (a int); + +insert into trans_abc values (5); + +insert into trans_abc values (10); + +declare foo cursor for select * from trans_abc; + +fetch from foo; + +rollback to x; + +fetch from foo; + +commit; + +begin; + +create table trans_abc (a int); + +insert into trans_abc values (5); + +insert into trans_abc values (10); + +insert into trans_abc values (15); + +declare foo cursor for select * from trans_abc; + +fetch from foo; + +savepoint x; + +fetch from foo; + +rollback to x; + +fetch from foo; + +abort; + +CREATE FUNCTION invert(x float8) RETURNS float8 LANGUAGE plpgsql AS +$$ begin return 1/x; end $$; + +CREATE FUNCTION create_temp_tab() RETURNS text +LANGUAGE plpgsql AS $$ +BEGIN + CREATE TEMP TABLE new_table (f1 float8); + -- case of interest is that we fail while holding an open + -- relcache reference to new_table + INSERT INTO new_table SELECT invert(0.0); + RETURN 'foo'; +END $$; + +BEGIN; + +DECLARE ok CURSOR FOR SELECT * FROM int8_tbl; + +DECLARE ctt CURSOR FOR SELECT create_temp_tab(); + +FETCH ok; + +SAVEPOINT s1; + +FETCH ok; + +FETCH ctt; + +ROLLBACK TO s1; + +FETCH ok; + +FETCH ctt; + +COMMIT; + +DROP FUNCTION create_temp_tab(); + +DROP FUNCTION invert(x float8); + +CREATE TABLE trans_abc (a int); + +SET default_transaction_read_only = on; + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +INSERT INTO trans_abc VALUES (1); + +INSERT INTO trans_abc VALUES (2); + +COMMIT AND CHAIN; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +INSERT INTO trans_abc VALUES ('error'); + +INSERT INTO trans_abc VALUES (3); + +COMMIT AND CHAIN; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +INSERT INTO trans_abc VALUES (4); + +COMMIT; + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +SAVEPOINT x; + +INSERT INTO trans_abc VALUES ('error'); + +COMMIT AND CHAIN; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +INSERT INTO trans_abc VALUES (5); + +COMMIT; + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +SAVEPOINT x; + +COMMIT AND CHAIN; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +COMMIT; + +START TRANSACTION ISOLATION LEVEL READ COMMITTED, READ WRITE, DEFERRABLE; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +SAVEPOINT x; + +COMMIT AND CHAIN; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +COMMIT; + +START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +INSERT INTO trans_abc VALUES (6); + +ROLLBACK AND CHAIN; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +INSERT INTO trans_abc VALUES ('error'); + +ROLLBACK AND CHAIN; + +SHOW transaction_isolation; + +SHOW transaction_read_only; + +SHOW transaction_deferrable; + +ROLLBACK; + +COMMIT AND CHAIN; + +ROLLBACK AND CHAIN; + +SELECT * FROM trans_abc ORDER BY 1; + +RESET default_transaction_read_only; + +DROP TABLE trans_abc; + +create temp table i_table (f1 int); + +SELECT 3; + +select * from i_table; + +select 1/0; + +select * from i_table; + +rollback; + +commit; + +rollback; + +rollback; + +rollback; + +insert into i_table values(5); + +commit; + +insert into i_table values(6); + +rollback; + +select 1/0; + +select 2; + +select * from i_table; + +rollback; + +VACUUM; + +VACUUM; + +SAVEPOINT sp; + +SAVEPOINT sp; + +SELECT 2; + +SELECT 3; + +COMMIT; + +COMMIT AND CHAIN; + +SHOW transaction_read_only; + +ROLLBACK AND CHAIN; + +SHOW transaction_read_only; + +CREATE TABLE trans_abc (a int); + +COMMIT AND CHAIN; + +ROLLBACK AND CHAIN; + +COMMIT; + +ROLLBACK; + +COMMIT AND CHAIN; + +SHOW transaction_isolation; + +COMMIT; + +ROLLBACK AND CHAIN; + +SHOW transaction_isolation; + +ROLLBACK; + +SET default_transaction_isolation = 'read committed'; + +COMMIT AND CHAIN; + +SHOW transaction_isolation; + +ROLLBACK AND CHAIN; + +SHOW transaction_isolation; + +RESET default_transaction_isolation; + +SELECT * FROM trans_abc ORDER BY 1; + +DROP TABLE trans_abc; + +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; + +SET TRANSACTION SNAPSHOT 'Incorrect Identifier'; + +ROLLBACK; + +BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ; + +SET TRANSACTION SNAPSHOT 'FFF-FFF-F'; + +ROLLBACK; + +begin; + +select 1/0; + +rollback to X; diff --git a/crates/pgt_pretty_print/tests/data/multi/triggers_60.sql b/crates/pgt_pretty_print/tests/data/multi/triggers_60.sql new file mode 100644 index 000000000..d76e4d158 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/triggers_60.sql @@ -0,0 +1,2974 @@ +CREATE FUNCTION trigger_return_old () + RETURNS trigger + AS 'regresslib' + LANGUAGE C; + +create table trigtest (f1 int, f2 text); + +create trigger trigger_return_old + before insert or delete or update on trigtest + for each row execute procedure trigger_return_old(); + +insert into trigtest values(1, 'foo'); + +select * from trigtest; + +update trigtest set f2 = f2 || 'bar'; + +select * from trigtest; + +delete from trigtest; + +select * from trigtest; + +create function f1_times_10() returns trigger as +$$ begin new.f1 := new.f1 * 10; return new; end $$ language plpgsql; + +create trigger trigger_alpha + before insert or update on trigtest + for each row execute procedure f1_times_10(); + +insert into trigtest values(1, 'foo'); + +select * from trigtest; + +update trigtest set f2 = f2 || 'bar'; + +select * from trigtest; + +delete from trigtest; + +select * from trigtest; + +create trigger trigger_zed + before insert or update on trigtest + for each row execute procedure f1_times_10(); + +insert into trigtest values(1, 'foo'); + +select * from trigtest; + +update trigtest set f2 = f2 || 'bar'; + +select * from trigtest; + +delete from trigtest; + +select * from trigtest; + +drop trigger trigger_alpha on trigtest; + +insert into trigtest values(1, 'foo'); + +select * from trigtest; + +update trigtest set f2 = f2 || 'bar'; + +select * from trigtest; + +delete from trigtest; + +select * from trigtest; + +drop table trigtest; + +create table trigtest ( + a integer, + b bool default true not null, + c text default 'xyzzy' not null); + +create trigger trigger_return_old + before insert or delete or update on trigtest + for each row execute procedure trigger_return_old(); + +insert into trigtest values(1); + +select * from trigtest; + +alter table trigtest add column d integer default 42 not null; + +select * from trigtest; + +update trigtest set a = 2 where a = 1 returning *; + +select * from trigtest; + +alter table trigtest drop column b; + +select * from trigtest; + +update trigtest set a = 2 where a = 1 returning *; + +select * from trigtest; + +drop table trigtest; + +CREATE TABLE log_table (tstamp timestamp default timeofday()::timestamp); + +CREATE TABLE main_table (a int unique, b int); + +CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS ' +BEGIN + RAISE NOTICE ''trigger_func(%) called: action = %, when = %, level = %'', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; + RETURN NULL; +END;'; + +CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_ins_stmt'); + +CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_ins_stmt'); + +CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_table +EXECUTE PROCEDURE trigger_func('after_upd_stmt'); + +INSERT INTO main_table (a, b) VALUES (5, 10) ON CONFLICT (a) + DO UPDATE SET b = EXCLUDED.b; + +CREATE TRIGGER after_upd_row_trig AFTER UPDATE ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_row'); + +INSERT INTO main_table DEFAULT VALUES; + +UPDATE main_table SET a = a + 1 WHERE b < 30; + +UPDATE main_table SET a = a + 2 WHERE b > 100; + +ALTER TABLE main_table DROP CONSTRAINT main_table_a_key; + +SELECT * FROM main_table ORDER BY a, b; + +COMMENT ON TRIGGER no_such_trigger ON main_table IS 'wrong'; + +COMMENT ON TRIGGER before_ins_stmt_trig ON main_table IS 'right'; + +COMMENT ON TRIGGER before_ins_stmt_trig ON main_table IS NULL; + +CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) EXECUTE PROCEDURE trigger_func('modified_a'); + +CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table +FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) EXECUTE PROCEDURE trigger_func('modified_any'); + +CREATE TRIGGER insert_a AFTER INSERT ON main_table +FOR EACH ROW WHEN (NEW.a = 123) EXECUTE PROCEDURE trigger_func('insert_a'); + +CREATE TRIGGER delete_a AFTER DELETE ON main_table +FOR EACH ROW WHEN (OLD.a = 123) EXECUTE PROCEDURE trigger_func('delete_a'); + +CREATE TRIGGER insert_when BEFORE INSERT ON main_table +FOR EACH STATEMENT WHEN (true) EXECUTE PROCEDURE trigger_func('insert_when'); + +CREATE TRIGGER delete_when AFTER DELETE ON main_table +FOR EACH STATEMENT WHEN (true) EXECUTE PROCEDURE trigger_func('delete_when'); + +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table IN ('main_table') + ORDER BY trigger_name COLLATE "C", 2; + +INSERT INTO main_table (a) VALUES (123), (456); + +DELETE FROM main_table WHERE a IN (123, 456); + +UPDATE main_table SET a = 50, b = 60; + +SELECT * FROM main_table ORDER BY a, b; + +SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; + +SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; + +SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any'; + +ALTER TRIGGER modified_a ON main_table RENAME TO modified_modified_a; + +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; + +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_modified_a'; + +DROP TRIGGER modified_modified_a ON main_table; + +DROP TRIGGER modified_any ON main_table; + +DROP TRIGGER insert_a ON main_table; + +DROP TRIGGER delete_a ON main_table; + +DROP TRIGGER insert_when ON main_table; + +DROP TRIGGER delete_when ON main_table; + +create table table_with_oids(a int); + +insert into table_with_oids values (1); + +create trigger oid_unchanged_trig after update on table_with_oids + for each row + when (new.tableoid = old.tableoid AND new.tableoid <> 0) + execute procedure trigger_func('after_upd_oid_unchanged'); + +update table_with_oids set a = a + 1; + +drop table table_with_oids; + +DROP TRIGGER after_upd_row_trig ON main_table; + +CREATE TRIGGER before_upd_a_row_trig BEFORE UPDATE OF a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_a_row'); + +CREATE TRIGGER after_upd_b_row_trig AFTER UPDATE OF b ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_b_row'); + +CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_a_b_row'); + +CREATE TRIGGER before_upd_a_stmt_trig BEFORE UPDATE OF a ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_upd_a_stmt'); + +CREATE TRIGGER after_upd_b_stmt_trig AFTER UPDATE OF b ON main_table +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_upd_b_stmt'); + +SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'after_upd_a_b_row_trig'; + +UPDATE main_table SET a = 50; + +UPDATE main_table SET b = 10; + +CREATE TABLE some_t (some_col boolean NOT NULL); + +CREATE FUNCTION dummy_update_func() RETURNS trigger AS $$ +BEGIN + RAISE NOTICE 'dummy_update_func(%) called: action = %, old = %, new = %', + TG_ARGV[0], TG_OP, OLD, NEW; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER some_trig_before BEFORE UPDATE ON some_t FOR EACH ROW + EXECUTE PROCEDURE dummy_update_func('before'); + +CREATE TRIGGER some_trig_aftera AFTER UPDATE ON some_t FOR EACH ROW + WHEN (NOT OLD.some_col AND NEW.some_col) + EXECUTE PROCEDURE dummy_update_func('aftera'); + +CREATE TRIGGER some_trig_afterb AFTER UPDATE ON some_t FOR EACH ROW + WHEN (NOT NEW.some_col) + EXECUTE PROCEDURE dummy_update_func('afterb'); + +INSERT INTO some_t VALUES (TRUE); + +UPDATE some_t SET some_col = TRUE; + +UPDATE some_t SET some_col = FALSE; + +UPDATE some_t SET some_col = TRUE; + +DROP TABLE some_t; + +CREATE TRIGGER error_upd_a_a BEFORE UPDATE OF a, a ON main_table +FOR EACH ROW EXECUTE PROCEDURE trigger_func('error_upd_a_a'); + +CREATE TRIGGER error_ins_when BEFORE INSERT OR UPDATE ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) +EXECUTE PROCEDURE trigger_func('error_ins_old'); + +CREATE TRIGGER error_del_when BEFORE DELETE OR UPDATE ON main_table +FOR EACH ROW WHEN (OLD.a <> NEW.a) +EXECUTE PROCEDURE trigger_func('error_del_new'); + +CREATE TRIGGER error_del_when BEFORE INSERT OR UPDATE ON main_table +FOR EACH ROW WHEN (NEW.tableoid <> 0) +EXECUTE PROCEDURE trigger_func('error_when_sys_column'); + +CREATE TRIGGER error_stmt_when BEFORE UPDATE OF a ON main_table +FOR EACH STATEMENT WHEN (OLD.* IS DISTINCT FROM NEW.*) +EXECUTE PROCEDURE trigger_func('error_stmt_when'); + +ALTER TABLE main_table DROP COLUMN b; + +begin; + +DROP TRIGGER after_upd_a_b_row_trig ON main_table; + +DROP TRIGGER after_upd_b_row_trig ON main_table; + +DROP TRIGGER after_upd_b_stmt_trig ON main_table; + +ALTER TABLE main_table DROP COLUMN b; + +rollback; + +create table trigtest (i serial primary key); + +create table trigtest2 (i int references trigtest(i) on delete cascade); + +create function trigtest() returns trigger as $$ +begin + raise notice '% % % %', TG_TABLE_NAME, TG_OP, TG_WHEN, TG_LEVEL; + return new; +end;$$ language plpgsql; + +create trigger trigtest_b_row_tg before insert or update or delete on trigtest +for each row execute procedure trigtest(); + +create trigger trigtest_a_row_tg after insert or update or delete on trigtest +for each row execute procedure trigtest(); + +create trigger trigtest_b_stmt_tg before insert or update or delete on trigtest +for each statement execute procedure trigtest(); + +create trigger trigtest_a_stmt_tg after insert or update or delete on trigtest +for each statement execute procedure trigtest(); + +insert into trigtest default values; + +alter table trigtest disable trigger trigtest_b_row_tg; + +insert into trigtest default values; + +alter table trigtest disable trigger user; + +insert into trigtest default values; + +alter table trigtest enable trigger trigtest_a_stmt_tg; + +insert into trigtest default values; + +set session_replication_role = replica; + +insert into trigtest default values; + +alter table trigtest enable always trigger trigtest_a_stmt_tg; + +insert into trigtest default values; + +reset session_replication_role; + +insert into trigtest2 values(1); + +insert into trigtest2 values(2); + +delete from trigtest where i=2; + +select * from trigtest2; + +alter table trigtest disable trigger all; + +delete from trigtest where i=1; + +select * from trigtest2; + +insert into trigtest default values; + +select * from trigtest; + +drop table trigtest2; + +drop table trigtest; + +CREATE TABLE trigger_test ( + i int, + v varchar +); + +CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger +LANGUAGE plpgsql AS $$ + +declare + + argstr text; + relid text; + +begin + + relid := TG_relid::regclass; + + -- plpgsql can't discover its trigger data in a hash like perl and python + -- can, or by a sort of reflection like tcl can, + -- so we have to hard code the names. + raise NOTICE 'TG_NAME: %', TG_name; + raise NOTICE 'TG_WHEN: %', TG_when; + raise NOTICE 'TG_LEVEL: %', TG_level; + raise NOTICE 'TG_OP: %', TG_op; + raise NOTICE 'TG_RELID::regclass: %', relid; + raise NOTICE 'TG_RELNAME: %', TG_relname; + raise NOTICE 'TG_TABLE_NAME: %', TG_table_name; + raise NOTICE 'TG_TABLE_SCHEMA: %', TG_table_schema; + raise NOTICE 'TG_NARGS: %', TG_nargs; + + argstr := '['; + for i in 0 .. TG_nargs - 1 loop + if i > 0 then + argstr := argstr || ', '; + end if; + argstr := argstr || TG_argv[i]; + end loop; + argstr := argstr || ']'; + raise NOTICE 'TG_ARGV: %', argstr; + + if TG_OP != 'INSERT' then + raise NOTICE 'OLD: %', OLD; + end if; + + if TG_OP != 'DELETE' then + raise NOTICE 'NEW: %', NEW; + end if; + + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; + +end; +$$; + +CREATE TRIGGER show_trigger_data_trig +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); + +insert into trigger_test values(1,'insert'); + +update trigger_test set v = 'update' where i = 1; + +delete from trigger_test; + +DROP TRIGGER show_trigger_data_trig on trigger_test; + +DROP FUNCTION trigger_data(); + +DROP TABLE trigger_test; + +CREATE TABLE trigger_test (f1 int, f2 text, f3 text); + +CREATE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql as $$ +begin + if row(old.*) = row(new.*) then + raise notice 'row % not changed', new.f1; + else + raise notice 'row % changed', new.f1; + end if; + return new; +end$$; + +CREATE TRIGGER t +BEFORE UPDATE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE mytrigger(); + +INSERT INTO trigger_test VALUES(1, 'foo', 'bar'); + +INSERT INTO trigger_test VALUES(2, 'baz', 'quux'); + +UPDATE trigger_test SET f3 = 'bar'; + +UPDATE trigger_test SET f3 = NULL; + +UPDATE trigger_test SET f3 = NULL; + +CREATE OR REPLACE FUNCTION mytrigger() RETURNS trigger LANGUAGE plpgsql as $$ +begin + if row(old.*) is distinct from row(new.*) then + raise notice 'row % changed', new.f1; + else + raise notice 'row % not changed', new.f1; + end if; + return new; +end$$; + +UPDATE trigger_test SET f3 = 'bar'; + +UPDATE trigger_test SET f3 = NULL; + +UPDATE trigger_test SET f3 = NULL; + +DROP TABLE trigger_test; + +DROP FUNCTION mytrigger(); + +CREATE FUNCTION serializable_update_trig() RETURNS trigger LANGUAGE plpgsql AS +$$ +declare + rec record; +begin + new.description = 'updated in trigger'; + return new; +end; +$$; + +CREATE TABLE serializable_update_tab ( + id int, + filler text, + description text +); + +CREATE TRIGGER serializable_update_trig BEFORE UPDATE ON serializable_update_tab + FOR EACH ROW EXECUTE PROCEDURE serializable_update_trig(); + +INSERT INTO serializable_update_tab SELECT a, repeat('xyzxz', 100), 'new' + FROM generate_series(1, 50) a; + +BEGIN; + +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +UPDATE serializable_update_tab SET description = 'no no', id = 1 WHERE id = 1; + +COMMIT; + +SELECT description FROM serializable_update_tab WHERE id = 1; + +DROP TABLE serializable_update_tab; + +CREATE TABLE min_updates_test ( + f1 text, + f2 int, + f3 int); + +INSERT INTO min_updates_test VALUES ('a',1,2),('b','2',null); + +CREATE TRIGGER z_min_update +BEFORE UPDATE ON min_updates_test +FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); + +UPDATE min_updates_test SET f1 = f1; + +UPDATE min_updates_test SET f2 = f2 + 1; + +UPDATE min_updates_test SET f3 = 2 WHERE f3 is null; + +SELECT * FROM min_updates_test; + +DROP TABLE min_updates_test; + +CREATE VIEW main_view AS SELECT a, b FROM main_table; + +CREATE OR REPLACE FUNCTION view_trigger() RETURNS trigger +LANGUAGE plpgsql AS $$ +declare + argstr text := ''; +begin + for i in 0 .. TG_nargs - 1 loop + if i > 0 then + argstr := argstr || ', '; + end if; + argstr := argstr || TG_argv[i]; + end loop; + + raise notice '% % % % (%)', TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, argstr; + + if TG_LEVEL = 'ROW' then + if TG_OP = 'INSERT' then + raise NOTICE 'NEW: %', NEW; + INSERT INTO main_table VALUES (NEW.a, NEW.b); + RETURN NEW; + end if; + + if TG_OP = 'UPDATE' then + raise NOTICE 'OLD: %, NEW: %', OLD, NEW; + UPDATE main_table SET a = NEW.a, b = NEW.b WHERE a = OLD.a AND b = OLD.b; + if NOT FOUND then RETURN NULL; end if; + RETURN NEW; + end if; + + if TG_OP = 'DELETE' then + raise NOTICE 'OLD: %', OLD; + DELETE FROM main_table WHERE a = OLD.a AND b = OLD.b; + if NOT FOUND then RETURN NULL; end if; + RETURN OLD; + end if; + end if; + + RETURN NULL; +end; +$$; + +CREATE TRIGGER invalid_trig BEFORE INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_ins_row'); + +CREATE TRIGGER invalid_trig BEFORE UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_row'); + +CREATE TRIGGER invalid_trig BEFORE DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_del_row'); + +CREATE TRIGGER invalid_trig AFTER INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_ins_row'); + +CREATE TRIGGER invalid_trig AFTER UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_upd_row'); + +CREATE TRIGGER invalid_trig AFTER DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE trigger_func('before_del_row'); + +CREATE TRIGGER invalid_trig BEFORE TRUNCATE ON main_view +EXECUTE PROCEDURE trigger_func('before_tru_row'); + +CREATE TRIGGER invalid_trig AFTER TRUNCATE ON main_view +EXECUTE PROCEDURE trigger_func('before_tru_row'); + +CREATE TRIGGER invalid_trig INSTEAD OF INSERT ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins'); + +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd'); + +CREATE TRIGGER invalid_trig INSTEAD OF DELETE ON main_table +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del'); + +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view +FOR EACH ROW WHEN (OLD.a <> NEW.a) EXECUTE PROCEDURE view_trigger('instead_of_upd'); + +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE OF a ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd'); + +CREATE TRIGGER invalid_trig INSTEAD OF UPDATE ON main_view +EXECUTE PROCEDURE view_trigger('instead_of_upd'); + +CREATE TRIGGER instead_of_insert_trig INSTEAD OF INSERT ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins'); + +CREATE TRIGGER instead_of_update_trig INSTEAD OF UPDATE ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd'); + +CREATE TRIGGER instead_of_delete_trig INSTEAD OF DELETE ON main_view +FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del'); + +CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_ins_stmt'); + +CREATE TRIGGER before_upd_stmt_trig BEFORE UPDATE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_upd_stmt'); + +CREATE TRIGGER before_del_stmt_trig BEFORE DELETE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_del_stmt'); + +CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_ins_stmt'); + +CREATE TRIGGER after_upd_stmt_trig AFTER UPDATE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_upd_stmt'); + +CREATE TRIGGER after_del_stmt_trig AFTER DELETE ON main_view +FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_del_stmt'); + +INSERT INTO main_view VALUES (20, 30); + +INSERT INTO main_view VALUES (21, 31) RETURNING a, b; + +UPDATE main_view SET b = 31 WHERE a = 20; + +UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b; + +DROP TRIGGER before_upd_a_row_trig ON main_table; + +UPDATE main_view SET b = 31 WHERE a = 20; + +UPDATE main_view SET b = 32 WHERE a = 21 AND b = 31 RETURNING a, b; + +UPDATE main_view SET b = 0 WHERE false; + +DELETE FROM main_view WHERE a IN (20,21); + +DELETE FROM main_view WHERE a = 31 RETURNING a, b; + +DROP TRIGGER instead_of_insert_trig ON main_view; + +DROP TRIGGER instead_of_delete_trig ON main_view; + +DROP VIEW main_view; + +CREATE TABLE country_table ( + country_id serial primary key, + country_name text unique not null, + continent text not null +); + +INSERT INTO country_table (country_name, continent) + VALUES ('Japan', 'Asia'), + ('UK', 'Europe'), + ('USA', 'North America') + RETURNING *; + +CREATE TABLE city_table ( + city_id serial primary key, + city_name text not null, + population bigint, + country_id int references country_table +); + +CREATE VIEW city_view AS + SELECT city_id, city_name, population, country_name, continent + FROM city_table ci + LEFT JOIN country_table co ON co.country_id = ci.country_id; + +CREATE FUNCTION city_insert() RETURNS trigger LANGUAGE plpgsql AS $$ +declare + ctry_id int; +begin + if NEW.country_name IS NOT NULL then + SELECT country_id, continent INTO ctry_id, NEW.continent + FROM country_table WHERE country_name = NEW.country_name; + if NOT FOUND then + raise exception 'No such country: "%"', NEW.country_name; + end if; + else + NEW.continent := NULL; + end if; + + if NEW.city_id IS NOT NULL then + INSERT INTO city_table + VALUES(NEW.city_id, NEW.city_name, NEW.population, ctry_id); + else + INSERT INTO city_table(city_name, population, country_id) + VALUES(NEW.city_name, NEW.population, ctry_id) + RETURNING city_id INTO NEW.city_id; + end if; + + RETURN NEW; +end; +$$; + +CREATE TRIGGER city_insert_trig INSTEAD OF INSERT ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_insert(); + +CREATE FUNCTION city_delete() RETURNS trigger LANGUAGE plpgsql AS $$ +begin + DELETE FROM city_table WHERE city_id = OLD.city_id; + if NOT FOUND then RETURN NULL; end if; + RETURN OLD; +end; +$$; + +CREATE TRIGGER city_delete_trig INSTEAD OF DELETE ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_delete(); + +CREATE FUNCTION city_update() RETURNS trigger LANGUAGE plpgsql AS $$ +declare + ctry_id int; +begin + if NEW.country_name IS DISTINCT FROM OLD.country_name then + SELECT country_id, continent INTO ctry_id, NEW.continent + FROM country_table WHERE country_name = NEW.country_name; + if NOT FOUND then + raise exception 'No such country: "%"', NEW.country_name; + end if; + + UPDATE city_table SET city_name = NEW.city_name, + population = NEW.population, + country_id = ctry_id + WHERE city_id = OLD.city_id; + else + UPDATE city_table SET city_name = NEW.city_name, + population = NEW.population + WHERE city_id = OLD.city_id; + NEW.continent := OLD.continent; + end if; + + if NOT FOUND then RETURN NULL; end if; + RETURN NEW; +end; +$$; + +CREATE TRIGGER city_update_trig INSTEAD OF UPDATE ON city_view +FOR EACH ROW EXECUTE PROCEDURE city_update(); + +INSERT INTO city_view(city_name) VALUES('Tokyo') RETURNING *; + +INSERT INTO city_view(city_name, population) VALUES('London', 7556900) RETURNING *; + +INSERT INTO city_view(city_name, country_name) VALUES('Washington DC', 'USA') RETURNING *; + +INSERT INTO city_view(city_id, city_name) VALUES(123456, 'New York') RETURNING *; + +INSERT INTO city_view VALUES(234567, 'Birmingham', 1016800, 'UK', 'EU') RETURNING *; + +UPDATE city_view SET country_name = 'Japon' WHERE city_name = 'Tokyo'; + +UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Takyo'; + +UPDATE city_view SET country_name = 'Japan' WHERE city_name = 'Tokyo' RETURNING *; + +UPDATE city_view SET population = 13010279 WHERE city_name = 'Tokyo' RETURNING *; + +UPDATE city_view SET country_name = 'UK' WHERE city_name = 'New York' RETURNING *; + +UPDATE city_view SET country_name = 'USA', population = 8391881 WHERE city_name = 'New York' RETURNING *; + +UPDATE city_view SET continent = 'EU' WHERE continent = 'Europe' RETURNING *; + +UPDATE city_view v1 SET country_name = v2.country_name FROM city_view v2 + WHERE v2.city_name = 'Birmingham' AND v1.city_name = 'London' RETURNING *; + +DELETE FROM city_view WHERE city_name = 'Birmingham' RETURNING *; + +CREATE VIEW european_city_view AS + SELECT * FROM city_view WHERE continent = 'Europe'; + +SELECT count(*) FROM european_city_view; + +CREATE FUNCTION no_op_trig_fn() RETURNS trigger LANGUAGE plpgsql +AS 'begin RETURN NULL; end'; + +CREATE TRIGGER no_op_trig INSTEAD OF INSERT OR UPDATE OR DELETE +ON european_city_view FOR EACH ROW EXECUTE PROCEDURE no_op_trig_fn(); + +INSERT INTO european_city_view VALUES (0, 'x', 10000, 'y', 'z'); + +UPDATE european_city_view SET population = 10000; + +DELETE FROM european_city_view; + +CREATE RULE european_city_insert_rule AS ON INSERT TO european_city_view +DO INSTEAD INSERT INTO city_view +VALUES (NEW.city_id, NEW.city_name, NEW.population, NEW.country_name, NEW.continent) +RETURNING *; + +CREATE RULE european_city_update_rule AS ON UPDATE TO european_city_view +DO INSTEAD UPDATE city_view SET + city_name = NEW.city_name, + population = NEW.population, + country_name = NEW.country_name +WHERE city_id = OLD.city_id +RETURNING NEW.*; + +CREATE RULE european_city_delete_rule AS ON DELETE TO european_city_view +DO INSTEAD DELETE FROM city_view WHERE city_id = OLD.city_id RETURNING *; + +INSERT INTO european_city_view(city_name, country_name) + VALUES ('Cambridge', 'USA') RETURNING *; + +UPDATE european_city_view SET country_name = 'UK' + WHERE city_name = 'Cambridge'; + +DELETE FROM european_city_view WHERE city_name = 'Cambridge'; + +UPDATE city_view SET country_name = 'UK' + WHERE city_name = 'Cambridge' RETURNING *; + +UPDATE european_city_view SET population = 122800 + WHERE city_name = 'Cambridge' RETURNING *; + +DELETE FROM european_city_view WHERE city_name = 'Cambridge' RETURNING *; + +UPDATE city_view v SET population = 599657 + FROM city_table ci, country_table co + WHERE ci.city_name = 'Washington DC' and co.country_name = 'USA' + AND v.city_id = ci.city_id AND v.country_name = co.country_name + RETURNING co.country_id, v.country_name, + v.city_id, v.city_name, v.population; + +SELECT * FROM city_view; + +DROP TABLE city_table CASCADE; + +DROP TABLE country_table; + +create table depth_a (id int not null primary key); + +create table depth_b (id int not null primary key); + +create table depth_c (id int not null primary key); + +create function depth_a_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + insert into depth_b values (new.id); + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + return new; +end; +$$; + +create trigger depth_a_tr before insert on depth_a + for each row execute procedure depth_a_tf(); + +create function depth_b_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + begin + execute 'insert into depth_c values (' || new.id::text || ')'; + exception + when sqlstate 'U9999' then + raise notice 'SQLSTATE = U9999: depth = %', pg_trigger_depth(); + end; + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + if new.id = 1 then + execute 'insert into depth_c values (' || new.id::text || ')'; + end if; + return new; +end; +$$; + +create trigger depth_b_tr before insert on depth_b + for each row execute procedure depth_b_tf(); + +create function depth_c_tf() returns trigger + language plpgsql as $$ +begin + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + if new.id = 1 then + raise exception sqlstate 'U9999'; + end if; + raise notice '%: depth = %', tg_name, pg_trigger_depth(); + return new; +end; +$$; + +create trigger depth_c_tr before insert on depth_c + for each row execute procedure depth_c_tf(); + +select pg_trigger_depth(); + +insert into depth_a values (1); + +select pg_trigger_depth(); + +insert into depth_a values (2); + +select pg_trigger_depth(); + +drop table depth_a, depth_b, depth_c; + +drop function depth_a_tf(); + +drop function depth_b_tf(); + +drop function depth_c_tf(); + +create temp table parent ( + aid int not null primary key, + val1 text, + val2 text, + val3 text, + val4 text, + bcnt int not null default 0); + +create temp table child ( + bid int not null primary key, + aid int not null, + val1 text); + +create function parent_upd_func() + returns trigger language plpgsql as +$$ +begin + if old.val1 <> new.val1 then + new.val2 = new.val1; + delete from child where child.aid = new.aid and child.val1 = new.val1; + end if; + return new; +end; +$$; + +create trigger parent_upd_trig before update on parent + for each row execute procedure parent_upd_func(); + +create function parent_del_func() + returns trigger language plpgsql as +$$ +begin + delete from child where aid = old.aid; + return old; +end; +$$; + +create trigger parent_del_trig before delete on parent + for each row execute procedure parent_del_func(); + +create function child_ins_func() + returns trigger language plpgsql as +$$ +begin + update parent set bcnt = bcnt + 1 where aid = new.aid; + return new; +end; +$$; + +create trigger child_ins_trig after insert on child + for each row execute procedure child_ins_func(); + +create function child_del_func() + returns trigger language plpgsql as +$$ +begin + update parent set bcnt = bcnt - 1 where aid = old.aid; + return old; +end; +$$; + +create trigger child_del_trig after delete on child + for each row execute procedure child_del_func(); + +insert into parent values (1, 'a', 'a', 'a', 'a', 0); + +insert into child values (10, 1, 'b'); + +select * from parent; + +select * from child; + +update parent set val1 = 'b' where aid = 1; + +select * from parent; + +select * from child; + +delete from parent where aid = 1; + +select * from parent; + +select * from child; + +create or replace function parent_del_func() + returns trigger language plpgsql as +$$ +begin + delete from child where aid = old.aid; + if found then + delete from parent where aid = old.aid; + return null; -- cancel outer deletion + end if; + return old; +end; +$$; + +delete from parent where aid = 1; + +select * from parent; + +select * from child; + +drop table parent, child; + +drop function parent_upd_func(); + +drop function parent_del_func(); + +drop function child_ins_func(); + +drop function child_del_func(); + +create temp table self_ref_trigger ( + id int primary key, + parent int references self_ref_trigger, + data text, + nchildren int not null default 0 +); + +create function self_ref_trigger_ins_func() + returns trigger language plpgsql as +$$ +begin + if new.parent is not null then + update self_ref_trigger set nchildren = nchildren + 1 + where id = new.parent; + end if; + return new; +end; +$$; + +create trigger self_ref_trigger_ins_trig before insert on self_ref_trigger + for each row execute procedure self_ref_trigger_ins_func(); + +create function self_ref_trigger_del_func() + returns trigger language plpgsql as +$$ +begin + if old.parent is not null then + update self_ref_trigger set nchildren = nchildren - 1 + where id = old.parent; + end if; + return old; +end; +$$; + +create trigger self_ref_trigger_del_trig before delete on self_ref_trigger + for each row execute procedure self_ref_trigger_del_func(); + +insert into self_ref_trigger values (1, null, 'root'); + +insert into self_ref_trigger values (2, 1, 'root child A'); + +insert into self_ref_trigger values (3, 1, 'root child B'); + +insert into self_ref_trigger values (4, 2, 'grandchild 1'); + +insert into self_ref_trigger values (5, 3, 'grandchild 2'); + +update self_ref_trigger set data = 'root!' where id = 1; + +select * from self_ref_trigger; + +delete from self_ref_trigger; + +select * from self_ref_trigger; + +drop table self_ref_trigger; + +drop function self_ref_trigger_ins_func(); + +drop function self_ref_trigger_del_func(); + +create table stmt_trig_on_empty_upd (a int); + +create table stmt_trig_on_empty_upd1 () inherits (stmt_trig_on_empty_upd); + +create function update_stmt_notice() returns trigger as $$ +begin + raise notice 'updating %', TG_TABLE_NAME; + return null; +end; +$$ language plpgsql; + +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd + execute procedure update_stmt_notice(); + +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd1 + execute procedure update_stmt_notice(); + +update stmt_trig_on_empty_upd set a = a where false returning a+1 as aa; + +update stmt_trig_on_empty_upd1 set a = a where false returning a+1 as aa; + +drop table stmt_trig_on_empty_upd cascade; + +drop function update_stmt_notice(); + +create table trigger_ddl_table ( + col1 integer, + col2 integer +); + +create function trigger_ddl_func() returns trigger as $$ +begin + alter table trigger_ddl_table add primary key (col1); + return new; +end$$ language plpgsql; + +create trigger trigger_ddl_func before insert on trigger_ddl_table for each row + execute procedure trigger_ddl_func(); + +insert into trigger_ddl_table values (1, 42); + +create or replace function trigger_ddl_func() returns trigger as $$ +begin + create index on trigger_ddl_table (col2); + return new; +end$$ language plpgsql; + +insert into trigger_ddl_table values (1, 42); + +drop table trigger_ddl_table; + +drop function trigger_ddl_func(); + +create table upsert (key int4 primary key, color text); + +create function upsert_before_func() + returns trigger language plpgsql as +$$ +begin + if (TG_OP = 'UPDATE') then + raise warning 'before update (old): %', old.*::text; + raise warning 'before update (new): %', new.*::text; + elsif (TG_OP = 'INSERT') then + raise warning 'before insert (new): %', new.*::text; + if new.key % 2 = 0 then + new.key := new.key + 1; + new.color := new.color || ' trig modified'; + raise warning 'before insert (new, modified): %', new.*::text; + end if; + end if; + return new; +end; +$$; + +create trigger upsert_before_trig before insert or update on upsert + for each row execute procedure upsert_before_func(); + +create function upsert_after_func() + returns trigger language plpgsql as +$$ +begin + if (TG_OP = 'UPDATE') then + raise warning 'after update (old): %', old.*::text; + raise warning 'after update (new): %', new.*::text; + elsif (TG_OP = 'INSERT') then + raise warning 'after insert (new): %', new.*::text; + end if; + return null; +end; +$$; + +create trigger upsert_after_trig after insert or update on upsert + for each row execute procedure upsert_after_func(); + +insert into upsert values(1, 'black') on conflict (key) do update set color = 'updated ' || upsert.color; + +insert into upsert values(2, 'red') on conflict (key) do update set color = 'updated ' || upsert.color; + +insert into upsert values(3, 'orange') on conflict (key) do update set color = 'updated ' || upsert.color; + +insert into upsert values(4, 'green') on conflict (key) do update set color = 'updated ' || upsert.color; + +insert into upsert values(5, 'purple') on conflict (key) do update set color = 'updated ' || upsert.color; + +insert into upsert values(6, 'white') on conflict (key) do update set color = 'updated ' || upsert.color; + +insert into upsert values(7, 'pink') on conflict (key) do update set color = 'updated ' || upsert.color; + +insert into upsert values(8, 'yellow') on conflict (key) do update set color = 'updated ' || upsert.color; + +select * from upsert; + +drop table upsert; + +drop function upsert_before_func(); + +drop function upsert_after_func(); + +create table my_table (i int); + +create view my_view as select * from my_table; + +create function my_trigger_function() returns trigger as $$ begin end; $$ language plpgsql; + +create trigger my_trigger after update on my_view referencing old table as old_table + for each statement execute procedure my_trigger_function(); + +drop function my_trigger_function(); + +drop view my_view; + +drop table my_table; + +create table parted_trig (a int) partition by list (a); + +create function trigger_nothing() returns trigger + language plpgsql as $$ begin end; $$; + +create trigger failed instead of update on parted_trig + for each row execute procedure trigger_nothing(); + +create trigger failed after update on parted_trig + referencing old table as old_table + for each row execute procedure trigger_nothing(); + +drop table parted_trig; + +create table trigpart (a int, b int) partition by range (a); + +create table trigpart1 partition of trigpart for values from (0) to (1000); + +create trigger trg1 after insert on trigpart for each row execute procedure trigger_nothing(); + +create table trigpart2 partition of trigpart for values from (1000) to (2000); + +create table trigpart3 (like trigpart); + +alter table trigpart attach partition trigpart3 for values from (2000) to (3000); + +create table trigpart4 partition of trigpart for values from (3000) to (4000) partition by range (a); + +create table trigpart41 partition of trigpart4 for values from (3000) to (3500); + +create table trigpart42 (like trigpart); + +alter table trigpart4 attach partition trigpart42 for values from (3500) to (4000); + +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text; + +drop trigger trg1 on trigpart1; + +drop trigger trg1 on trigpart2; + +drop trigger trg1 on trigpart3; + +drop table trigpart2; + +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text; + +drop trigger trg1 on trigpart; + +select tgrelid::regclass, tgname, tgfoid::regproc from pg_trigger + where tgrelid::regclass::text like 'trigpart%' order by tgrelid::regclass::text; + +create trigger trg1 after insert on trigpart for each row execute procedure trigger_nothing(); + +alter table trigpart detach partition trigpart3; + +drop trigger trg1 on trigpart3; + +alter table trigpart detach partition trigpart4; + +drop trigger trg1 on trigpart41; + +drop table trigpart4; + +alter table trigpart attach partition trigpart3 for values from (2000) to (3000); + +alter table trigpart detach partition trigpart3; + +alter table trigpart attach partition trigpart3 for values from (2000) to (3000); + +drop table trigpart3; + +select tgrelid::regclass::text, tgname, tgfoid::regproc, tgenabled, tgisinternal from pg_trigger + where tgname ~ '^trg1' order by 1; + +create table trigpart3 (like trigpart); + +create trigger trg1 after insert on trigpart3 for each row execute procedure trigger_nothing(); + +alter table trigpart attach partition trigpart3 FOR VALUES FROM (2000) to (3000); + +drop table trigpart3; + +create trigger samename after delete on trigpart execute function trigger_nothing(); + +create trigger samename after delete on trigpart1 execute function trigger_nothing(); + +drop table trigpart; + +drop function trigger_nothing(); + +create table parted_stmt_trig (a int) partition by list (a); + +create table parted_stmt_trig1 partition of parted_stmt_trig for values in (1); + +create table parted_stmt_trig2 partition of parted_stmt_trig for values in (2); + +create table parted2_stmt_trig (a int) partition by list (a); + +create table parted2_stmt_trig1 partition of parted2_stmt_trig for values in (1); + +create table parted2_stmt_trig2 partition of parted2_stmt_trig for values in (2); + +create or replace function trigger_notice() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %', TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL; + if TG_LEVEL = 'ROW' then + return NEW; + end if; + return null; + end; + $$ language plpgsql; + +create trigger trig_ins_before before insert on parted_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_ins_after after insert on parted_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_upd_before before update on parted_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_upd_after after update on parted_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_del_before before delete on parted_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_del_after after delete on parted_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_ins_after_parent after insert on parted_stmt_trig + for each row execute procedure trigger_notice(); + +create trigger trig_upd_after_parent after update on parted_stmt_trig + for each row execute procedure trigger_notice(); + +create trigger trig_del_after_parent after delete on parted_stmt_trig + for each row execute procedure trigger_notice(); + +create trigger trig_ins_before_child before insert on parted_stmt_trig1 + for each row execute procedure trigger_notice(); + +create trigger trig_ins_after_child after insert on parted_stmt_trig1 + for each row execute procedure trigger_notice(); + +create trigger trig_upd_before_child before update on parted_stmt_trig1 + for each row execute procedure trigger_notice(); + +create trigger trig_upd_after_child after update on parted_stmt_trig1 + for each row execute procedure trigger_notice(); + +create trigger trig_del_before_child before delete on parted_stmt_trig1 + for each row execute procedure trigger_notice(); + +create trigger trig_del_after_child after delete on parted_stmt_trig1 + for each row execute procedure trigger_notice(); + +create trigger trig_ins_before_3 before insert on parted2_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_ins_after_3 after insert on parted2_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_upd_before_3 before update on parted2_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_upd_after_3 after update on parted2_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_del_before_3 before delete on parted2_stmt_trig + for each statement execute procedure trigger_notice(); + +create trigger trig_del_after_3 after delete on parted2_stmt_trig + for each statement execute procedure trigger_notice(); + +with ins (a) as ( + insert into parted2_stmt_trig values (1), (2) returning a +) insert into parted_stmt_trig select a from ins returning tableoid::regclass, a; + +with upd as ( + update parted2_stmt_trig set a = a +) update parted_stmt_trig set a = a; + +delete from parted_stmt_trig; + +copy parted_stmt_trig(a) from stdin; + +copy parted_stmt_trig1(a) from stdin; + +alter table parted_stmt_trig disable trigger trig_ins_after_parent; + +insert into parted_stmt_trig values (1); + +alter table parted_stmt_trig enable trigger trig_ins_after_parent; + +insert into parted_stmt_trig values (1); + +drop table parted_stmt_trig, parted2_stmt_trig; + +create table parted_trig (a int) partition by range (a); + +create table parted_trig_1 partition of parted_trig for values from (0) to (1000) + partition by range (a); + +create table parted_trig_1_1 partition of parted_trig_1 for values from (0) to (100); + +create table parted_trig_2 partition of parted_trig for values from (1000) to (2000); + +create trigger zzz after insert on parted_trig for each row execute procedure trigger_notice(); + +create trigger mmm after insert on parted_trig_1_1 for each row execute procedure trigger_notice(); + +create trigger aaa after insert on parted_trig_1 for each row execute procedure trigger_notice(); + +create trigger bbb after insert on parted_trig for each row execute procedure trigger_notice(); + +create trigger qqq after insert on parted_trig_1_1 for each row execute procedure trigger_notice(); + +insert into parted_trig values (50), (1500); + +drop table parted_trig; + +create table parted_trig (a int) partition by list (a); + +create table parted_trig1 partition of parted_trig for values in (1); + +create table parted_trig2 partition of parted_trig for values in (2); + +insert into parted_trig values (1); + +create or replace function trigger_notice() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %', TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL; + if TG_LEVEL = 'ROW' then + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; + end if; + return null; + end; + $$ language plpgsql; + +create trigger parted_trig_before_stmt before insert or update or delete on parted_trig + for each statement execute procedure trigger_notice(); + +create trigger parted_trig_before_row before insert or update or delete on parted_trig + for each row execute procedure trigger_notice(); + +create trigger parted_trig_after_row after insert or update or delete on parted_trig + for each row execute procedure trigger_notice(); + +create trigger parted_trig_after_stmt after insert or update or delete on parted_trig + for each statement execute procedure trigger_notice(); + +update parted_trig set a = 2 where a = 1; + +drop table parted_trig; + +create table parted_trig (a int) partition by list (a); + +create table parted_trig1 partition of parted_trig for values in (1); + +create or replace function trigger_notice() returns trigger as $$ + declare + arg1 text = TG_ARGV[0]; + arg2 integer = TG_ARGV[1]; + begin + raise notice 'trigger % on % % % for % args % %', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, arg1, arg2; + return null; + end; + $$ language plpgsql; + +create trigger aaa after insert on parted_trig + for each row execute procedure trigger_notice('quirky', 1); + +create table parted_trig2 partition of parted_trig for values in (2); + +create table parted_trig3 (like parted_trig); + +alter table parted_trig attach partition parted_trig3 for values in (3); + +insert into parted_trig values (1), (2), (3); + +drop table parted_trig; + +create function bark(text) returns bool language plpgsql immutable + as $$ begin raise notice '% <- woof!', $1; return true; end; $$; + +create or replace function trigger_notice_ab() returns trigger as $$ + begin + raise notice 'trigger % on % % % for %: (a,b)=(%,%)', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, + NEW.a, NEW.b; + if TG_LEVEL = 'ROW' then + return NEW; + end if; + return null; + end; + $$ language plpgsql; + +create table parted_irreg_ancestor (fd text, b text, fd2 int, fd3 int, a int) + partition by range (b); + +alter table parted_irreg_ancestor drop column fd, + drop column fd2, drop column fd3; + +create table parted_irreg (fd int, a int, fd2 int, b text) + partition by range (b); + +alter table parted_irreg drop column fd, drop column fd2; + +alter table parted_irreg_ancestor attach partition parted_irreg + for values from ('aaaa') to ('zzzz'); + +create table parted1_irreg (b text, fd int, a int); + +alter table parted1_irreg drop column fd; + +alter table parted_irreg attach partition parted1_irreg + for values from ('aaaa') to ('bbbb'); + +create trigger parted_trig after insert on parted_irreg + for each row execute procedure trigger_notice_ab(); + +create trigger parted_trig_odd after insert on parted_irreg for each row + when (bark(new.b) AND new.a % 2 = 1) execute procedure trigger_notice_ab(); + +insert into parted_irreg values (1, 'aardvark'), (2, 'aanimals'); + +insert into parted1_irreg values ('aardwolf', 2); + +insert into parted_irreg_ancestor values ('aasvogel', 3); + +drop table parted_irreg_ancestor; + +create table parted (a int, b int, c text) partition by list (a); + +create table parted_1 partition of parted for values in (1) + partition by list (b); + +create table parted_1_1 partition of parted_1 for values in (1); + +create function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.a = new.a + 1; + return new; +end; +$$; + +insert into parted values (1, 1, 'uno uno v1'); + +create trigger t before insert or update or delete on parted + for each row execute function parted_trigfunc(); + +insert into parted values (1, 1, 'uno uno v2'); + +update parted set c = c || 'v3'; + +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.b = new.b + 1; + return new; +end; +$$; + +insert into parted values (1, 1, 'uno uno v4'); + +update parted set c = c || 'v5'; + +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.c = new.c || ' did '|| TG_OP; + return new; +end; +$$; + +insert into parted values (1, 1, 'uno uno'); + +update parted set c = c || ' v6'; + +select tableoid::regclass, * from parted; + +truncate table parted; + +create table parted_2 partition of parted for values in (2); + +insert into parted values (1, 1, 'uno uno v5'); + +update parted set a = 2; + +select tableoid::regclass, * from parted; + +create or replace function parted_trigfunc2() returns trigger language plpgsql as $$ +begin + new.a = new.a + 1; + return new; +end; +$$; + +create trigger t2 before update on parted + for each row execute function parted_trigfunc2(); + +truncate table parted; + +insert into parted values (1, 1, 'uno uno v6'); + +create table parted_3 partition of parted for values in (3); + +update parted set a = a + 1; + +select tableoid::regclass, * from parted; + +update parted set a = 0; + +select tableoid::regclass, * from parted; + +drop table parted; + +create table parted (a int, b int, c text) partition by list ((a + b)); + +create or replace function parted_trigfunc() returns trigger language plpgsql as $$ +begin + new.a = new.a + new.b; + return new; +end; +$$; + +create table parted_1 partition of parted for values in (1, 2); + +create table parted_2 partition of parted for values in (3, 4); + +create trigger t before insert or update on parted + for each row execute function parted_trigfunc(); + +insert into parted values (0, 1, 'zero win'); + +insert into parted values (1, 1, 'one fail'); + +insert into parted values (1, 2, 'two fail'); + +select * from parted; + +drop table parted; + +drop function parted_trigfunc(); + +create table parted_constr_ancestor (a int, b text) + partition by range (b); + +create table parted_constr (a int, b text) + partition by range (b); + +alter table parted_constr_ancestor attach partition parted_constr + for values from ('aaaa') to ('zzzz'); + +create table parted1_constr (a int, b text); + +alter table parted_constr attach partition parted1_constr + for values from ('aaaa') to ('bbbb'); + +create constraint trigger parted_trig after insert on parted_constr_ancestor + deferrable + for each row execute procedure trigger_notice_ab(); + +begin; + +insert into parted_constr values (1, 'aardvark'); + +insert into parted1_constr values (2, 'aardwolf'); + +insert into parted_constr_ancestor values (3, 'aasvogel'); + +commit; + +begin; + +set constraints parted_trig deferred; + +insert into parted_constr values (1, 'aardvark'); + +insert into parted1_constr values (2, 'aardwolf'), (3, 'aasvogel'); + +commit; + +drop table parted_constr_ancestor; + +drop function bark(text); + +create table parted_trigger (a int, b text) partition by range (a); + +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000); + +create table parted_trigger_2 (drp int, a int, b text); + +alter table parted_trigger_2 drop column drp; + +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000); + +create trigger parted_trigger after update on parted_trigger + for each row when (new.a % 2 = 1 and length(old.b) >= 2) execute procedure trigger_notice_ab(); + +create table parted_trigger_3 (b text, a int) partition by range (length(b)); + +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (3); + +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (3) to (5); + +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000); + +insert into parted_trigger values + (0, 'a'), (1, 'bbb'), (2, 'bcd'), (3, 'c'), + (1000, 'c'), (1001, 'ddd'), (1002, 'efg'), (1003, 'f'), + (2000, 'e'), (2001, 'fff'), (2002, 'ghi'), (2003, 'h'); + +update parted_trigger set a = a + 2; + +drop table parted_trigger; + +create table parted_referenced (a int); + +create table unparted_trigger (a int, b text); + +create table parted_trigger (a int, b text) partition by range (a); + +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000); + +create table parted_trigger_2 (drp int, a int, b text); + +alter table parted_trigger_2 drop column drp; + +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000); + +create constraint trigger parted_trigger after update on parted_trigger + from parted_referenced + for each row execute procedure trigger_notice_ab(); + +create constraint trigger parted_trigger after update on unparted_trigger + from parted_referenced + for each row execute procedure trigger_notice_ab(); + +create table parted_trigger_3 (b text, a int) partition by range (length(b)); + +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (3); + +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (3) to (5); + +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000); + +select tgname, conname, t.tgrelid::regclass, t.tgconstrrelid::regclass, + c.conrelid::regclass, c.confrelid::regclass + from pg_trigger t join pg_constraint c on (t.tgconstraint = c.oid) + where tgname = 'parted_trigger' + order by t.tgrelid::regclass::text; + +drop table parted_referenced, parted_trigger, unparted_trigger; + +create table parted_trigger (a int, b text) partition by range (a); + +create table parted_trigger_1 partition of parted_trigger for values from (0) to (1000); + +create table parted_trigger_2 (drp int, a int, b text); + +alter table parted_trigger_2 drop column drp; + +alter table parted_trigger attach partition parted_trigger_2 for values from (1000) to (2000); + +create trigger parted_trigger after update of b on parted_trigger + for each row execute procedure trigger_notice_ab(); + +create table parted_trigger_3 (b text, a int) partition by range (length(b)); + +create table parted_trigger_3_1 partition of parted_trigger_3 for values from (1) to (4); + +create table parted_trigger_3_2 partition of parted_trigger_3 for values from (4) to (8); + +alter table parted_trigger attach partition parted_trigger_3 for values from (2000) to (3000); + +insert into parted_trigger values (0, 'a'), (1000, 'c'), (2000, 'e'), (2001, 'eeee'); + +update parted_trigger set a = a + 2; + +update parted_trigger set b = b || 'b'; + +drop table parted_trigger; + +drop function trigger_notice_ab(); + +create table trg_clone (a int) partition by range (a); + +create table trg_clone1 partition of trg_clone for values from (0) to (1000); + +alter table trg_clone add constraint uniq unique (a) deferrable; + +create table trg_clone2 partition of trg_clone for values from (1000) to (2000); + +create table trg_clone3 partition of trg_clone for values from (2000) to (3000) + partition by range (a); + +create table trg_clone_3_3 partition of trg_clone3 for values from (2000) to (2100); + +select tgrelid::regclass, count(*) from pg_trigger + where tgrelid::regclass in ('trg_clone', 'trg_clone1', 'trg_clone2', + 'trg_clone3', 'trg_clone_3_3') + group by tgrelid::regclass order by tgrelid::regclass; + +drop table trg_clone; + +create table parent (a int); + +create table child1 () inherits (parent); + +create function trig_nothing() returns trigger language plpgsql + as $$ begin return null; end $$; + +create trigger tg after insert on parent + for each row execute function trig_nothing(); + +create trigger tg after insert on child1 + for each row execute function trig_nothing(); + +alter table parent disable trigger tg; + +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text; + +alter table only parent enable always trigger tg; + +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text; + +drop table parent, child1; + +create table parent (a int) partition by list (a); + +create table child1 partition of parent for values in (1); + +create trigger tg after insert on parent + for each row execute procedure trig_nothing(); + +create trigger tg_stmt after insert on parent + for statement execute procedure trig_nothing(); + +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname; + +alter table only parent enable always trigger tg; + +alter table parent enable always trigger tg_stmt; + +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname; + +alter table parent enable always trigger tg; + +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname; + +alter table parent disable trigger user; + +select tgrelid::regclass, tgname, tgenabled from pg_trigger + where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgname; + +drop table parent, child1; + +create table parent (a int primary key, f int references parent) + partition by list (a); + +create table child1 partition of parent for values in (1); + +select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname, + tgfoid::regproc, tgenabled + from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgfoid; + +alter table parent disable trigger all; + +select tgrelid::regclass, rtrim(tgname, '0123456789') as tgname, + tgfoid::regproc, tgenabled + from pg_trigger where tgrelid in ('parent'::regclass, 'child1'::regclass) + order by tgrelid::regclass::text, tgfoid; + +drop table parent, child1; + +CREATE TABLE trgfire (i int) PARTITION BY RANGE (i); + +CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10); + +CREATE OR REPLACE FUNCTION tgf() RETURNS trigger LANGUAGE plpgsql + AS $$ begin raise exception 'except'; end $$; + +CREATE TRIGGER tg AFTER INSERT ON trgfire FOR EACH ROW EXECUTE FUNCTION tgf(); + +INSERT INTO trgfire VALUES (1); + +ALTER TABLE trgfire DISABLE TRIGGER tg; + +INSERT INTO trgfire VALUES (1); + +CREATE TABLE trgfire2 PARTITION OF trgfire FOR VALUES FROM (10) TO (20); + +INSERT INTO trgfire VALUES (11); + +CREATE TABLE trgfire3 (LIKE trgfire); + +ALTER TABLE trgfire ATTACH PARTITION trgfire3 FOR VALUES FROM (20) TO (30); + +INSERT INTO trgfire VALUES (21); + +CREATE TABLE trgfire4 PARTITION OF trgfire FOR VALUES FROM (30) TO (40) PARTITION BY LIST (i); + +CREATE TABLE trgfire4_30 PARTITION OF trgfire4 FOR VALUES IN (30); + +INSERT INTO trgfire VALUES (30); + +CREATE TABLE trgfire5 (LIKE trgfire) PARTITION BY LIST (i); + +CREATE TABLE trgfire5_40 PARTITION OF trgfire5 FOR VALUES IN (40); + +ALTER TABLE trgfire ATTACH PARTITION trgfire5 FOR VALUES FROM (40) TO (50); + +INSERT INTO trgfire VALUES (40); + +SELECT tgrelid::regclass, tgenabled FROM pg_trigger + WHERE tgrelid::regclass IN (SELECT oid from pg_class where relname LIKE 'trgfire%') + ORDER BY tgrelid::regclass::text; + +ALTER TABLE trgfire ENABLE TRIGGER tg; + +INSERT INTO trgfire VALUES (1); + +INSERT INTO trgfire VALUES (11); + +INSERT INTO trgfire VALUES (21); + +INSERT INTO trgfire VALUES (30); + +INSERT INTO trgfire VALUES (40); + +DROP TABLE trgfire; + +DROP FUNCTION tgf(); + +create or replace function dump_insert() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, new table = %', + TG_NAME, + (select string_agg(new_table::text, ', ' order by a) from new_table); + return null; + end; +$$; + +create or replace function dump_update() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, old table = %, new table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by a) from old_table), + (select string_agg(new_table::text, ', ' order by a) from new_table); + return null; + end; +$$; + +create or replace function dump_delete() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, old table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by a) from old_table); + return null; + end; +$$; + +create table parent (a text, b int) partition by list (a); + +create table child1 partition of parent for values in ('AAA'); + +create table child2 (x int, a text, b int); + +alter table child2 drop column x; + +alter table parent attach partition child2 for values in ('BBB'); + +create table child3 (b int, a text); + +alter table parent attach partition child3 for values in ('CCC'); + +create trigger parent_insert_trig + after insert on parent referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger parent_update_trig + after update on parent referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger parent_delete_trig + after delete on parent referencing old table as old_table + for each statement execute procedure dump_delete(); + +create trigger child1_insert_trig + after insert on child1 referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger child1_update_trig + after update on child1 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger child1_delete_trig + after delete on child1 referencing old table as old_table + for each statement execute procedure dump_delete(); + +create trigger child2_insert_trig + after insert on child2 referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger child2_update_trig + after update on child2 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger child2_delete_trig + after delete on child2 referencing old table as old_table + for each statement execute procedure dump_delete(); + +create trigger child3_insert_trig + after insert on child3 referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger child3_update_trig + after update on child3 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger child3_delete_trig + after delete on child3 referencing old table as old_table + for each statement execute procedure dump_delete(); + +SELECT trigger_name, event_manipulation, event_object_schema, event_object_table, + action_order, action_condition, action_orientation, action_timing, + action_reference_old_table, action_reference_new_table + FROM information_schema.triggers + WHERE event_object_table IN ('parent', 'child1', 'child2', 'child3') + ORDER BY trigger_name COLLATE "C", 2; + +insert into child1 values ('AAA', 42); + +insert into child2 values ('BBB', 42); + +insert into child3 values (42, 'CCC'); + +update parent set b = b + 1; + +delete from parent; + +insert into parent values ('AAA', 42); + +insert into parent values ('BBB', 42); + +insert into parent values ('CCC', 42); + +delete from child1; + +delete from child2; + +delete from child3; + +copy parent (a, b) from stdin; + +alter table parent detach partition child1; + +alter table parent attach partition child1 for values in ('AAA'); + +drop trigger child1_insert_trig on child1; + +drop trigger child1_update_trig on child1; + +drop trigger child1_delete_trig on child1; + +drop trigger child2_insert_trig on child2; + +drop trigger child2_update_trig on child2; + +drop trigger child2_delete_trig on child2; + +drop trigger child3_insert_trig on child3; + +drop trigger child3_update_trig on child3; + +drop trigger child3_delete_trig on child3; + +delete from parent; + +copy parent (a, b) from stdin; + +create or replace function intercept_insert() returns trigger language plpgsql as +$$ + begin + new.b = new.b + 1000; + return new; + end; +$$; + +create trigger intercept_insert_child3 + before insert on child3 + for each row execute procedure intercept_insert(); + +insert into parent values ('AAA', 42), ('BBB', 42), ('CCC', 66); + +copy parent (a, b) from stdin; + +drop table child1, child2, child3, parent; + +drop function intercept_insert(); + +create table parent (a text, b int) partition by list (a); + +create table child partition of parent for values in ('AAA'); + +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert(); + +alter table parent detach partition child; + +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert(); + +alter table parent attach partition child for values in ('AAA'); + +drop trigger child_row_trig on child; + +alter table parent attach partition child for values in ('AAA'); + +drop table child, parent; + +create or replace function dump_update_new() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, new table = %', TG_NAME, + (select string_agg(new_table::text, ', ' order by a) from new_table); + return null; + end; +$$; + +create or replace function dump_update_old() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = %, old table = %', TG_NAME, + (select string_agg(old_table::text, ', ' order by a) from old_table); + return null; + end; +$$; + +create table trans_tab_parent (a text) partition by list (a); + +create table trans_tab_child1 partition of trans_tab_parent for values in ('AAA1', 'AAA2'); + +create table trans_tab_child2 partition of trans_tab_parent for values in ('BBB1', 'BBB2'); + +create trigger trans_tab_parent_update_trig + after update on trans_tab_parent referencing old table as old_table + for each statement execute procedure dump_update_old(); + +create trigger trans_tab_parent_insert_trig + after insert on trans_tab_parent referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger trans_tab_parent_delete_trig + after delete on trans_tab_parent referencing old table as old_table + for each statement execute procedure dump_delete(); + +insert into trans_tab_parent values ('AAA1'), ('BBB1'); + +update trans_tab_parent set a = 'BBB2' where a = 'AAA1'; + +drop trigger trans_tab_parent_update_trig on trans_tab_parent; + +create trigger trans_tab_parent_update_trig + after update on trans_tab_parent referencing new table as new_table + for each statement execute procedure dump_update_new(); + +update trans_tab_parent set a = 'AAA2' where a = 'BBB1'; + +delete from trans_tab_parent; + +drop table trans_tab_parent, trans_tab_child1, trans_tab_child2; + +drop function dump_update_new, dump_update_old; + +create table parent (a text, b int); + +create table child1 () inherits (parent); + +create table child2 (b int, a text); + +alter table child2 inherit parent; + +create table child3 (c text) inherits (parent); + +create trigger parent_insert_trig + after insert on parent referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger parent_update_trig + after update on parent referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger parent_delete_trig + after delete on parent referencing old table as old_table + for each statement execute procedure dump_delete(); + +create trigger child1_insert_trig + after insert on child1 referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger child1_update_trig + after update on child1 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger child1_delete_trig + after delete on child1 referencing old table as old_table + for each statement execute procedure dump_delete(); + +create trigger child2_insert_trig + after insert on child2 referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger child2_update_trig + after update on child2 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger child2_delete_trig + after delete on child2 referencing old table as old_table + for each statement execute procedure dump_delete(); + +create trigger child3_insert_trig + after insert on child3 referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger child3_update_trig + after update on child3 referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger child3_delete_trig + after delete on child3 referencing old table as old_table + for each statement execute procedure dump_delete(); + +insert into child1 values ('AAA', 42); + +insert into child2 values (42, 'BBB'); + +insert into child3 values ('CCC', 42, 'foo'); + +update parent set b = b + 1; + +delete from parent; + +insert into child1 values ('AAA', 42); + +insert into child2 values (42, 'BBB'); + +insert into child3 values ('CCC', 42, 'foo'); + +delete from child1; + +delete from child2; + +delete from child3; + +copy parent (a, b) from stdin; + +create index on parent(b); + +copy parent (a, b) from stdin; + +alter table child1 no inherit parent; + +alter table child1 inherit parent; + +drop trigger child1_insert_trig on child1; + +drop trigger child1_update_trig on child1; + +drop trigger child1_delete_trig on child1; + +drop trigger child2_insert_trig on child2; + +drop trigger child2_update_trig on child2; + +drop trigger child2_delete_trig on child2; + +drop trigger child3_insert_trig on child3; + +drop trigger child3_update_trig on child3; + +drop trigger child3_delete_trig on child3; + +delete from parent; + +drop table child1, child2, child3, parent; + +create table parent (a text, b int); + +create table child () inherits (parent); + +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert(); + +alter table child no inherit parent; + +create trigger child_row_trig + after insert on child referencing new table as new_table + for each row execute procedure dump_insert(); + +alter table child inherit parent; + +drop trigger child_row_trig on child; + +alter table child inherit parent; + +drop table child, parent; + +create table table1 (a int); + +create table table2 (a text); + +create trigger table1_trig + after insert on table1 referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger table2_trig + after insert on table2 referencing new table as new_table + for each statement execute procedure dump_insert(); + +with wcte as (insert into table1 values (42)) + insert into table2 values ('hello world'); + +with wcte as (insert into table1 values (43)) + insert into table1 values (44); + +select * from table1; + +select * from table2; + +drop table table1; + +drop table table2; + +create table my_table (a int primary key, b text); + +create trigger my_table_insert_trig + after insert on my_table referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger my_table_update_trig + after update on my_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +insert into my_table values (1, 'AAA'), (2, 'BBB') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b; + +insert into my_table values (1, 'AAA'), (2, 'BBB'), (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b; + +insert into my_table values (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = my_table.b || ':' || excluded.b; + +create table iocdu_tt_parted (a int primary key, b text) partition by list (a); + +create table iocdu_tt_parted1 partition of iocdu_tt_parted for values in (1); + +create table iocdu_tt_parted2 partition of iocdu_tt_parted for values in (2); + +create table iocdu_tt_parted3 partition of iocdu_tt_parted for values in (3); + +create table iocdu_tt_parted4 partition of iocdu_tt_parted for values in (4); + +create trigger iocdu_tt_parted_insert_trig + after insert on iocdu_tt_parted referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger iocdu_tt_parted_update_trig + after update on iocdu_tt_parted referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +insert into iocdu_tt_parted values (1, 'AAA'), (2, 'BBB') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b; + +insert into iocdu_tt_parted values (1, 'AAA'), (2, 'BBB'), (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b; + +insert into iocdu_tt_parted values (3, 'CCC'), (4, 'DDD') + on conflict (a) do + update set b = iocdu_tt_parted.b || ':' || excluded.b; + +drop table iocdu_tt_parted; + +create trigger my_table_multievent_trig + after insert or update on my_table referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger my_table_col_update_trig + after update of b on my_table referencing new table as new_table + for each statement execute procedure dump_insert(); + +drop table my_table; + +create table my_table (a int); + +create function make_bogus_matview() returns trigger as +$$ begin + create materialized view transition_test_mv as select * from new_table; + return new; +end $$ +language plpgsql; + +create trigger make_bogus_matview + after insert on my_table + referencing new table as new_table + for each statement execute function make_bogus_matview(); + +insert into my_table values (42); + +drop table my_table; + +drop function make_bogus_matview(); + +create table refd_table (a int primary key, b text); + +create table trig_table (a int, b text, + foreign key (a) references refd_table on update cascade on delete cascade +); + +create trigger trig_table_before_trig + before insert or update or delete on trig_table + for each statement execute procedure trigger_func('trig_table'); + +create trigger trig_table_insert_trig + after insert on trig_table referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger trig_table_update_trig + after update on trig_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger trig_table_delete_trig + after delete on trig_table referencing old table as old_table + for each statement execute procedure dump_delete(); + +insert into refd_table values + (1, 'one'), + (2, 'two'), + (3, 'three'); + +insert into trig_table values + (1, 'one a'), + (1, 'one b'), + (2, 'two a'), + (2, 'two b'), + (3, 'three a'), + (3, 'three b'); + +update refd_table set a = 11 where b = 'one'; + +select * from trig_table; + +delete from refd_table where length(b) = 3; + +select * from trig_table; + +drop table refd_table, trig_table; + +create table refd_table (id int primary key); + +create table trig_table (fk int references refd_table initially deferred); + +begin; + +insert into trig_table values (1); + +drop table refd_table cascade; + +commit; + +drop table trig_table; + +create table self_ref (a int primary key, + b int references self_ref(a) on delete cascade); + +create trigger self_ref_before_trig + before delete on self_ref + for each statement execute procedure trigger_func('self_ref'); + +create trigger self_ref_r_trig + after delete on self_ref referencing old table as old_table + for each row execute procedure dump_delete(); + +create trigger self_ref_s_trig + after delete on self_ref referencing old table as old_table + for each statement execute procedure dump_delete(); + +insert into self_ref values (1, null), (2, 1), (3, 2); + +delete from self_ref where a = 1; + +drop trigger self_ref_r_trig on self_ref; + +insert into self_ref values (1, null), (2, 1), (3, 2), (4, 3); + +delete from self_ref where a = 1; + +drop table self_ref; + +create table merge_target_table (a int primary key, b text); + +create trigger merge_target_table_insert_trig + after insert on merge_target_table referencing new table as new_table + for each statement execute procedure dump_insert(); + +create trigger merge_target_table_update_trig + after update on merge_target_table referencing old table as old_table new table as new_table + for each statement execute procedure dump_update(); + +create trigger merge_target_table_delete_trig + after delete on merge_target_table referencing old table as old_table + for each statement execute procedure dump_delete(); + +create table merge_source_table (a int, b text); + +insert into merge_source_table + values (1, 'initial1'), (2, 'initial2'), + (3, 'initial3'), (4, 'initial4'); + +drop table merge_source_table, merge_target_table; + +drop function dump_insert(); + +drop function dump_update(); + +drop function dump_delete(); + +create table my_table (id integer); + +create function funcA() returns trigger as $$ +begin + raise notice 'hello from funcA'; + return null; +end; $$ language plpgsql; + +create function funcB() returns trigger as $$ +begin + raise notice 'hello from funcB'; + return null; +end; $$ language plpgsql; + +create trigger my_trig + after insert on my_table + for each row execute procedure funcA(); + +create trigger my_trig + before insert on my_table + for each row execute procedure funcB(); + +insert into my_table values (1); + +create or replace trigger my_trig + before insert on my_table + for each row execute procedure funcB(); + +insert into my_table values (2); + +table my_table; + +drop table my_table; + +create table parted_trig (a int) partition by range (a); + +create table parted_trig_1 partition of parted_trig + for values from (0) to (1000) partition by range (a); + +create table parted_trig_1_1 partition of parted_trig_1 for values from (0) to (100); + +create table parted_trig_2 partition of parted_trig for values from (1000) to (2000); + +create table default_parted_trig partition of parted_trig default; + +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcA(); + +insert into parted_trig (a) values (50); + +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcB(); + +insert into parted_trig (a) values (50); + +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcA(); + +insert into parted_trig (a) values (50); + +create or replace trigger my_trig + after insert on parted_trig_1 + for each row execute procedure funcB(); + +insert into parted_trig (a) values (50); + +drop trigger my_trig on parted_trig; + +insert into parted_trig (a) values (50); + +create trigger my_trig + after insert on parted_trig_1 + for each row execute procedure funcA(); + +insert into parted_trig (a) values (50); + +create trigger my_trig + after insert on parted_trig + for each row execute procedure funcB(); + +insert into parted_trig (a) values (50); + +create or replace trigger my_trig + after insert on parted_trig + for each row execute procedure funcB(); + +insert into parted_trig (a) values (50); + +drop table parted_trig; + +drop function funcA(); + +drop function funcB(); + +create table trigger_parted (a int primary key) partition by list (a); + +create function trigger_parted_trigfunc() returns trigger language plpgsql as + $$ begin end; $$; + +create trigger aft_row after insert or update on trigger_parted + for each row execute function trigger_parted_trigfunc(); + +create table trigger_parted_p1 partition of trigger_parted for values in (1) + partition by list (a); + +create table trigger_parted_p1_1 partition of trigger_parted_p1 for values in (1); + +create table trigger_parted_p2 partition of trigger_parted for values in (2) + partition by list (a); + +create table trigger_parted_p2_2 partition of trigger_parted_p2 for values in (2); + +alter table only trigger_parted_p2 disable trigger aft_row; + +alter table trigger_parted_p2_2 enable always trigger aft_row; + +create table convslot_test_parent (col1 text primary key); + +create table convslot_test_child (col1 text primary key, + foreign key (col1) references convslot_test_parent(col1) on delete cascade on update cascade +); + +alter table convslot_test_child add column col2 text not null default 'tutu'; + +insert into convslot_test_parent(col1) values ('1'); + +insert into convslot_test_child(col1) values ('1'); + +insert into convslot_test_parent(col1) values ('3'); + +insert into convslot_test_child(col1) values ('3'); + +create function convslot_trig1() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, old_table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by col1) from old_table); +return null; +end; $$; + +create function convslot_trig2() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, new table = %', + TG_NAME, + (select string_agg(new_table::text, ', ' order by col1) from new_table); +return null; +end; $$; + +create trigger but_trigger after update on convslot_test_child +referencing new table as new_table +for each statement execute function convslot_trig2(); + +update convslot_test_parent set col1 = col1 || '1'; + +create function convslot_trig3() +returns trigger +language plpgsql +AS $$ +begin +raise notice 'trigger = %, old_table = %, new table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' order by col1) from old_table), + (select string_agg(new_table::text, ', ' order by col1) from new_table); +return null; +end; $$; + +create trigger but_trigger2 after update on convslot_test_child +referencing old table as old_table new table as new_table +for each statement execute function convslot_trig3(); + +update convslot_test_parent set col1 = col1 || '1'; + +create trigger bdt_trigger after delete on convslot_test_child +referencing old table as old_table +for each statement execute function convslot_trig1(); + +delete from convslot_test_parent; + +drop table convslot_test_child, convslot_test_parent; + +drop function convslot_trig1(); + +drop function convslot_trig2(); + +drop function convslot_trig3(); + +create table convslot_test_parent (id int primary key, val int) +partition by range (id); + +create table convslot_test_part (val int, id int not null); + +alter table convslot_test_parent + attach partition convslot_test_part for values from (1) to (1000); + +create function convslot_trig4() returns trigger as +$$begin raise exception 'BOOM!'; end$$ language plpgsql; + +create trigger convslot_test_parent_update + after update on convslot_test_parent + referencing old table as old_rows new table as new_rows + for each statement execute procedure convslot_trig4(); + +insert into convslot_test_parent (id, val) values (1, 2); + +begin; + +savepoint svp; + +update convslot_test_parent set val = 3; + +rollback to savepoint svp; + +rollback; + +drop table convslot_test_parent; + +drop function convslot_trig4(); + +create table grandparent (id int, primary key (id)) partition by range (id); + +create table middle partition of grandparent for values from (1) to (10) +partition by range (id); + +create table chi partition of middle for values from (1) to (5); + +create table cho partition of middle for values from (6) to (10); + +create function f () returns trigger as +$$ begin return new; end; $$ +language plpgsql; + +create trigger a after insert on grandparent +for each row execute procedure f(); + +alter trigger a on grandparent rename to b; + +select tgrelid::regclass, tgname, +(select tgname from pg_trigger tr where tr.oid = pg_trigger.tgparentid) parent_tgname +from pg_trigger where tgrelid in (select relid from pg_partition_tree('grandparent')) +order by tgname, tgrelid::regclass::text COLLATE "C"; + +alter trigger b on middle rename to c; + +create trigger c after insert on middle +for each row execute procedure f(); + +alter trigger b on grandparent rename to c; + +create trigger p after insert on grandparent for each statement execute function f(); + +create trigger p after insert on middle for each statement execute function f(); + +alter trigger p on grandparent rename to q; + +select tgrelid::regclass, tgname, +(select tgname from pg_trigger tr where tr.oid = pg_trigger.tgparentid) parent_tgname +from pg_trigger where tgrelid in (select relid from pg_partition_tree('grandparent')) +order by tgname, tgrelid::regclass::text COLLATE "C"; + +drop table grandparent; + +create table parent (a int); + +create table child () inherits (parent); + +create trigger parenttrig after insert on parent +for each row execute procedure f(); + +create trigger parenttrig after insert on child +for each row execute procedure f(); + +alter trigger parenttrig on parent rename to anothertrig; + +drop table parent, child; + +drop function f(); + +create role regress_caller; + +create role regress_fn_owner; + +create function whoami() returns trigger language plpgsql +as $$ +begin + raise notice 'I am %', current_user; + return null; +end; +$$; + +alter function whoami() owner to regress_fn_owner; + +create table defer_trig (id integer); + +grant insert on defer_trig to public; + +create constraint trigger whoami after insert on defer_trig + deferrable initially deferred + for each row + execute function whoami(); + +begin; + +set role regress_caller; + +insert into defer_trig values (1); + +reset role; + +set role regress_fn_owner; + +insert into defer_trig values (2); + +reset role; + +commit; + +alter function whoami() security definer; + +begin; + +set role regress_caller; + +insert into defer_trig values (3); + +reset role; + +commit; + +alter function whoami() security invoker; + +create or replace function whoami() returns trigger language plpgsql +as $$ +begin + raise notice 'I am %', current_user; + perform 1 / 0; + return null; +end; +$$; + +begin; + +set role regress_caller; + +insert into defer_trig values (4); + +reset role; + +commit; + +select current_user = session_user; + +drop table defer_trig; + +drop function whoami(); + +drop role regress_fn_owner; + +drop role regress_caller; diff --git a/crates/pgt_pretty_print/tests/data/multi/truncate_60.sql b/crates/pgt_pretty_print/tests/data/multi/truncate_60.sql new file mode 100644 index 000000000..d5f484396 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/truncate_60.sql @@ -0,0 +1,435 @@ +CREATE TABLE truncate_a (col1 integer primary key); + +INSERT INTO truncate_a VALUES (1); + +INSERT INTO truncate_a VALUES (2); + +SELECT * FROM truncate_a; + +BEGIN; + +TRUNCATE truncate_a; + +ROLLBACK; + +SELECT * FROM truncate_a; + +BEGIN; + +TRUNCATE truncate_a; + +COMMIT; + +SELECT * FROM truncate_a; + +CREATE TABLE trunc_b (a int REFERENCES truncate_a); + +CREATE TABLE trunc_c (a serial PRIMARY KEY); + +CREATE TABLE trunc_d (a int REFERENCES trunc_c); + +CREATE TABLE trunc_e (a int REFERENCES truncate_a, b int REFERENCES trunc_c); + +TRUNCATE TABLE truncate_a; + +TRUNCATE TABLE truncate_a,trunc_b; + +TRUNCATE TABLE truncate_a,trunc_b,trunc_e; + +TRUNCATE TABLE truncate_a,trunc_e; + +TRUNCATE TABLE trunc_c; + +TRUNCATE TABLE trunc_c,trunc_d; + +TRUNCATE TABLE trunc_c,trunc_d,trunc_e; + +TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a; + +TRUNCATE TABLE trunc_c,trunc_d,trunc_e,truncate_a,trunc_b; + +TRUNCATE TABLE truncate_a RESTRICT; + +TRUNCATE TABLE truncate_a CASCADE; + +ALTER TABLE truncate_a ADD FOREIGN KEY (col1) REFERENCES trunc_c; + +INSERT INTO trunc_c VALUES (1); + +INSERT INTO truncate_a VALUES (1); + +INSERT INTO trunc_b VALUES (1); + +INSERT INTO trunc_d VALUES (1); + +INSERT INTO trunc_e VALUES (1,1); + +TRUNCATE TABLE trunc_c; + +TRUNCATE TABLE trunc_c,truncate_a; + +TRUNCATE TABLE trunc_c,truncate_a,trunc_d; + +TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e; + +TRUNCATE TABLE trunc_c,truncate_a,trunc_d,trunc_e,trunc_b; + +SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d; + +SELECT * FROM trunc_e; + +INSERT INTO trunc_c VALUES (1); + +INSERT INTO truncate_a VALUES (1); + +INSERT INTO trunc_b VALUES (1); + +INSERT INTO trunc_d VALUES (1); + +INSERT INTO trunc_e VALUES (1,1); + +TRUNCATE TABLE trunc_c CASCADE; + +SELECT * FROM truncate_a + UNION ALL + SELECT * FROM trunc_c + UNION ALL + SELECT * FROM trunc_b + UNION ALL + SELECT * FROM trunc_d; + +SELECT * FROM trunc_e; + +DROP TABLE truncate_a,trunc_c,trunc_b,trunc_d,trunc_e CASCADE; + +CREATE TABLE trunc_f (col1 integer primary key); + +INSERT INTO trunc_f VALUES (1); + +INSERT INTO trunc_f VALUES (2); + +CREATE TABLE trunc_fa (col2a text) INHERITS (trunc_f); + +INSERT INTO trunc_fa VALUES (3, 'three'); + +CREATE TABLE trunc_fb (col2b int) INHERITS (trunc_f); + +INSERT INTO trunc_fb VALUES (4, 444); + +CREATE TABLE trunc_faa (col3 text) INHERITS (trunc_fa); + +INSERT INTO trunc_faa VALUES (5, 'five', 'FIVE'); + +BEGIN; + +SELECT * FROM trunc_f; + +TRUNCATE trunc_f; + +SELECT * FROM trunc_f; + +ROLLBACK; + +BEGIN; + +SELECT * FROM trunc_f; + +TRUNCATE ONLY trunc_f; + +SELECT * FROM trunc_f; + +ROLLBACK; + +BEGIN; + +SELECT * FROM trunc_f; + +SELECT * FROM trunc_fa; + +SELECT * FROM trunc_faa; + +TRUNCATE ONLY trunc_fb, ONLY trunc_fa; + +SELECT * FROM trunc_f; + +SELECT * FROM trunc_fa; + +SELECT * FROM trunc_faa; + +ROLLBACK; + +BEGIN; + +SELECT * FROM trunc_f; + +SELECT * FROM trunc_fa; + +SELECT * FROM trunc_faa; + +TRUNCATE ONLY trunc_fb, trunc_fa; + +SELECT * FROM trunc_f; + +SELECT * FROM trunc_fa; + +SELECT * FROM trunc_faa; + +ROLLBACK; + +DROP TABLE trunc_f CASCADE; + +CREATE TABLE trunc_trigger_test (f1 int, f2 text, f3 text); + +CREATE TABLE trunc_trigger_log (tgop text, tglevel text, tgwhen text, + tgargv text, tgtable name, rowcount bigint); + +CREATE FUNCTION trunctrigger() RETURNS trigger as $$ +declare c bigint; +begin + execute 'select count(*) from ' || quote_ident(tg_table_name) into c; + insert into trunc_trigger_log values + (TG_OP, TG_LEVEL, TG_WHEN, TG_ARGV[0], tg_table_name, c); + return null; +end; +$$ LANGUAGE plpgsql; + +INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux'); + +CREATE TRIGGER t +BEFORE TRUNCATE ON trunc_trigger_test +FOR EACH STATEMENT +EXECUTE PROCEDURE trunctrigger('before trigger truncate'); + +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test; + +SELECT * FROM trunc_trigger_log; + +TRUNCATE trunc_trigger_test; + +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test; + +SELECT * FROM trunc_trigger_log; + +DROP TRIGGER t ON trunc_trigger_test; + +truncate trunc_trigger_log; + +INSERT INTO trunc_trigger_test VALUES(1, 'foo', 'bar'), (2, 'baz', 'quux'); + +CREATE TRIGGER tt +AFTER TRUNCATE ON trunc_trigger_test +FOR EACH STATEMENT +EXECUTE PROCEDURE trunctrigger('after trigger truncate'); + +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test; + +SELECT * FROM trunc_trigger_log; + +TRUNCATE trunc_trigger_test; + +SELECT count(*) as "Row count in test table" FROM trunc_trigger_test; + +SELECT * FROM trunc_trigger_log; + +DROP TABLE trunc_trigger_test; + +DROP TABLE trunc_trigger_log; + +DROP FUNCTION trunctrigger(); + +CREATE SEQUENCE truncate_a_id1 START WITH 33; + +CREATE TABLE truncate_a (id serial, + id1 integer default nextval('truncate_a_id1')); + +ALTER SEQUENCE truncate_a_id1 OWNED BY truncate_a.id1; + +INSERT INTO truncate_a DEFAULT VALUES; + +INSERT INTO truncate_a DEFAULT VALUES; + +SELECT * FROM truncate_a; + +TRUNCATE truncate_a; + +INSERT INTO truncate_a DEFAULT VALUES; + +INSERT INTO truncate_a DEFAULT VALUES; + +SELECT * FROM truncate_a; + +TRUNCATE truncate_a RESTART IDENTITY; + +INSERT INTO truncate_a DEFAULT VALUES; + +INSERT INTO truncate_a DEFAULT VALUES; + +SELECT * FROM truncate_a; + +CREATE TABLE truncate_b (id int GENERATED ALWAYS AS IDENTITY (START WITH 44)); + +INSERT INTO truncate_b DEFAULT VALUES; + +INSERT INTO truncate_b DEFAULT VALUES; + +SELECT * FROM truncate_b; + +TRUNCATE truncate_b; + +INSERT INTO truncate_b DEFAULT VALUES; + +INSERT INTO truncate_b DEFAULT VALUES; + +SELECT * FROM truncate_b; + +TRUNCATE truncate_b RESTART IDENTITY; + +INSERT INTO truncate_b DEFAULT VALUES; + +INSERT INTO truncate_b DEFAULT VALUES; + +SELECT * FROM truncate_b; + +BEGIN; + +TRUNCATE truncate_a RESTART IDENTITY; + +INSERT INTO truncate_a DEFAULT VALUES; + +SELECT * FROM truncate_a; + +ROLLBACK; + +INSERT INTO truncate_a DEFAULT VALUES; + +INSERT INTO truncate_a DEFAULT VALUES; + +SELECT * FROM truncate_a; + +DROP TABLE truncate_a; + +SELECT nextval('truncate_a_id1'); + +CREATE TABLE truncparted (a int, b char) PARTITION BY LIST (a); + +TRUNCATE ONLY truncparted; + +CREATE TABLE truncparted1 PARTITION OF truncparted FOR VALUES IN (1); + +INSERT INTO truncparted VALUES (1, 'a'); + +TRUNCATE ONLY truncparted; + +TRUNCATE truncparted; + +DROP TABLE truncparted; + +CREATE FUNCTION tp_ins_data() RETURNS void LANGUAGE plpgsql AS $$ + BEGIN + INSERT INTO truncprim VALUES (1), (100), (150); + INSERT INTO truncpart VALUES (1), (100), (150); + END +$$; + +CREATE FUNCTION tp_chk_data(OUT pktb regclass, OUT pkval int, OUT fktb regclass, OUT fkval int) + RETURNS SETOF record LANGUAGE plpgsql AS $$ + BEGIN + RETURN QUERY SELECT + pk.tableoid::regclass, pk.a, fk.tableoid::regclass, fk.a + FROM truncprim pk FULL JOIN truncpart fk USING (a) + ORDER BY 2, 4; + END +$$; + +CREATE TABLE truncprim (a int PRIMARY KEY); + +CREATE TABLE truncpart (a int REFERENCES truncprim) + PARTITION BY RANGE (a); + +CREATE TABLE truncpart_1 PARTITION OF truncpart FOR VALUES FROM (0) TO (100); + +CREATE TABLE truncpart_2 PARTITION OF truncpart FOR VALUES FROM (100) TO (200) + PARTITION BY RANGE (a); + +CREATE TABLE truncpart_2_1 PARTITION OF truncpart_2 FOR VALUES FROM (100) TO (150); + +CREATE TABLE truncpart_2_d PARTITION OF truncpart_2 DEFAULT; + +TRUNCATE TABLE truncprim; + +select tp_ins_data(); + +TRUNCATE TABLE truncprim, truncpart; + +select * from tp_chk_data(); + +select tp_ins_data(); + +TRUNCATE TABLE truncprim CASCADE; + +SELECT * FROM tp_chk_data(); + +SELECT tp_ins_data(); + +TRUNCATE TABLE truncpart; + +SELECT * FROM tp_chk_data(); + +DROP TABLE truncprim, truncpart; + +DROP FUNCTION tp_ins_data(), tp_chk_data(); + +CREATE TABLE trunc_a (a INT PRIMARY KEY) PARTITION BY RANGE (a); + +CREATE TABLE trunc_a1 PARTITION OF trunc_a FOR VALUES FROM (0) TO (10); + +CREATE TABLE trunc_a2 PARTITION OF trunc_a FOR VALUES FROM (10) TO (20) + PARTITION BY RANGE (a); + +CREATE TABLE trunc_a21 PARTITION OF trunc_a2 FOR VALUES FROM (10) TO (12); + +CREATE TABLE trunc_a22 PARTITION OF trunc_a2 FOR VALUES FROM (12) TO (16); + +CREATE TABLE trunc_a2d PARTITION OF trunc_a2 DEFAULT; + +CREATE TABLE trunc_a3 PARTITION OF trunc_a FOR VALUES FROM (20) TO (30); + +INSERT INTO trunc_a VALUES (0), (5), (10), (15), (20), (25); + +CREATE TABLE ref_b ( + b INT PRIMARY KEY, + a INT REFERENCES trunc_a(a) ON DELETE CASCADE +); + +INSERT INTO ref_b VALUES (10, 0), (50, 5), (100, 10), (150, 15); + +TRUNCATE TABLE trunc_a1 CASCADE; + +SELECT a FROM ref_b; + +DROP TABLE ref_b; + +CREATE TABLE ref_c ( + c INT PRIMARY KEY, + a INT REFERENCES trunc_a(a) ON DELETE CASCADE +) PARTITION BY RANGE (c); + +CREATE TABLE ref_c1 PARTITION OF ref_c FOR VALUES FROM (100) TO (200); + +CREATE TABLE ref_c2 PARTITION OF ref_c FOR VALUES FROM (200) TO (300); + +INSERT INTO ref_c VALUES (100, 10), (150, 15), (200, 20), (250, 25); + +TRUNCATE TABLE trunc_a21 CASCADE; + +SELECT a as "from table ref_c" FROM ref_c; + +SELECT a as "from table trunc_a" FROM trunc_a ORDER BY a; + +DROP TABLE trunc_a, ref_c; diff --git a/crates/pgt_pretty_print/tests/data/multi/tsdicts_60.sql b/crates/pgt_pretty_print/tests/data/multi/tsdicts_60.sql new file mode 100644 index 000000000..753fab05f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tsdicts_60.sql @@ -0,0 +1,228 @@ +CREATE TEXT SEARCH DICTIONARY ispell ( + Template=ispell, + DictFile=ispell_sample, + AffFile=ispell_sample +); + +SELECT ts_lexize('ispell', 'skies'); + +SELECT ts_lexize('ispell', 'bookings'); + +SELECT ts_lexize('ispell', 'booking'); + +SELECT ts_lexize('ispell', 'foot'); + +SELECT ts_lexize('ispell', 'foots'); + +SELECT ts_lexize('ispell', 'rebookings'); + +SELECT ts_lexize('ispell', 'rebooking'); + +SELECT ts_lexize('ispell', 'rebook'); + +SELECT ts_lexize('ispell', 'unbookings'); + +SELECT ts_lexize('ispell', 'unbooking'); + +SELECT ts_lexize('ispell', 'unbook'); + +SELECT ts_lexize('ispell', 'footklubber'); + +SELECT ts_lexize('ispell', 'footballklubber'); + +SELECT ts_lexize('ispell', 'ballyklubber'); + +SELECT ts_lexize('ispell', 'footballyklubber'); + +CREATE TEXT SEARCH DICTIONARY hunspell ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample +); + +SELECT ts_lexize('hunspell', 'skies'); + +SELECT ts_lexize('hunspell', 'bookings'); + +SELECT ts_lexize('hunspell', 'booking'); + +SELECT ts_lexize('hunspell', 'foot'); + +SELECT ts_lexize('hunspell', 'foots'); + +SELECT ts_lexize('hunspell', 'rebookings'); + +SELECT ts_lexize('hunspell', 'rebooking'); + +SELECT ts_lexize('hunspell', 'rebook'); + +SELECT ts_lexize('hunspell', 'unbookings'); + +SELECT ts_lexize('hunspell', 'unbooking'); + +SELECT ts_lexize('hunspell', 'unbook'); + +SELECT ts_lexize('hunspell', 'footklubber'); + +SELECT ts_lexize('hunspell', 'footballklubber'); + +SELECT ts_lexize('hunspell', 'ballyklubber'); + +SELECT ts_lexize('hunspell', 'footballyklubber'); + +CREATE TEXT SEARCH DICTIONARY hunspell_long ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=hunspell_sample_long +); + +SELECT ts_lexize('hunspell_long', 'skies'); + +SELECT ts_lexize('hunspell_long', 'bookings'); + +SELECT ts_lexize('hunspell_long', 'booking'); + +SELECT ts_lexize('hunspell_long', 'foot'); + +SELECT ts_lexize('hunspell_long', 'foots'); + +SELECT ts_lexize('hunspell_long', 'rebookings'); + +SELECT ts_lexize('hunspell_long', 'rebooking'); + +SELECT ts_lexize('hunspell_long', 'rebook'); + +SELECT ts_lexize('hunspell_long', 'unbookings'); + +SELECT ts_lexize('hunspell_long', 'unbooking'); + +SELECT ts_lexize('hunspell_long', 'unbook'); + +SELECT ts_lexize('hunspell_long', 'booked'); + +SELECT ts_lexize('hunspell_long', 'footklubber'); + +SELECT ts_lexize('hunspell_long', 'footballklubber'); + +SELECT ts_lexize('hunspell_long', 'ballyklubber'); + +SELECT ts_lexize('hunspell_long', 'ballsklubber'); + +SELECT ts_lexize('hunspell_long', 'footballyklubber'); + +SELECT ts_lexize('hunspell_long', 'ex-machina'); + +CREATE TEXT SEARCH DICTIONARY hunspell_num ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=hunspell_sample_num +); + +SELECT ts_lexize('hunspell_num', 'skies'); + +SELECT ts_lexize('hunspell_num', 'sk'); + +SELECT ts_lexize('hunspell_num', 'bookings'); + +SELECT ts_lexize('hunspell_num', 'booking'); + +SELECT ts_lexize('hunspell_num', 'foot'); + +SELECT ts_lexize('hunspell_num', 'foots'); + +SELECT ts_lexize('hunspell_num', 'rebookings'); + +SELECT ts_lexize('hunspell_num', 'rebooking'); + +SELECT ts_lexize('hunspell_num', 'rebook'); + +SELECT ts_lexize('hunspell_num', 'unbookings'); + +SELECT ts_lexize('hunspell_num', 'unbooking'); + +SELECT ts_lexize('hunspell_num', 'unbook'); + +SELECT ts_lexize('hunspell_num', 'booked'); + +SELECT ts_lexize('hunspell_num', 'footklubber'); + +SELECT ts_lexize('hunspell_num', 'footballklubber'); + +SELECT ts_lexize('hunspell_num', 'ballyklubber'); + +SELECT ts_lexize('hunspell_num', 'footballyklubber'); + +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample_long +); + +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=ispell_sample, + AffFile=hunspell_sample_num +); + +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=ispell_sample +); + +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 ( + Template=ispell, + DictFile=hunspell_sample_long, + AffFile=hunspell_sample_num +); + +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=ispell_sample +); + +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + Template=ispell, + DictFile=hunspell_sample_num, + AffFile=hunspell_sample_long +); + +CREATE TEXT SEARCH DICTIONARY synonym ( + Template=synonym, + Synonyms=synonym_sample +); + +SELECT ts_lexize('synonym', 'PoStGrEs'); + +SELECT ts_lexize('synonym', 'Gogle'); + +SELECT ts_lexize('synonym', 'indices'); + +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym'; + +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = 1); + +SELECT ts_lexize('synonym', 'PoStGrEs'); + +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym'; + +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = 2); + +ALTER TEXT SEARCH DICTIONARY synonym (CaseSensitive = off); + +SELECT ts_lexize('synonym', 'PoStGrEs'); + +SELECT dictinitoption FROM pg_ts_dict WHERE dictname = 'synonym'; + +CREATE TEXT SEARCH DICTIONARY thesaurus ( + Template=thesaurus, + DictFile=thesaurus_sample, + Dictionary=english_stem +); + +SELECT ts_lexize('thesaurus', 'one'); + +CREATE TEXT SEARCH CONFIGURATION ispell_tst ( + COPY=english +); diff --git a/crates/pgt_pretty_print/tests/data/multi/tsearch_60.sql b/crates/pgt_pretty_print/tests/data/multi/tsearch_60.sql new file mode 100644 index 000000000..e2fbf6ab7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tsearch_60.sql @@ -0,0 +1,1135 @@ +SELECT oid, prsname +FROM pg_ts_parser +WHERE prsnamespace = 0 OR prsstart = 0 OR prstoken = 0 OR prsend = 0 OR + -- prsheadline is optional + prslextype = 0; + +SELECT oid, dictname +FROM pg_ts_dict +WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0; + +SELECT oid, tmplname +FROM pg_ts_template +WHERE tmplnamespace = 0 OR tmpllexize = 0; + +SELECT oid, cfgname +FROM pg_ts_config +WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0; + +SELECT mapcfg, maptokentype, mapseqno +FROM pg_ts_config_map +WHERE mapcfg = 0 OR mapdict = 0; + +SELECT * FROM + ( SELECT oid AS cfgid, (ts_token_type(cfgparser)).tokid AS tokid + FROM pg_ts_config ) AS tt +RIGHT JOIN pg_ts_config_map AS m + ON (tt.cfgid=m.mapcfg AND tt.tokid=m.maptokentype) +WHERE + tt.cfgid IS NULL OR tt.tokid IS NULL; + +CREATE TABLE test_tsvector( + t text, + a tsvector +); + +COPY test_tsvector FROM 'filename'; + +ANALYZE test_tsvector; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; + +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); + +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; + +create index wowidx on test_tsvector using gist (a); + +SET enable_seqscan=OFF; + +SET enable_indexscan=ON; + +SET enable_bitmapscan=OFF; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; + +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); + +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; + +SET enable_indexscan=OFF; + +SET enable_bitmapscan=ON; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; + +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); + +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; + +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(foo=1)); + +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=0)); + +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=2048)); + +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100,foo='bar')); + +CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100, siglen = 200)); + +CREATE INDEX wowidx2 ON test_tsvector USING gist (a tsvector_ops(siglen=1)); + +DROP INDEX wowidx; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; + +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); + +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; + +DROP INDEX wowidx2; + +CREATE INDEX wowidx ON test_tsvector USING gist (a tsvector_ops(siglen=484)); + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; + +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); + +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; + +RESET enable_seqscan; + +RESET enable_indexscan; + +RESET enable_bitmapscan; + +DROP INDEX wowidx; + +CREATE INDEX wowidx ON test_tsvector USING gin (a); + +SET enable_seqscan=OFF; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; + +SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); + +SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ '!qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh'; + +SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh'; + +RESET enable_seqscan; + +INSERT INTO test_tsvector VALUES ('???', 'DFG:1A,2B,6C,10 FGH'); + +SELECT * FROM ts_stat('SELECT a FROM test_tsvector') ORDER BY ndoc DESC, nentry DESC, word LIMIT 10; + +SELECT * FROM ts_stat('SELECT a FROM test_tsvector', 'AB') ORDER BY ndoc DESC, nentry DESC, word; + +SELECT ts_lexize('english_stem', 'skies'); + +SELECT ts_lexize('english_stem', 'identity'); + +SELECT * FROM ts_token_type('default'); + +SELECT * FROM ts_parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net teodor@123-stack.net 123_teodor@stack.net 123-teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 + wow < jqw <> qwerty'); + +SELECT to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net teodor@123-stack.net 123_teodor@stack.net 123-teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 + wow < jqw <> qwerty'); + +SELECT length(to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net teodor@123-stack.net 123_teodor@stack.net 123-teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 +/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 + wow < jqw <> qwerty')); + +SELECT * from ts_debug('english', 'abc&nm1;def©ghiõjkl'); + +SELECT * from ts_debug('english', 'http://www.harewoodsolutions.co.uk/press.aspx'); + +SELECT * from ts_debug('english', 'http://aew.wer0c.ewr/id?ad=qwe&dw'); + +SELECT * from ts_debug('english', 'http://5aew.werc.ewr:8100/?'); + +SELECT * from ts_debug('english', '5aew.werc.ewr:8100/?xx'); + +SELECT token, alias, + dictionaries, dictionaries is null as dnull, array_dims(dictionaries) as ddims, + lexemes, lexemes is null as lnull, array_dims(lexemes) as ldims +from ts_debug('english', 'a title'); + +SELECT to_tsquery('english', 'qwe & sKies '); + +SELECT to_tsquery('simple', 'qwe & sKies '); + +SELECT to_tsquery('english', '''the wether'':dc & '' sKies '':BC '); + +SELECT to_tsquery('english', 'asd&(and|fghj)'); + +SELECT to_tsquery('english', '(asd&and)|fghj'); + +SELECT to_tsquery('english', '(asd&!and)|fghj'); + +SELECT to_tsquery('english', '(the|and&(i&1))&fghj'); + +SELECT plainto_tsquery('english', 'the and z 1))& fghj'); + +SELECT plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd'); + +SELECT plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg'); + +SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg'); + +SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg'; + +SELECT to_tsquery('english', '!(a & !b) & c'); + +SELECT to_tsquery('english', '!(a & !b)'); + +SELECT to_tsquery('english', '(1 <-> 2) <-> a'); + +SELECT to_tsquery('english', '(1 <-> a) <-> 2'); + +SELECT to_tsquery('english', '(a <-> 1) <-> 2'); + +SELECT to_tsquery('english', 'a <-> (1 <-> 2)'); + +SELECT to_tsquery('english', '1 <-> (a <-> 2)'); + +SELECT to_tsquery('english', '1 <-> (2 <-> a)'); + +SELECT to_tsquery('english', '(1 <-> 2) <3> a'); + +SELECT to_tsquery('english', '(1 <-> a) <3> 2'); + +SELECT to_tsquery('english', '(a <-> 1) <3> 2'); + +SELECT to_tsquery('english', 'a <3> (1 <-> 2)'); + +SELECT to_tsquery('english', '1 <3> (a <-> 2)'); + +SELECT to_tsquery('english', '1 <3> (2 <-> a)'); + +SELECT to_tsquery('english', '(1 <3> 2) <-> a'); + +SELECT to_tsquery('english', '(1 <3> a) <-> 2'); + +SELECT to_tsquery('english', '(a <3> 1) <-> 2'); + +SELECT to_tsquery('english', 'a <-> (1 <3> 2)'); + +SELECT to_tsquery('english', '1 <-> (a <3> 2)'); + +SELECT to_tsquery('english', '1 <-> (2 <3> a)'); + +SELECT to_tsquery('english', '((a <-> 1) <-> 2) <-> s'); + +SELECT to_tsquery('english', '(2 <-> (a <-> 1)) <-> s'); + +SELECT to_tsquery('english', '((1 <-> a) <-> 2) <-> s'); + +SELECT to_tsquery('english', '(2 <-> (1 <-> a)) <-> s'); + +SELECT to_tsquery('english', 's <-> ((a <-> 1) <-> 2)'); + +SELECT to_tsquery('english', 's <-> (2 <-> (a <-> 1))'); + +SELECT to_tsquery('english', 's <-> ((1 <-> a) <-> 2)'); + +SELECT to_tsquery('english', 's <-> (2 <-> (1 <-> a))'); + +SELECT to_tsquery('english', '((a <-> 1) <-> s) <-> 2'); + +SELECT to_tsquery('english', '(s <-> (a <-> 1)) <-> 2'); + +SELECT to_tsquery('english', '((1 <-> a) <-> s) <-> 2'); + +SELECT to_tsquery('english', '(s <-> (1 <-> a)) <-> 2'); + +SELECT to_tsquery('english', '2 <-> ((a <-> 1) <-> s)'); + +SELECT to_tsquery('english', '2 <-> (s <-> (a <-> 1))'); + +SELECT to_tsquery('english', '2 <-> ((1 <-> a) <-> s)'); + +SELECT to_tsquery('english', '2 <-> (s <-> (1 <-> a))'); + +SELECT to_tsquery('english', 'foo <-> (a <-> (the <-> bar))'); + +SELECT to_tsquery('english', '((foo <-> a) <-> the) <-> bar'); + +SELECT to_tsquery('english', 'foo <-> a <-> the <-> bar'); + +SELECT phraseto_tsquery('english', 'PostgreSQL can be extended by the user in many ways'); + +SELECT ts_rank_cd(to_tsvector('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +'), to_tsquery('english', 'paint&water')); + +SELECT ts_rank_cd(to_tsvector('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +'), to_tsquery('english', 'breath&motion&water')); + +SELECT ts_rank_cd(to_tsvector('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +'), to_tsquery('english', 'ocean')); + +SELECT ts_rank_cd(to_tsvector('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +'), to_tsquery('english', 'painted <-> Ship')); + +SELECT ts_rank_cd(strip(to_tsvector('both stripped')), + to_tsquery('both & stripped')); + +SELECT ts_rank_cd(to_tsvector('unstripped') || strip(to_tsvector('stripped')), + to_tsquery('unstripped & stripped')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'paint&water')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'breath&motion&water')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'ocean')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'day & drink')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'day | drink')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'day | !drink')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'painted <-> Ship & drink')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'painted <-> Ship | drink')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'painted <-> Ship | !drink')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', phraseto_tsquery('english', 'painted Ocean')); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', phraseto_tsquery('english', 'idle as a painted Ship')); + +SELECT ts_headline('english', +'Lorem ipsum urna. Nullam nullam ullamcorper urna.', +to_tsquery('english','Lorem') && phraseto_tsquery('english','ullamcorper urna'), +'MaxWords=100, MinWords=1'); + +SELECT ts_headline('english', +'Lorem ipsum urna. Nullam nullam ullamcorper urna.', +phraseto_tsquery('english','ullamcorper urna'), +'MaxWords=100, MinWords=5'); + +SELECT ts_headline('english', ' + + + +Sea view wow foo bar qq +YES   +ff-bg + + +', +to_tsquery('english', 'sea&foo'), 'HighlightAll=true'); + +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=2, MinWords=1'); + +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 & 3', 'MaxWords=4, MinWords=1'); + +SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=4, MinWords=1'); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'ocean'), 'MaxFragments=1'); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2'); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'ocean & seahorse'), 'MaxFragments=1'); + +SELECT ts_headline('english', ' +Day after day, day after day, + We stuck, nor breath nor motion, +As idle as a painted Ship + Upon a painted Ocean. +Water, water, every where + And all the boards did shrink; +Water, water, every where, + Nor any drop to drink. +S. T. Coleridge (1772-1834) +', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2,FragmentDelimiter=***'); + +SELECT ts_headline('english', +'Lorem ipsum urna. Nullam nullam ullamcorper urna.', +to_tsquery('english','Lorem') && phraseto_tsquery('english','ullamcorper urna'), +'MaxFragments=100, MaxWords=100, MinWords=1'); + +SELECT ts_headline('english', +'', to_tsquery('english', '')); + +SELECT ts_headline('english', +'foo bar', to_tsquery('english', '')); + +CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT); + +ALTER TABLE test_tsquery ADD COLUMN keyword tsquery; + +UPDATE test_tsquery SET keyword = to_tsquery('english', txtkeyword); + +ALTER TABLE test_tsquery ADD COLUMN sample tsquery; + +UPDATE test_tsquery SET sample = to_tsquery('english', txtsample::text); + +SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new <-> york'; + +CREATE UNIQUE INDEX bt_tsq ON test_tsquery (keyword); + +SET enable_seqscan=OFF; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new <-> york'; + +SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new <-> york'; + +RESET enable_seqscan; + +SELECT ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city'); + +SELECT ts_rewrite(ts_rewrite('new & !york ', 'york', '!jersey'), + 'jersey', 'mexico'); + +SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text ); + +SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::text ); + +SELECT ts_rewrite('bar & qq & foo & (new <-> york)', 'SELECT keyword, sample FROM test_tsquery'::text ); + +SELECT ts_rewrite( 'moscow', 'SELECT keyword, sample FROM test_tsquery'); + +SELECT ts_rewrite( 'moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'); + +SELECT ts_rewrite( 'bar & qq & foo & (new <-> york)', 'SELECT keyword, sample FROM test_tsquery'); + +SELECT ts_rewrite('1 & (2 <-> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ); + +SELECT ts_rewrite('1 & (2 <2> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ); + +SELECT ts_rewrite('5 <-> (1 & (2 <-> 3))', 'SELECT keyword, sample FROM test_tsquery'::text ); + +SELECT ts_rewrite('5 <-> (6 | 8)', 'SELECT keyword, sample FROM test_tsquery'::text ); + +SELECT ts_rewrite(to_tsquery('5 & (6 | 5)'), to_tsquery('5'), to_tsquery('')); + +SELECT ts_rewrite(to_tsquery('!5'), to_tsquery('5'), to_tsquery('')); + +SELECT keyword FROM test_tsquery WHERE keyword @> 'new'; + +SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow'; + +SELECT keyword FROM test_tsquery WHERE keyword <@ 'new'; + +SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow'; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query; + +CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops); + +SET enable_seqscan=OFF; + +SELECT keyword FROM test_tsquery WHERE keyword @> 'new'; + +SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow'; + +SELECT keyword FROM test_tsquery WHERE keyword <@ 'new'; + +SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow'; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; + +SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & qq & foo & (new <-> york)') AS query; + +SELECT ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz'); + +SELECT to_tsvector('foo bar') @@ + ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz'); + +SELECT to_tsvector('bar baz') @@ + ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz'); + +RESET enable_seqscan; + +SET default_text_search_config=simple; + +SELECT to_tsvector('SKIES My booKs'); + +SELECT plainto_tsquery('SKIES My booKs'); + +SELECT to_tsquery('SKIES & My | booKs'); + +SET default_text_search_config=english; + +SELECT to_tsvector('SKIES My booKs'); + +SELECT plainto_tsquery('SKIES My booKs'); + +SELECT to_tsquery('SKIES & My | booKs'); + +CREATE TRIGGER tsvectorupdate +BEFORE UPDATE OR INSERT ON test_tsvector +FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t); + +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); + +INSERT INTO test_tsvector (t) VALUES ('345 qwerty'); + +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); + +UPDATE test_tsvector SET t = null WHERE t = '345 qwerty'; + +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); + +INSERT INTO test_tsvector (t) VALUES ('345 qwerty'); + +SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); + +select * from test_tsquery, to_tsquery('new') q where txtsample @@ q; + +select * from test_tsquery, to_tsquery('english', 'new') q where txtsample @@ q; + +create temp table pendtest (ts tsvector); + +create index pendtest_idx on pendtest using gin(ts); + +insert into pendtest values (to_tsvector('Lore ipsam')); + +insert into pendtest values (to_tsvector('Lore ipsum')); + +select * from pendtest where 'ipsu:*'::tsquery @@ ts; + +select * from pendtest where 'ipsa:*'::tsquery @@ ts; + +select * from pendtest where 'ips:*'::tsquery @@ ts; + +select * from pendtest where 'ipt:*'::tsquery @@ ts; + +select * from pendtest where 'ipi:*'::tsquery @@ ts; + +create temp table phrase_index_test(fts tsvector); + +insert into phrase_index_test values ('A fat cat has just eaten a rat.'); + +insert into phrase_index_test values (to_tsvector('english', 'A fat cat has just eaten a rat.')); + +create index phrase_index_test_idx on phrase_index_test using gin(fts); + +set enable_seqscan = off; + +select * from phrase_index_test where fts @@ phraseto_tsquery('english', 'fat cat'); + +set enable_seqscan = on; + +select websearch_to_tsquery('simple', 'I have a fat:*ABCD cat'); + +select websearch_to_tsquery('simple', 'orange:**AABBCCDD'); + +select websearch_to_tsquery('simple', 'fat:A!cat:B|rat:C<'); + +select websearch_to_tsquery('simple', 'fat:A : cat:B'); + +select websearch_to_tsquery('simple', 'fat*rat'); + +select websearch_to_tsquery('simple', 'fat-rat'); + +select websearch_to_tsquery('simple', 'fat_rat'); + +select websearch_to_tsquery('simple', 'abc : def'); + +select websearch_to_tsquery('simple', 'abc:def'); + +select websearch_to_tsquery('simple', 'a:::b'); + +select websearch_to_tsquery('simple', 'abc:d'); + +select websearch_to_tsquery('simple', ':'); + +select websearch_to_tsquery('simple', 'abc & def'); + +select websearch_to_tsquery('simple', 'abc | def'); + +select websearch_to_tsquery('simple', 'abc <-> def'); + +select websearch_to_tsquery('simple', 'abc (pg or class)'); + +select websearch_to_tsquery('simple', '(foo bar) or (ding dong)'); + +select websearch_to_tsquery('english', 'My brand new smartphone'); + +select websearch_to_tsquery('english', 'My brand "new smartphone"'); + +select websearch_to_tsquery('english', 'My brand "new -smartphone"'); + +select websearch_to_tsquery('simple', 'cat or rat'); + +select websearch_to_tsquery('simple', 'cat OR rat'); + +select websearch_to_tsquery('simple', 'cat "OR" rat'); + +select websearch_to_tsquery('simple', 'cat OR'); + +select websearch_to_tsquery('simple', 'OR rat'); + +select websearch_to_tsquery('simple', '"fat cat OR rat"'); + +select websearch_to_tsquery('simple', 'fat (cat OR rat'); + +select websearch_to_tsquery('simple', 'or OR or'); + +select websearch_to_tsquery('simple', '"fat cat"or"fat rat"'); + +select websearch_to_tsquery('simple', 'fat or(rat'); + +select websearch_to_tsquery('simple', 'fat or)rat'); + +select websearch_to_tsquery('simple', 'fat or&rat'); + +select websearch_to_tsquery('simple', 'fat or|rat'); + +select websearch_to_tsquery('simple', 'fat or!rat'); + +select websearch_to_tsquery('simple', 'fat orrat'); + +select websearch_to_tsquery('simple', 'fat or '); + +select websearch_to_tsquery('simple', 'abc orange'); + +select websearch_to_tsquery('simple', 'abc OR1234'); + +select websearch_to_tsquery('simple', 'abc or-abc'); + +select websearch_to_tsquery('simple', 'abc OR_abc'); + +select websearch_to_tsquery('english', '"pg_class pg'); + +select websearch_to_tsquery('english', 'pg_class pg"'); + +select websearch_to_tsquery('english', '"pg_class pg"'); + +select websearch_to_tsquery('english', '"pg_class : pg"'); + +select websearch_to_tsquery('english', 'abc "pg_class pg"'); + +select websearch_to_tsquery('english', '"pg_class pg" def'); + +select websearch_to_tsquery('english', 'abc "pg pg_class pg" def'); + +select websearch_to_tsquery('english', ' or "pg pg_class pg" or '); + +select websearch_to_tsquery('english', '""pg pg_class pg""'); + +select websearch_to_tsquery('english', 'abc """"" def'); + +select websearch_to_tsquery('english', 'cat -"fat rat"'); + +select websearch_to_tsquery('english', 'cat -"fat rat" cheese'); + +select websearch_to_tsquery('english', 'abc "def -"'); + +select websearch_to_tsquery('english', 'abc "def :"'); + +select websearch_to_tsquery('english', '"A fat cat" has just eaten a -rat.'); + +select websearch_to_tsquery('english', '"A fat cat" has just eaten OR !rat.'); + +select websearch_to_tsquery('english', '"A fat cat" has just (+eaten OR -rat)'); + +select websearch_to_tsquery('english', 'this is ----fine'); + +select websearch_to_tsquery('english', '(()) )))) this ||| is && -fine, "dear friend" OR good'); + +select websearch_to_tsquery('english', 'an old <-> cat " is fine &&& too'); + +select websearch_to_tsquery('english', '"A the" OR just on'); + +select websearch_to_tsquery('english', '"a fat cat" ate a rat'); + +select to_tsvector('english', 'A fat cat ate a rat') @@ + websearch_to_tsquery('english', '"a fat cat" ate a rat'); + +select to_tsvector('english', 'A fat grey cat ate a rat') @@ + websearch_to_tsquery('english', '"a fat cat" ate a rat'); + +select websearch_to_tsquery(''''); + +select websearch_to_tsquery('''abc''''def'''); + +select websearch_to_tsquery('\abc'); + +select websearch_to_tsquery('\'); diff --git a/crates/pgt_pretty_print/tests/data/multi/tsrf_60.sql b/crates/pgt_pretty_print/tests/data/multi/tsrf_60.sql new file mode 100644 index 000000000..88a689f1f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tsrf_60.sql @@ -0,0 +1,158 @@ +SELECT generate_series(1, 3); + +SELECT generate_series(1, 3), generate_series(3,5); + +SELECT generate_series(1, 2), generate_series(1,4); + +SELECT generate_series(1, generate_series(1, 3)); + +SELECT * FROM generate_series(1, generate_series(1, 3)); + +SELECT generate_series(generate_series(1,3), generate_series(2, 4)); + +SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4); + +SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4); + +CREATE TABLE few(id int, dataa text, datab text); + +INSERT INTO few VALUES(1, 'a', 'foo'),(2, 'a', 'bar'),(3, 'b', 'bar'); + +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false; + +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false; + +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss; + +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss; + +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id DESC; + +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, g DESC; + +SELECT few.id, generate_series(1,3) g FROM few ORDER BY id, generate_series(1,3) DESC; + +SELECT few.id FROM few ORDER BY id, generate_series(1,3) DESC; + +SET enable_hashagg TO 0; + +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa; + +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, unnest('{1,1,3}'::int[]); + +SELECT few.dataa, count(*), min(id), max(id), unnest('{1,1,3}'::int[]) FROM few WHERE few.id = 1 GROUP BY few.dataa, 5; + +RESET enable_hashagg; + +SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1 HAVING count(*) > 1; + +SELECT dataa, generate_series(1,1), count(*) FROM few GROUP BY 1, 2 HAVING count(*) > 1; + +SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa ORDER BY 2; + +SELECT few.dataa, count(*) FROM few WHERE dataa = 'a' GROUP BY few.dataa, unnest('{1,1,3}'::int[]) ORDER BY 2; + +SELECT q1, case when q1 > 0 then generate_series(1,3) else 0 end FROM int8_tbl; + +SELECT q1, coalesce(generate_series(1,3), 0) FROM int8_tbl; + +SELECT min(generate_series(1, 3)) FROM few; + +SELECT sum((3 = ANY(SELECT generate_series(1,4)))::int); + +SELECT sum((3 = ANY(SELECT lag(x) over(order by x) + FROM generate_series(1,4) x))::int); + +SELECT min(generate_series(1, 3)) OVER() FROM few; + +SELECT id,lag(id) OVER(), count(*) OVER(), generate_series(1,3) FROM few; + +SELECT SUM(count(*)) OVER(PARTITION BY generate_series(1,3) ORDER BY generate_series(1,3)), generate_series(1,3) g FROM few GROUP BY g; + +SELECT few.dataa, count(*), min(id), max(id), generate_series(1,3) FROM few GROUP BY few.dataa ORDER BY 5, 1; + +set enable_hashagg = false; + +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab); + +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY dataa; + +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab) ORDER BY g; + +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g); + +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY dataa; + +SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY g; + +reset enable_hashagg; + +select 'foo' as f, generate_series(1,2) as g from few order by 1; + +select 'foo' as f, generate_series(1,2) as g from few order by 1; + +CREATE TABLE fewmore AS SELECT generate_series(1,3) AS data; + +INSERT INTO fewmore VALUES(generate_series(4,5)); + +SELECT * FROM fewmore; + +UPDATE fewmore SET data = generate_series(4,9); + +INSERT INTO fewmore VALUES(1) RETURNING generate_series(1,3); + +VALUES(1, generate_series(1,2)); + +SELECT int4mul(generate_series(1,2), 10); + +SELECT generate_series(1,3) IS DISTINCT FROM 2; + +SELECT * FROM int4mul(generate_series(1,2), 10); + +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b); + +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC; + +SELECT DISTINCT ON (a) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC, g DESC; + +SELECT DISTINCT ON (a, b, g) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b) +ORDER BY a, b DESC, g DESC; + +SELECT DISTINCT ON (g) a, b, generate_series(1,3) g +FROM (VALUES (3, 2), (3,1), (1,1), (1,4), (5,3), (5,1)) AS t(a, b); + +SELECT a, generate_series(1,2) FROM (VALUES(1),(2),(3)) r(a) LIMIT 2 OFFSET 2; + +SELECT 1 LIMIT generate_series(1,3); + +SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET few.id) FROM few; + +SELECT (SELECT generate_series(1,3) LIMIT 1 OFFSET g.i) FROM generate_series(0,3) g(i); + +CREATE OPERATOR |@| (PROCEDURE = unnest, RIGHTARG = ANYARRAY); + +SELECT |@|ARRAY[1,2,3]; + +select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1; + +select generate_series(1,3) as x, generate_series(1,3) + 1 as xp1; + +select generate_series(1,3)+1 order by generate_series(1,3); + +select generate_series(1,3)+1 order by generate_series(1,3); + +select generate_series(1,3) as x, generate_series(3,6) + 1 as y; + +select generate_series(1,3) as x, generate_series(3,6) + 1 as y; + +DROP TABLE few; + +DROP TABLE fewmore; diff --git a/crates/pgt_pretty_print/tests/data/multi/tstypes_60.sql b/crates/pgt_pretty_print/tests/data/multi/tstypes_60.sql new file mode 100644 index 000000000..cf3c41066 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tstypes_60.sql @@ -0,0 +1,475 @@ +SET extra_float_digits = 0; + +SELECT '1'::tsvector; + +SELECT '1 '::tsvector; + +SELECT ' 1'::tsvector; + +SELECT ' 1 '::tsvector; + +SELECT '1 2'::tsvector; + +SELECT '''1 2'''::tsvector; + +SELECT E'''1 \\''2'''::tsvector; + +SELECT E'''1 \\''2''3'::tsvector; + +SELECT E'''1 \\''2'' 3'::tsvector; + +SELECT E'''1 \\''2'' '' 3'' 4 '::tsvector; + +SELECT $$'\\as' ab\c ab\\c AB\\\c ab\\\\c$$::tsvector; + +SELECT tsvectorin(tsvectorout($$'\\as' ab\c ab\\c AB\\\c ab\\\\c$$::tsvector)); + +SELECT '''w'':4A,3B,2C,1D,5 a:8'; + +SELECT 'a:3A b:2a'::tsvector || 'ba:1234 a:1B'; + +SELECT $$'' '1' '2'$$::tsvector; + +SELECT pg_input_is_valid('foo', 'tsvector'); + +SELECT pg_input_is_valid($$''$$, 'tsvector'); + +SELECT * FROM pg_input_error_info($$''$$, 'tsvector'); + +SELECT '1'::tsquery; + +SELECT '1 '::tsquery; + +SELECT ' 1'::tsquery; + +SELECT ' 1 '::tsquery; + +SELECT '''1 2'''::tsquery; + +SELECT E'''1 \\''2'''::tsquery; + +SELECT '!1'::tsquery; + +SELECT '1|2'::tsquery; + +SELECT '1|!2'::tsquery; + +SELECT '!1|2'::tsquery; + +SELECT '!1|!2'::tsquery; + +SELECT '!(!1|!2)'::tsquery; + +SELECT '!(!1|2)'::tsquery; + +SELECT '!(1|!2)'::tsquery; + +SELECT '!(1|2)'::tsquery; + +SELECT '1&2'::tsquery; + +SELECT '!1&2'::tsquery; + +SELECT '1&!2'::tsquery; + +SELECT '!1&!2'::tsquery; + +SELECT '(1&2)'::tsquery; + +SELECT '1&(2)'::tsquery; + +SELECT '!(1)&2'::tsquery; + +SELECT '!(1&2)'::tsquery; + +SELECT '1|2&3'::tsquery; + +SELECT '1|(2&3)'::tsquery; + +SELECT '(1|2)&3'::tsquery; + +SELECT '1|2&!3'::tsquery; + +SELECT '1|!2&3'::tsquery; + +SELECT '!1|2&3'::tsquery; + +SELECT '!1|(2&3)'::tsquery; + +SELECT '!(1|2)&3'::tsquery; + +SELECT '(!1|2)&3'::tsquery; + +SELECT '1|(2|(4|(5|6)))'::tsquery; + +SELECT '1|2|4|5|6'::tsquery; + +SELECT '1&(2&(4&(5&6)))'::tsquery; + +SELECT '1&2&4&5&6'::tsquery; + +SELECT '1&(2&(4&(5|6)))'::tsquery; + +SELECT '1&(2&(4&(5|!6)))'::tsquery; + +SELECT E'1&(''2''&('' 4''&(\\|5 | ''6 \\'' !|&'')))'::tsquery; + +SELECT $$'\\as'$$::tsquery; + +SELECT 'a:* & nbb:*ac | doo:a* | goo'::tsquery; + +SELECT '!!b'::tsquery; + +SELECT '!!!b'::tsquery; + +SELECT '!(!b)'::tsquery; + +SELECT 'a & !!b'::tsquery; + +SELECT '!!a & b'::tsquery; + +SELECT '!!a & !!b'::tsquery; + +SELECT pg_input_is_valid('foo', 'tsquery'); + +SELECT pg_input_is_valid('foo!', 'tsquery'); + +SELECT * FROM pg_input_error_info('foo!', 'tsquery'); + +SELECT * FROM pg_input_error_info('a <100000> b', 'tsquery'); + +SELECT 'a' < 'b & c'::tsquery as "true"; + +SELECT 'a' > 'b & c'::tsquery as "false"; + +SELECT 'a | f' < 'b & c'::tsquery as "false"; + +SELECT 'a | ff' < 'b & c'::tsquery as "false"; + +SELECT 'a | f | g' < 'b & c'::tsquery as "false"; + +SELECT numnode( 'new'::tsquery ); + +SELECT numnode( 'new & york'::tsquery ); + +SELECT numnode( 'new & york | qwery'::tsquery ); + +SELECT 'foo & bar'::tsquery && 'asd'; + +SELECT 'foo & bar'::tsquery || 'asd & fg'; + +SELECT 'foo & bar'::tsquery || !!'asd & fg'::tsquery; + +SELECT 'foo & bar'::tsquery && 'asd | fg'; + +SELECT 'a' <-> 'b & d'::tsquery; + +SELECT 'a & g' <-> 'b & d'::tsquery; + +SELECT 'a & g' <-> 'b | d'::tsquery; + +SELECT 'a & g' <-> 'b <-> d'::tsquery; + +SELECT tsquery_phrase('a <3> g', 'b & d', 10); + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca' as "true"; + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:B' as "true"; + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:A' as "true"; + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:C' as "false"; + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:CB' as "true"; + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*C' as "false"; + +SELECT 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & c:*CB' as "true"; + +SELECT 'a b:89 ca:23A,64b cb:80c d:34c'::tsvector @@ 'd:AC & c:*C' as "true"; + +SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*C' as "true"; + +SELECT 'a b:89 ca:23A,64c cb:80b d:34c'::tsvector @@ 'd:AC & c:*B' as "true"; + +SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D & w:*A'::tsquery as "true"; + +SELECT 'wa:1D wb:2A'::tsvector @@ 'w:*D <-> w:*A'::tsquery as "true"; + +SELECT 'wa:1A wb:2D'::tsvector @@ 'w:*D <-> w:*A'::tsquery as "false"; + +SELECT 'wa:1A'::tsvector @@ 'w:*A'::tsquery as "true"; + +SELECT 'wa:1A'::tsvector @@ 'w:*D'::tsquery as "false"; + +SELECT 'wa:1A'::tsvector @@ '!w:*A'::tsquery as "false"; + +SELECT 'wa:1A'::tsvector @@ '!w:*D'::tsquery as "true"; + +SELECT strip('wa:1A'::tsvector) @@ 'w:*A'::tsquery as "true"; + +SELECT strip('wa:1A'::tsvector) @@ 'w:*D'::tsquery as "true"; + +SELECT strip('wa:1A'::tsvector) @@ '!w:*A'::tsquery as "false"; + +SELECT strip('wa:1A'::tsvector) @@ '!w:*D'::tsquery as "false"; + +SELECT 'supernova'::tsvector @@ 'super'::tsquery AS "false"; + +SELECT 'supeanova supernova'::tsvector @@ 'super'::tsquery AS "false"; + +SELECT 'supeznova supernova'::tsvector @@ 'super'::tsquery AS "false"; + +SELECT 'supernova'::tsvector @@ 'super:*'::tsquery AS "true"; + +SELECT 'supeanova supernova'::tsvector @@ 'super:*'::tsquery AS "true"; + +SELECT 'supeznova supernova'::tsvector @@ 'super:*'::tsquery AS "true"; + +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 2' AS "true"; + +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 2' AS "false"; + +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <-> 3' AS "false"; + +SELECT to_tsvector('simple', '1 2 3 1') @@ '1 <2> 3' AS "true"; + +SELECT to_tsvector('simple', '1 2 1 2') @@ '1 <3> 2' AS "true"; + +SELECT to_tsvector('simple', '1 2 11 3') @@ '1 <-> 3' AS "false"; + +SELECT to_tsvector('simple', '1 2 11 3') @@ '1:* <-> 3' AS "true"; + +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> 2 <-> 3' AS "true"; + +SELECT to_tsvector('simple', '1 2 3 4') @@ '(1 <-> 2) <-> 3' AS "true"; + +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <-> (2 <-> 3)' AS "true"; + +SELECT to_tsvector('simple', '1 2 3 4') @@ '1 <2> (2 <-> 3)' AS "false"; + +SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '(1 <-> 2) <-> 3' AS "true"; + +SELECT to_tsvector('simple', '1 2 1 2 3 4') @@ '1 <-> 2 <-> 3' AS "true"; + +SELECT strip(to_tsvector('simple', '1 2 3 4')) @@ '1 <-> 2 <-> 3' AS "false"; + +select to_tsvector('simple', 'q x q y') @@ 'q <-> (x & y)' AS "false"; + +select to_tsvector('simple', 'q x') @@ 'q <-> (x | y <-> z)' AS "true"; + +select to_tsvector('simple', 'q y') @@ 'q <-> (x | y <-> z)' AS "false"; + +select to_tsvector('simple', 'q y z') @@ 'q <-> (x | y <-> z)' AS "true"; + +select to_tsvector('simple', 'q y x') @@ 'q <-> (x | y <-> z)' AS "false"; + +select to_tsvector('simple', 'q x y') @@ 'q <-> (x | y <-> z)' AS "true"; + +select to_tsvector('simple', 'q x') @@ '(x | y <-> z) <-> q' AS "false"; + +select to_tsvector('simple', 'x q') @@ '(x | y <-> z) <-> q' AS "true"; + +select to_tsvector('simple', 'x y q') @@ '(x | y <-> z) <-> q' AS "false"; + +select to_tsvector('simple', 'x y z') @@ '(x | y <-> z) <-> q' AS "false"; + +select to_tsvector('simple', 'x y z q') @@ '(x | y <-> z) <-> q' AS "true"; + +select to_tsvector('simple', 'y z q') @@ '(x | y <-> z) <-> q' AS "true"; + +select to_tsvector('simple', 'y y q') @@ '(x | y <-> z) <-> q' AS "false"; + +select to_tsvector('simple', 'y y q') @@ '(!x | y <-> z) <-> q' AS "true"; + +select to_tsvector('simple', 'x y q') @@ '(!x | y <-> z) <-> q' AS "true"; + +select to_tsvector('simple', 'y y q') @@ '(x | y <-> !z) <-> q' AS "true"; + +select to_tsvector('simple', 'x q') @@ '(x | y <-> !z) <-> q' AS "true"; + +select to_tsvector('simple', 'x q') @@ '(!x | y <-> z) <-> q' AS "false"; + +select to_tsvector('simple', 'z q') @@ '(!x | y <-> z) <-> q' AS "true"; + +select to_tsvector('simple', 'x y q') @@ '(!x | y) <-> y <-> q' AS "false"; + +select to_tsvector('simple', 'x y q') @@ '(!x | !y) <-> y <-> q' AS "true"; + +select to_tsvector('simple', 'x y q') @@ '(x | !y) <-> y <-> q' AS "true"; + +select to_tsvector('simple', 'x y q') @@ '(x | !!z) <-> y <-> q' AS "true"; + +select to_tsvector('simple', 'x y q y') @@ '!x <-> y' AS "true"; + +select to_tsvector('simple', 'x y q y') @@ '!x <-> !y' AS "true"; + +select to_tsvector('simple', 'x y q y') @@ '!x <-> !!y' AS "true"; + +select to_tsvector('simple', 'x y q y') @@ '!(x <-> y)' AS "false"; + +select to_tsvector('simple', 'x y q y') @@ '!(x <2> y)' AS "true"; + +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> y' AS "false"; + +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !y' AS "false"; + +select strip(to_tsvector('simple', 'x y q y')) @@ '!x <-> !!y' AS "false"; + +select strip(to_tsvector('simple', 'x y q y')) @@ '!(x <-> y)' AS "true"; + +select strip(to_tsvector('simple', 'x y q y')) @@ '!(x <2> y)' AS "true"; + +select to_tsvector('simple', 'x y q y') @@ '!foo' AS "true"; + +select to_tsvector('simple', '') @@ '!foo' AS "true"; + +SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a | s'); + +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s'); + +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | s:*'); + +SELECT ts_rank(' a:1 sa:2C d g'::tsvector, 'a | sa:*'); + +SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a | s'); + +SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a | s'); + +SELECT ts_rank(' a:1 s:2C d g'::tsvector, 'a & s'); + +SELECT ts_rank(' a:1 s:2B d g'::tsvector, 'a & s'); + +SELECT ts_rank(' a:1 s:2 d g'::tsvector, 'a & s'); + +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a | s'); + +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s'); + +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | s:*'); + +SELECT ts_rank_cd(' a:1 sa:2C d g'::tsvector, 'a | sa:*'); + +SELECT ts_rank_cd(' a:1 sa:3C sab:2c d g'::tsvector, 'a | sa:*'); + +SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a | s'); + +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a | s'); + +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a & s'); + +SELECT ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a & s'); + +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a & s'); + +SELECT ts_rank_cd(' a:1 s:2A d g'::tsvector, 'a <-> s'); + +SELECT ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a <-> s'); + +SELECT ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a <-> s'); + +SELECT ts_rank_cd(' a:1 s:2 d:2A g'::tsvector, 'a <-> s'); + +SELECT ts_rank_cd(' a:1 s:2,3A d:2A g'::tsvector, 'a <2> s:A'); + +SELECT ts_rank_cd(' a:1 b:2 s:3A d:2A g'::tsvector, 'a <2> s:A'); + +SELECT ts_rank_cd(' a:1 sa:2D sb:2A g'::tsvector, 'a <-> s:*'); + +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:*'); + +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:A'); + +SELECT ts_rank_cd(' a:1 sa:2A sb:2D g'::tsvector, 'a <-> s:* <-> sa:B'); + +SELECT 'a:1 b:2'::tsvector @@ 'a <-> b'::tsquery AS "true"; + +SELECT 'a:1 b:2'::tsvector @@ 'a <0> b'::tsquery AS "false"; + +SELECT 'a:1 b:2'::tsvector @@ 'a <1> b'::tsquery AS "true"; + +SELECT 'a:1 b:2'::tsvector @@ 'a <2> b'::tsquery AS "false"; + +SELECT 'a:1 b:3'::tsvector @@ 'a <-> b'::tsquery AS "false"; + +SELECT 'a:1 b:3'::tsvector @@ 'a <0> b'::tsquery AS "false"; + +SELECT 'a:1 b:3'::tsvector @@ 'a <1> b'::tsquery AS "false"; + +SELECT 'a:1 b:3'::tsvector @@ 'a <2> b'::tsquery AS "true"; + +SELECT 'a:1 b:3'::tsvector @@ 'a <3> b'::tsquery AS "false"; + +SELECT 'a:1 b:3'::tsvector @@ 'a <0> a:*'::tsquery AS "true"; + +SELECT strip('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd'::tsvector); + +SELECT strip('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector); + +SELECT strip('base hidden rebel spaceship strike'::tsvector); + +SELECT ts_delete(to_tsvector('english', 'Rebel spaceships, striking from a hidden base'), 'spaceship'); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'base'); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bas'); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'bases'); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, 'spaceship'); + +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, 'spaceship'); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceship','rebel']); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceships','rebel']); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceshi','rebel']); + +SELECT ts_delete('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector, ARRAY['spaceship','leya','rebel']); + +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel']); + +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel','rebel']); + +SELECT ts_delete('base hidden rebel spaceship strike'::tsvector, ARRAY['spaceship','leya','rebel', '', NULL]); + +SELECT unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector); + +SELECT unnest('base hidden rebel spaceship strike'::tsvector); + +SELECT * FROM unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector); + +SELECT * FROM unnest('base hidden rebel spaceship strike'::tsvector); + +SELECT lexeme, positions[1] from unnest('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector); + +SELECT tsvector_to_array('base:7 hidden:6 rebel:1 spaceship:2,33A,34B,35C,36D strike:3'::tsvector); + +SELECT tsvector_to_array('base hidden rebel spaceship strike'::tsvector); + +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship','strike']); + +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship', NULL]); + +SELECT array_to_tsvector(ARRAY['base','hidden','rebel','spaceship', '']); + +SELECT array_to_tsvector(ARRAY['foo','bar','baz','bar']); + +SELECT setweight('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd zxc:81,567,222A'::tsvector, 'c'); + +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c'); + +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}'); + +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a}'); + +SELECT setweight('a:1,3A asd:1C w:5,6,12B,13A zxc:81,222A,567'::tsvector, 'c', '{a,zxc}'); + +SELECT setweight('a asd w:5,6,12B,13A zxc'::tsvector, 'c', ARRAY['a', 'zxc', '', NULL]); + +SELECT ts_filter('base:7A empir:17 evil:15 first:11 galact:16 hidden:6A rebel:1A spaceship:2A strike:3A victori:12 won:9'::tsvector, '{a}'); + +SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a}'); + +SELECT ts_filter('base hidden rebel spaceship strike'::tsvector, '{a,b,NULL}'); diff --git a/crates/pgt_pretty_print/tests/data/multi/tuplesort_60.sql b/crates/pgt_pretty_print/tests/data/multi/tuplesort_60.sql new file mode 100644 index 000000000..f57589bc9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/tuplesort_60.sql @@ -0,0 +1,280 @@ +SET max_parallel_maintenance_workers = 0; + +SET max_parallel_workers = 0; + +CREATE TEMP TABLE abbrev_abort_uuids ( + id serial not null, + abort_increasing uuid, + abort_decreasing uuid, + noabort_increasing uuid, + noabort_decreasing uuid); + +INSERT INTO abbrev_abort_uuids (abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing) + SELECT + ('00000000-0000-0000-0000-'||to_char(g.i, '000000000000FM'))::uuid abort_increasing, + ('00000000-0000-0000-0000-'||to_char(20000 - g.i, '000000000000FM'))::uuid abort_decreasing, + (to_char(g.i % 10009, '00000000FM')||'-0000-0000-0000-'||to_char(g.i, '000000000000FM'))::uuid noabort_increasing, + (to_char(((20000 - g.i) % 10009), '00000000FM')||'-0000-0000-0000-'||to_char(20000 - g.i, '000000000000FM'))::uuid noabort_decreasing + FROM generate_series(0, 20000, 1) g(i); + +INSERT INTO abbrev_abort_uuids(id) VALUES(0); + +INSERT INTO abbrev_abort_uuids DEFAULT VALUES; + +INSERT INTO abbrev_abort_uuids DEFAULT VALUES; + +INSERT INTO abbrev_abort_uuids (abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing) + SELECT abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing + FROM abbrev_abort_uuids + WHERE (id < 10 OR id > 19990) AND id % 3 = 0 AND abort_increasing is not null; + +SELECT abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing OFFSET 20000 - 4; + +SELECT abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing NULLS FIRST OFFSET 20000 - 4; + +SELECT noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing OFFSET 20000 - 4; + +SELECT noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing NULLS FIRST OFFSET 20000 - 4; + +SELECT abort_increasing, noabort_increasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5; + +SELECT abort_increasing, noabort_increasing FROM abbrev_abort_uuids ORDER BY noabort_increasing NULLS FIRST LIMIT 5; + +CREATE INDEX abbrev_abort_uuids__noabort_increasing_idx ON abbrev_abort_uuids (noabort_increasing); + +CREATE INDEX abbrev_abort_uuids__noabort_decreasing_idx ON abbrev_abort_uuids (noabort_decreasing); + +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing LIMIT 5; + +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_increasing LIMIT 5; + +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing LIMIT 5; + +SELECT id, noabort_increasing, noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing LIMIT 5; + +CREATE INDEX abbrev_abort_uuids__abort_increasing_idx ON abbrev_abort_uuids (abort_increasing); + +CREATE INDEX abbrev_abort_uuids__abort_decreasing_idx ON abbrev_abort_uuids (abort_decreasing); + +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5; + +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_increasing LIMIT 5; + +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing LIMIT 5; + +SELECT id, abort_increasing, abort_decreasing FROM abbrev_abort_uuids ORDER BY abort_decreasing LIMIT 5; + +BEGIN; + +SET LOCAL enable_indexscan = false; + +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_increasing_idx; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5; + +ROLLBACK; + +BEGIN; + +SET LOCAL enable_indexscan = false; + +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__abort_decreasing_idx; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5; + +ROLLBACK; + +BEGIN; + +SET LOCAL enable_indexscan = false; + +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_increasing_idx; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5; + +ROLLBACK; + +BEGIN; + +SET LOCAL enable_indexscan = false; + +CLUSTER abbrev_abort_uuids USING abbrev_abort_uuids__noabort_decreasing_idx; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid LIMIT 5; + +SELECT id, abort_increasing, abort_decreasing, noabort_increasing, noabort_decreasing +FROM abbrev_abort_uuids +ORDER BY ctid DESC LIMIT 5; + +ROLLBACK; + +SELECT LEFT(a,10),b FROM + (VALUES(REPEAT('a', 512 * 1024),1),(REPEAT('b', 512 * 1024),2)) v(a,b) +ORDER BY v.a DESC; + +BEGIN; + +SET LOCAL enable_indexscan = false; + +EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing; + +DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing; + +FETCH NEXT FROM c; + +FETCH NEXT FROM c; + +FETCH BACKWARD FROM c; + +FETCH BACKWARD FROM c; + +FETCH BACKWARD FROM c; + +FETCH BACKWARD FROM c; + +FETCH NEXT FROM c; + +FETCH LAST FROM c; + +FETCH BACKWARD FROM c; + +FETCH NEXT FROM c; + +FETCH NEXT FROM c; + +FETCH NEXT FROM c; + +FETCH BACKWARD FROM c; + +FETCH NEXT FROM c; + +COMMIT; + +BEGIN; + +SET LOCAL enable_indexscan = false; + +SET LOCAL work_mem = '100kB'; + +EXPLAIN (COSTS OFF) DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing; + +DECLARE c SCROLL CURSOR FOR SELECT noabort_decreasing FROM abbrev_abort_uuids ORDER BY noabort_decreasing; + +FETCH NEXT FROM c; + +FETCH NEXT FROM c; + +FETCH BACKWARD FROM c; + +FETCH BACKWARD FROM c; + +FETCH BACKWARD FROM c; + +FETCH BACKWARD FROM c; + +FETCH NEXT FROM c; + +FETCH LAST FROM c; + +FETCH BACKWARD FROM c; + +FETCH NEXT FROM c; + +FETCH NEXT FROM c; + +FETCH NEXT FROM c; + +FETCH BACKWARD FROM c; + +FETCH NEXT FROM c; + +COMMIT; + +SELECT + -- fixed-width by-value datum + (array_agg(id ORDER BY id DESC NULLS FIRST))[0:5], + -- fixed-width by-ref datum + (array_agg(abort_increasing ORDER BY abort_increasing DESC NULLS LAST))[0:5], + -- variable-width datum + (array_agg(id::text ORDER BY id::text DESC NULLS LAST))[0:5], + -- fixed width by-value datum tuplesort + percentile_disc(0.99) WITHIN GROUP (ORDER BY id), + -- ensure state is shared + percentile_disc(0.01) WITHIN GROUP (ORDER BY id), + -- fixed width by-ref datum tuplesort + percentile_disc(0.8) WITHIN GROUP (ORDER BY abort_increasing), + -- variable width by-ref datum tuplesort + percentile_disc(0.2) WITHIN GROUP (ORDER BY id::text), + -- multi-column tuplesort + rank('00000000-0000-0000-0000-000000000000', '2', '2') WITHIN GROUP (ORDER BY noabort_increasing, id, id::text) +FROM ( + SELECT * FROM abbrev_abort_uuids + UNION ALL + SELECT NULL, NULL, NULL, NULL, NULL) s; + +BEGIN; + +SET LOCAL work_mem = '100kB'; + +SELECT + (array_agg(id ORDER BY id DESC NULLS FIRST))[0:5], + (array_agg(abort_increasing ORDER BY abort_increasing DESC NULLS LAST))[0:5], + (array_agg(id::text ORDER BY id::text DESC NULLS LAST))[0:5], + percentile_disc(0.99) WITHIN GROUP (ORDER BY id), + percentile_disc(0.01) WITHIN GROUP (ORDER BY id), + percentile_disc(0.8) WITHIN GROUP (ORDER BY abort_increasing), + percentile_disc(0.2) WITHIN GROUP (ORDER BY id::text), + rank('00000000-0000-0000-0000-000000000000', '2', '2') WITHIN GROUP (ORDER BY noabort_increasing, id, id::text) +FROM ( + SELECT * FROM abbrev_abort_uuids + UNION ALL + SELECT NULL, NULL, NULL, NULL, NULL) s; + +ROLLBACK; + +CREATE TEMP TABLE test_mark_restore(col1 int, col2 int, col12 int); + +INSERT INTO test_mark_restore(col1, col2, col12) + SELECT a.i, b.i, a.i * b.i FROM generate_series(1, 500) a(i), generate_series(1, 5) b(i); + +BEGIN; + +SET LOCAL enable_nestloop = off; + +SET LOCAL enable_hashjoin = off; + +SET LOCAL enable_material = off; + +SELECT $$ + SELECT col12, count(distinct a.col1), count(distinct a.col2), count(distinct b.col1), count(distinct b.col2), count(*) + FROM test_mark_restore a + JOIN test_mark_restore b USING(col12) + GROUP BY 1 + HAVING count(*) > 1 + ORDER BY 2 DESC, 1 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC + LIMIT 10 +$$ AS qry ; + +SET LOCAL work_mem = '100kB'; + +COMMIT; diff --git a/crates/pgt_pretty_print/tests/data/multi/txid_60.sql b/crates/pgt_pretty_print/tests/data/multi/txid_60.sql new file mode 100644 index 000000000..a48897d9a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/txid_60.sql @@ -0,0 +1,115 @@ +select '12:13:'::txid_snapshot; + +select '12:18:14,16'::txid_snapshot; + +select '12:16:14,14'::txid_snapshot; + +select '31:12:'::txid_snapshot; + +select '0:1:'::txid_snapshot; + +select '12:13:0'::txid_snapshot; + +select '12:16:14,13'::txid_snapshot; + +create temp table snapshot_test ( + nr integer, + snap txid_snapshot +); + +insert into snapshot_test values (1, '12:13:'); + +insert into snapshot_test values (2, '12:20:13,15,18'); + +insert into snapshot_test values (3, '100001:100009:100005,100007,100008'); + +insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131'); + +select snap from snapshot_test order by nr; + +select txid_snapshot_xmin(snap), + txid_snapshot_xmax(snap), + txid_snapshot_xip(snap) +from snapshot_test order by nr; + +select id, txid_visible_in_snapshot(id, snap) +from snapshot_test, generate_series(11, 21) id +where nr = 2; + +select id, txid_visible_in_snapshot(id, snap) +from snapshot_test, generate_series(90, 160) id +where nr = 4; + +select txid_current() >= txid_snapshot_xmin(txid_current_snapshot()); + +select txid_visible_in_snapshot(txid_current(), txid_current_snapshot()); + +select txid_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013'; + +select txid_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); + +select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); + +SELECT txid_snapshot '1:9223372036854775807:3'; + +SELECT txid_snapshot '1:9223372036854775808:3'; + +BEGIN; + +SELECT txid_current_if_assigned() IS NULL; + +SELECT txid_current() ; + +SELECT txid_current_if_assigned() IS NOT DISTINCT FROM BIGINT 'txid_current'; + +COMMIT; + +BEGIN; + +SELECT txid_current() AS committed ; + +COMMIT; + +BEGIN; + +SELECT txid_current() AS rolledback ; + +ROLLBACK; + +BEGIN; + +SELECT txid_current() AS inprogress ; + +SELECT txid_status('committed') AS committed; + +SELECT txid_status('rolledback') AS rolledback; + +SELECT txid_status('inprogress') AS inprogress; + +SELECT txid_status(1); + +SELECT txid_status(2); + +SELECT txid_status(3); + +COMMIT; + +BEGIN; + +CREATE FUNCTION test_future_xid_status(bigint) +RETURNS void +LANGUAGE plpgsql +AS +$$ +BEGIN + PERFORM txid_status($1); + RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected'; +EXCEPTION + WHEN invalid_parameter_value THEN + RAISE NOTICE 'Got expected error for xid in the future'; +END; +$$; + +SELECT test_future_xid_status('inprogress' + 10000); + +ROLLBACK; diff --git a/crates/pgt_pretty_print/tests/data/multi/type_sanity_60.sql b/crates/pgt_pretty_print/tests/data/multi/type_sanity_60.sql new file mode 100644 index 000000000..82287b6cd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/type_sanity_60.sql @@ -0,0 +1,444 @@ +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typnamespace = 0 OR + (t1.typlen <= 0 AND t1.typlen != -1 AND t1.typlen != -2) OR + (t1.typtype not in ('b', 'c', 'd', 'e', 'm', 'p', 'r')) OR + NOT t1.typisdefined OR + (t1.typalign not in ('c', 's', 'i', 'd')) OR + (t1.typstorage not in ('p', 'x', 'e', 'm')); + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typbyval AND + (t1.typlen != 1 OR t1.typalign != 'c') AND + (t1.typlen != 2 OR t1.typalign != 's') AND + (t1.typlen != 4 OR t1.typalign != 'i') AND + (t1.typlen != 8 OR t1.typalign != 'd'); + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typstorage != 'p' AND + (t1.typbyval OR t1.typlen != -1); + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE (t1.typtype = 'c' AND t1.typrelid = 0) OR + (t1.typtype != 'c' AND t1.typrelid != 0); + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typtype not in ('p') AND t1.typname NOT LIKE E'\\_%' + AND NOT EXISTS + (SELECT 1 FROM pg_type as t2 + WHERE t2.typname = ('_' || t1.typname)::name AND + t2.typelem = t1.oid and t1.typarray = t2.oid) +ORDER BY t1.oid; + +SELECT t1.oid, t1.typname as basetype, t2.typname as arraytype, + t2.typsubscript +FROM pg_type t1 LEFT JOIN pg_type t2 ON (t1.typarray = t2.oid) +WHERE t1.typarray <> 0 AND + (t2.oid IS NULL OR + t2.typsubscript <> 'array_subscript_handler'::regproc); + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE t1.typtype = 'r' AND + NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = t1.oid); + +SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign +FROM pg_type as t1 + LEFT JOIN pg_range as r ON rngtypid = t1.oid + LEFT JOIN pg_type as t2 ON rngsubtype = t2.oid +WHERE t1.typtype = 'r' AND + (t1.typalign != (CASE WHEN t2.typalign = 'd' THEN 'd'::"char" + ELSE 'i'::"char" END) + OR t2.oid IS NULL); + +SELECT t1.oid, t1.typname +FROM pg_type as t1 +WHERE (t1.typinput = 0 OR t1.typoutput = 0); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND NOT + ((p1.pronargs = 1 AND p1.proargtypes[0] = 'cstring'::regtype) OR + (p1.pronargs = 2 AND p1.proargtypes[0] = 'cstring'::regtype AND + p1.proargtypes[1] = 'oid'::regtype) OR + (p1.pronargs = 3 AND p1.proargtypes[0] = 'cstring'::regtype AND + p1.proargtypes[1] = 'oid'::regtype AND + p1.proargtypes[2] = 'int4'::regtype)); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.prorettype = t1.oid AND NOT p1.proretset) +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.oid = 'array_in'::regproc) +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typinput = p1.oid AND p1.provolatile NOT IN ('i', 's'); + +SELECT DISTINCT typtype, typinput +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'p') +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (p1.pronargs = 1 AND + (p1.proargtypes[0] = t1.oid OR + (p1.oid = 'array_out'::regproc AND + t1.typelem != 0 AND t1.typlen = -1))) +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND NOT + (p1.prorettype = 'cstring'::regtype AND NOT p1.proretset); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typoutput = p1.oid AND p1.provolatile NOT IN ('i', 's'); + +SELECT DISTINCT typtype, typoutput +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'd', 'p') +ORDER BY 1; + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid +WHERE t1.typtype = 'd' AND t1.typoutput IS DISTINCT FROM t2.typoutput; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND NOT + ((p1.pronargs = 1 AND p1.proargtypes[0] = 'internal'::regtype) OR + (p1.pronargs = 2 AND p1.proargtypes[0] = 'internal'::regtype AND + p1.proargtypes[1] = 'oid'::regtype) OR + (p1.pronargs = 3 AND p1.proargtypes[0] = 'internal'::regtype AND + p1.proargtypes[1] = 'oid'::regtype AND + p1.proargtypes[2] = 'int4'::regtype)); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.prorettype = t1.oid AND NOT p1.proretset) +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND + (t1.typelem != 0 AND t1.typlen < 0) AND NOT + (p1.oid = 'array_recv'::regproc) +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname, p2.oid, p2.proname +FROM pg_type AS t1, pg_proc AS p1, pg_proc AS p2 +WHERE t1.typinput = p1.oid AND t1.typreceive = p2.oid AND + p1.pronargs != p2.pronargs; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typreceive = p1.oid AND p1.provolatile NOT IN ('i', 's'); + +SELECT DISTINCT typtype, typreceive +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'p') +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND t1.typtype in ('b', 'p') AND NOT + (p1.pronargs = 1 AND + (p1.proargtypes[0] = t1.oid OR + (p1.oid = 'array_send'::regproc AND + t1.typelem != 0 AND t1.typlen = -1))) +ORDER BY 1; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND NOT + (p1.prorettype = 'bytea'::regtype AND NOT p1.proretset); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typsend = p1.oid AND p1.provolatile NOT IN ('i', 's'); + +SELECT DISTINCT typtype, typsend +FROM pg_type AS t1 +WHERE t1.typtype not in ('b', 'd', 'p') +ORDER BY 1; + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid +WHERE t1.typtype = 'd' AND t1.typsend IS DISTINCT FROM t2.typsend; + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodin = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'cstring[]'::regtype AND + p1.prorettype = 'int4'::regtype AND NOT p1.proretset); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodin = p1.oid AND p1.provolatile NOT IN ('i', 's'); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodout = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'int4'::regtype AND + p1.prorettype = 'cstring'::regtype AND NOT p1.proretset); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typmodout = p1.oid AND p1.provolatile NOT IN ('i', 's'); + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typelem = t2.oid AND NOT + (t1.typmodin = t2.typmodin AND t1.typmodout = t2.typmodout); + +SELECT t1.oid, t1.typname, t2.oid, t2.typname +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typarray = t2.oid AND NOT (t1.typdelim = t2.typdelim); + +SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign +FROM pg_type AS t1, pg_type AS t2 +WHERE t1.typarray = t2.oid AND + t2.typalign != (CASE WHEN t1.typalign = 'd' THEN 'd'::"char" + ELSE 'i'::"char" END); + +SELECT t1.oid, t1.typname, t1.typelem +FROM pg_type AS t1 +WHERE t1.typelem != 0 AND t1.typsubscript = 0; + +SELECT t1.oid, t1.typname, + t1.typelem, t1.typlen, t1.typbyval +FROM pg_type AS t1 +WHERE t1.typsubscript = 'array_subscript_handler'::regproc AND NOT + (t1.typelem != 0 AND t1.typlen = -1 AND NOT t1.typbyval); + +SELECT t1.oid, t1.typname, + t1.typelem, t1.typlen, t1.typbyval +FROM pg_type AS t1 +WHERE t1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT + (t1.typelem != 0 AND t1.typlen > 0 AND NOT t1.typbyval); + +SELECT t1.oid, t1.typname, p1.oid, p1.proname +FROM pg_type AS t1, pg_proc AS p1 +WHERE t1.typanalyze = p1.oid AND NOT + (p1.pronargs = 1 AND + p1.proargtypes[0] = 'internal'::regtype AND + p1.prorettype = 'bool'::regtype AND NOT p1.proretset); + +SELECT d.oid, d.typname, d.typanalyze, t.oid, t.typname, t.typanalyze +FROM pg_type d JOIN pg_type t ON d.typbasetype = t.oid +WHERE d.typanalyze != t.typanalyze; + +SELECT t.oid, t.typname, t.typanalyze +FROM pg_type t LEFT JOIN pg_range r on t.oid = r.rngtypid +WHERE t.typbasetype = 0 AND + (t.typanalyze = 'range_typanalyze'::regproc) != (r.rngtypid IS NOT NULL); + +SELECT t.oid, t.typname, t.typanalyze +FROM pg_type t +WHERE t.typbasetype = 0 AND + (t.typanalyze = 'array_typanalyze'::regproc) != + (t.typsubscript = 'array_subscript_handler'::regproc) +ORDER BY 1; + +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p', 'I') OR + relpersistence NOT IN ('p', 'u', 't') OR + relreplident NOT IN ('d', 'n', 'f', 'i'); + +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE c1.relkind NOT IN ('S', 'v', 'f', 'c', 'p') and + c1.relam = 0; + +SELECT c1.oid, c1.relname +FROM pg_class as c1 +WHERE c1.relkind IN ('S', 'v', 'f', 'c', 'p') and + c1.relam != 0; + +SELECT pc.oid, pc.relname, pa.amname, pa.amtype +FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) +WHERE pc.relkind IN ('i', 'I') and + pa.amtype != 'i'; + +SELECT pc.oid, pc.relname, pa.amname, pa.amtype +FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) +WHERE pc.relkind IN ('r', 't', 'm') and + pa.amtype != 't'; + +SELECT a1.attrelid, a1.attname +FROM pg_attribute as a1 +WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR + a1.attinhcount < 0 OR (a1.attinhcount = 0 AND NOT a1.attislocal); + +SELECT a1.attrelid, a1.attname, c1.oid, c1.relname +FROM pg_attribute AS a1, pg_class AS c1 +WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts; + +SELECT c1.oid, c1.relname +FROM pg_class AS c1 +WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1 + WHERE a1.attrelid = c1.oid AND a1.attnum > 0); + +SELECT a1.attrelid, a1.attname, t1.oid, t1.typname +FROM pg_attribute AS a1, pg_type AS t1 +WHERE a1.atttypid = t1.oid AND + (a1.attlen != t1.typlen OR + a1.attalign != t1.typalign OR + a1.attbyval != t1.typbyval OR + (a1.attstorage != t1.typstorage AND a1.attstorage != 'p')); + +CREATE FUNCTION is_catalog_text_unique_index_oid(oid) RETURNS bool + AS 'regresslib', 'is_catalog_text_unique_index_oid' + LANGUAGE C STRICT; + +SELECT indexrelid::regclass +FROM pg_index +WHERE (is_catalog_text_unique_index_oid(indexrelid) <> + (indisunique AND + indexrelid < 16384 AND + EXISTS (SELECT 1 FROM pg_attribute + WHERE attrelid = indexrelid AND atttypid = 'text'::regtype))); + +SELECT r.rngtypid, r.rngsubtype +FROM pg_range as r +WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0; + +SELECT r.rngtypid, r.rngsubtype, r.rngcollation, t.typcollation +FROM pg_range r JOIN pg_type t ON t.oid = r.rngsubtype +WHERE (rngcollation = 0) != (typcollation = 0); + +SELECT r.rngtypid, r.rngsubtype, o.opcmethod, o.opcname +FROM pg_range r JOIN pg_opclass o ON o.oid = r.rngsubopc +WHERE o.opcmethod != 403 OR + ((o.opcintype != r.rngsubtype) AND NOT + (o.opcintype = 'pg_catalog.anyarray'::regtype AND + EXISTS(select 1 from pg_catalog.pg_type where + oid = r.rngsubtype and typelem != 0 and + typsubscript = 'array_subscript_handler'::regproc))); + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngcanonical +WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid; + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngsubdiff +WHERE pronargs != 2 + OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype + OR prorettype != 'pg_catalog.float8'::regtype; + +SELECT r.rngtypid, r.rngsubtype, r.rngmultitypid +FROM pg_range r +WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0; + +CREATE TABLE tab_core_types AS SELECT + '(11,12)'::point, + '(1,1),(2,2)'::line, + '((11,11),(12,12))'::lseg, + '((11,11),(13,13))'::box, + '((11,12),(13,13),(14,14))'::path AS openedpath, + '[(11,12),(13,13),(14,14)]'::path AS closedpath, + '((11,12),(13,13),(14,14))'::polygon, + '1,1,1'::circle, + 'today'::date, + 'now'::time, + 'now'::timestamp, + 'now'::timetz, + 'now'::timestamptz, + '12 seconds'::interval, + '{"reason":"because"}'::json, + '{"when":"now"}'::jsonb, + '$.a[*] ? (@ > 2)'::jsonpath, + '127.0.0.1'::inet, + '127.0.0.0/8'::cidr, + '00:01:03:86:1c:ba'::macaddr8, + '00:01:03:86:1c:ba'::macaddr, + 2::int2, 4::int4, 8::int8, + 4::float4, '8'::float8, pi()::numeric, + 'foo'::"char", + 'c'::bpchar, + 'abc'::varchar, + 'name'::name, + 'txt'::text, + true::bool, + E'\\xDEADBEEF'::bytea, + B'10001'::bit, + B'10001'::varbit AS varbit, + '12.34'::money, + 'abc'::refcursor, + '1 2'::int2vector, + '1 2'::oidvector, + format('%I=UC/%I', USER, USER)::aclitem AS aclitem, + 'a fat cat sat on a mat and ate a fat rat'::tsvector, + 'fat & rat'::tsquery, + 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid, + '11'::xid8, + 'pg_class'::regclass, + 'regtype'::regtype type, + 'pg_monitor'::regrole, + 'pg_class'::regclass::oid, + 'template1'::regdatabase, + '(1,1)'::tid, '2'::xid, '3'::cid, + '10:20:10,14,15'::txid_snapshot, + '10:20:10,14,15'::pg_snapshot, + '16/B374D848'::pg_lsn, + 1::information_schema.cardinal_number, + 'l'::information_schema.character_data, + 'n'::information_schema.sql_identifier, + 'now'::information_schema.time_stamp, + 'YES'::information_schema.yes_or_no, + '(1,2)'::int4range, '{(1,2)}'::int4multirange, + '(3,4)'::int8range, '{(3,4)}'::int8multirange, + '(3,4)'::numrange, '{(3,4)}'::nummultirange, + '(2020-01-02, 2021-02-03)'::daterange, + '{(2020-01-02, 2021-02-03)}'::datemultirange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tsrange, + '{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tsmultirange, + '(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tstzrange, + '{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tstzmultirange; + +SELECT oid, typname, typtype, typelem, typarray + FROM pg_type t + WHERE oid < 16384 AND + -- Exclude pseudotypes and composite types. + typtype NOT IN ('p', 'c') AND + -- These reg* types cannot be pg_upgraded, so discard them. + oid != ALL(ARRAY['regproc', 'regprocedure', 'regoper', + 'regoperator', 'regconfig', 'regdictionary', + 'regnamespace', 'regcollation']::regtype[]) AND + -- Discard types that do not accept input values as these cannot be + -- tested easily. + -- Note: XML might be disabled at compile-time. + oid != ALL(ARRAY['gtsvector', 'pg_node_tree', + 'pg_ndistinct', 'pg_dependencies', 'pg_mcv_list', + 'pg_brin_bloom_summary', + 'pg_brin_minmax_multi_summary', 'xml']::regtype[]) AND + -- Discard arrays. + NOT EXISTS (SELECT 1 FROM pg_type u WHERE u.typarray = t.oid) + -- Exclude everything from the table created above. This checks + -- that no in-core types are missing in tab_core_types. + AND NOT EXISTS (SELECT 1 + FROM pg_attribute a + WHERE a.atttypid=t.oid AND + a.attnum > 0 AND + a.attrelid='tab_core_types'::regclass); diff --git a/crates/pgt_pretty_print/tests/data/multi/typed_table_60.sql b/crates/pgt_pretty_print/tests/data/multi/typed_table_60.sql new file mode 100644 index 000000000..4e73be06d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/typed_table_60.sql @@ -0,0 +1,80 @@ +CREATE TABLE ttable1 OF nothing; + +CREATE TYPE person_type AS (id int, name text); + +CREATE TABLE persons OF person_type; + +CREATE TABLE IF NOT EXISTS persons OF person_type; + +SELECT * FROM persons; + +CREATE FUNCTION get_all_persons() RETURNS SETOF person_type +LANGUAGE SQL +AS $$ + SELECT * FROM persons; +$$; + +SELECT * FROM get_all_persons(); + +ALTER TABLE persons ADD COLUMN comment text; + +ALTER TABLE persons DROP COLUMN name; + +ALTER TABLE persons RENAME COLUMN id TO num; + +ALTER TABLE persons ALTER COLUMN name TYPE varchar; + +CREATE TABLE stuff (id int); + +ALTER TABLE persons INHERIT stuff; + +CREATE TABLE personsx OF person_type (myname WITH OPTIONS NOT NULL); + +CREATE TABLE persons2 OF person_type ( + id WITH OPTIONS PRIMARY KEY, + UNIQUE (name) +); + +CREATE TABLE persons3 OF person_type ( + PRIMARY KEY (id), + name WITH OPTIONS DEFAULT '' +); + +CREATE TABLE persons4 OF person_type ( + name WITH OPTIONS NOT NULL, + name WITH OPTIONS DEFAULT '' -- error, specified more than once +); + +DROP TYPE person_type RESTRICT; + +DROP TYPE person_type CASCADE; + +CREATE TABLE persons5 OF stuff; + +CREATE TYPE tt_enum_type AS ENUM ('a'); + +CREATE TABLE of_tt_enum_type OF tt_enum_type; + +DROP TYPE tt_enum_type; + +DROP TABLE stuff; + +CREATE TYPE person_type AS (id int, name text); + +CREATE TABLE persons OF person_type; + +INSERT INTO persons VALUES (1, 'test'); + +CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE SQL AS $$ SELECT length($1.name) $$; + +SELECT id, namelen(persons) FROM persons; + +CREATE TABLE persons2 OF person_type ( + id WITH OPTIONS PRIMARY KEY, + UNIQUE (name) +); + +CREATE TABLE persons3 OF person_type ( + PRIMARY KEY (id), + name NOT NULL DEFAULT '' +); diff --git a/crates/pgt_pretty_print/tests/data/multi/unicode_60.sql b/crates/pgt_pretty_print/tests/data/multi/unicode_60.sql new file mode 100644 index 000000000..2f0ef1299 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/unicode_60.sql @@ -0,0 +1,44 @@ +SELECT getdatabaseencoding() <> 'UTF8' AS skip_test ; + +SELECT U&'\0061\0308bc' <> U&'\00E4bc' COLLATE "C" AS sanity_check; + +SELECT unicode_version() IS NOT NULL; + +SELECT unicode_assigned(U&'abc'); + +SELECT unicode_assigned(U&'abc\+10FFFF'); + +SELECT normalize(''); + +SELECT normalize(U&'\0061\0308\24D1c') = U&'\00E4\24D1c' COLLATE "C" AS test_default; + +SELECT normalize(U&'\0061\0308\24D1c', NFC) = U&'\00E4\24D1c' COLLATE "C" AS test_nfc; + +SELECT normalize(U&'\00E4bc', NFC) = U&'\00E4bc' COLLATE "C" AS test_nfc_idem; + +SELECT normalize(U&'\00E4\24D1c', NFD) = U&'\0061\0308\24D1c' COLLATE "C" AS test_nfd; + +SELECT normalize(U&'\0061\0308\24D1c', NFKC) = U&'\00E4bc' COLLATE "C" AS test_nfkc; + +SELECT normalize(U&'\00E4\24D1c', NFKD) = U&'\0061\0308bc' COLLATE "C" AS test_nfkd; + +SELECT "normalize"('abc', 'def'); + +SELECT U&'\00E4\24D1c' IS NORMALIZED AS test_default; + +SELECT U&'\00E4\24D1c' IS NFC NORMALIZED AS test_nfc; + +SELECT num, val, + val IS NFC NORMALIZED AS NFC, + val IS NFD NORMALIZED AS NFD, + val IS NFKC NORMALIZED AS NFKC, + val IS NFKD NORMALIZED AS NFKD +FROM + (VALUES (1, U&'\00E4bc'), + (2, U&'\0061\0308bc'), + (3, U&'\00E4\24D1c'), + (4, U&'\0061\0308\24D1c'), + (5, '')) vals (num, val) +ORDER BY num; + +SELECT is_normalized('abc', 'def'); diff --git a/crates/pgt_pretty_print/tests/data/multi/union_60.sql b/crates/pgt_pretty_print/tests/data/multi/union_60.sql new file mode 100644 index 000000000..40bb73497 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/union_60.sql @@ -0,0 +1,311 @@ +SELECT 1 AS two UNION SELECT 2 ORDER BY 1; + +SELECT 1 AS one UNION SELECT 1 ORDER BY 1; + +SELECT 1 AS two UNION ALL SELECT 2; + +SELECT 1 AS two UNION ALL SELECT 1; + +SELECT 1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1; + +SELECT 1 AS two UNION SELECT 2 UNION SELECT 2 ORDER BY 1; + +SELECT 1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1; + +SELECT 1.1 AS two UNION SELECT 2.2 ORDER BY 1; + +SELECT 1.1 AS two UNION SELECT 2 ORDER BY 1; + +SELECT 1 AS two UNION SELECT 2.2 ORDER BY 1; + +SELECT 1 AS one UNION SELECT 1.0::float8 ORDER BY 1; + +SELECT 1.1 AS two UNION ALL SELECT 2 ORDER BY 1; + +SELECT 1.0::float8 AS two UNION ALL SELECT 1 ORDER BY 1; + +SELECT 1.1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1; + +SELECT 1.1::float8 AS two UNION SELECT 2 UNION SELECT 2.0::float8 ORDER BY 1; + +SELECT 1.1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1; + +SELECT 1.1 AS two UNION (SELECT 2 UNION ALL SELECT 2) ORDER BY 1; + +SELECT f1 AS five FROM FLOAT8_TBL +UNION +SELECT f1 FROM FLOAT8_TBL +ORDER BY 1; + +SELECT f1 AS ten FROM FLOAT8_TBL +UNION ALL +SELECT f1 FROM FLOAT8_TBL; + +SELECT f1 AS nine FROM FLOAT8_TBL +UNION +SELECT f1 FROM INT4_TBL +ORDER BY 1; + +SELECT f1 AS ten FROM FLOAT8_TBL +UNION ALL +SELECT f1 FROM INT4_TBL; + +SELECT f1 AS five FROM FLOAT8_TBL + WHERE f1 BETWEEN -1e6 AND 1e6 +UNION +SELECT f1 FROM INT4_TBL + WHERE f1 BETWEEN 0 AND 1000000 +ORDER BY 1; + +SELECT CAST(f1 AS char(4)) AS three FROM VARCHAR_TBL +UNION +SELECT f1 FROM CHAR_TBL +ORDER BY 1; + +SELECT f1 AS three FROM VARCHAR_TBL +UNION +SELECT CAST(f1 AS varchar) FROM CHAR_TBL +ORDER BY 1; + +SELECT f1 AS eight FROM VARCHAR_TBL +UNION ALL +SELECT f1 FROM CHAR_TBL; + +SELECT f1 AS five FROM TEXT_TBL +UNION +SELECT f1 FROM VARCHAR_TBL +UNION +SELECT TRIM(TRAILING FROM f1) FROM CHAR_TBL +ORDER BY 1; + +SELECT q1 FROM int8_tbl ORDER BY 1; + +SELECT q2 FROM int8_tbl INTERSECT ALL SELECT q1 FROM int8_tbl ORDER BY 1; + +SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1; + +SELECT q2 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl ORDER BY 1; + +SELECT q2 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q1 FROM int8_tbl ORDER BY 1; + +SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY 1; + +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q2 FROM int8_tbl ORDER BY 1; + +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q2 FROM int8_tbl ORDER BY 1; + +SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl FOR NO KEY UPDATE; + +SELECT 4,5,6; + +SELECT 4,5,6; + +(SELECT 1,2,3 UNION SELECT 4,5,6) EXCEPT SELECT 4,5,6; + +(SELECT 1,2,3 UNION SELECT 4,5,6 ORDER BY 1,2) EXCEPT SELECT 4,5,6; + +set enable_hashagg to on; + +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss; + +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss; + +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss; + +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss; + +set enable_indexscan to off; + +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10; + +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10; + +reset enable_indexscan; + +select q2, q1 from int8_tbl order by 1, 2; + +select q2, q1 from int8_tbl order by 1, 2; + +select * from int8_tbl order by 1, 2; + +set enable_hashagg to off; + +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss; + +select count(*) from + ( select unique1 from tenk1 union select fivethous from tenk1 ) ss; + +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss; + +select count(*) from + ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss; + +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10; + +select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10; + +select f1 from int4_tbl union all + (select unique1 from tenk1 union select unique2 from tenk1); + +reset enable_hashagg; + +set enable_hashagg to on; + +select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x); + +set enable_hashagg to off; + +select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x); + +reset enable_hashagg; + +set enable_hashagg to on; + +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x); + +select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x); + +set enable_hashagg to off; + +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); + +select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); + +reset enable_hashagg; + +set enable_hashagg to on; + +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x); + +select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x); + +create type ct1 as (f1 varbit); + +select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x); + +select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x); + +drop type ct1; + +set enable_hashagg to off; + +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); + +select '123'::xid union select '123'::xid; + +reset enable_hashagg; + +SELECT f1 FROM int4_tbl ORDER BY 1; + +SELECT f1 FROM float8_tbl EXCEPT SELECT f1 FROM int4_tbl ORDER BY 1; + +SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl ORDER BY 1; + +SELECT q1 FROM int8_tbl INTERSECT (((SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) ORDER BY 1; + +(((SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl ORDER BY 1))) UNION ALL SELECT q2 FROM int8_tbl; + +SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1; + +SELECT q1 FROM int8_tbl UNION ALL (((SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1))); + +(((SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1; + +SELECT q1,q2 FROM int8_tbl EXCEPT SELECT q2,q1 FROM int8_tbl +ORDER BY q2,q1; + +SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1; + +SELECT q1 FROM int8_tbl EXCEPT (((SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1))) ORDER BY 1; + +(((((select * from int8_tbl))))); + +select union select; + +select; + +select except select; + +set enable_hashagg = true; + +set enable_sort = false; + +select from generate_series(1,3); + +select from generate_series(1,5) union all select from generate_series(1,3); + +select from generate_series(1,3); + +select from generate_series(1,5) intersect all select from generate_series(1,3); + +select from generate_series(1,5) except select from generate_series(1,3); + +select from generate_series(1,5) except all select from generate_series(1,3); + +set enable_hashagg = false; + +set enable_sort = true; + +select from generate_series(1,5) union select from generate_series(1,3); + +select from generate_series(1,3); + +select from generate_series(1,5) union select from generate_series(1,3); + +select from generate_series(1,5) union all select from generate_series(1,3); + +select from generate_series(1,3); + +select from generate_series(1,5) intersect all select from generate_series(1,3); + +select from generate_series(1,5) except select from generate_series(1,3); + +select from generate_series(1,5) except all select from generate_series(1,3); diff --git a/crates/pgt_pretty_print/tests/data/multi/updatable_views_60.sql b/crates/pgt_pretty_print/tests/data/multi/updatable_views_60.sql new file mode 100644 index 000000000..c38f7c759 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/updatable_views_60.sql @@ -0,0 +1,2334 @@ +SET extra_float_digits = 0; + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); + +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i); + +CREATE VIEW ro_view1 AS SELECT DISTINCT a, b FROM base_tbl; + +CREATE VIEW ro_view2 AS SELECT a, b FROM base_tbl GROUP BY a, b; + +CREATE VIEW ro_view3 AS SELECT 1 FROM base_tbl HAVING max(a) > 0; + +CREATE VIEW ro_view4 AS SELECT count(*) FROM base_tbl; + +CREATE VIEW ro_view5 AS SELECT a, rank() OVER() FROM base_tbl; + +CREATE VIEW ro_view6 AS SELECT a, b FROM base_tbl UNION SELECT -a, b FROM base_tbl; + +SELECT * FROM t; + +CREATE VIEW ro_view8 AS SELECT a, b FROM base_tbl ORDER BY a OFFSET 1; + +CREATE VIEW ro_view9 AS SELECT a, b FROM base_tbl ORDER BY a LIMIT 1; + +CREATE VIEW ro_view10 AS SELECT 1 AS a; + +CREATE VIEW ro_view11 AS SELECT b1.a, b2.b FROM base_tbl b1, base_tbl b2; + +CREATE VIEW ro_view12 AS SELECT * FROM generate_series(1, 10) AS g(a); + +CREATE VIEW ro_view13 AS SELECT a, b FROM (SELECT * FROM base_tbl) AS t; + +CREATE VIEW rw_view14 AS SELECT ctid, a, b FROM base_tbl; + +CREATE VIEW rw_view15 AS SELECT a, upper(b) FROM base_tbl; + +CREATE VIEW rw_view16 AS SELECT a, b, a AS aa FROM base_tbl; + +CREATE VIEW ro_view17 AS SELECT * FROM ro_view1; + +CREATE VIEW ro_view18 AS SELECT * FROM (VALUES(1)) AS tmp(a); + +CREATE SEQUENCE uv_seq; + +CREATE VIEW ro_view19 AS SELECT * FROM uv_seq; + +CREATE VIEW ro_view20 AS SELECT a, b, generate_series(1, a) g FROM base_tbl; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name, ordinal_position; + +DELETE FROM ro_view1; + +DELETE FROM ro_view2; + +DELETE FROM ro_view3; + +DELETE FROM ro_view4; + +DELETE FROM ro_view5; + +DELETE FROM ro_view6; + +UPDATE ro_view7 SET a=a+1; + +UPDATE ro_view8 SET a=a+1; + +UPDATE ro_view9 SET a=a+1; + +UPDATE ro_view10 SET a=a+1; + +UPDATE ro_view11 SET a=a+1; + +UPDATE ro_view12 SET a=a+1; + +INSERT INTO ro_view13 VALUES (3, 'Row 3'); + +MERGE INTO ro_view13 AS t USING (VALUES (2, 'Row 2')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN DO NOTHING; + +MERGE INTO ro_view13 AS t USING (VALUES (3, 'Row 3')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING + WHEN NOT MATCHED THEN DO NOTHING; + +INSERT INTO rw_view14 VALUES (null, 3, 'Row 3'); + +INSERT INTO rw_view14 (a, b) VALUES (3, 'Row 3'); + +UPDATE rw_view14 SET ctid=null WHERE a=3; + +UPDATE rw_view14 SET b='ROW 3' WHERE a=3; + +SELECT * FROM base_tbl; + +DELETE FROM rw_view14 WHERE a=3; + +SELECT * FROM base_tbl ORDER BY a; + +SELECT * FROM base_tbl ORDER BY a; + +INSERT INTO rw_view15 VALUES (3, 'ROW 3'); + +INSERT INTO rw_view15 (a) VALUES (3); + +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT DO NOTHING; + +SELECT * FROM rw_view15; + +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO NOTHING; + +SELECT * FROM rw_view15; + +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE set a = excluded.a; + +SELECT * FROM rw_view15; + +INSERT INTO rw_view15 (a) VALUES (3) ON CONFLICT (a) DO UPDATE set upper = 'blarg'; + +SELECT * FROM rw_view15; + +SELECT * FROM rw_view15; + +ALTER VIEW rw_view15 ALTER COLUMN upper SET DEFAULT 'NOT SET'; + +INSERT INTO rw_view15 (a) VALUES (4); + +UPDATE rw_view15 SET upper='ROW 3' WHERE a=3; + +UPDATE rw_view15 SET upper=DEFAULT WHERE a=3; + +UPDATE rw_view15 SET a=4 WHERE a=3; + +SELECT * FROM base_tbl; + +DELETE FROM rw_view15 WHERE a=4; + +INSERT INTO rw_view16 VALUES (3, 'Row 3', 3); + +INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3'); + +UPDATE rw_view16 SET a=3, aa=-3 WHERE a=3; + +UPDATE rw_view16 SET aa=-3 WHERE a=3; + +SELECT * FROM base_tbl; + +DELETE FROM rw_view16 WHERE a=-3; + +INSERT INTO ro_view17 VALUES (3, 'ROW 3'); + +DELETE FROM ro_view18; + +MERGE INTO ro_view18 AS t USING (VALUES (1, 'Row 1')) AS v(a,b) ON t.a = v.a + WHEN MATCHED THEN DO NOTHING; + +UPDATE ro_view19 SET last_value=1000; + +UPDATE ro_view20 SET b=upper(b); + +CREATE RULE rw_view16_ins_rule AS ON INSERT TO rw_view16 + WHERE NEW.a > 0 DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, NEW.b); + +CREATE RULE rw_view16_upd_rule AS ON UPDATE TO rw_view16 + WHERE OLD.a > 0 DO INSTEAD UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a; + +CREATE RULE rw_view16_del_rule AS ON DELETE TO rw_view16 + WHERE OLD.a > 0 DO INSTEAD DELETE FROM base_tbl WHERE a=OLD.a; + +INSERT INTO rw_view16 (a, b) VALUES (3, 'Row 3'); + +UPDATE rw_view16 SET b='ROW 2' WHERE a=2; + +DELETE FROM rw_view16 WHERE a=2; + +DROP TABLE base_tbl CASCADE; + +DROP VIEW ro_view10, ro_view12, ro_view18; + +DROP SEQUENCE uv_seq CASCADE; + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); + +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i); + +CREATE VIEW rw_view1 AS + SELECT *, 'Const' AS c, (SELECT concat('b: ', b)) AS d FROM base_tbl WHERE a>0; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view1'; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1'; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view1' + ORDER BY ordinal_position; + +INSERT INTO rw_view1 VALUES (3, 'Row 3'); + +INSERT INTO rw_view1 (a) VALUES (4); + +UPDATE rw_view1 SET a=5 WHERE a=4; + +DELETE FROM rw_view1 WHERE b='Row 2'; + +SELECT * FROM base_tbl; + +SET jit_above_cost = 0; + +SET jit_above_cost TO DEFAULT; + +SELECT * FROM base_tbl ORDER BY a; + +SELECT * FROM base_tbl ORDER BY a; + +UPDATE rw_view1 SET a=6 WHERE a=5; + +DELETE FROM rw_view1 WHERE a=5; + +CREATE TABLE base_tbl_hist(ts timestamptz default now(), a int, b text); + +CREATE RULE base_tbl_log AS ON INSERT TO rw_view1 DO ALSO + INSERT INTO base_tbl_hist(a,b) VALUES(new.a, new.b); + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1'; + +INSERT INTO rw_view1 VALUES (9, DEFAULT), (10, DEFAULT); + +SELECT a, b FROM base_tbl_hist; + +DROP TABLE base_tbl CASCADE; + +DROP TABLE base_tbl_hist; + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); + +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i); + +CREATE VIEW rw_view1 AS + SELECT b AS bb, a AS aa, 'Const1' AS c FROM base_tbl WHERE a>0; + +CREATE VIEW rw_view2 AS + SELECT aa AS aaa, bb AS bbb, c AS c1, 'Const2' AS c2 FROM rw_view1 WHERE aa<10; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view2'; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view2'; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view2' + ORDER BY ordinal_position; + +INSERT INTO rw_view2 VALUES (3, 'Row 3'); + +INSERT INTO rw_view2 (aaa) VALUES (4); + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET bbb='Row 4' WHERE aaa=4; + +DELETE FROM rw_view2 WHERE aaa=2; + +SELECT * FROM rw_view2; + +SELECT * FROM rw_view2 ORDER BY aaa; + +SELECT * FROM rw_view2 ORDER BY aaa; + +UPDATE rw_view2 SET aaa=5 WHERE aaa=4; + +DELETE FROM rw_view2 WHERE aaa=4; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); + +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a>0 OFFSET 0; + +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a<10; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, NEW.b) RETURNING *; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 + DO INSTEAD UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a RETURNING NEW.*; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +CREATE RULE rw_view1_del_rule AS ON DELETE TO rw_view1 + DO INSTEAD DELETE FROM base_tbl WHERE a=OLD.a RETURNING OLD.*; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING old.*, new.*; + +UPDATE rw_view2 SET b='R3' WHERE a=3 RETURNING old.*, new.*; + +DROP RULE rw_view1_upd_rule ON rw_view1; + +CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 + DO INSTEAD UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a RETURNING *; + +UPDATE rw_view2 SET b='Row three' WHERE a=3 RETURNING old.*, new.*; + +SELECT * FROM rw_view2; + +DELETE FROM rw_view2 WHERE a=3 RETURNING old.*, new.*; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET a=3 WHERE a=2; + +DELETE FROM rw_view2 WHERE a=2; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); + +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i); + +CREATE VIEW rw_view1 AS + SELECT *, 'Const1' AS c1 FROM base_tbl WHERE a>0 OFFSET 0; + +CREATE VIEW rw_view2 AS + SELECT *, 'Const2' AS c2 FROM rw_view1 WHERE a<10; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + INSERT INTO base_tbl VALUES (NEW.a, NEW.b); + NEW.c1 = 'Trigger Const1'; + RETURN NEW; + ELSIF TG_OP = 'UPDATE' THEN + UPDATE base_tbl SET b=NEW.b WHERE a=OLD.a; + NEW.c1 = 'Trigger Const1'; + RETURN NEW; + ELSIF TG_OP = 'DELETE' THEN + DELETE FROM base_tbl WHERE a=OLD.a; + RETURN OLD; + END IF; +END; +$$ +LANGUAGE plpgsql; + +CREATE TRIGGER rw_view1_ins_trig INSTEAD OF INSERT ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn(); + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +CREATE TRIGGER rw_view1_upd_trig INSTEAD OF UPDATE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn(); + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +CREATE TRIGGER rw_view1_del_trig INSTEAD OF DELETE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn(); + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into, + is_trigger_updatable, is_trigger_deletable, + is_trigger_insertable_into + FROM information_schema.views + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE 'rw_view%' + ORDER BY table_name, ordinal_position; + +INSERT INTO rw_view2 VALUES (3, 'Row 3') RETURNING old.*, new.*; + +UPDATE rw_view2 SET b='Row three' WHERE a=3 RETURNING old.*, new.*; + +SELECT * FROM rw_view2; + +DELETE FROM rw_view2 WHERE a=3 RETURNING old.*, new.*; + +SELECT * FROM rw_view2; + +SELECT * FROM base_tbl ORDER BY a; + +SELECT * FROM base_tbl ORDER BY a; + +UPDATE rw_view2 SET a=3 WHERE a=2; + +DELETE FROM rw_view2 WHERE a=2; + +DROP TRIGGER rw_view1_del_trig ON rw_view1; + +DROP TRIGGER rw_view1_ins_trig ON rw_view1; + +CREATE TRIGGER rw_view2_upd_trig INSTEAD OF UPDATE ON rw_view2 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn(); + +SELECT * FROM base_tbl ORDER BY a; + +DROP TABLE base_tbl CASCADE; + +DROP FUNCTION rw_view1_trig_fn(); + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); + +INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i); + +CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl; + +CREATE FUNCTION rw_view1_aa(x rw_view1) + RETURNS int AS $$ SELECT x.aa $$ LANGUAGE sql; + +UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2 + RETURNING rw_view1_aa(v), v.bb; + +SELECT * FROM base_tbl; + +UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2 + RETURNING rw_view1_aa(v), v.bb; + +DROP TABLE base_tbl CASCADE; + +CREATE USER regress_view_user1; + +CREATE USER regress_view_user2; + +CREATE USER regress_view_user3; + +SET SESSION AUTHORIZATION regress_view_user1; + +CREATE TABLE base_tbl(a int, b text, c float); + +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0); + +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl; + +INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2); + +GRANT SELECT ON base_tbl TO regress_view_user2; + +GRANT SELECT ON rw_view1 TO regress_view_user2; + +GRANT UPDATE (a,c) ON base_tbl TO regress_view_user2; + +GRANT UPDATE (bb,cc) ON rw_view1 TO regress_view_user2; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_view_user2; + +CREATE VIEW rw_view2 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl; + +SELECT * FROM base_tbl; + +SELECT * FROM rw_view1; + +SELECT * FROM rw_view2; + +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0); + +INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3); + +INSERT INTO rw_view2 VALUES ('Row 3', 3.0, 3); + +UPDATE base_tbl SET a=a, c=c; + +UPDATE base_tbl SET b=b; + +UPDATE rw_view1 SET bb=bb, cc=cc; + +UPDATE rw_view1 SET aa=aa; + +UPDATE rw_view2 SET aa=aa, cc=cc; + +UPDATE rw_view2 SET bb=bb; + +DELETE FROM base_tbl; + +DELETE FROM rw_view1; + +DELETE FROM rw_view2; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_view_user1; + +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_view_user2; + +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0); + +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4); + +INSERT INTO rw_view2 VALUES ('Row 4', 4.0, 4); + +DELETE FROM base_tbl WHERE a=1; + +DELETE FROM rw_view1 WHERE aa=2; + +DELETE FROM rw_view2 WHERE aa=2; + +SELECT * FROM base_tbl; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_view_user1; + +REVOKE INSERT, DELETE ON base_tbl FROM regress_view_user2; + +GRANT INSERT, DELETE ON rw_view1 TO regress_view_user2; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_view_user2; + +INSERT INTO base_tbl VALUES (5, 'Row 5', 5.0); + +INSERT INTO rw_view1 VALUES ('Row 5', 5.0, 5); + +INSERT INTO rw_view2 VALUES ('Row 6', 6.0, 6); + +DELETE FROM base_tbl WHERE a=3; + +DELETE FROM rw_view1 WHERE aa=3; + +DELETE FROM rw_view2 WHERE aa=4; + +SELECT * FROM base_tbl; + +RESET SESSION AUTHORIZATION; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl(a int, b text, c float); + +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0); + +SET SESSION AUTHORIZATION regress_view_user1; + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl; + +SELECT * FROM rw_view1; + +SELECT * FROM rw_view1 FOR UPDATE; + +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; + +SET SESSION AUTHORIZATION regress_view_user2; + +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1; + +SELECT * FROM rw_view2; + +SELECT * FROM rw_view2 FOR UPDATE; + +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; + +RESET SESSION AUTHORIZATION; + +GRANT SELECT ON base_tbl TO regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; + +SELECT * FROM rw_view1; + +SELECT * FROM rw_view1 FOR UPDATE; + +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +SELECT * FROM rw_view2 FOR UPDATE; + +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; + +SET SESSION AUTHORIZATION regress_view_user1; + +GRANT SELECT ON rw_view1 TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +SELECT * FROM rw_view2 FOR UPDATE; + +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; + +RESET SESSION AUTHORIZATION; + +GRANT UPDATE ON base_tbl TO regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; + +SELECT * FROM rw_view1; + +SELECT * FROM rw_view1 FOR UPDATE; + +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +SELECT * FROM rw_view2 FOR UPDATE; + +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; + +SET SESSION AUTHORIZATION regress_view_user1; + +GRANT UPDATE ON rw_view1 TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +SELECT * FROM rw_view2 FOR UPDATE; + +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; + +RESET SESSION AUTHORIZATION; + +REVOKE UPDATE ON base_tbl FROM regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; + +SELECT * FROM rw_view1; + +SELECT * FROM rw_view1 FOR UPDATE; + +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +SELECT * FROM rw_view2 FOR UPDATE; + +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; + +RESET SESSION AUTHORIZATION; + +DROP TABLE base_tbl CASCADE; + +SET SESSION AUTHORIZATION regress_view_user1; + +CREATE TABLE base_tbl(a int, b text, c float); + +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0); + +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl; + +ALTER VIEW rw_view1 SET (security_invoker = true); + +INSERT INTO rw_view1 VALUES ('Row 2', 2.0, 2); + +GRANT SELECT ON rw_view1 TO regress_view_user2; + +GRANT UPDATE (bb,cc) ON rw_view1 TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM base_tbl; + +SELECT * FROM rw_view1; + +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0); + +INSERT INTO rw_view1 VALUES ('Row 3', 3.0, 3); + +UPDATE base_tbl SET a=a; + +UPDATE rw_view1 SET bb=bb, cc=cc; + +DELETE FROM base_tbl; + +DELETE FROM rw_view1; + +SET SESSION AUTHORIZATION regress_view_user1; + +GRANT SELECT ON base_tbl TO regress_view_user2; + +GRANT UPDATE (a,c) ON base_tbl TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM base_tbl; + +SELECT * FROM rw_view1; + +UPDATE base_tbl SET a=a, c=c; + +UPDATE base_tbl SET b=b; + +UPDATE rw_view1 SET cc=cc; + +UPDATE rw_view1 SET aa=aa; + +UPDATE rw_view1 SET bb=bb; + +SET SESSION AUTHORIZATION regress_view_user1; + +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +INSERT INTO base_tbl VALUES (3, 'Row 3', 3.0); + +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4); + +DELETE FROM base_tbl WHERE a=1; + +DELETE FROM rw_view1 WHERE aa=2; + +SET SESSION AUTHORIZATION regress_view_user1; + +REVOKE INSERT, DELETE ON base_tbl FROM regress_view_user2; + +GRANT INSERT, DELETE ON rw_view1 TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4); + +DELETE FROM rw_view1 WHERE aa=2; + +SET SESSION AUTHORIZATION regress_view_user1; + +GRANT INSERT, DELETE ON base_tbl TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +INSERT INTO rw_view1 VALUES ('Row 4', 4.0, 4); + +DELETE FROM rw_view1 WHERE aa=2; + +SELECT * FROM base_tbl; + +RESET SESSION AUTHORIZATION; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl(a int, b text, c float); + +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0); + +SET SESSION AUTHORIZATION regress_view_user1; + +CREATE VIEW rw_view1 AS SELECT b AS bb, c AS cc, a AS aa FROM base_tbl; + +ALTER VIEW rw_view1 SET (security_invoker = true); + +SELECT * FROM rw_view1; + +UPDATE rw_view1 SET aa=aa; + +SET SESSION AUTHORIZATION regress_view_user2; + +CREATE VIEW rw_view2 AS SELECT cc AS ccc, aa AS aaa, bb AS bbb FROM rw_view1; + +GRANT SELECT, UPDATE ON rw_view2 TO regress_view_user3; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +RESET SESSION AUTHORIZATION; + +GRANT SELECT ON base_tbl TO regress_view_user1; + +GRANT UPDATE (a, b) ON base_tbl TO regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; + +SELECT * FROM rw_view1; + +UPDATE rw_view1 SET aa=aa, bb=bb; + +UPDATE rw_view1 SET cc=cc; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +SET SESSION AUTHORIZATION regress_view_user3; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +SET SESSION AUTHORIZATION regress_view_user1; + +GRANT SELECT ON rw_view1 TO regress_view_user2; + +GRANT UPDATE (bb, cc) ON rw_view1 TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET bbb=bbb; + +SET SESSION AUTHORIZATION regress_view_user3; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET bbb=bbb; + +RESET SESSION AUTHORIZATION; + +GRANT SELECT ON base_tbl TO regress_view_user2; + +GRANT UPDATE (a, c) ON base_tbl TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +UPDATE rw_view2 SET bbb=bbb; + +UPDATE rw_view2 SET ccc=ccc; + +SET SESSION AUTHORIZATION regress_view_user3; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +UPDATE rw_view2 SET bbb=bbb; + +UPDATE rw_view2 SET ccc=ccc; + +RESET SESSION AUTHORIZATION; + +GRANT SELECT ON base_tbl TO regress_view_user3; + +GRANT UPDATE (a, c) ON base_tbl TO regress_view_user3; + +SET SESSION AUTHORIZATION regress_view_user3; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +UPDATE rw_view2 SET bbb=bbb; + +UPDATE rw_view2 SET ccc=ccc; + +RESET SESSION AUTHORIZATION; + +REVOKE SELECT, UPDATE ON base_tbl FROM regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; + +SELECT * FROM rw_view1; + +UPDATE rw_view1 SET aa=aa; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +UPDATE rw_view2 SET bbb=bbb; + +UPDATE rw_view2 SET ccc=ccc; + +SET SESSION AUTHORIZATION regress_view_user3; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +UPDATE rw_view2 SET bbb=bbb; + +UPDATE rw_view2 SET ccc=ccc; + +RESET SESSION AUTHORIZATION; + +REVOKE SELECT, UPDATE ON base_tbl FROM regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +UPDATE rw_view2 SET bbb=bbb; + +UPDATE rw_view2 SET ccc=ccc; + +SET SESSION AUTHORIZATION regress_view_user3; + +SELECT * FROM rw_view2; + +UPDATE rw_view2 SET aaa=aaa; + +UPDATE rw_view2 SET bbb=bbb; + +UPDATE rw_view2 SET ccc=ccc; + +RESET SESSION AUTHORIZATION; + +DROP TABLE base_tbl CASCADE; + +DROP USER regress_view_user1; + +DROP USER regress_view_user2; + +DROP USER regress_view_user3; + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified', c serial); + +INSERT INTO base_tbl VALUES (1, 'Row 1'); + +INSERT INTO base_tbl VALUES (2, 'Row 2'); + +INSERT INTO base_tbl VALUES (3); + +CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl; + +ALTER VIEW rw_view1 ALTER COLUMN bb SET DEFAULT 'View default'; + +INSERT INTO rw_view1 VALUES (4, 'Row 4'); + +INSERT INTO rw_view1 (aa) VALUES (5); + +SELECT * FROM base_tbl; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); + +INSERT INTO base_tbl VALUES (1, 'Row 1'); + +INSERT INTO base_tbl VALUES (2, 'Row 2'); + +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + UPDATE base_tbl SET b=NEW.b WHERE a=1; + RETURN NULL; + END IF; + RETURN NULL; +END; +$$ +LANGUAGE plpgsql; + +CREATE TRIGGER rw_view1_ins_trig AFTER INSERT ON base_tbl + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn(); + +CREATE VIEW rw_view1 AS SELECT a AS aa, b AS bb FROM base_tbl; + +INSERT INTO rw_view1 VALUES (3, 'Row 3'); + +select * from base_tbl; + +DROP VIEW rw_view1; + +DROP TRIGGER rw_view1_ins_trig on base_tbl; + +DROP FUNCTION rw_view1_trig_fn(); + +DROP TABLE base_tbl; + +CREATE TABLE base_tbl (a int, b int); + +INSERT INTO base_tbl VALUES (1,2), (4,5), (3,-3); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl ORDER BY a+b; + +SELECT * FROM rw_view1; + +INSERT INTO rw_view1 VALUES (7,-8); + +SELECT * FROM rw_view1; + +UPDATE rw_view1 SET b = b + 1 RETURNING *; + +UPDATE rw_view1 SET b = b + 1 RETURNING *; + +SELECT * FROM rw_view1; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int, arr int[]); + +INSERT INTO base_tbl VALUES (1,ARRAY[2]), (3,ARRAY[4]); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl; + +UPDATE rw_view1 SET arr[1] = 42, arr[2] = 77 WHERE a = 3; + +SELECT * FROM rw_view1; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl(a float); + +INSERT INTO base_tbl SELECT i/10.0 FROM generate_series(1,10) g(i); + +CREATE VIEW rw_view1 AS + SELECT ctid, sin(a) s, a, cos(a) c + FROM base_tbl + WHERE a != 0 + ORDER BY abs(a); + +INSERT INTO rw_view1 VALUES (null, null, 1.1, null); + +INSERT INTO rw_view1 (s, c, a) VALUES (null, null, 1.1); + +INSERT INTO rw_view1 (s, c, a) VALUES (default, default, 1.1); + +INSERT INTO rw_view1 (a) VALUES (1.1) RETURNING a, s, c; + +UPDATE rw_view1 SET s = s WHERE a = 1.1; + +UPDATE rw_view1 SET a = 1.05 WHERE a = 1.1 RETURNING s; + +DELETE FROM rw_view1 WHERE a = 1.05; + +CREATE VIEW rw_view2 AS + SELECT s, c, s/c t, a base_a, ctid + FROM rw_view1; + +INSERT INTO rw_view2 VALUES (null, null, null, 1.1, null); + +INSERT INTO rw_view2(s, c, base_a) VALUES (null, null, 1.1); + +INSERT INTO rw_view2(base_a) VALUES (1.1) RETURNING t; + +UPDATE rw_view2 SET s = s WHERE base_a = 1.1; + +UPDATE rw_view2 SET t = t WHERE base_a = 1.1; + +UPDATE rw_view2 SET base_a = 1.05 WHERE base_a = 1.1; + +DELETE FROM rw_view2 WHERE base_a = 1.05 RETURNING base_a, s, c, t; + +CREATE VIEW rw_view3 AS + SELECT s, c, s/c t, ctid + FROM rw_view1; + +INSERT INTO rw_view3 VALUES (null, null, null, null); + +INSERT INTO rw_view3(s) VALUES (null); + +UPDATE rw_view3 SET s = s; + +DELETE FROM rw_view3 WHERE s = sin(0.1); + +SELECT * FROM base_tbl ORDER BY a; + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name LIKE E'r_\\_view%' + ORDER BY table_name, ordinal_position; + +SELECT events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + FROM pg_catalog.pg_relation_is_updatable('rw_view3'::regclass, false) t(events); + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (id int, idplus1 int GENERATED ALWAYS AS (id + 1) STORED); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl; + +INSERT INTO base_tbl (id) VALUES (1); + +INSERT INTO rw_view1 (id) VALUES (2); + +INSERT INTO base_tbl (id, idplus1) VALUES (3, DEFAULT); + +INSERT INTO rw_view1 (id, idplus1) VALUES (4, DEFAULT); + +INSERT INTO base_tbl (id, idplus1) VALUES (5, 6); + +INSERT INTO rw_view1 (id, idplus1) VALUES (6, 7); + +SELECT * FROM base_tbl; + +UPDATE base_tbl SET id = 2000 WHERE id = 2; + +UPDATE rw_view1 SET id = 3000 WHERE id = 3; + +SELECT * FROM base_tbl; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl_parent (a int); + +CREATE TABLE base_tbl_child (CHECK (a > 0)) INHERITS (base_tbl_parent); + +INSERT INTO base_tbl_parent SELECT * FROM generate_series(-8, -1); + +INSERT INTO base_tbl_child SELECT * FROM generate_series(1, 8); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl_parent; + +CREATE VIEW rw_view2 AS SELECT * FROM ONLY base_tbl_parent; + +SELECT * FROM rw_view1 ORDER BY a; + +SELECT * FROM ONLY rw_view1 ORDER BY a; + +SELECT * FROM rw_view2 ORDER BY a; + +INSERT INTO rw_view1 VALUES (-100), (100); + +INSERT INTO rw_view2 VALUES (-200), (200); + +UPDATE rw_view1 SET a = a*10 WHERE a IN (-1, 1); + +UPDATE ONLY rw_view1 SET a = a*10 WHERE a IN (-2, 2); + +UPDATE rw_view2 SET a = a*10 WHERE a IN (-3, 3); + +UPDATE ONLY rw_view2 SET a = a*10 WHERE a IN (-4, 4); + +DELETE FROM rw_view1 WHERE a IN (-5, 5); + +DELETE FROM ONLY rw_view1 WHERE a IN (-6, 6); + +DELETE FROM rw_view2 WHERE a IN (-7, 7); + +DELETE FROM ONLY rw_view2 WHERE a IN (-8, 8); + +SELECT * FROM ONLY base_tbl_parent ORDER BY a; + +SELECT * FROM base_tbl_child ORDER BY a; + +SELECT * FROM ONLY base_tbl_parent ORDER BY a; + +SELECT * FROM base_tbl_child ORDER BY a; + +CREATE TABLE other_tbl_parent (id int); + +CREATE TABLE other_tbl_child () INHERITS (other_tbl_parent); + +INSERT INTO other_tbl_parent VALUES (7),(200); + +INSERT INTO other_tbl_child VALUES (8),(100); + +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; + +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; + +SELECT * FROM ONLY base_tbl_parent ORDER BY a; + +SELECT * FROM base_tbl_child ORDER BY a; + +DROP TABLE base_tbl_parent, base_tbl_child CASCADE; + +DROP TABLE other_tbl_parent CASCADE; + +CREATE TABLE base_tbl (a int, b int DEFAULT 10); + +INSERT INTO base_tbl VALUES (1,2), (2,3), (1,-1); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b + WITH LOCAL CHECK OPTION; + +SELECT * FROM information_schema.views WHERE table_name = 'rw_view1'; + +INSERT INTO rw_view1 VALUES(3,4); + +INSERT INTO rw_view1 VALUES(4,3); + +INSERT INTO rw_view1 VALUES(5,null); + +UPDATE rw_view1 SET b = 5 WHERE a = 3; + +UPDATE rw_view1 SET b = -5 WHERE a = 3; + +INSERT INTO rw_view1(a) VALUES (9); + +INSERT INTO rw_view1(a) VALUES (10); + +SELECT * FROM base_tbl ORDER BY a, b; + +SELECT * FROM base_tbl ORDER BY a, b; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a > 0; + +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 + WITH CHECK OPTION; + +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2'; + +INSERT INTO rw_view2 VALUES (-5); + +INSERT INTO rw_view2 VALUES (5); + +INSERT INTO rw_view2 VALUES (15); + +SELECT * FROM base_tbl; + +UPDATE rw_view2 SET a = a - 10; + +UPDATE rw_view2 SET a = a + 10; + +CREATE OR REPLACE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a < 10 + WITH LOCAL CHECK OPTION; + +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2'; + +INSERT INTO rw_view2 VALUES (-10); + +INSERT INTO rw_view2 VALUES (20); + +SELECT * FROM base_tbl; + +ALTER VIEW rw_view1 SET (check_option=here); + +ALTER VIEW rw_view1 SET (check_option=local); + +INSERT INTO rw_view2 VALUES (-20); + +INSERT INTO rw_view2 VALUES (30); + +ALTER VIEW rw_view2 RESET (check_option); + +SELECT * FROM information_schema.views WHERE table_name = 'rw_view2'; + +INSERT INTO rw_view2 VALUES (30); + +SELECT * FROM base_tbl; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WITH CHECK OPTION; + +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1 WHERE a > 0; + +CREATE VIEW rw_view3 AS SELECT * FROM rw_view2 WITH CHECK OPTION; + +SELECT * FROM information_schema.views WHERE table_name LIKE E'rw\\_view_' ORDER BY table_name; + +INSERT INTO rw_view1 VALUES (-1); + +INSERT INTO rw_view1 VALUES (1); + +INSERT INTO rw_view2 VALUES (-2); + +INSERT INTO rw_view2 VALUES (2); + +INSERT INTO rw_view3 VALUES (-3); + +INSERT INTO rw_view3 VALUES (3); + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int, b int[]); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a = ANY (b) + WITH CHECK OPTION; + +INSERT INTO rw_view1 VALUES (1, ARRAY[1,2,3]); + +INSERT INTO rw_view1 VALUES (10, ARRAY[4,5]); + +UPDATE rw_view1 SET b[2] = -b[2] WHERE a = 1; + +UPDATE rw_view1 SET b[1] = -b[1] WHERE a = 1; + +INSERT INTO rw_view1 VALUES($1, $2); + +EXECUTE ins(2, ARRAY[1,2,3]); + +EXECUTE ins(10, ARRAY[4,5]); + +DEALLOCATE PREPARE ins; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (a int); + +CREATE TABLE ref_tbl (a int PRIMARY KEY); + +INSERT INTO ref_tbl SELECT * FROM generate_series(1,10); + +CREATE VIEW rw_view1 AS + SELECT * FROM base_tbl b + WHERE EXISTS(SELECT 1 FROM ref_tbl r WHERE r.a = b.a) + WITH CHECK OPTION; + +INSERT INTO rw_view1 VALUES (5); + +INSERT INTO rw_view1 VALUES (15); + +UPDATE rw_view1 SET a = a + 5; + +UPDATE rw_view1 SET a = a + 5; + +INSERT INTO rw_view1 VALUES (5); + +UPDATE rw_view1 SET a = a + 5; + +DROP TABLE base_tbl, ref_tbl CASCADE; + +CREATE TABLE base_tbl (a int, b int); + +CREATE FUNCTION base_tbl_trig_fn() +RETURNS trigger AS +$$ +BEGIN + NEW.b := 10; + RETURN NEW; +END; +$$ +LANGUAGE plpgsql; + +CREATE TRIGGER base_tbl_trig BEFORE INSERT OR UPDATE ON base_tbl + FOR EACH ROW EXECUTE PROCEDURE base_tbl_trig_fn(); + +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl WHERE a < b WITH CHECK OPTION; + +INSERT INTO rw_view1 VALUES (5,0); + +INSERT INTO rw_view1 VALUES (15, 20); + +UPDATE rw_view1 SET a = 20, b = 30; + +DROP TABLE base_tbl CASCADE; + +DROP FUNCTION base_tbl_trig_fn(); + +CREATE TABLE base_tbl (a int, b int); + +CREATE VIEW rw_view1 AS SELECT a FROM base_tbl WHERE a < b; + +CREATE FUNCTION rw_view1_trig_fn() +RETURNS trigger AS +$$ +BEGIN + IF TG_OP = 'INSERT' THEN + INSERT INTO base_tbl VALUES (NEW.a, 10); + RETURN NEW; + ELSIF TG_OP = 'UPDATE' THEN + UPDATE base_tbl SET a=NEW.a WHERE a=OLD.a; + RETURN NEW; + ELSIF TG_OP = 'DELETE' THEN + DELETE FROM base_tbl WHERE a=OLD.a; + RETURN OLD; + END IF; +END; +$$ +LANGUAGE plpgsql; + +CREATE TRIGGER rw_view1_trig + INSTEAD OF INSERT OR UPDATE OR DELETE ON rw_view1 + FOR EACH ROW EXECUTE PROCEDURE rw_view1_trig_fn(); + +CREATE VIEW rw_view2 AS + SELECT * FROM rw_view1 WHERE a > 0 WITH LOCAL CHECK OPTION; + +INSERT INTO rw_view2 VALUES (-5); + +INSERT INTO rw_view2 VALUES (5); + +INSERT INTO rw_view2 VALUES (50); + +UPDATE rw_view2 SET a = a - 10; + +SELECT * FROM base_tbl; + +ALTER VIEW rw_view2 SET (check_option=cascaded); + +INSERT INTO rw_view2 VALUES (100); + +UPDATE rw_view2 SET a = 200 WHERE a = 5; + +SELECT * FROM base_tbl; + +DROP TRIGGER rw_view1_trig ON rw_view1; + +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a, 10); + +CREATE RULE rw_view1_upd_rule AS ON UPDATE TO rw_view1 + DO INSTEAD UPDATE base_tbl SET a=NEW.a WHERE a=OLD.a; + +INSERT INTO rw_view2 VALUES (-10); + +INSERT INTO rw_view2 VALUES (5); + +INSERT INTO rw_view2 VALUES (20); + +UPDATE rw_view2 SET a = 30 WHERE a = 5; + +INSERT INTO rw_view2 VALUES (5); + +UPDATE rw_view2 SET a = -5 WHERE a = 5; + +SELECT * FROM base_tbl; + +DROP TABLE base_tbl CASCADE; + +DROP FUNCTION rw_view1_trig_fn(); + +CREATE TABLE base_tbl (a int); + +CREATE VIEW rw_view1 AS SELECT a,10 AS b FROM base_tbl; + +CREATE RULE rw_view1_ins_rule AS ON INSERT TO rw_view1 + DO INSTEAD INSERT INTO base_tbl VALUES (NEW.a); + +CREATE VIEW rw_view2 AS + SELECT * FROM rw_view1 WHERE a > b WITH LOCAL CHECK OPTION; + +INSERT INTO rw_view2 VALUES (2,3); + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl (person text, visibility text); + +INSERT INTO base_tbl VALUES ('Tom', 'public'), + ('Dick', 'private'), + ('Harry', 'public'); + +CREATE VIEW rw_view1 AS + SELECT person FROM base_tbl WHERE visibility = 'public'; + +CREATE FUNCTION snoop(anyelement) +RETURNS boolean AS +$$ +BEGIN + RAISE NOTICE 'snooped value: %', $1; + RETURN true; +END; +$$ +LANGUAGE plpgsql COST 0.000001; + +CREATE OR REPLACE FUNCTION leakproof(anyelement) +RETURNS boolean AS +$$ +BEGIN + RETURN true; +END; +$$ +LANGUAGE plpgsql STRICT IMMUTABLE LEAKPROOF; + +SELECT * FROM rw_view1 WHERE snoop(person); + +UPDATE rw_view1 SET person=person WHERE snoop(person); + +DELETE FROM rw_view1 WHERE NOT snoop(person); + +ALTER VIEW rw_view1 SET (security_barrier = true); + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view1'; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view1'; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view1' + ORDER BY ordinal_position; + +SELECT * FROM rw_view1 WHERE snoop(person); + +UPDATE rw_view1 SET person=person WHERE snoop(person); + +DELETE FROM rw_view1 WHERE NOT snoop(person); + +SELECT * FROM rw_view1 WHERE snoop(person); + +UPDATE rw_view1 SET person=person WHERE snoop(person); + +DELETE FROM rw_view1 WHERE NOT snoop(person); + +CREATE VIEW rw_view2 WITH (security_barrier = true) AS + SELECT * FROM rw_view1 WHERE snoop(person); + +SELECT table_name, is_insertable_into + FROM information_schema.tables + WHERE table_name = 'rw_view2'; + +SELECT table_name, is_updatable, is_insertable_into + FROM information_schema.views + WHERE table_name = 'rw_view2'; + +SELECT table_name, column_name, is_updatable + FROM information_schema.columns + WHERE table_name = 'rw_view2' + ORDER BY ordinal_position; + +SELECT * FROM rw_view2 WHERE snoop(person); + +UPDATE rw_view2 SET person=person WHERE snoop(person); + +DELETE FROM rw_view2 WHERE NOT snoop(person); + +SELECT * FROM rw_view2 WHERE snoop(person); + +UPDATE rw_view2 SET person=person WHERE snoop(person); + +DELETE FROM rw_view2 WHERE NOT snoop(person); + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE base_tbl(id int PRIMARY KEY, data text, deleted boolean); + +INSERT INTO base_tbl VALUES (1, 'Row 1', false), (2, 'Row 2', true); + +CREATE RULE base_tbl_ins_rule AS ON INSERT TO base_tbl + WHERE EXISTS (SELECT 1 FROM base_tbl t WHERE t.id = new.id) + DO INSTEAD + UPDATE base_tbl SET data = new.data, deleted = false WHERE id = new.id; + +CREATE RULE base_tbl_del_rule AS ON DELETE TO base_tbl + DO INSTEAD + UPDATE base_tbl SET deleted = true WHERE id = old.id; + +CREATE VIEW rw_view1 WITH (security_barrier=true) AS + SELECT id, data FROM base_tbl WHERE NOT deleted; + +SELECT * FROM rw_view1; + +DELETE FROM rw_view1 WHERE id = 1 AND snoop(data); + +DELETE FROM rw_view1 WHERE id = 1 AND snoop(data); + +INSERT INTO rw_view1 VALUES (2, 'New row 2'); + +INSERT INTO rw_view1 VALUES (2, 'New row 2'); + +SELECT * FROM base_tbl; + +DROP TABLE base_tbl CASCADE; + +CREATE TABLE t1 (a int, b float, c text); + +CREATE INDEX t1_a_idx ON t1(a); + +INSERT INTO t1 +SELECT i,i,'t1' FROM generate_series(1,10) g(i); + +ANALYZE t1; + +CREATE TABLE t11 (d text) INHERITS (t1); + +CREATE INDEX t11_a_idx ON t11(a); + +INSERT INTO t11 +SELECT i,i,'t11','t11d' FROM generate_series(1,10) g(i); + +ANALYZE t11; + +CREATE TABLE t12 (e int[]) INHERITS (t1); + +CREATE INDEX t12_a_idx ON t12(a); + +INSERT INTO t12 +SELECT i,i,'t12','{1,2}'::int[] FROM generate_series(1,10) g(i); + +ANALYZE t12; + +CREATE TABLE t111 () INHERITS (t11, t12); + +CREATE INDEX t111_a_idx ON t111(a); + +INSERT INTO t111 +SELECT i,i,'t111','t111d','{1,1,1}'::int[] FROM generate_series(1,10) g(i); + +ANALYZE t111; + +CREATE VIEW v1 WITH (security_barrier=true) AS +SELECT *, (SELECT d FROM t11 WHERE t11.a = t1.a LIMIT 1) AS d +FROM t1 +WHERE a > 5 AND EXISTS(SELECT 1 FROM t12 WHERE t12.a = t1.a); + +SELECT * FROM v1 WHERE a=3; + +SELECT * FROM v1 WHERE a=8; + +UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6; + +UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6; + +SELECT * FROM v1 WHERE a=100; + +SELECT * FROM t1 WHERE a=100; + +UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8; + +UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8; + +SELECT * FROM v1 WHERE b=8; + +DELETE FROM v1 WHERE snoop(a) AND leakproof(a); + +TABLE t1; + +DROP TABLE t1, t11, t12, t111 CASCADE; + +DROP FUNCTION snoop(anyelement); + +DROP FUNCTION leakproof(anyelement); + +CREATE TABLE tx1 (a integer); + +CREATE TABLE tx2 (b integer); + +CREATE TABLE tx3 (c integer); + +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c); + +INSERT INTO vx1 values (1); + +SELECT * FROM tx1; + +SELECT * FROM vx1; + +DROP VIEW vx1; + +DROP TABLE tx1; + +DROP TABLE tx2; + +DROP TABLE tx3; + +CREATE TABLE tx1 (a integer); + +CREATE TABLE tx2 (b integer); + +CREATE TABLE tx3 (c integer); + +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c); + +INSERT INTO vx1 VALUES (1); + +INSERT INTO vx1 VALUES (1); + +SELECT * FROM tx1; + +SELECT * FROM vx1; + +DROP VIEW vx1; + +DROP TABLE tx1; + +DROP TABLE tx2; + +DROP TABLE tx3; + +CREATE TABLE tx1 (a integer, b integer); + +CREATE TABLE tx2 (b integer, c integer); + +CREATE TABLE tx3 (c integer, d integer); + +ALTER TABLE tx1 DROP COLUMN b; + +ALTER TABLE tx2 DROP COLUMN c; + +ALTER TABLE tx3 DROP COLUMN d; + +CREATE VIEW vx1 AS SELECT a FROM tx1 WHERE EXISTS(SELECT 1 FROM tx2 JOIN tx3 ON b=c); + +INSERT INTO vx1 VALUES (1); + +INSERT INTO vx1 VALUES (1); + +SELECT * FROM tx1; + +SELECT * FROM vx1; + +DROP VIEW vx1; + +DROP TABLE tx1; + +DROP TABLE tx2; + +DROP TABLE tx3; + +CREATE TABLE t1 (a int, b text, c int); + +INSERT INTO t1 VALUES (1, 'one', 10); + +CREATE TABLE t2 (cc int); + +INSERT INTO t2 VALUES (10), (20); + +CREATE VIEW v1 WITH (security_barrier = true) AS + SELECT * FROM t1 WHERE (a > 0) + WITH CHECK OPTION; + +CREATE VIEW v2 WITH (security_barrier = true) AS + SELECT * FROM v1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.cc = v1.c) + WITH CHECK OPTION; + +INSERT INTO v2 VALUES (2, 'two', 20); + +INSERT INTO v2 VALUES (-2, 'minus two', 20); + +INSERT INTO v2 VALUES (3, 'three', 30); + +UPDATE v2 SET b = 'ONE' WHERE a = 1; + +UPDATE v2 SET a = -1 WHERE a = 1; + +UPDATE v2 SET c = 30 WHERE a = 1; + +DELETE FROM v2 WHERE a = 2; + +SELECT * FROM v2; + +DROP VIEW v2; + +DROP VIEW v1; + +DROP TABLE t2; + +DROP TABLE t1; + +CREATE TABLE t1 (a int); + +CREATE VIEW v1 WITH (security_barrier = true) AS + SELECT * FROM t1; + +CREATE RULE v1_upd_rule AS ON UPDATE TO v1 DO INSTEAD + UPDATE t1 SET a = NEW.a WHERE a = OLD.a; + +CREATE VIEW v2 WITH (security_barrier = true) AS + SELECT * FROM v1 WHERE EXISTS (SELECT 1); + +UPDATE v2 SET a = 1; + +DROP VIEW v2; + +DROP VIEW v1; + +DROP TABLE t1; + +CREATE TABLE t1 (a int, b text); + +CREATE VIEW v1 AS SELECT null::int AS a; + +CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 WHERE a > 0 WITH CHECK OPTION; + +INSERT INTO v1 VALUES (1, 'ok'); + +INSERT INTO v1 VALUES (-1, 'invalid'); + +DROP VIEW v1; + +DROP TABLE t1; + +create table uv_pt (a int, b int, v varchar) partition by range (a, b); + +create table uv_pt1 (b int not null, v varchar, a int not null) partition by range (b); + +create table uv_pt11 (like uv_pt1); + +alter table uv_pt11 drop a; + +alter table uv_pt11 add a int; + +alter table uv_pt11 drop a; + +alter table uv_pt11 add a int not null; + +alter table uv_pt1 attach partition uv_pt11 for values from (2) to (5); + +alter table uv_pt attach partition uv_pt1 for values from (1, 2) to (1, 10); + +create view uv_ptv as select * from uv_pt; + +select events & 4 != 0 AS upd, + events & 8 != 0 AS ins, + events & 16 != 0 AS del + from pg_catalog.pg_relation_is_updatable('uv_pt'::regclass, false) t(events); + +select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 1::smallint, false); + +select pg_catalog.pg_column_is_updatable('uv_pt'::regclass, 2::smallint, false); + +select table_name, is_updatable, is_insertable_into + from information_schema.views where table_name = 'uv_ptv'; + +select table_name, column_name, is_updatable + from information_schema.columns where table_name = 'uv_ptv' order by column_name; + +insert into uv_ptv values (1, 2); + +select tableoid::regclass, * from uv_pt; + +create view uv_ptv_wco as select * from uv_pt where a = 0 with check option; + +insert into uv_ptv_wco values (1, 2); + +select tableoid::regclass, * from uv_pt order by a, b; + +drop view uv_ptv, uv_ptv_wco; + +drop table uv_pt, uv_pt1, uv_pt11; + +create table wcowrtest (a int) partition by list (a); + +create table wcowrtest1 partition of wcowrtest for values in (1); + +create view wcowrtest_v as select * from wcowrtest where wcowrtest = '(2)'::wcowrtest with check option; + +insert into wcowrtest_v values (1); + +alter table wcowrtest add b text; + +create table wcowrtest2 (b text, c int, a int); + +alter table wcowrtest2 drop c; + +alter table wcowrtest attach partition wcowrtest2 for values in (2); + +create table sometable (a int, b text); + +insert into sometable values (1, 'a'), (2, 'b'); + +create view wcowrtest_v2 as + select * + from wcowrtest r + where r in (select s from sometable s where r.a = s.a) +with check option; + +insert into wcowrtest_v2 values (2, 'no such row in sometable'); + +drop view wcowrtest_v, wcowrtest_v2; + +drop table wcowrtest, sometable; + +create table uv_iocu_tab (a text unique, b float); + +insert into uv_iocu_tab values ('xyxyxy', 0); + +create view uv_iocu_view as + select b, b+1 as c, a, '2.0'::text as two from uv_iocu_tab; + +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = uv_iocu_view.b; + +select * from uv_iocu_tab; + +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = excluded.b; + +select * from uv_iocu_tab; + +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = cast(excluded.two as float); + +select * from uv_iocu_tab; + +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0; + +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0; + +select * from uv_iocu_tab; + +drop view uv_iocu_view; + +drop table uv_iocu_tab; + +create table uv_iocu_tab (a int unique, b text); + +create view uv_iocu_view as + select b as bb, a as aa, uv_iocu_tab::text as cc from uv_iocu_tab; + +insert into uv_iocu_view (aa,bb) values (1,'x'); + +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null; + +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null; + +select * from uv_iocu_view; + +delete from uv_iocu_view; + +insert into uv_iocu_view (aa,bb) values (1,'x'); + +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; + +select * from uv_iocu_view; + +alter table uv_iocu_tab alter column b set default 'table default'; + +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; + +select * from uv_iocu_view; + +alter view uv_iocu_view alter column bb set default 'view default'; + +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; + +select * from uv_iocu_view; + +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set cc = 'XXX'; + +drop view uv_iocu_view; + +drop table uv_iocu_tab; + +create user regress_view_user1; + +create user regress_view_user2; + +set session authorization regress_view_user1; + +create table base_tbl(a int unique, b text, c float); + +insert into base_tbl values (1,'xxx',1.0); + +create view rw_view1 as select b as bb, c as cc, a as aa from base_tbl; + +grant select (aa,bb) on rw_view1 to regress_view_user2; + +grant insert on rw_view1 to regress_view_user2; + +grant update (bb) on rw_view1 to regress_view_user2; + +set session authorization regress_view_user2; + +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.cc; + +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = rw_view1.cc; + +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.bb; + +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set bb = rw_view1.bb||'xxx'; + +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set cc = 3.0; + +reset session authorization; + +select * from base_tbl; + +set session authorization regress_view_user1; + +grant select (a,b) on base_tbl to regress_view_user2; + +grant insert (a,b) on base_tbl to regress_view_user2; + +grant update (a,b) on base_tbl to regress_view_user2; + +set session authorization regress_view_user2; + +create view rw_view2 as select b as bb, c as cc, a as aa from base_tbl; + +insert into rw_view2 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb; + +create view rw_view3 as select b as bb, a as aa from base_tbl; + +insert into rw_view3 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb; + +reset session authorization; + +select * from base_tbl; + +set session authorization regress_view_user2; + +create view rw_view4 as select aa, bb, cc FROM rw_view1; + +insert into rw_view4 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb; + +create view rw_view5 as select aa, bb FROM rw_view1; + +insert into rw_view5 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb; + +reset session authorization; + +select * from base_tbl; + +drop view rw_view5; + +drop view rw_view4; + +drop view rw_view3; + +drop view rw_view2; + +drop view rw_view1; + +drop table base_tbl; + +drop user regress_view_user1; + +drop user regress_view_user2; + +create table base_tab_def (a int, b text default 'Table default', + c text default 'Table default', d text, e text); + +create view base_tab_def_view as select * from base_tab_def; + +alter view base_tab_def_view alter b set default 'View default'; + +alter view base_tab_def_view alter d set default 'View default'; + +insert into base_tab_def values (1); + +insert into base_tab_def values (2), (3); + +insert into base_tab_def values (4, default, default, default, default); + +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); + +insert into base_tab_def_view values (11); + +insert into base_tab_def_view values (12), (13); + +insert into base_tab_def_view values (14, default, default, default, default); + +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); + +insert into base_tab_def_view values (17), (default); + +select * from base_tab_def order by a; + +create function base_tab_def_view_instrig_func() returns trigger +as +$$ +begin + insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); + return new; +end; +$$ +language plpgsql; + +create trigger base_tab_def_view_instrig instead of insert on base_tab_def_view + for each row execute function base_tab_def_view_instrig_func(); + +truncate base_tab_def; + +insert into base_tab_def values (1); + +insert into base_tab_def values (2), (3); + +insert into base_tab_def values (4, default, default, default, default); + +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); + +insert into base_tab_def_view values (11); + +insert into base_tab_def_view values (12), (13); + +insert into base_tab_def_view values (14, default, default, default, default); + +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); + +insert into base_tab_def_view values (17), (default); + +select * from base_tab_def order by a; + +drop trigger base_tab_def_view_instrig on base_tab_def_view; + +drop function base_tab_def_view_instrig_func; + +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do instead insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); + +truncate base_tab_def; + +insert into base_tab_def values (1); + +insert into base_tab_def values (2), (3); + +insert into base_tab_def values (4, default, default, default, default); + +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); + +insert into base_tab_def_view values (11); + +insert into base_tab_def_view values (12), (13); + +insert into base_tab_def_view values (14, default, default, default, default); + +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); + +insert into base_tab_def_view values (17), (default); + +select * from base_tab_def order by a; + +drop rule base_tab_def_view_ins_rule on base_tab_def_view; + +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do also insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); + +truncate base_tab_def; + +insert into base_tab_def values (1); + +insert into base_tab_def values (2), (3); + +insert into base_tab_def values (4, default, default, default, default); + +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); + +insert into base_tab_def_view values (11); + +insert into base_tab_def_view values (12), (13); + +insert into base_tab_def_view values (14, default, default, default, default); + +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); + +insert into base_tab_def_view values (17), (default); + +select * from base_tab_def order by a, c NULLS LAST; + +drop rule base_tab_def_view_ins_rule on base_tab_def_view; + +select new.a, new.b, 'xxx'; + +truncate base_tab_def; + +insert into base_tab_def_view values (1, default, default, default, default); + +insert into base_tab_def_view values (2, default, default, default, default), + (3, default, default, default, default); + +select * from base_tab_def order by a, e nulls first; + +drop view base_tab_def_view; + +drop table base_tab_def; + +create table base_tab (a serial, b int[], c text, d text default 'Table default'); + +create view base_tab_view as select c, a, b from base_tab; + +alter view base_tab_view alter column c set default 'View default'; + +insert into base_tab_view (b[1], b[2], c, b[5], b[4], a, b[3]) +values (1, 2, default, 5, 4, default, 3), (10, 11, 'C value', 14, 13, 100, 12); + +select * from base_tab order by a; + +drop view base_tab_view; + +drop table base_tab; diff --git a/crates/pgt_pretty_print/tests/data/multi/update_60.sql b/crates/pgt_pretty_print/tests/data/multi/update_60.sql new file mode 100644 index 000000000..ea7a6baab --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/update_60.sql @@ -0,0 +1,630 @@ +CREATE TABLE update_test ( + a INT DEFAULT 10, + b INT, + c TEXT +); + +CREATE TABLE upsert_test ( + a INT PRIMARY KEY, + b TEXT +); + +INSERT INTO update_test VALUES (5, 10, 'foo'); + +INSERT INTO update_test(b, a) VALUES (15, 10); + +SELECT * FROM update_test; + +UPDATE update_test SET a = DEFAULT, b = DEFAULT; + +SELECT * FROM update_test; + +UPDATE update_test AS t SET b = 10 WHERE t.a = 10; + +SELECT * FROM update_test; + +UPDATE update_test t SET b = t.b + 10 WHERE t.a = 10; + +SELECT * FROM update_test; + +UPDATE update_test t SET t.b = t.b + 10 WHERE t.a = 10; + +UPDATE update_test SET a=v.i FROM (VALUES(100, 20)) AS v(i, j) + WHERE update_test.b = v.j; + +SELECT * FROM update_test; + +UPDATE update_test SET a = v.* FROM (VALUES(100, 20)) AS v(i, j) + WHERE update_test.b = v.j; + +INSERT INTO update_test SELECT a,b+1,c FROM update_test; + +SELECT * FROM update_test; + +UPDATE update_test SET (c,b,a) = ('bugle', b+11, DEFAULT) WHERE c = 'foo'; + +SELECT * FROM update_test; + +UPDATE update_test SET (c,b) = ('car', a+b), a = a + 1 WHERE a = 10; + +SELECT * FROM update_test; + +UPDATE update_test SET (c,b) = ('car', a+b), b = a + 1 WHERE a = 10; + +UPDATE update_test + SET (b,a) = (select a,b from update_test where b = 41 and c = 'car') + WHERE a = 100 AND b = 20; + +SELECT * FROM update_test; + +UPDATE update_test o + SET (b,a) = (select a+1,b from update_test i + where i.a=o.a and i.b=o.b and i.c is not distinct from o.c); + +SELECT * FROM update_test; + +UPDATE update_test SET (b,a) = (select a+1,b from update_test); + +UPDATE update_test SET (b,a) = (select a+1,b from update_test where a = 1000) + WHERE a = 11; + +SELECT * FROM update_test; + +UPDATE update_test SET (a,b) = ROW(v.*) FROM (VALUES(21, 100)) AS v(i, j) + WHERE update_test.a = v.i; + +UPDATE update_test SET (a,b) = (v.*) FROM (VALUES(21, 101)) AS v(i, j) + WHERE update_test.a = v.i; + +UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10; + +UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car'; + +SELECT a, b, char_length(c) FROM update_test; + +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER; + +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER; + +SELECT a, b, char_length(c) FROM update_test; + +INSERT INTO upsert_test VALUES(1, 'Boo'), (3, 'Zoo'); + +WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test + VALUES (1, 'Bar') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING *; + +INSERT INTO upsert_test VALUES (1, 'Baz'), (3, 'Zaz') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Correlated', a from upsert_test i WHERE i.a = upsert_test.a) + RETURNING *; + +INSERT INTO upsert_test VALUES (1, 'Bat'), (3, 'Zot') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING *; + +INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = 0 AS xmax_correct; + +INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = pg_current_xact_id()::xid AS xmax_correct; + +DROP TABLE update_test; + +DROP TABLE upsert_test; + +CREATE TABLE upsert_test ( + a INT PRIMARY KEY, + b TEXT +) PARTITION BY LIST (a); + +CREATE TABLE upsert_test_1 PARTITION OF upsert_test FOR VALUES IN (1); + +CREATE TABLE upsert_test_2 (b TEXT, a INT PRIMARY KEY); + +ALTER TABLE upsert_test ATTACH PARTITION upsert_test_2 FOR VALUES IN (2); + +INSERT INTO upsert_test VALUES(1, 'Boo'), (2, 'Zoo'); + +WITH aaa AS (SELECT 1 AS a, 'Foo' AS b) INSERT INTO upsert_test + VALUES (1, 'Bar') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING *; + +WITH aaa AS (SELECT 1 AS ctea, ' Foo' AS cteb) INSERT INTO upsert_test + VALUES (1, 'Bar'), (2, 'Baz') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT upsert_test.b||cteb, upsert_test.a FROM aaa) RETURNING *; + +DROP TABLE upsert_test; + +CREATE TABLE range_parted ( + a text, + b bigint, + c numeric, + d int, + e varchar +) PARTITION BY RANGE (a, b); + +CREATE TABLE part_b_20_b_30 (e varchar, c numeric, a text, b bigint, d int); + +ALTER TABLE range_parted ATTACH PARTITION part_b_20_b_30 FOR VALUES FROM ('b', 20) TO ('b', 30); + +CREATE TABLE part_b_10_b_20 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY RANGE (c); + +CREATE TABLE part_b_1_b_10 PARTITION OF range_parted FOR VALUES FROM ('b', 1) TO ('b', 10); + +ALTER TABLE range_parted ATTACH PARTITION part_b_10_b_20 FOR VALUES FROM ('b', 10) TO ('b', 20); + +CREATE TABLE part_a_10_a_20 PARTITION OF range_parted FOR VALUES FROM ('a', 10) TO ('a', 20); + +CREATE TABLE part_a_1_a_10 PARTITION OF range_parted FOR VALUES FROM ('a', 1) TO ('a', 10); + +UPDATE part_b_10_b_20 set b = b - 6; + +CREATE TABLE part_c_100_200 (e varchar, c numeric, a text, b bigint, d int) PARTITION BY range (abs(d)); + +ALTER TABLE part_c_100_200 DROP COLUMN e, DROP COLUMN c, DROP COLUMN a; + +ALTER TABLE part_c_100_200 ADD COLUMN c numeric, ADD COLUMN e varchar, ADD COLUMN a text; + +ALTER TABLE part_c_100_200 DROP COLUMN b; + +ALTER TABLE part_c_100_200 ADD COLUMN b bigint; + +CREATE TABLE part_d_1_15 PARTITION OF part_c_100_200 FOR VALUES FROM (1) TO (15); + +CREATE TABLE part_d_15_20 PARTITION OF part_c_100_200 FOR VALUES FROM (15) TO (20); + +ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_100_200 FOR VALUES FROM (100) TO (200); + +CREATE TABLE part_c_1_100 (e varchar, d int, c numeric, b bigint, a text); + +ALTER TABLE part_b_10_b_20 ATTACH PARTITION part_c_1_100 FOR VALUES FROM (1) TO (100); + +UPDATE range_parted set c = c - 50 WHERE c > 97; + +UPDATE part_c_100_200 set c = c - 20, d = c WHERE c = 105; + +UPDATE part_b_10_b_20 set a = 'a'; + +UPDATE range_parted set d = d - 10 WHERE d > 10; + +UPDATE range_parted set e = d; + +UPDATE part_c_1_100 set c = c + 20 WHERE c = 98; + +UPDATE part_b_10_b_20 set c = c + 20 returning c, b, a; + +UPDATE part_b_10_b_20 set b = b - 6 WHERE c > 116 returning *; + +UPDATE range_parted set b = b - 6 WHERE c > 116 returning a, b + c; + +CREATE TABLE mintab(c1 int); + +INSERT into mintab VALUES (120); + +CREATE VIEW upview AS SELECT * FROM range_parted WHERE (select c > c1 FROM mintab) WITH CHECK OPTION; + +UPDATE upview set c = 199 WHERE b = 4; + +UPDATE upview set c = 120 WHERE b = 4; + +UPDATE upview set a = 'b', b = 15, c = 120 WHERE b = 4; + +UPDATE upview set a = 'b', b = 15 WHERE b = 4; + +DROP VIEW upview; + +UPDATE range_parted set c = 95 WHERE a = 'b' and b > 10 and c > 100 returning (range_parted), *; + +CREATE FUNCTION trans_updatetrigfunc() RETURNS trigger LANGUAGE plpgsql AS +$$ + begin + raise notice 'trigger = %, old table = %, new table = %', + TG_NAME, + (select string_agg(old_table::text, ', ' ORDER BY a) FROM old_table), + (select string_agg(new_table::text, ', ' ORDER BY a) FROM new_table); + return null; + end; +$$; + +CREATE TRIGGER trans_updatetrig + AFTER UPDATE ON range_parted REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc(); + +UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end ) WHERE a = 'b' and b > 10 and c >= 96; + +CREATE TRIGGER trans_deletetrig + AFTER DELETE ON range_parted REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc(); + +CREATE TRIGGER trans_inserttrig + AFTER INSERT ON range_parted REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc(); + +UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96; + +DROP TRIGGER trans_deletetrig ON range_parted; + +DROP TRIGGER trans_inserttrig ON range_parted; + +CREATE FUNCTION func_parted_mod_b() RETURNS trigger AS $$ +BEGIN + NEW.b = NEW.b + 1; + return NEW; +END $$ language plpgsql; + +CREATE TRIGGER trig_c1_100 BEFORE UPDATE OR INSERT ON part_c_1_100 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b(); + +CREATE TRIGGER trig_d1_15 BEFORE UPDATE OR INSERT ON part_d_1_15 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b(); + +CREATE TRIGGER trig_d15_20 BEFORE UPDATE OR INSERT ON part_d_15_20 + FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b(); + +UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end) WHERE a = 'b' and b > 10 and c >= 96; + +UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96; + +UPDATE range_parted set b = 15 WHERE b = 1; + +DROP TRIGGER trans_updatetrig ON range_parted; + +DROP TRIGGER trig_c1_100 ON part_c_1_100; + +DROP TRIGGER trig_d1_15 ON part_d_1_15; + +DROP TRIGGER trig_d15_20 ON part_d_15_20; + +DROP FUNCTION func_parted_mod_b(); + +ALTER TABLE range_parted ENABLE ROW LEVEL SECURITY; + +CREATE USER regress_range_parted_user; + +GRANT ALL ON range_parted, mintab TO regress_range_parted_user; + +CREATE POLICY seeall ON range_parted AS PERMISSIVE FOR SELECT USING (true); + +CREATE POLICY policy_range_parted ON range_parted for UPDATE USING (true) WITH CHECK (c % 2 = 0); + +SET SESSION AUTHORIZATION regress_range_parted_user; + +UPDATE range_parted set a = 'b', c = 151 WHERE a = 'a' and c = 200; + +RESET SESSION AUTHORIZATION; + +CREATE FUNCTION func_d_1_15() RETURNS trigger AS $$ +BEGIN + NEW.c = NEW.c + 1; -- Make even numbers odd, or vice versa + return NEW; +END $$ LANGUAGE plpgsql; + +CREATE TRIGGER trig_d_1_15 BEFORE INSERT ON part_d_1_15 + FOR EACH ROW EXECUTE PROCEDURE func_d_1_15(); + +SET SESSION AUTHORIZATION regress_range_parted_user; + +UPDATE range_parted set a = 'b', c = 151 WHERE a = 'a' and c = 200; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_range_parted_user; + +UPDATE range_parted set a = 'b', c = 150 WHERE a = 'a' and c = 200; + +RESET SESSION AUTHORIZATION; + +DROP TRIGGER trig_d_1_15 ON part_d_1_15; + +DROP FUNCTION func_d_1_15(); + +RESET SESSION AUTHORIZATION; + +CREATE POLICY policy_range_parted_subplan on range_parted + AS RESTRICTIVE for UPDATE USING (true) + WITH CHECK ((SELECT range_parted.c <= c1 FROM mintab)); + +SET SESSION AUTHORIZATION regress_range_parted_user; + +UPDATE range_parted set a = 'b', c = 122 WHERE a = 'a' and c = 200; + +UPDATE range_parted set a = 'b', c = 120 WHERE a = 'a' and c = 200; + +RESET SESSION AUTHORIZATION; + +CREATE POLICY policy_range_parted_wholerow on range_parted AS RESTRICTIVE for UPDATE USING (true) + WITH CHECK (range_parted = row('b', 10, 112, 1, NULL)::range_parted); + +SET SESSION AUTHORIZATION regress_range_parted_user; + +UPDATE range_parted set a = 'b', c = 112 WHERE a = 'a' and c = 200; + +RESET SESSION AUTHORIZATION; + +SET SESSION AUTHORIZATION regress_range_parted_user; + +UPDATE range_parted set a = 'b', c = 116 WHERE a = 'a' and c = 200; + +RESET SESSION AUTHORIZATION; + +DROP POLICY policy_range_parted ON range_parted; + +DROP POLICY policy_range_parted_subplan ON range_parted; + +DROP POLICY policy_range_parted_wholerow ON range_parted; + +REVOKE ALL ON range_parted, mintab FROM regress_range_parted_user; + +DROP USER regress_range_parted_user; + +DROP TABLE mintab; + +CREATE FUNCTION trigfunc() returns trigger language plpgsql as +$$ + begin + raise notice 'trigger = % fired on table % during %', + TG_NAME, TG_TABLE_NAME, TG_OP; + return null; + end; +$$; + +CREATE TRIGGER parent_delete_trig + AFTER DELETE ON range_parted for each statement execute procedure trigfunc(); + +CREATE TRIGGER parent_update_trig + AFTER UPDATE ON range_parted for each statement execute procedure trigfunc(); + +CREATE TRIGGER parent_insert_trig + AFTER INSERT ON range_parted for each statement execute procedure trigfunc(); + +CREATE TRIGGER c1_delete_trig + AFTER DELETE ON part_c_1_100 for each statement execute procedure trigfunc(); + +CREATE TRIGGER c1_update_trig + AFTER UPDATE ON part_c_1_100 for each statement execute procedure trigfunc(); + +CREATE TRIGGER c1_insert_trig + AFTER INSERT ON part_c_1_100 for each statement execute procedure trigfunc(); + +CREATE TRIGGER d1_delete_trig + AFTER DELETE ON part_d_1_15 for each statement execute procedure trigfunc(); + +CREATE TRIGGER d1_update_trig + AFTER UPDATE ON part_d_1_15 for each statement execute procedure trigfunc(); + +CREATE TRIGGER d1_insert_trig + AFTER INSERT ON part_d_1_15 for each statement execute procedure trigfunc(); + +CREATE TRIGGER d15_delete_trig + AFTER DELETE ON part_d_15_20 for each statement execute procedure trigfunc(); + +CREATE TRIGGER d15_update_trig + AFTER UPDATE ON part_d_15_20 for each statement execute procedure trigfunc(); + +CREATE TRIGGER d15_insert_trig + AFTER INSERT ON part_d_15_20 for each statement execute procedure trigfunc(); + +UPDATE range_parted set c = c - 50 WHERE c > 97; + +DROP TRIGGER parent_delete_trig ON range_parted; + +DROP TRIGGER parent_update_trig ON range_parted; + +DROP TRIGGER parent_insert_trig ON range_parted; + +DROP TRIGGER c1_delete_trig ON part_c_1_100; + +DROP TRIGGER c1_update_trig ON part_c_1_100; + +DROP TRIGGER c1_insert_trig ON part_c_1_100; + +DROP TRIGGER d1_delete_trig ON part_d_1_15; + +DROP TRIGGER d1_update_trig ON part_d_1_15; + +DROP TRIGGER d1_insert_trig ON part_d_1_15; + +DROP TRIGGER d15_delete_trig ON part_d_15_20; + +DROP TRIGGER d15_update_trig ON part_d_15_20; + +DROP TRIGGER d15_insert_trig ON part_d_15_20; + +create table part_def partition of range_parted default; + +insert into range_parted values ('c', 9); + +update part_def set a = 'd' where a = 'c'; + +update part_def set a = 'a' where a = 'd'; + +UPDATE part_a_10_a_20 set a = 'ad' WHERE a = 'a'; + +UPDATE range_parted set a = 'ad' WHERE a = 'a'; + +UPDATE range_parted set a = 'bd' WHERE a = 'b'; + +UPDATE range_parted set a = 'a' WHERE a = 'ad'; + +UPDATE range_parted set a = 'b' WHERE a = 'bd'; + +DROP TABLE range_parted; + +CREATE TABLE list_parted ( + a text, + b int +) PARTITION BY list (a); + +CREATE TABLE list_part1 PARTITION OF list_parted for VALUES in ('a', 'b'); + +CREATE TABLE list_default PARTITION OF list_parted default; + +INSERT into list_part1 VALUES ('a', 1); + +INSERT into list_default VALUES ('d', 10); + +UPDATE list_default set a = 'a' WHERE a = 'd'; + +UPDATE list_default set a = 'x' WHERE a = 'd'; + +DROP TABLE list_parted; + +create table utrtest (a int, b text) partition by list (a); + +create table utr1 (a int check (a in (1)), q text, b text); + +create table utr2 (a int check (a in (2)), b text); + +alter table utr1 drop column q; + +alter table utrtest attach partition utr1 for values in (1); + +alter table utrtest attach partition utr2 for values in (2); + +insert into utrtest values (1, 'foo') + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; + +insert into utrtest values (2, 'bar') + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; + +insert into utrtest values (2, 'bar') + returning *, tableoid::regclass; + +update utrtest set b = b || b from (values (1), (2)) s(x) where a = s.x + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; + +update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x + returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; + +update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x + returning *, tableoid::regclass; + +delete from utrtest + returning *, tableoid::regclass, xmax = pg_current_xact_id()::xid as xmax_ok; + +drop table utrtest; + +CREATE TABLE list_parted (a numeric, b int, c int8) PARTITION BY list (a); + +CREATE TABLE sub_parted PARTITION OF list_parted for VALUES in (1) PARTITION BY list (b); + +CREATE TABLE sub_part1(b int, c int8, a numeric); + +ALTER TABLE sub_parted ATTACH PARTITION sub_part1 for VALUES in (1); + +CREATE TABLE sub_part2(b int, c int8, a numeric); + +ALTER TABLE sub_parted ATTACH PARTITION sub_part2 for VALUES in (2); + +CREATE TABLE list_part1(a numeric, b int, c int8); + +ALTER TABLE list_parted ATTACH PARTITION list_part1 for VALUES in (2,3); + +INSERT into list_parted VALUES (2,5,50); + +INSERT into list_parted VALUES (3,6,60); + +INSERT into sub_parted VALUES (1,1,60); + +INSERT into sub_parted VALUES (1,2,10); + +UPDATE sub_parted set a = 2 WHERE c = 10; + +SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1; + +UPDATE list_parted set b = c + a WHERE a = 2; + +SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1; + +CREATE FUNCTION func_parted_mod_b() returns trigger as $$ +BEGIN + NEW.b = 2; -- This is changing partition key column. + return NEW; +END $$ LANGUAGE plpgsql; + +CREATE TRIGGER parted_mod_b before update on sub_part1 + for each row execute procedure func_parted_mod_b(); + +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; + +UPDATE list_parted set c = 70 WHERE b = 1; + +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; + +DROP TRIGGER parted_mod_b ON sub_part1; + +CREATE OR REPLACE FUNCTION func_parted_mod_b() returns trigger as $$ +BEGIN + raise notice 'Trigger: Got OLD row %, but returning NULL', OLD; + return NULL; +END $$ LANGUAGE plpgsql; + +CREATE TRIGGER trig_skip_delete before delete on sub_part2 + for each row execute procedure func_parted_mod_b(); + +UPDATE list_parted set b = 1 WHERE c = 70; + +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; + +DROP TRIGGER trig_skip_delete ON sub_part2; + +UPDATE list_parted set b = 1 WHERE c = 70; + +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; + +DROP FUNCTION func_parted_mod_b(); + +CREATE TABLE non_parted (id int); + +INSERT into non_parted VALUES (1), (1), (1), (2), (2), (2), (3), (3), (3); + +UPDATE list_parted t1 set a = 2 FROM non_parted t2 WHERE t1.a = t2.id and a = 1; + +SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; + +DROP TABLE non_parted; + +DROP TABLE list_parted; + +create or replace function dummy_hashint4(a int4, seed int8) returns int8 as +$$ begin return (a + seed); end; $$ language 'plpgsql' immutable; + +create operator class custom_opclass for type int4 using hash as +operator 1 = , function 2 dummy_hashint4(int4, int8); + +create table hash_parted ( + a int, + b int +) partition by hash (a custom_opclass, b custom_opclass); + +create table hpart1 partition of hash_parted for values with (modulus 2, remainder 1); + +create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2); + +create table hpart3 partition of hash_parted for values with (modulus 8, remainder 0); + +create table hpart4 partition of hash_parted for values with (modulus 8, remainder 4); + +insert into hpart1 values (1, 1); + +insert into hpart2 values (2, 5); + +insert into hpart4 values (3, 4); + +update hpart1 set a = 3, b=4 where a = 1; + +update hash_parted set b = b - 1 where b = 1; + +update hash_parted set b = b + 8 where b = 1; + +drop table hash_parted; + +drop operator class custom_opclass using hash; + +drop function dummy_hashint4(a int4, seed int8); diff --git a/crates/pgt_pretty_print/tests/data/multi/uuid_60.sql b/crates/pgt_pretty_print/tests/data/multi/uuid_60.sql new file mode 100644 index 000000000..be6714e37 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/uuid_60.sql @@ -0,0 +1,146 @@ +CREATE TABLE guid1 +( + guid_field UUID, + text_field TEXT DEFAULT(now()) +); + +CREATE TABLE guid2 +( + guid_field UUID, + text_field TEXT DEFAULT(now()) +); + +CREATE TABLE guid3 +( + id SERIAL, + guid_field UUID +); + +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111F'); + +INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-1111-11111111111}'); + +INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-1111-111111111111'); + +INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222 '); + +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G111-111111111111'); + +INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111'); + +SELECT pg_input_is_valid('11', 'uuid'); + +SELECT * FROM pg_input_error_info('11', 'uuid'); + +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111'); + +INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}'); + +INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e'); + +SELECT guid_field FROM guid1; + +SELECT guid_field FROM guid1 ORDER BY guid_field ASC; + +SELECT guid_field FROM guid1 ORDER BY guid_field DESC; + +SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e'; + +SELECT COUNT(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111'; + +SELECT COUNT(*) FROM guid1 WHERE guid_field < '22222222-2222-2222-2222-222222222222'; + +SELECT COUNT(*) FROM guid1 WHERE guid_field <= '22222222-2222-2222-2222-222222222222'; + +SELECT COUNT(*) FROM guid1 WHERE guid_field > '22222222-2222-2222-2222-222222222222'; + +SELECT COUNT(*) FROM guid1 WHERE guid_field >= '22222222-2222-2222-2222-222222222222'; + +CREATE INDEX guid1_btree ON guid1 USING BTREE (guid_field); + +CREATE INDEX guid1_hash ON guid1 USING HASH (guid_field); + +CREATE UNIQUE INDEX guid1_unique_BTREE ON guid1 USING BTREE (guid_field); + +SELECT COUNT(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111' OR + guid_field <> '3f3e3c3b-3a30-3938-3736-353433a2313e'; + +SELECT COUNT(*) FROM guid1 WHERE guid_field <= '22222222-2222-2222-2222-222222222222' OR + guid_field <= '11111111111111111111111111111111' OR + guid_field <= '3f3e3c3b-3a30-3938-3736-353433a2313e'; + +SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e' OR + guid_field = '11111111111111111111111111111111'; + +INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111'); + +SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%'; + +INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444'); + +INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111'); + +INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}'); + +INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e'); + +SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field; + +SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE g2.guid_field IS NULL; + +TRUNCATE guid1; + +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()); + +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()); + +SELECT count(DISTINCT guid_field) FROM guid1; + +TRUNCATE guid1; + +INSERT INTO guid1 (guid_field) VALUES (uuidv4()); + +INSERT INTO guid1 (guid_field) VALUES (uuidv4()); + +SELECT count(DISTINCT guid_field) FROM guid1; + +TRUNCATE guid1; + +INSERT INTO guid1 (guid_field) VALUES (uuidv7()); + +INSERT INTO guid1 (guid_field) VALUES (uuidv7()); + +INSERT INTO guid1 (guid_field) VALUES (uuidv7(INTERVAL '1 day')); + +SELECT count(DISTINCT guid_field) FROM guid1; + +INSERT INTO guid3 (guid_field) SELECT uuidv7() FROM generate_series(1, 10); + +SELECT array_agg(id ORDER BY guid_field) FROM guid3; + +WITH uuidts AS ( + SELECT y, ts as ts, lag(ts) OVER (ORDER BY y) AS prev_ts + FROM (SELECT y, uuid_extract_timestamp(uuidv7((y || ' years')::interval)) AS ts + FROM generate_series(1970 - extract(year from now())::int, 10888 - extract(year from now())::int) y) +) +SELECT y, ts, prev_ts FROM uuidts WHERE ts < prev_ts; + +SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111'); + +SELECT uuid_extract_version(gen_random_uuid()); + +SELECT uuid_extract_version('11111111-1111-1111-1111-111111111111'); + +SELECT uuid_extract_version(uuidv4()); + +SELECT uuid_extract_version(uuidv7()); + +SELECT uuid_extract_timestamp('C232AB00-9414-11EC-B3C8-9F6BDECED846') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; + +SELECT uuid_extract_timestamp('017F22E2-79B0-7CC3-98C4-DC0C0C07398F') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; + +SELECT uuid_extract_timestamp(gen_random_uuid()); + +SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111'); + +DROP TABLE guid1, guid2, guid3 CASCADE; diff --git a/crates/pgt_pretty_print/tests/data/multi/vacuum_60.sql b/crates/pgt_pretty_print/tests/data/multi/vacuum_60.sql new file mode 100644 index 000000000..9fc5c43d1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/vacuum_60.sql @@ -0,0 +1,717 @@ +CREATE TABLE vactst (i INT); + +INSERT INTO vactst VALUES (1); + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst VALUES (0); + +SELECT count(*) FROM vactst; + +DELETE FROM vactst WHERE i != 0; + +SELECT * FROM vactst; + +VACUUM FULL vactst; + +UPDATE vactst SET i = i + 1; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst SELECT * FROM vactst; + +INSERT INTO vactst VALUES (0); + +SELECT count(*) FROM vactst; + +DELETE FROM vactst WHERE i != 0; + +VACUUM (FULL) vactst; + +DELETE FROM vactst; + +SELECT * FROM vactst; + +VACUUM (FULL, FREEZE) vactst; + +VACUUM (ANALYZE, FULL) vactst; + +CREATE TABLE vaccluster (i INT PRIMARY KEY); + +ALTER TABLE vaccluster CLUSTER ON vaccluster_pkey; + +CLUSTER vaccluster; + +CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL + AS 'ANALYZE pg_am'; + +CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL + AS 'SELECT $1 FROM public.do_analyze()'; + +CREATE INDEX ON vaccluster(wrap_do_analyze(i)); + +INSERT INTO vaccluster VALUES (1), (2); + +ANALYZE vaccluster; + +INSERT INTO vactst SELECT generate_series(1, 300); + +DELETE FROM vactst WHERE i % 7 = 0; + +BEGIN; + +INSERT INTO vactst SELECT generate_series(301, 400); + +DELETE FROM vactst WHERE i % 5 <> 0; + +ANALYZE vactst; + +COMMIT; + +BEGIN; + +CREATE TABLE past_inh_parent (); + +CREATE TABLE past_inh_child () INHERITS (past_inh_parent); + +INSERT INTO past_inh_child DEFAULT VALUES; + +INSERT INTO past_inh_child DEFAULT VALUES; + +ANALYZE past_inh_parent; + +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_parent'::regclass; + +DROP TABLE past_inh_child; + +ANALYZE past_inh_parent; + +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_inh_parent'::regclass; + +COMMIT; + +BEGIN; + +CREATE TABLE past_parted (i int) PARTITION BY LIST(i); + +CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1); + +INSERT INTO past_parted VALUES (1),(1); + +ANALYZE past_parted; + +DROP TABLE past_part; + +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_parted'::regclass; + +ANALYZE past_parted; + +SELECT reltuples, relhassubclass + FROM pg_class WHERE oid = 'past_parted'::regclass; + +COMMIT; + +VACUUM FULL pg_am; + +VACUUM FULL pg_class; + +VACUUM FULL pg_database; + +VACUUM FULL vaccluster; + +VACUUM FULL vactst; + +VACUUM (DISABLE_PAGE_SKIPPING) vaccluster; + +CREATE TABLE pvactst (i INT, a INT[], p POINT) with (autovacuum_enabled = off); + +INSERT INTO pvactst SELECT i, array[1,2,3], point(i, i+1) FROM generate_series(1,1000) i; + +CREATE INDEX btree_pvactst ON pvactst USING btree (i); + +CREATE INDEX hash_pvactst ON pvactst USING hash (i); + +CREATE INDEX brin_pvactst ON pvactst USING brin (i); + +CREATE INDEX gin_pvactst ON pvactst USING gin (a); + +CREATE INDEX gist_pvactst ON pvactst USING gist (p); + +CREATE INDEX spgist_pvactst ON pvactst USING spgist (p); + +CREATE TABLE pvactst2 (i INT) WITH (autovacuum_enabled = off); + +INSERT INTO pvactst2 SELECT generate_series(1, 1000); + +CREATE INDEX ON pvactst2 (i); + +CREATE INDEX ON pvactst2 (i); + +SET min_parallel_index_scan_size to 0; + +VACUUM (PARALLEL 2) pvactst; + +UPDATE pvactst SET i = i WHERE i < 1000; + +VACUUM (PARALLEL 2) pvactst; + +UPDATE pvactst SET i = i WHERE i < 1000; + +VACUUM (PARALLEL 0) pvactst; + +VACUUM (PARALLEL -1) pvactst; + +VACUUM (PARALLEL 2, INDEX_CLEANUP FALSE) pvactst; + +VACUUM (PARALLEL 2, FULL TRUE) pvactst; + +VACUUM (PARALLEL) pvactst; + +SET maintenance_work_mem TO 64; + +VACUUM (PARALLEL 2) pvactst2; + +DELETE FROM pvactst2 WHERE i < 1000; + +VACUUM (PARALLEL 2) pvactst2; + +RESET maintenance_work_mem; + +CREATE TEMPORARY TABLE tmp (a int PRIMARY KEY); + +CREATE INDEX tmp_idx1 ON tmp (a); + +VACUUM (PARALLEL 1, FULL FALSE) tmp; + +VACUUM (PARALLEL 0, FULL TRUE) tmp; + +RESET min_parallel_index_scan_size; + +DROP TABLE pvactst; + +DROP TABLE pvactst2; + +CREATE TABLE no_index_cleanup (i INT PRIMARY KEY, t TEXT); + +CREATE INDEX no_index_cleanup_idx ON no_index_cleanup(t); + +ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE EXTERNAL; + +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(1,30), + repeat('1234567890',269)); + +VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup; + +VACUUM (FULL TRUE) no_index_cleanup; + +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false); + +DELETE FROM no_index_cleanup WHERE i < 15; + +VACUUM no_index_cleanup; + +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true); + +VACUUM no_index_cleanup; + +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = auto); + +VACUUM no_index_cleanup; + +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), + repeat('1234567890',269)); + +DELETE FROM no_index_cleanup WHERE i < 45; + +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = off, + toast.vacuum_index_cleanup = yes); + +VACUUM no_index_cleanup; + +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, + toast.vacuum_index_cleanup = false); + +VACUUM no_index_cleanup; + +VACUUM (INDEX_CLEANUP FALSE) vaccluster; + +VACUUM (INDEX_CLEANUP AUTO) vactst; + +VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster; + +CREATE TEMP TABLE vac_truncate_test(i INT NOT NULL, j text) + WITH (vacuum_truncate=true, autovacuum_enabled=false); + +INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL); + +VACUUM (TRUNCATE FALSE, DISABLE_PAGE_SKIPPING) vac_truncate_test; + +SELECT pg_relation_size('vac_truncate_test') > 0; + +SET vacuum_truncate = false; + +VACUUM (DISABLE_PAGE_SKIPPING) vac_truncate_test; + +SELECT pg_relation_size('vac_truncate_test') = 0; + +VACUUM (TRUNCATE FALSE, FULL TRUE) vac_truncate_test; + +ALTER TABLE vac_truncate_test RESET (vacuum_truncate); + +INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL); + +VACUUM (DISABLE_PAGE_SKIPPING) vac_truncate_test; + +SELECT pg_relation_size('vac_truncate_test') > 0; + +RESET vacuum_truncate; + +VACUUM (TRUNCATE FALSE, DISABLE_PAGE_SKIPPING) vac_truncate_test; + +SELECT pg_relation_size('vac_truncate_test') > 0; + +VACUUM (DISABLE_PAGE_SKIPPING) vac_truncate_test; + +SELECT pg_relation_size('vac_truncate_test') = 0; + +DROP TABLE vac_truncate_test; + +CREATE TABLE vacparted (a int, b char) PARTITION BY LIST (a); + +CREATE TABLE vacparted1 PARTITION OF vacparted FOR VALUES IN (1); + +INSERT INTO vacparted VALUES (1, 'a'); + +UPDATE vacparted SET b = 'b'; + +VACUUM (ANALYZE) vacparted; + +VACUUM (FULL) vacparted; + +VACUUM (FREEZE) vacparted; + +VACUUM ANALYZE vacparted(a,b,a); + +ANALYZE vacparted(a,b,b); + +CREATE TABLE vacparted_i (a int primary key, b varchar(100)) + PARTITION BY HASH (a); + +CREATE TABLE vacparted_i1 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 0); + +CREATE TABLE vacparted_i2 PARTITION OF vacparted_i + FOR VALUES WITH (MODULUS 2, REMAINDER 1); + +INSERT INTO vacparted_i SELECT i, 'test_'|| i from generate_series(1,10) i; + +VACUUM (ANALYZE) vacparted_i; + +VACUUM (FULL) vacparted_i; + +VACUUM (FREEZE) vacparted_i; + +SELECT relname, relhasindex FROM pg_class + WHERE relname LIKE 'vacparted_i%' AND relkind IN ('p','r') + ORDER BY relname; + +DROP TABLE vacparted_i; + +VACUUM vaccluster, vactst; + +VACUUM vacparted, does_not_exist; + +VACUUM (FREEZE) vacparted, vaccluster, vactst; + +VACUUM (FREEZE) does_not_exist, vaccluster; + +VACUUM ANALYZE vactst, vacparted (a); + +VACUUM ANALYZE vactst (does_not_exist), vacparted (b); + +VACUUM FULL vacparted, vactst; + +VACUUM FULL vactst, vacparted (a, b), vaccluster (i); + +ANALYZE vactst, vacparted; + +ANALYZE vacparted (b), vactst; + +ANALYZE vactst, does_not_exist, vacparted; + +ANALYZE vactst (i), vacparted (does_not_exist); + +ANALYZE vactst, vactst; + +BEGIN; + +ANALYZE vactst, vactst; + +COMMIT; + +CREATE TABLE only_parted (a int, b text) PARTITION BY LIST (a); + +CREATE TABLE only_parted1 PARTITION OF only_parted FOR VALUES IN (1); + +INSERT INTO only_parted VALUES (1, 'a'); + +SELECT relname, last_analyze IS NOT NULL AS analyzed, last_vacuum IS NOT NULL AS vacuumed + FROM pg_stat_user_tables + WHERE relid IN ('only_parted'::regclass, 'only_parted1'::regclass) + ORDER BY relname; + +ANALYZE only_parted; + +SELECT relname, last_analyze IS NOT NULL AS analyzed, last_vacuum IS NOT NULL AS vacuumed + FROM pg_stat_user_tables + WHERE relid IN ('only_parted'::regclass, 'only_parted1'::regclass) + ORDER BY relname; + +DROP TABLE only_parted; + +CREATE TABLE only_inh_parent (a int primary key, b TEXT); + +CREATE TABLE only_inh_child () INHERITS (only_inh_parent); + +INSERT INTO only_inh_child(a,b) VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); + +SELECT relname, last_analyze IS NOT NULL AS analyzed, last_vacuum IS NOT NULL AS vacuumed + FROM pg_stat_user_tables + WHERE relid IN ('only_inh_parent'::regclass, 'only_inh_child'::regclass) + ORDER BY relname; + +ANALYZE only_inh_parent; + +SELECT relname, last_analyze IS NOT NULL AS analyzed, last_vacuum IS NOT NULL AS vacuumed + FROM pg_stat_user_tables + WHERE relid IN ('only_inh_parent'::regclass, 'only_inh_child'::regclass) + ORDER BY relname; + +SELECT relname, last_analyze IS NOT NULL AS analyzed, last_vacuum IS NOT NULL AS vacuumed + FROM pg_stat_user_tables + WHERE relid IN ('only_inh_parent'::regclass, 'only_inh_child'::regclass) + ORDER BY relname; + +VACUUM only_inh_parent; + +SELECT relname, last_analyze IS NOT NULL AS analyzed, last_vacuum IS NOT NULL AS vacuumed + FROM pg_stat_user_tables + WHERE relid IN ('only_inh_parent'::regclass, 'only_inh_child'::regclass) + ORDER BY relname; + +DROP TABLE only_inh_parent CASCADE; + +ANALYZE (VERBOSE) does_not_exist; + +ANALYZE (nonexistentarg) does_not_exit; + +SET client_min_messages TO 'ERROR'; + +ANALYZE (SKIP_LOCKED, VERBOSE) does_not_exist; + +ANALYZE (VERBOSE, SKIP_LOCKED) does_not_exist; + +VACUUM (SKIP_LOCKED) vactst; + +VACUUM (SKIP_LOCKED, FULL) vactst; + +ANALYZE (SKIP_LOCKED) vactst; + +RESET client_min_messages; + +SET default_transaction_isolation = serializable; + +VACUUM vactst; + +ANALYZE vactst; + +RESET default_transaction_isolation; + +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +ANALYZE vactst; + +COMMIT; + +CREATE TABLE vac_option_tab (a INT, t TEXT); + +INSERT INTO vac_option_tab SELECT a, 't' || a FROM generate_series(1, 10) AS a; + +ALTER TABLE vac_option_tab ALTER COLUMN t SET STORAGE EXTERNAL; + +CREATE VIEW vac_option_tab_counts AS + SELECT CASE WHEN c.relname IS NULL + THEN 'main' ELSE 'toast' END as rel, + s.vacuum_count + FROM pg_stat_all_tables s + LEFT JOIN pg_class c ON s.relid = c.reltoastrelid + WHERE c.relname = 'vac_option_tab' OR s.relname = 'vac_option_tab' + ORDER BY rel; + +VACUUM (PROCESS_TOAST TRUE) vac_option_tab; + +SELECT * FROM vac_option_tab_counts; + +VACUUM (PROCESS_TOAST FALSE) vac_option_tab; + +SELECT * FROM vac_option_tab_counts; + +VACUUM (PROCESS_TOAST FALSE, FULL) vac_option_tab; + +VACUUM (PROCESS_MAIN FALSE) vac_option_tab; + +SELECT * FROM vac_option_tab_counts; + +VACUUM (PROCESS_MAIN FALSE, PROCESS_TOAST FALSE) vac_option_tab; + +SELECT * FROM vac_option_tab_counts; + +SELECT relfilenode AS main_filenode FROM pg_class + WHERE relname = 'vac_option_tab' ; + +SELECT t.relfilenode AS toast_filenode FROM pg_class c, pg_class t + WHERE c.reltoastrelid = t.oid AND c.relname = 'vac_option_tab' ; + +VACUUM (PROCESS_MAIN FALSE, FULL) vac_option_tab; + +SELECT relfilenode = 'main_filenode' AS is_same_main_filenode + FROM pg_class WHERE relname = 'vac_option_tab'; + +SELECT t.relfilenode = 'toast_filenode' AS is_same_toast_filenode + FROM pg_class c, pg_class t + WHERE c.reltoastrelid = t.oid AND c.relname = 'vac_option_tab'; + +VACUUM (BUFFER_USAGE_LIMIT '512 kB') vac_option_tab; + +ANALYZE (BUFFER_USAGE_LIMIT '512 kB') vac_option_tab; + +VACUUM (BUFFER_USAGE_LIMIT 0) vac_option_tab; + +ANALYZE (BUFFER_USAGE_LIMIT 0) vac_option_tab; + +VACUUM (BUFFER_USAGE_LIMIT 16777220) vac_option_tab; + +VACUUM (BUFFER_USAGE_LIMIT 120) vac_option_tab; + +VACUUM (BUFFER_USAGE_LIMIT 10000000000) vac_option_tab; + +VACUUM (BUFFER_USAGE_LIMIT '512 kB', FULL) vac_option_tab; + +VACUUM (SKIP_DATABASE_STATS) vactst; + +VACUUM (ONLY_DATABASE_STATS); + +VACUUM (ONLY_DATABASE_STATS) vactst; + +DROP VIEW vac_option_tab_counts; + +DROP TABLE vac_option_tab; + +DROP TABLE vaccluster; + +DROP TABLE vactst; + +DROP TABLE vacparted; + +DROP TABLE no_index_cleanup; + +CREATE TABLE vacowned (a int); + +CREATE TABLE vacowned_parted (a int) PARTITION BY LIST (a); + +CREATE TABLE vacowned_part1 PARTITION OF vacowned_parted FOR VALUES IN (1); + +CREATE TABLE vacowned_part2 PARTITION OF vacowned_parted FOR VALUES IN (2); + +CREATE ROLE regress_vacuum; + +SET ROLE regress_vacuum; + +VACUUM vacowned; + +ANALYZE vacowned; + +VACUUM (ANALYZE) vacowned; + +VACUUM pg_catalog.pg_class; + +ANALYZE pg_catalog.pg_class; + +VACUUM (ANALYZE) pg_catalog.pg_class; + +VACUUM pg_catalog.pg_authid; + +ANALYZE pg_catalog.pg_authid; + +VACUUM (ANALYZE) pg_catalog.pg_authid; + +VACUUM vacowned_parted; + +VACUUM vacowned_part1; + +VACUUM vacowned_part2; + +ANALYZE vacowned_parted; + +ANALYZE vacowned_part1; + +ANALYZE vacowned_part2; + +VACUUM (ANALYZE) vacowned_parted; + +VACUUM (ANALYZE) vacowned_part1; + +VACUUM (ANALYZE) vacowned_part2; + +RESET ROLE; + +ALTER TABLE vacowned_parted OWNER TO regress_vacuum; + +ALTER TABLE vacowned_part1 OWNER TO regress_vacuum; + +SET ROLE regress_vacuum; + +VACUUM vacowned_parted; + +VACUUM vacowned_part1; + +VACUUM vacowned_part2; + +ANALYZE vacowned_parted; + +ANALYZE vacowned_part1; + +ANALYZE vacowned_part2; + +VACUUM (ANALYZE) vacowned_parted; + +VACUUM (ANALYZE) vacowned_part1; + +VACUUM (ANALYZE) vacowned_part2; + +RESET ROLE; + +ALTER TABLE vacowned_parted OWNER TO CURRENT_USER; + +SET ROLE regress_vacuum; + +VACUUM vacowned_parted; + +VACUUM vacowned_part1; + +VACUUM vacowned_part2; + +ANALYZE vacowned_parted; + +ANALYZE vacowned_part1; + +ANALYZE vacowned_part2; + +VACUUM (ANALYZE) vacowned_parted; + +VACUUM (ANALYZE) vacowned_part1; + +VACUUM (ANALYZE) vacowned_part2; + +RESET ROLE; + +ALTER TABLE vacowned_parted OWNER TO regress_vacuum; + +ALTER TABLE vacowned_part1 OWNER TO CURRENT_USER; + +SET ROLE regress_vacuum; + +VACUUM vacowned_parted; + +VACUUM vacowned_part1; + +VACUUM vacowned_part2; + +ANALYZE vacowned_parted; + +ANALYZE vacowned_part1; + +ANALYZE vacowned_part2; + +VACUUM (ANALYZE) vacowned_parted; + +VACUUM (ANALYZE) vacowned_part1; + +VACUUM (ANALYZE) vacowned_part2; + +RESET ROLE; + +DROP TABLE vacowned; + +DROP TABLE vacowned_parted; + +DROP ROLE regress_vacuum; + +CREATE TABLE vac_rewrite_toast (id int, f1 TEXT STORAGE plain); + +INSERT INTO vac_rewrite_toast values (1, repeat('a', 7000)); + +ALTER TABLE vac_rewrite_toast ALTER COLUMN f1 SET STORAGE EXTERNAL; + +INSERT INTO vac_rewrite_toast values (2, repeat('a', 7000)); + +SELECT pg_column_toast_chunk_id(f1) AS id_2_chunk FROM vac_rewrite_toast + WHERE id = 2 ; + +SELECT id, pg_column_toast_chunk_id(f1) IS NULL AS f1_chunk_null, + substr(f1, 5, 10) AS f1_data, + pg_column_compression(f1) AS f1_comp + FROM vac_rewrite_toast ORDER BY id; + +VACUUM FULL vac_rewrite_toast; + +SELECT id, pg_column_toast_chunk_id(f1) IS NULL AS f1_chunk_null, + substr(f1, 5, 10) AS f1_data, + pg_column_compression(f1) AS f1_comp + FROM vac_rewrite_toast ORDER BY id; + +SELECT pg_column_toast_chunk_id(f1) = 'id_2_chunk' AS same_chunk + FROM vac_rewrite_toast WHERE id = 2; + +DROP TABLE vac_rewrite_toast; diff --git a/crates/pgt_pretty_print/tests/data/multi/vacuum_parallel_60.sql b/crates/pgt_pretty_print/tests/data/multi/vacuum_parallel_60.sql new file mode 100644 index 000000000..52cc9f2e1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/vacuum_parallel_60.sql @@ -0,0 +1,37 @@ +SET max_parallel_maintenance_workers TO 4; + +SET min_parallel_index_scan_size TO '128kB'; + +CREATE TABLE parallel_vacuum_table (a int) WITH (autovacuum_enabled = off); + +INSERT INTO parallel_vacuum_table SELECT i from generate_series(1, 10000) i; + +CREATE INDEX regular_sized_index ON parallel_vacuum_table(a); + +CREATE INDEX typically_sized_index ON parallel_vacuum_table(a); + +CREATE INDEX vacuum_in_leader_small_index ON parallel_vacuum_table((1)); + +SELECT EXISTS ( +SELECT 1 +FROM pg_class +WHERE oid = 'vacuum_in_leader_small_index'::regclass AND + pg_relation_size(oid) < + pg_size_bytes(current_setting('min_parallel_index_scan_size')) +) as leader_will_handle_small_index; + +SELECT count(*) as trigger_parallel_vacuum_nindexes +FROM pg_class +WHERE oid in ('regular_sized_index'::regclass, 'typically_sized_index'::regclass) AND + pg_relation_size(oid) >= + pg_size_bytes(current_setting('min_parallel_index_scan_size')); + +DELETE FROM parallel_vacuum_table; + +VACUUM (PARALLEL 4, INDEX_CLEANUP ON) parallel_vacuum_table; + +INSERT INTO parallel_vacuum_table SELECT i FROM generate_series(1, 10000) i; + +RESET max_parallel_maintenance_workers; + +RESET min_parallel_index_scan_size; diff --git a/crates/pgt_pretty_print/tests/data/multi/varchar_60.sql b/crates/pgt_pretty_print/tests/data/multi/varchar_60.sql new file mode 100644 index 000000000..6e344563c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/varchar_60.sql @@ -0,0 +1,55 @@ +CREATE TEMP TABLE VARCHAR_TBL(f1 varchar(1)); + +INSERT INTO VARCHAR_TBL (f1) VALUES ('a'); + +INSERT INTO VARCHAR_TBL (f1) VALUES ('A'); + +INSERT INTO VARCHAR_TBL (f1) VALUES ('1'); + +INSERT INTO VARCHAR_TBL (f1) VALUES (2); + +INSERT INTO VARCHAR_TBL (f1) VALUES ('3'); + +INSERT INTO VARCHAR_TBL (f1) VALUES (''); + +INSERT INTO VARCHAR_TBL (f1) VALUES ('cd'); + +INSERT INTO VARCHAR_TBL (f1) VALUES ('c '); + +SELECT * FROM VARCHAR_TBL; + +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 <> 'a'; + +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 = 'a'; + +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 < 'a'; + +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 <= 'a'; + +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 > 'a'; + +SELECT c.* + FROM VARCHAR_TBL c + WHERE c.f1 >= 'a'; + +DROP TABLE VARCHAR_TBL; + +INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde'); + +SELECT * FROM VARCHAR_TBL; + +SELECT pg_input_is_valid('abcd ', 'varchar(4)'); + +SELECT pg_input_is_valid('abcde', 'varchar(4)'); + +SELECT * FROM pg_input_error_info('abcde', 'varchar(4)'); diff --git a/crates/pgt_pretty_print/tests/data/multi/window_60.sql b/crates/pgt_pretty_print/tests/data/multi/window_60.sql new file mode 100644 index 000000000..e516ce969 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/window_60.sql @@ -0,0 +1,1788 @@ +CREATE TEMPORARY TABLE empsalary ( + depname varchar, + empno bigint, + salary int, + enroll_date date +); + +INSERT INTO empsalary VALUES +('develop', 10, 5200, '2007-08-01'), +('sales', 1, 5000, '2006-10-01'), +('personnel', 5, 3500, '2007-12-10'), +('sales', 4, 4800, '2007-08-08'), +('personnel', 2, 3900, '2006-12-23'), +('develop', 7, 4200, '2008-01-01'), +('develop', 9, 4500, '2008-01-01'), +('sales', 3, 4800, '2007-08-01'), +('develop', 8, 6000, '2006-10-01'), +('develop', 11, 5200, '2007-08-15'); + +SELECT depname, empno, salary, sum(salary) OVER (PARTITION BY depname) FROM empsalary ORDER BY depname, salary; + +SELECT depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary) FROM empsalary; + +SELECT four, ten, SUM(SUM(four)) OVER (PARTITION BY four), AVG(ten) FROM tenk1 +GROUP BY four, ten ORDER BY four, ten; + +SELECT depname, empno, salary, sum(salary) OVER w FROM empsalary WINDOW w AS (PARTITION BY depname); + +SELECT depname, empno, salary, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary) ORDER BY rank() OVER w; + +SELECT COUNT(*) OVER () FROM tenk1 WHERE unique2 < 10; + +SELECT COUNT(*) OVER w FROM tenk1 WHERE unique2 < 10 WINDOW w AS (); + +SELECT four FROM tenk1 WHERE FALSE WINDOW w AS (PARTITION BY ten); + +SELECT sum(four) OVER (PARTITION BY ten ORDER BY unique2) AS sum_1, ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT row_number() OVER (ORDER BY unique2) FROM tenk1 WHERE unique2 < 10; + +SELECT rank() OVER (PARTITION BY four ORDER BY ten) AS rank_1, ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT ntile(NULL) OVER (ORDER BY ten, four), ten, four FROM tenk1 LIMIT 2; + +SELECT lag(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT lag(ten, four) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT lag(ten, four, 0) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT lag(ten, four, 0.7) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten; + +SELECT lead(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT lead(ten * 2, 1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT lead(ten * 2, 1, -1) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT lead(ten * 2, 1, -1.4) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten; + +SELECT first_value(ten) OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT last_value(four) OVER (ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; + +SELECT last_value(ten) OVER (PARTITION BY four), ten, four FROM + (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s + ORDER BY four, ten; + +SELECT nth_value(ten, four + 1) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten)s; + +SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER (PARTITION BY two ORDER BY ten) AS wsum +FROM tenk1 GROUP BY ten, two; + +SELECT count(*) OVER (PARTITION BY four), four FROM (SELECT * FROM tenk1 WHERE two = 1)s WHERE unique2 < 10; + +SELECT (count(*) OVER (PARTITION BY four ORDER BY ten) + + sum(hundred) OVER (PARTITION BY four ORDER BY ten))::varchar AS cntsum + FROM tenk1 WHERE unique2 < 10; + +SELECT * FROM( + SELECT count(*) OVER (PARTITION BY four ORDER BY ten) + + sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS total, + count(*) OVER (PARTITION BY four ORDER BY ten) AS fourcount, + sum(hundred) OVER (PARTITION BY two ORDER BY ten) AS twosum + FROM tenk1 +)sub +WHERE total <> fourcount + twosum; + +SELECT avg(four) OVER (PARTITION BY four ORDER BY thousand / 100) FROM tenk1 WHERE unique2 < 10; + +SELECT ten, two, sum(hundred) AS gsum, sum(sum(hundred)) OVER win AS wsum +FROM tenk1 GROUP BY ten, two WINDOW win AS (PARTITION BY two ORDER BY ten); + +SELECT sum(salary), + row_number() OVER (ORDER BY depname), + sum(sum(salary)) OVER (ORDER BY depname DESC) +FROM empsalary GROUP BY depname; + +SELECT sum(salary) OVER w1, count(*) OVER w2 +FROM empsalary WINDOW w1 AS (ORDER BY salary), w2 AS (ORDER BY salary); + +SELECT lead(ten, (SELECT two FROM tenk1 WHERE s.unique2 = unique2)) OVER (PARTITION BY four ORDER BY ten) +FROM tenk1 s WHERE unique2 < 10; + +SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 WHERE FALSE)s; + +SELECT sum(salary) OVER w, rank() OVER w FROM empsalary WINDOW w AS (PARTITION BY depname ORDER BY salary DESC); + +SELECT empno, depname, salary, bonus, depadj, MIN(bonus) OVER (ORDER BY empno), MAX(depadj) OVER () FROM( + SELECT *, + CASE WHEN enroll_date < '2008-01-01' THEN 2008 - extract(YEAR FROM enroll_date) END * 500 AS bonus, + CASE WHEN + AVG(salary) OVER (PARTITION BY depname) < salary + THEN 200 END AS depadj FROM empsalary +)s; + +SELECT SUM(COUNT(f1)) OVER () FROM int4_tbl WHERE f1=42; + +select ten, + sum(unique1) + sum(unique2) as res, + rank() over (order by sum(unique1) + sum(unique2)) as rank +from tenk1 +group by ten order by ten; + +select first_value(max(x)) over (), y + from (select unique1 as x, ten+four as y from tenk1) ss + group by y; + +select x, lag(x, 1) over (order by x), lead(x, 3) over (order by x) +from (select x::numeric as x from generate_series(1,10) x); + +SELECT four, ten, + sum(ten) over (partition by four order by ten), + last_value(ten) over (partition by four order by ten) +FROM (select distinct ten, four from tenk1) ss; + +SELECT four, ten, + sum(ten) over (partition by four order by ten range between unbounded preceding and current row), + last_value(ten) over (partition by four order by ten range between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss; + +SELECT four, ten, + sum(ten) over (partition by four order by ten range between unbounded preceding and unbounded following), + last_value(ten) over (partition by four order by ten range between unbounded preceding and unbounded following) +FROM (select distinct ten, four from tenk1) ss; + +SELECT four, ten/4 as two, + sum(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row), + last_value(ten/4) over (partition by four order by ten/4 range between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss; + +SELECT four, ten/4 as two, + sum(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row), + last_value(ten/4) over (partition by four order by ten/4 rows between unbounded preceding and current row) +FROM (select distinct ten, four from tenk1) ss; + +SELECT sum(unique1) over (order by four range between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between 2 preceding and 2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude no others), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between 2 preceding and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT first_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT last_value(unique1) over (ORDER BY four rows between current row and 2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between 2 preceding and 1 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between 1 following and 3 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between unbounded preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (w range between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four); + +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four); + +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four); + +SELECT sum(unique1) over (w range between unbounded preceding and current row exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10 WINDOW w AS (order by four); + +SELECT first_value(unique1) over w, + nth_value(unique1, 2) over w AS nth_2, + last_value(unique1) over w, unique1, four +FROM tenk1 WHERE unique1 < 10 +WINDOW w AS (order by four range between current row and unbounded following); + +SELECT sum(unique1) over + (order by unique1 + rows (SELECT unique1 FROM tenk1 ORDER BY unique1 LIMIT 1) + 1 PRECEDING), + unique1 +FROM tenk1 WHERE unique1 < 10; + +CREATE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following) as sum_rows + FROM generate_series(1, 10) i; + +SELECT * FROM v_window; + +SELECT pg_get_viewdef('v_window'); + +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude current row) as sum_rows FROM generate_series(1, 10) i; + +SELECT * FROM v_window; + +SELECT pg_get_viewdef('v_window'); + +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude group) as sum_rows FROM generate_series(1, 10) i; + +SELECT * FROM v_window; + +SELECT pg_get_viewdef('v_window'); + +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude ties) as sum_rows FROM generate_series(1, 10) i; + +SELECT * FROM v_window; + +SELECT pg_get_viewdef('v_window'); + +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i rows between 1 preceding and 1 following + exclude no others) as sum_rows FROM generate_series(1, 10) i; + +SELECT * FROM v_window; + +SELECT pg_get_viewdef('v_window'); + +CREATE OR REPLACE TEMP VIEW v_window AS + SELECT i, sum(i) over (order by i groups between 1 preceding and 1 following) as sum_rows FROM generate_series(1, 10) i; + +SELECT * FROM v_window; + +SELECT pg_get_viewdef('v_window'); + +DROP VIEW v_window; + +CREATE TEMP VIEW v_window AS + SELECT i, min(i) over (order by i range between '1 day' preceding and '10 days' following) as min_i + FROM generate_series(now(), now()+'100 days'::interval, '1 hour') i; + +SELECT pg_get_viewdef('v_window'); + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four desc range between 2::int8 preceding and 1::int2 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude no others), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude current row), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 1::int2 preceding exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude ties), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four range between 2::int8 preceding and 6::int2 following exclude group), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (partition by four order by unique1 range between 5::int8 preceding and 6::int2 following + exclude current row),unique1, four +FROM tenk1 WHERE unique1 < 10; + +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following), + salary, enroll_date from empsalary; + +select sum(salary) over (order by enroll_date desc range between '1 year'::interval preceding and '1 year'::interval following), + salary, enroll_date from empsalary; + +select sum(salary) over (order by enroll_date desc range between '1 year'::interval following and '1 year'::interval following), + salary, enroll_date from empsalary; + +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude current row), salary, enroll_date from empsalary; + +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude group), salary, enroll_date from empsalary; + +select sum(salary) over (order by enroll_date range between '1 year'::interval preceding and '1 year'::interval following + exclude ties), salary, enroll_date from empsalary; + +select first_value(salary) over(order by salary range between 1000 preceding and 1000 following), + lead(salary) over(order by salary range between 1000 preceding and 1000 following), + nth_value(salary, 1) over(order by salary range between 1000 preceding and 1000 following), + salary from empsalary; + +select last_value(salary) over(order by salary range between 1000 preceding and 1000 following), + lag(salary) over(order by salary range between 1000 preceding and 1000 following), + salary from empsalary; + +select first_value(salary) over(order by salary range between 1000 following and 3000 following + exclude current row), + lead(salary) over(order by salary range between 1000 following and 3000 following exclude ties), + nth_value(salary, 1) over(order by salary range between 1000 following and 3000 following + exclude ties), + salary from empsalary; + +select last_value(salary) over(order by salary range between 1000 following and 3000 following + exclude group), + lag(salary) over(order by salary range between 1000 following and 3000 following exclude group), + salary from empsalary; + +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following), + salary, enroll_date from empsalary; + +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude ties), + salary, enroll_date from empsalary; + +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude group), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude group), + salary, enroll_date from empsalary; + +select first_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude current row), + last_value(salary) over(order by enroll_date range between unbounded preceding and '1 year'::interval following + exclude current row), + salary, enroll_date from empsalary; + +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x asc nulls first range between 2 preceding and 2 following); + +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x asc nulls last range between 2 preceding and 2 following); + +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x desc nulls first range between 2 preceding and 2 following); + +select x, y, + first_value(y) over w, + last_value(y) over w +from + (select x, x as y from generate_series(1,5) as x + union all select null, 42 + union all select null, 43) ss +window w as + (order by x desc nulls last range between 2 preceding and 2 following); + +SELECT sum(unique1) over (rows between x preceding and x following), + unique1, four + FROM tenk1 WHERE unique1 < 10; + +END; + +CREATE FUNCTION unbounded_syntax_test1b(x int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +AS $$ + SELECT sum(unique1) over (rows between x preceding and x following), + unique1, four + FROM tenk1 WHERE unique1 < 10; +$$; + +SELECT * FROM unbounded_syntax_test1a(2); + +SELECT * FROM unbounded_syntax_test1b(2); + +SELECT sum(unique1) over (rows between unbounded preceding and unbounded following), + unique1, four + FROM tenk1 WHERE unique1 < 10; + +END; + +CREATE FUNCTION unbounded_syntax_test2b(unbounded int) RETURNS TABLE (a int, b int, c int) +LANGUAGE SQL +AS $$ + SELECT sum(unique1) over (rows between unbounded preceding and unbounded following), + unique1, four + FROM tenk1 WHERE unique1 < 10; +$$; + +SELECT * FROM unbounded_syntax_test2a(2); + +SELECT * FROM unbounded_syntax_test2b(2); + +DROP FUNCTION unbounded_syntax_test1a, unbounded_syntax_test1b, + unbounded_syntax_test2a, unbounded_syntax_test2b; + +CREATE FUNCTION unbounded(x int) RETURNS int LANGUAGE SQL IMMUTABLE RETURN x; + +SELECT sum(unique1) over (rows between 1 preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between unbounded(1) preceding and unbounded(1) following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (rows between unbounded.x preceding and unbounded.x following), + unique1, four +FROM tenk1, (values (1)) as unbounded(x) WHERE unique1 < 10; + +DROP FUNCTION unbounded; + +select x, last_value(x) over (order by x::smallint range between current row and 2147450884 following) +from generate_series(32764, 32766) x; + +select x, last_value(x) over (order by x::smallint desc range between current row and 2147450885 following) +from generate_series(-32766, -32764) x; + +select x, last_value(x) over (order by x range between current row and 4 following) +from generate_series(2147483644, 2147483646) x; + +select x, last_value(x) over (order by x desc range between current row and 5 following) +from generate_series(-2147483646, -2147483644) x; + +select x, last_value(x) over (order by x range between current row and 4 following) +from generate_series(9223372036854775804, 9223372036854775806) x; + +select x, last_value(x) over (order by x desc range between current row and 5 following) +from generate_series(-9223372036854775806, -9223372036854775804) x; + +create temp table numerics( + id int, + f_float4 float4, + f_float8 float8, + f_numeric numeric +); + +insert into numerics values +(0, '-infinity', '-infinity', '-infinity'), +(1, -3, -3, -3), +(2, -1, -1, -1), +(3, 0, 0, 0), +(4, 1.1, 1.1, 1.1), +(5, 1.12, 1.12, 1.12), +(6, 2, 2, 2), +(7, 100, 100, 100), +(8, 'infinity', 'infinity', 'infinity'), +(9, 'NaN', 'NaN', 'NaN'); + +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1 preceding and 1 following); + +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1 preceding and 1.1::float4 following); + +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' preceding and 'inf' following); + +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' preceding and 'inf' preceding); + +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 'inf' following and 'inf' following); + +select id, f_float4, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float4 range between + 1.1 preceding and 'NaN' following); + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1 preceding and 1 following); + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1 preceding and 1.1::float8 following); + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' preceding and 'inf' following); + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' preceding and 'inf' preceding); + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 'inf' following and 'inf' following); + +select id, f_float8, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_float8 range between + 1.1 preceding and 'NaN' following); + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1 following); + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1.1::numeric following); + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1 preceding and 1.1::float8 following); + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' preceding and 'inf' following); + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' preceding and 'inf' preceding); + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 'inf' following and 'inf' following); + +select id, f_numeric, first_value(id) over w, last_value(id) over w +from numerics +window w as (order by f_numeric range between + 1.1 preceding and 'NaN' following); + +create temp table datetimes( + id int, + f_time time, + f_timetz timetz, + f_interval interval, + f_timestamptz timestamptz, + f_timestamp timestamp +); + +insert into datetimes values +(0, '10:00', '10:00 BST', '-infinity', '-infinity', '-infinity'), +(1, '11:00', '11:00 BST', '1 year', '2000-10-19 10:23:54+01', '2000-10-19 10:23:54'), +(2, '12:00', '12:00 BST', '2 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'), +(3, '13:00', '13:00 BST', '3 years', '2001-10-19 10:23:54+01', '2001-10-19 10:23:54'), +(4, '14:00', '14:00 BST', '4 years', '2002-10-19 10:23:54+01', '2002-10-19 10:23:54'), +(5, '15:00', '15:00 BST', '5 years', '2003-10-19 10:23:54+01', '2003-10-19 10:23:54'), +(6, '15:00', '15:00 BST', '5 years', '2004-10-19 10:23:54+01', '2004-10-19 10:23:54'), +(7, '17:00', '17:00 BST', '7 years', '2005-10-19 10:23:54+01', '2005-10-19 10:23:54'), +(8, '18:00', '18:00 BST', '8 years', '2006-10-19 10:23:54+01', '2006-10-19 10:23:54'), +(9, '19:00', '19:00 BST', '9 years', '2007-10-19 10:23:54+01', '2007-10-19 10:23:54'), +(10, '20:00', '20:00 BST', '10 years', '2008-10-19 10:23:54+01', '2008-10-19 10:23:54'), +(11, '21:00', '21:00 BST', 'infinity', 'infinity', 'infinity'); + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + '70 min'::interval preceding and '2 hours'::interval following); + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time desc range between + '70 min' preceding and '2 hours' following); + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time desc range between + '-70 min' preceding and '2 hours' following); + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval preceding and 'infinity'::interval following); + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval preceding and 'infinity'::interval preceding); + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + 'infinity'::interval following and 'infinity'::interval following); + +select id, f_time, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_time range between + '-infinity'::interval following and + 'infinity'::interval following); + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + '70 min'::interval preceding and '2 hours'::interval following); + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz desc range between + '70 min' preceding and '2 hours' following); + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz desc range between + '70 min' preceding and '-2 hours' following); + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval preceding and 'infinity'::interval following); + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval preceding and 'infinity'::interval preceding); + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval following and 'infinity'::interval following); + +select id, f_timetz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timetz range between + 'infinity'::interval following and + '-infinity'::interval following); + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + '1 year'::interval preceding and '1 year'::interval following); + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval desc range between + '1 year' preceding and '1 year' following); + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval desc range between + '-1 year' preceding and '1 year' following); + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval preceding and 'infinity'::interval following); + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval preceding and 'infinity'::interval preceding); + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + 'infinity'::interval following and 'infinity'::interval following); + +select id, f_interval, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_interval range between + '-infinity'::interval following and + 'infinity'::interval following); + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + '1 year'::interval preceding and '1 year'::interval following); + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz desc range between + '1 year' preceding and '1 year' following); + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz desc range between + '1 year' preceding and '-1 year' following); + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval preceding and 'infinity'::interval following); + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval preceding and 'infinity'::interval preceding); + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + 'infinity'::interval following and 'infinity'::interval following); + +select id, f_timestamptz, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamptz range between + '-infinity'::interval following and + 'infinity'::interval following); + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + '1 year'::interval preceding and '1 year'::interval following); + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp desc range between + '1 year' preceding and '1 year' following); + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp desc range between + '-1 year' preceding and '1 year' following); + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval preceding and 'infinity'::interval following); + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval preceding and 'infinity'::interval preceding); + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + 'infinity'::interval following and 'infinity'::interval following); + +select id, f_timestamp, first_value(id) over w, last_value(id) over w +from datetimes +window w as (order by f_timestamp range between + '-infinity'::interval following and + 'infinity'::interval following); + +select sum(salary) over (order by enroll_date, salary range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary; + +select sum(salary) over (range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary; + +select sum(salary) over (order by depname range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary; + +select max(enroll_date) over (order by enroll_date range between 1 preceding and 2 following + exclude ties), salary, enroll_date from empsalary; + +select max(enroll_date) over (order by salary range between -1 preceding and 2 following + exclude ties), salary, enroll_date from empsalary; + +select max(enroll_date) over (order by salary range between 1 preceding and -2 following + exclude ties), salary, enroll_date from empsalary; + +select max(enroll_date) over (order by salary range between '1 year'::interval preceding and '2 years'::interval following + exclude ties), salary, enroll_date from empsalary; + +select max(enroll_date) over (order by enroll_date range between '1 year'::interval preceding and '-2 years'::interval following + exclude ties), salary, enroll_date from empsalary; + +SELECT sum(unique1) over (order by four groups between unbounded preceding and current row), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between unbounded preceding and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between current row and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 1 preceding and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 1 following and unbounded following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between unbounded preceding and 2 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 preceding), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 0 preceding and 0 following), + unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude current row), unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude group), unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (order by four groups between 2 preceding and 1 following + exclude ties), unique1, four +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following),unique1, four, ten +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude current row), unique1, four, ten +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude group), unique1, four, ten +FROM tenk1 WHERE unique1 < 10; + +SELECT sum(unique1) over (partition by ten + order by four groups between 0 preceding and 0 following exclude ties), unique1, four, ten +FROM tenk1 WHERE unique1 < 10; + +select first_value(salary) over(order by enroll_date groups between 1 preceding and 1 following), + lead(salary) over(order by enroll_date groups between 1 preceding and 1 following), + nth_value(salary, 1) over(order by enroll_date groups between 1 preceding and 1 following), + salary, enroll_date from empsalary; + +select last_value(salary) over(order by enroll_date groups between 1 preceding and 1 following), + lag(salary) over(order by enroll_date groups between 1 preceding and 1 following), + salary, enroll_date from empsalary; + +select first_value(salary) over(order by enroll_date groups between 1 following and 3 following + exclude current row), + lead(salary) over(order by enroll_date groups between 1 following and 3 following exclude ties), + nth_value(salary, 1) over(order by enroll_date groups between 1 following and 3 following + exclude ties), + salary, enroll_date from empsalary; + +select last_value(salary) over(order by enroll_date groups between 1 following and 3 following + exclude group), + lag(salary) over(order by enroll_date groups between 1 following and 3 following exclude group), + salary, enroll_date from empsalary; + +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following); + +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x range between 1 preceding and 1 following); + +WITH cte (x) AS ( + SELECT * FROM generate_series(1, 35, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following); + +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x rows between 1 preceding and 1 following); + +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x range between 1 preceding and 1 following); + +WITH cte (x) AS ( + select 1 union all select 1 union all select 1 union all + SELECT * FROM generate_series(5, 49, 2) +) +SELECT x, (sum(x) over w) +FROM cte +WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following); + +SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2)s LIMIT 0; + +create temp table t1 (f1 int, f2 int8); + +insert into t1 values (1,1),(1,2),(2,2); + +select f1, sum(f1) over (partition by f1 + range between 1 preceding and 1 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1, f1 order by f2 + range between 2 preceding and 1 preceding) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1, f2 order by f2 + range between 1 following and 2 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1, f1 order by f2 + groups between 2 preceding and 1 preceding) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1, f2 order by f2 + groups between 1 following and 2 following) +from t1 where f1 = f2; + +SELECT rank() OVER (ORDER BY length('abc')); + +SELECT rank() OVER (ORDER BY rank() OVER (ORDER BY random())); + +SELECT * FROM empsalary WHERE row_number() OVER (ORDER BY salary) < 10; + +SELECT * FROM empsalary INNER JOIN tenk1 ON row_number() OVER (ORDER BY salary) < 10; + +SELECT rank() OVER (ORDER BY 1), count(*) FROM empsalary GROUP BY 1; + +DELETE FROM empsalary WHERE (rank() OVER (ORDER BY random())) > 10; + +DELETE FROM empsalary RETURNING rank() OVER (ORDER BY random()); + +SELECT count(*) OVER w FROM tenk1 WINDOW w AS (ORDER BY unique1), w AS (ORDER BY unique1); + +SELECT count() OVER () FROM tenk1; + +SELECT generate_series(1, 100) OVER () FROM empsalary; + +SELECT ntile(0) OVER (ORDER BY ten), ten, four FROM tenk1; + +SELECT nth_value(four, 0) OVER (ORDER BY ten), ten, four FROM tenk1; + +SELECT sum(salary), row_number() OVER (ORDER BY depname), sum( + sum(salary) FILTER (WHERE enroll_date > '2007-01-01') +) FILTER (WHERE depname <> 'sales') OVER (ORDER BY depname DESC) AS "filtered_sum", + depname +FROM empsalary GROUP BY depname; + +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + dense_rank() OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) drnk, + ntile(10) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) nt, + percent_rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) pr, + cume_dist() OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND UNBOUNDED FOLLOWING) cd +FROM empsalary; + +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + count(*) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) cnt +FROM empsalary; + +SELECT + empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) rn, + rank() OVER (PARTITION BY depname ORDER BY enroll_date ROWS BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rnk, + count(*) OVER (PARTITION BY depname ORDER BY enroll_date RANGE BETWEEN + CURRENT ROW AND CURRENT ROW) cnt +FROM empsalary; + +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname) depsalary, + min(salary) OVER (PARTITION BY depname || 'A', depname) depminsalary + FROM empsalary) emp +WHERE depname = 'sales'; + +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY enroll_date) enroll_salary, + min(salary) OVER (PARTITION BY depname) depminsalary + FROM empsalary) emp +WHERE depname = 'sales'; + +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3; + +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3; + +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE 3 > rn; + +SELECT * FROM + (SELECT empno, + row_number() OVER (ORDER BY empno) rn + FROM empsalary) emp +WHERE 2 >= rn; + +SELECT * FROM + (SELECT empno, + salary, + rank() OVER (ORDER BY salary DESC) r + FROM empsalary) emp +WHERE r <= 3; + +SELECT * FROM + (SELECT empno, + salary, + rank() OVER (ORDER BY salary DESC) r + FROM empsalary) emp +WHERE r <= 3; + +SELECT * FROM + (SELECT empno, + salary, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1; + +SELECT * FROM + (SELECT empno, + salary, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1; + +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3; + +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3; + +SELECT * FROM + (SELECT empno, + salary, + count(empno) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3; + +SELECT * FROM + (SELECT empno, + salary, + count(empno) OVER (ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3; + +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) c + FROM empsalary) emp +WHERE c >= 3; + +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER () c + FROM empsalary) emp +WHERE 11 <= c; + +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC) c, + dense_rank() OVER (ORDER BY salary DESC) dr + FROM empsalary) emp +WHERE dr = 1; + +SELECT * FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3; + +SELECT * FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3; + +SELECT empno, depname FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3; + +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (PARTITION BY depname ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3; + +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER (PARTITION BY depname ORDER BY salary DESC) c + FROM empsalary) emp +WHERE c <= 3; + +SELECT * FROM + (SELECT empno, + depname, + salary, + count(empno) OVER () c + FROM empsalary) emp +WHERE c = 1; + +SELECT * FROM + (SELECT row_number() OVER (PARTITION BY salary) AS rn, + lead(depname) OVER (PARTITION BY salary) || ' Department' AS n_dep + FROM empsalary) emp +WHERE rn < 1; + +SELECT * FROM + (SELECT *, + count(salary) OVER (PARTITION BY depname || '') c1, -- w1 + row_number() OVER (PARTITION BY depname) rn, -- w2 + count(*) OVER (PARTITION BY depname) c2, -- w2 + count(*) OVER (PARTITION BY '' || depname) c3, -- w3 + ntile(2) OVER (PARTITION BY depname) nt -- w2 + FROM empsalary +) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2; + +SELECT * FROM + (SELECT *, + count(salary) OVER (PARTITION BY depname || '') c1, -- w1 + row_number() OVER (PARTITION BY depname) rn, -- w2 + count(*) OVER (PARTITION BY depname) c2, -- w2 + count(*) OVER (PARTITION BY '' || depname) c3, -- w3 + ntile(2) OVER (PARTITION BY depname) nt -- w2 + FROM empsalary +) e WHERE rn <= 1 AND c1 <= 3 AND nt < 2; + +SELECT 1 FROM + (SELECT ntile(e2.salary) OVER (PARTITION BY e1.depname) AS c + FROM empsalary e1 LEFT JOIN empsalary e2 ON TRUE + WHERE e1.empno = e2.empno) s +WHERE s.c = 1; + +SELECT 1 FROM + (SELECT ntile(s1.x) OVER () AS c + FROM (SELECT (SELECT 1) AS x) AS s1) s +WHERE s.c = 1; + +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) c + FROM empsalary) emp +WHERE c <= 3; + +SELECT * FROM + (SELECT empno, + salary, + count(*) OVER (ORDER BY salary) c + FROM empsalary) emp +WHERE 3 <= c; + +SELECT * FROM + (SELECT empno, + salary, + count(random()) OVER (ORDER BY empno DESC) c + FROM empsalary) emp +WHERE c = 1; + +SELECT * FROM + (SELECT empno, + salary, + count((SELECT 1)) OVER (ORDER BY empno DESC) c + FROM empsalary) emp +WHERE c = 1; + +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname, empno order by enroll_date) depminsalary + FROM empsalary) emp +WHERE depname = 'sales'; + +SELECT empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, empno; + +SELECT empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, enroll_date; + +SET enable_hashagg TO off; + +SELECT DISTINCT + empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, enroll_date; + +SELECT DISTINCT + empno, + enroll_date, + depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname order by enroll_date) depminsalary +FROM empsalary +ORDER BY depname, empno; + +RESET enable_hashagg; + +SELECT + lead(1) OVER (PARTITION BY depname ORDER BY salary, enroll_date), + lag(1) OVER (PARTITION BY depname ORDER BY salary,enroll_date,empno) +FROM empsalary; + +SELECT * FROM + (SELECT depname, + empno, + salary, + enroll_date, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp + FROM empsalary) emp +WHERE first_emp = 1 OR last_emp = 1; + +SELECT * FROM + (SELECT depname, + empno, + salary, + enroll_date, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date) AS first_emp, + row_number() OVER (PARTITION BY depname ORDER BY enroll_date DESC) AS last_emp + FROM empsalary) emp +WHERE first_emp = 1 OR last_emp = 1; + +DROP TABLE empsalary; + +CREATE FUNCTION nth_value_def(val anyelement, n integer = 1) RETURNS anyelement + LANGUAGE internal WINDOW IMMUTABLE STRICT AS 'window_nth_value'; + +SELECT nth_value_def(n := 2, val := ten) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s; + +SELECT nth_value_def(ten) OVER (PARTITION BY four), ten, four + FROM (SELECT * FROM tenk1 WHERE unique2 < 10 ORDER BY four, ten) s; + +CREATE FUNCTION logging_sfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT COALESCE($1, '') || '*' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE; + +CREATE FUNCTION logging_msfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT COALESCE($1, '') || '+' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE; + +CREATE FUNCTION logging_minvfunc_nonstrict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '-' || quote_nullable($2) $$ +LANGUAGE SQL IMMUTABLE; + +CREATE AGGREGATE logging_agg_nonstrict (anyelement) +( + stype = text, + sfunc = logging_sfunc_nonstrict, + mstype = text, + msfunc = logging_msfunc_nonstrict, + minvfunc = logging_minvfunc_nonstrict +); + +CREATE AGGREGATE logging_agg_nonstrict_initcond (anyelement) +( + stype = text, + sfunc = logging_sfunc_nonstrict, + mstype = text, + msfunc = logging_msfunc_nonstrict, + minvfunc = logging_minvfunc_nonstrict, + initcond = 'I', + minitcond = 'MI' +); + +CREATE FUNCTION logging_sfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '*' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE; + +CREATE FUNCTION logging_msfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '+' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE; + +CREATE FUNCTION logging_minvfunc_strict(text, anyelement) RETURNS text AS +$$ SELECT $1 || '-' || quote_nullable($2) $$ +LANGUAGE SQL STRICT IMMUTABLE; + +CREATE AGGREGATE logging_agg_strict (text) +( + stype = text, + sfunc = logging_sfunc_strict, + mstype = text, + msfunc = logging_msfunc_strict, + minvfunc = logging_minvfunc_strict +); + +CREATE AGGREGATE logging_agg_strict_initcond (anyelement) +( + stype = text, + sfunc = logging_sfunc_strict, + mstype = text, + msfunc = logging_msfunc_strict, + minvfunc = logging_minvfunc_strict, + initcond = 'I', + minitcond = 'MI' +); + +SELECT + p::text || ',' || i::text || ':' || COALESCE(v::text, 'NULL') AS row, + logging_agg_nonstrict(v) over wnd as nstrict, + logging_agg_nonstrict_initcond(v) over wnd as nstrict_init, + logging_agg_strict(v::text) over wnd as strict, + logging_agg_strict_initcond(v) over wnd as strict_init +FROM (VALUES + (1, 1, NULL), + (1, 2, 'a'), + (1, 3, 'b'), + (1, 4, NULL), + (1, 5, NULL), + (1, 6, 'c'), + (2, 1, NULL), + (2, 2, 'x'), + (3, 1, 'z') +) AS t(p, i, v) +WINDOW wnd AS (PARTITION BY P ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY p, i; + +SELECT + p::text || ',' || i::text || ':' || + CASE WHEN f THEN COALESCE(v::text, 'NULL') ELSE '-' END as row, + logging_agg_nonstrict(v) filter(where f) over wnd as nstrict_filt, + logging_agg_nonstrict_initcond(v) filter(where f) over wnd as nstrict_init_filt, + logging_agg_strict(v::text) filter(where f) over wnd as strict_filt, + logging_agg_strict_initcond(v) filter(where f) over wnd as strict_init_filt +FROM (VALUES + (1, 1, true, NULL), + (1, 2, false, 'a'), + (1, 3, true, 'b'), + (1, 4, false, NULL), + (1, 5, false, NULL), + (1, 6, false, 'c'), + (2, 1, false, NULL), + (2, 2, true, 'x'), + (3, 1, true, 'z') +) AS t(p, i, f, v) +WINDOW wnd AS (PARTITION BY p ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY p, i; + +SELECT + i::text || ':' || COALESCE(v::text, 'NULL') as row, + logging_agg_strict(v::text) + over wnd as inverse, + logging_agg_strict(v::text || CASE WHEN random() < 0 then '?' ELSE '' END) + over wnd as noinverse +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY i; + +SELECT + i::text || ':' || COALESCE(v::text, 'NULL') as row, + logging_agg_strict(v::text) filter(where true) + over wnd as inverse, + logging_agg_strict(v::text) filter(where random() >= 0) + over wnd as noinverse +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +ORDER BY i; + +SELECT + logging_agg_strict(v::text) OVER wnd +FROM (VALUES + (1, 'a'), + (2, 'b'), + (3, 'c') +) AS t(i, v) +WINDOW wnd AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW) +ORDER BY i; + +CREATE FUNCTION sum_int_randrestart_minvfunc(int4, int4) RETURNS int4 AS +$$ SELECT CASE WHEN random() < 0.2 THEN NULL ELSE $1 - $2 END $$ +LANGUAGE SQL STRICT; + +CREATE AGGREGATE sum_int_randomrestart (int4) +( + stype = int4, + sfunc = int4pl, + mstype = int4, + msfunc = int4pl, + minvfunc = sum_int_randrestart_minvfunc +); + +WITH +vs AS ( + SELECT i, (random() * 100)::int4 AS v + FROM generate_series(1, 100) AS i +), +sum_following AS ( + SELECT i, SUM(v) OVER + (ORDER BY i DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS s + FROM vs +) +SELECT DISTINCT + sum_following.s = sum_int_randomrestart(v) OVER fwd AS eq1, + -sum_following.s = sum_int_randomrestart(-v) OVER fwd AS eq2, + 100*3+(vs.i-1)*3 = length(logging_agg_nonstrict(''::text) OVER fwd) AS eq3 +FROM vs +JOIN sum_following ON sum_following.i = vs.i +WINDOW fwd AS ( + ORDER BY vs.i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +); + +SELECT i,AVG(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,AVG(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,AVG(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,AVG(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.5),(2,2.5),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,AVG(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v); + +SELECT x + ,avg(x) OVER(ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ) as curr_next_avg + ,avg(x) OVER(ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) as prev_curr_avg + ,sum(x) OVER(ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ) as curr_next_sum + ,sum(x) OVER(ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ) as prev_curr_sum +FROM (VALUES (NULL::interval), + ('infinity'::interval), + ('-2147483648 days -2147483648 months -9223372036854775807 usecs'), -- extreme interval value + ('-infinity'::interval), + ('2147483647 days 2147483647 months 9223372036854775806 usecs'), -- extreme interval value + ('infinity'::interval), + ('6 days'::interval), + ('7 days'::interval), + (NULL::interval), + ('-infinity'::interval)) v(x); + +SELECT x, avg(x) OVER(ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) +FROM (VALUES (NULL::interval), + ('3 days'::interval), + ('infinity'::timestamptz - now()), + ('6 days'::interval), + ('-infinity'::interval)) v(x); + +SELECT x, sum(x) OVER(ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) +FROM (VALUES (NULL::interval), + ('3 days'::interval), + ('infinity'::timestamptz - now()), + ('6 days'::interval), + ('-infinity'::interval)) v(x); + +SELECT i,SUM(v::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,SUM(v::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,SUM(v::money) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1.10'),(2,'2.20'),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,SUM(v::interval) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,'1 sec'),(2,'2 sec'),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,SUM(v::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.1),(2,2.2),(3,NULL),(4,NULL)) t(i,v); + +SELECT SUM(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1.01),(2,2),(3,3)) v(i,n); + +SELECT i,COUNT(v) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,COUNT(*) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT VAR_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VAR_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VAR_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VAR_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VAR_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VAR_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VAR_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VAR_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VARIANCE(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VARIANCE(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VARIANCE(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT VARIANCE(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT STDDEV_POP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV_POP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV_POP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV_POP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV_SAMP(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV_SAMP(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV_SAMP(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV_SAMP(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(1,NULL),(2,600),(3,470),(4,170),(5,430),(6,300)) r(i,n); + +SELECT STDDEV(n::bigint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT STDDEV(n::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT STDDEV(n::smallint) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT STDDEV(n::numeric) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + FROM (VALUES(0,NULL),(1,600),(2,470),(3,170),(4,430),(5,300)) r(i,n); + +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND CURRENT ROW) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,NULL),(4,NULL)) t(i,v); + +SELECT i,SUM(v::int) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) + FROM (VALUES(1,1),(2,2),(3,3),(4,4)) t(i,v); + +SELECT a, b, + SUM(b) OVER(ORDER BY A ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) +FROM (VALUES(1,1::numeric),(2,2),(3,'NaN'),(4,3),(5,4)) t(a,b); + +SELECT to_char(SUM(n::float8) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),'999999999999999999999D9') + FROM (VALUES(1,1e20),(2,1)) n(i,n); + +SELECT i, b, bool_and(b) OVER w, bool_or(b) OVER w + FROM (VALUES (1,true), (2,true), (3,false), (4,false), (5,true)) v(i,b) + WINDOW w AS (ORDER BY i ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING); + +SELECT COUNT(*) OVER (ORDER BY t1.unique1) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1; + +SELECT COUNT(*) OVER () +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +WHERE t2.two = 1 +LIMIT 1; + +SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1; + +SELECT COUNT(*) OVER (ORDER BY t1.unique1 ROWS BETWEEN UNBOUNDED PRECEDING AND 10000 FOLLOWING) +FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.tenthous +LIMIT 1; + +SELECT array_agg(i) OVER w + FROM generate_series(1,5) i +WINDOW w AS (ORDER BY i ROWS BETWEEN (('foo' < 'foobar')::integer) PRECEDING AND CURRENT ROW); + +CREATE FUNCTION pg_temp.f(group_size BIGINT) RETURNS SETOF integer[] +AS $$ + SELECT array_agg(s) OVER w + FROM generate_series(1,5) s + WINDOW w AS (ORDER BY s ROWS BETWEEN CURRENT ROW AND GROUP_SIZE FOLLOWING) +$$ LANGUAGE SQL STABLE; + +SELECT * FROM pg_temp.f(2); + +SELECT * FROM pg_temp.f(2); diff --git a/crates/pgt_pretty_print/tests/data/multi/with_60.sql b/crates/pgt_pretty_print/tests/data/multi/with_60.sql new file mode 100644 index 000000000..53ce8ef6f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/with_60.sql @@ -0,0 +1,305 @@ +WITH q1(x,y) AS (SELECT 1,2) +SELECT * FROM q1, q1 AS q2; + +SELECT count(*) FROM ( + WITH q1(x) AS (SELECT random() FROM generate_series(1, 5)) + SELECT * FROM q1 + UNION + SELECT * FROM q1 +) ss; + +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t; + +WITH RECURSIVE t(n) AS ( + SELECT (VALUES(1)) +UNION ALL + SELECT n+1 FROM t WHERE n < 5 +) +SELECT * FROM t; + +WITH RECURSIVE t(n) AS ( + VALUES ('01'::varbit) +UNION + SELECT n || '10'::varbit FROM t WHERE n < '100'::varbit +) +SELECT n FROM t; + +CREATE RECURSIVE VIEW nums (n) AS + VALUES (1) +UNION ALL + SELECT n+1 FROM nums WHERE n < 5; + +SELECT * FROM nums; + +CREATE OR REPLACE RECURSIVE VIEW nums (n) AS + VALUES (1) +UNION ALL + SELECT n+1 FROM nums WHERE n < 6; + +SELECT * FROM nums; + +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT 10-n FROM t) +SELECT * FROM t; + +WITH RECURSIVE t(n) AS ( + VALUES (1) +UNION ALL + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10; + +WITH RECURSIVE t(n) AS ( + SELECT 1 +UNION + SELECT n+1 FROM t) +SELECT * FROM t LIMIT 10; + +WITH q AS (SELECT 'foo' AS x) +SELECT x, pg_typeof(x) FROM q; + +WITH RECURSIVE t(n) AS ( + SELECT 'foo' +UNION ALL + SELECT n || ' bar' FROM t WHERE length(n) < 20 +) +SELECT n, pg_typeof(n) FROM t; + +WITH RECURSIVE t(n) AS ( + SELECT '7' +UNION ALL + SELECT n+1 FROM t WHERE n < 10 +) +SELECT n, pg_typeof(n) FROM t; + +WITH RECURSIVE w1(c1) AS + (WITH w2(c2) AS + (WITH w3(c3) AS + (WITH w4(c4) AS + (WITH w5(c5) AS + (WITH RECURSIVE w6(c6) AS + (WITH w6(c6) AS + (WITH w8(c8) AS + (SELECT 1) + SELECT * FROM w8) + SELECT * FROM w6) + SELECT * FROM w6) + SELECT * FROM w5) + SELECT * FROM w4) + SELECT * FROM w3) + SELECT * FROM w2) +SELECT * FROM w1; + +WITH RECURSIVE outermost(x) AS ( + SELECT 1 + UNION (WITH innermost1 AS ( + SELECT 2 + UNION (WITH innermost2 AS ( + SELECT 3 + UNION (WITH innermost3 AS ( + SELECT 4 + UNION (WITH innermost4 AS ( + SELECT 5 + UNION (WITH innermost5 AS ( + SELECT 6 + UNION (WITH innermost6 AS + (SELECT 7) + SELECT * FROM innermost6)) + SELECT * FROM innermost5)) + SELECT * FROM innermost4)) + SELECT * FROM innermost3)) + SELECT * FROM innermost2)) + SELECT * FROM outermost + UNION SELECT * FROM innermost1) + ) + SELECT * FROM outermost ORDER BY 1; + +CREATE TEMP TABLE department ( + id INTEGER PRIMARY KEY, -- department ID + parent_department INTEGER REFERENCES department, -- upper department ID + name TEXT -- department name +); + +INSERT INTO department VALUES (0, NULL, 'ROOT'); + +INSERT INTO department VALUES (1, 0, 'A'); + +INSERT INTO department VALUES (2, 1, 'B'); + +INSERT INTO department VALUES (3, 2, 'C'); + +INSERT INTO department VALUES (4, 2, 'D'); + +INSERT INTO department VALUES (5, 0, 'E'); + +INSERT INTO department VALUES (6, 4, 'F'); + +INSERT INTO department VALUES (7, 5, 'G'); + +WITH RECURSIVE subdepartment AS +( + -- non recursive term + SELECT name as root_name, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.root_name, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name; + +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name; + +WITH RECURSIVE subdepartment(level, id, parent_department, name) AS +( + -- non recursive term + SELECT 1, * FROM department WHERE name = 'A' + + UNION ALL + + -- recursive term + SELECT sd.level + 1, d.* FROM department AS d, subdepartment AS sd + WHERE d.parent_department = sd.id +) +SELECT * FROM subdepartment WHERE level >= 2 ORDER BY name; + +WITH RECURSIVE subdepartment AS +( + -- note lack of recursive UNION structure + SELECT * FROM department WHERE name = 'A' +) +SELECT * FROM subdepartment ORDER BY name; + +WITH RECURSIVE subdepartment AS +( + -- select all columns to prevent projection + SELECT id, parent_department, name FROM department WHERE name = 'A' + + UNION + + -- joins do projection + SELECT d.id, d.parent_department, d.name FROM department AS d + INNER JOIN subdepartment AS sd ON d.parent_department = sd.id +) +SELECT * FROM subdepartment ORDER BY name; + +SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 500 + ) + SELECT * FROM t) AS t WHERE n < ( + SELECT count(*) FROM ( + WITH RECURSIVE t(n) AS ( + SELECT 1 UNION ALL SELECT n + 1 FROM t WHERE n < 100 + ) + SELECT * FROM t WHERE n < 50000 + ) AS t WHERE n < 100); + +WITH q1(x,y) AS ( + SELECT hundred, sum(ten) FROM tenk1 GROUP BY hundred + ) +SELECT count(*) FROM q1 WHERE y > (SELECT sum(y)/100 FROM q1 qsub); + +SELECT * FROM subdepartment; + +SELECT * FROM vsubdepartment ORDER BY name; + +SELECT pg_get_viewdef('vsubdepartment'::regclass); + +SELECT pg_get_viewdef('vsubdepartment'::regclass, true); + +SELECT sum(n) FROM t; + +with recursive q as ( + select * from department + union all + (with x as (select * from q) + select * from x) + ) +select * from q limit 24; + +with recursive q as ( + select * from department + union all + (with recursive x as ( + select * from department + union all + (select * from q union all select * from x) + ) + select * from x) + ) +select * from q limit 32; + +SELECT * FROM t; + +CREATE TEMPORARY TABLE tree( + id INTEGER PRIMARY KEY, + parent_id INTEGER REFERENCES tree(id) +); + +INSERT INTO tree +VALUES (1, NULL), (2, 1), (3,1), (4,2), (5,2), (6,2), (7,3), (8,3), + (9,4), (10,4), (11,7), (12,7), (13,7), (14, 9), (15,11), (16,11); + +WITH RECURSIVE t(id, path) AS ( + VALUES(1,ARRAY[]::integer[]) +UNION ALL + SELECT tree.id, t.path || tree.id + FROM tree JOIN t ON (tree.parent_id = t.id) +) +SELECT t1.*, t2.* FROM t AS t1 JOIN t AS t2 ON + (t1.path[1] = t2.path[1] AND + array_upper(t1.path,1) = 1 AND + array_upper(t2.path,1) > 1) + ORDER BY t1.id, t2.id; + +WITH RECURSIVE t(id, path) AS ( + VALUES(1,ARRAY[]::integer[]) +UNION ALL + SELECT tree.id, t.path || tree.id + FROM tree JOIN t ON (tree.parent_id = t.id) +) +SELECT t1.id, count(t2.*) FROM t AS t1 JOIN t AS t2 ON + (t1.path[1] = t2.path[1] AND + array_upper(t1.path,1) = 1 AND + array_upper(t2.path,1) > 1) + GROUP BY t1.id + ORDER BY t1.id; + +WITH RECURSIVE t(id, path) AS ( + VALUES(1,ARRAY[]::integer[]) +UNION ALL + SELECT tree.id, t.path || tree.id + FROM tree JOIN t ON (tree.parent_id = t.id) +) +SELECT t1.id, t2.path, t2 FROM t AS t1 JOIN t AS t2 ON +(t1.id=t2.id); + +CREATE TEMP TABLE duplicates (a INT NOT NULL); + +INSERT INTO duplicates VALUES(1), (1); + +WITH RECURSIVE cte (a) as ( + SELECT a FROM duplicates + UNION + SELECT a FROM cte +) +SELECT a FROM cte; diff --git a/crates/pgt_pretty_print/tests/data/multi/without_overlaps_60.sql b/crates/pgt_pretty_print/tests/data/multi/without_overlaps_60.sql new file mode 100644 index 000000000..490157b14 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/without_overlaps_60.sql @@ -0,0 +1,1313 @@ +SET datestyle TO ISO, YMD; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_rng_pk'; + +SELECT pg_get_indexdef(conindid, 0, true) FROM pg_constraint WHERE conname = 'temporal_rng_pk'; + +CREATE TABLE temporal_rng2 (LIKE temporal_rng INCLUDING ALL); + +DROP TABLE temporal_rng2; + +CREATE TABLE temporal_rng2 () INHERITS (temporal_rng); + +DROP TABLE temporal_rng2; + +DROP TABLE temporal_rng; + +CREATE TABLE temporal_rng ( + id int4range, + valid_at daterange +); + +DROP TABLE temporal_rng CASCADE; + +CREATE TABLE temporal_rng ( + id int4range, + valid_at daterange +); + +CREATE TABLE temporal_rng2 () INHERITS (temporal_rng); + +DROP TABLE temporal_rng2; + +DROP TABLE temporal_rng; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_rng2_pk'; + +SELECT pg_get_indexdef(conindid, 0, true) FROM pg_constraint WHERE conname = 'temporal_rng2_pk'; + +CREATE TYPE textrange2 AS range (subtype=text, collation="C"); + +ALTER TABLE temporal_rng3 DROP CONSTRAINT temporal_rng3_pk; + +DROP TABLE temporal_rng3; + +DROP TYPE textrange2; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_mltrng_pk'; + +SELECT pg_get_indexdef(conindid, 0, true) FROM pg_constraint WHERE conname = 'temporal_mltrng_pk'; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_mltrng2_pk'; + +SELECT pg_get_indexdef(conindid, 0, true) FROM pg_constraint WHERE conname = 'temporal_mltrng2_pk'; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_rng3_uq'; + +SELECT pg_get_indexdef(conindid, 0, true) FROM pg_constraint WHERE conname = 'temporal_rng3_uq'; + +DROP TABLE temporal_rng3; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_rng3_uq'; + +SELECT pg_get_indexdef(conindid, 0, true) FROM pg_constraint WHERE conname = 'temporal_rng3_uq'; + +DROP TABLE temporal_rng3; + +CREATE TYPE textrange2 AS range (subtype=text, collation="C"); + +ALTER TABLE temporal_rng3 DROP CONSTRAINT temporal_rng3_uq; + +DROP TABLE temporal_rng3; + +DROP TYPE textrange2; + +CREATE TABLE temporal_rng ( + id int4range, + valid_at daterange +); + +CREATE TABLE temporal3 ( + id int4range, + valid_at daterange +); + +CREATE INDEX idx_temporal3_uq ON temporal3 USING gist (id, valid_at); + +ALTER TABLE temporal3 + ADD CONSTRAINT temporal3_pk + PRIMARY KEY USING INDEX idx_temporal3_uq; + +DROP TABLE temporal3; + +CREATE TABLE temporal3 ( + id int4range, + valid_at daterange +); + +CREATE INDEX idx_temporal3_uq ON temporal3 USING gist (id, valid_at); + +ALTER TABLE temporal3 + ADD CONSTRAINT temporal3_uq + UNIQUE USING INDEX idx_temporal3_uq; + +DROP TABLE temporal3; + +CREATE TABLE temporal3 ( + id int4range, + valid_at daterange +); + +CREATE UNIQUE INDEX idx_temporal3_uq ON temporal3 (id, valid_at); + +ALTER TABLE temporal3 + ADD CONSTRAINT temporal3_uq + UNIQUE USING INDEX idx_temporal3_uq; + +DROP TABLE temporal3; + +CREATE TABLE temporal3 ( + id int4range +); + +DROP TABLE temporal3; + +CREATE TABLE temporal3 ( + id int4range +); + +DROP TABLE temporal3; + +ALTER TABLE temporal_rng DROP CONSTRAINT temporal_rng_pk; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2018-01-02', '2018-02-03')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2018-03-03', '2018-04-04')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[2,3)', daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[3,4)', daterange('2018-01-01', NULL)); + +ALTER TABLE temporal_rng DROP CONSTRAINT temporal_rng_pk; + +BEGIN; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2018-01-01', '2018-01-05')); + +ROLLBACK; + +BEGIN; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[3,4)', 'empty'); + +ROLLBACK; + +DELETE FROM temporal_rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2018-01-02', '2018-02-03')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2018-03-03', '2018-04-04')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[2,3)', daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[3,4)', daterange('2018-01-01', NULL)); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng (id, valid_at) VALUES (NULL, daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[3,4)', NULL); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[3,4)', 'empty'); + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +UPDATE temporal_rng +SET id = '[11,12)' +WHERE id = '[1,2)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_rng +SET valid_at = '[2020-01-01,2021-01-01)' +WHERE id = '[11,12)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_rng +SET id = '[21,22)', + valid_at = '[2018-01-02,2018-02-03)' +WHERE id = '[11,12)' +AND valid_at @> '2020-01-15'::date; + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +UPDATE temporal_rng +SET id = '[1,2)', + valid_at = daterange('2018-03-05', '2018-05-05') +WHERE id = '[21,22)'; + +UPDATE temporal_rng +SET id = NULL, + valid_at = daterange('2018-03-05', '2018-05-05') +WHERE id = '[21,22)'; + +UPDATE temporal_rng +SET id = '[1,2)', + valid_at = NULL +WHERE id = '[21,22)'; + +UPDATE temporal_rng +SET id = '[1,2)', + valid_at = 'empty' +WHERE id = '[21,22)'; + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +CREATE TABLE temporal_rng3 ( + id int4range, + valid_at daterange +); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[1,2)', daterange('2018-01-02', '2018-02-03')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[1,2)', daterange('2018-03-03', '2018-04-04')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[2,3)', daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[3,4)', daterange('2018-01-01', NULL)); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES (NULL, daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[3,4)', NULL); + +ALTER TABLE temporal_rng3 DROP CONSTRAINT temporal_rng3_uq; + +BEGIN; + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[1,2)', daterange('2018-01-01', '2018-01-05')); + +ROLLBACK; + +BEGIN; + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[3,4)', 'empty'); + +ROLLBACK; + +DELETE FROM temporal_rng3; + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[1,2)', daterange('2018-01-02', '2018-02-03')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[1,2)', daterange('2018-03-03', '2018-04-04')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[2,3)', daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[3,4)', daterange('2018-01-01', NULL)); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES (NULL, daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[3,4)', NULL); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[1,2)', daterange('2018-01-01', '2018-01-05')); + +INSERT INTO temporal_rng3 (id, valid_at) VALUES ('[3,4)', 'empty'); + +SELECT * FROM temporal_rng3 ORDER BY id, valid_at; + +UPDATE temporal_rng3 +SET id = '[11,12)' +WHERE id = '[1,2)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_rng3 +SET valid_at = '[2020-01-01,2021-01-01)' +WHERE id = '[11,12)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_rng3 +SET id = '[21,22)', + valid_at = '[2018-01-02,2018-02-03)' +WHERE id = '[11,12)' +AND valid_at @> '2020-01-15'::date; + +UPDATE temporal_rng3 +SET id = NULL, + valid_at = daterange('2020-01-01', '2021-01-01') +WHERE id = '[21,22)'; + +UPDATE temporal_rng3 +SET id = '[1,2)', + valid_at = NULL +WHERE id IS NULL AND valid_at @> '2020-06-01'::date; + +SELECT * FROM temporal_rng3 ORDER BY id, valid_at; + +UPDATE temporal_rng3 +SET valid_at = daterange('2018-03-01', '2018-05-05') +WHERE id = '[1,2)' AND valid_at IS NULL; + +UPDATE temporal_rng3 +SET valid_at = 'empty' +WHERE id = '[1,2)' AND valid_at IS NULL; + +UPDATE temporal_rng3 +SET id = NULL, + valid_at = 'empty' +WHERE id = '[1,2)' AND valid_at IS NULL; + +SELECT * FROM temporal_rng3 ORDER BY id, valid_at; + +DROP TABLE temporal_rng3; + +ALTER TABLE temporal_mltrng DROP CONSTRAINT temporal_mltrng_pk; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-02', '2018-02-03'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-03-03', '2018-04-04'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[3,4)', datemultirange(daterange('2018-01-01', NULL))); + +ALTER TABLE temporal_mltrng DROP CONSTRAINT temporal_mltrng_pk; + +BEGIN; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +ROLLBACK; + +BEGIN; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[3,4)', '{}'); + +ROLLBACK; + +DELETE FROM temporal_mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-02', '2018-02-03'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-03-03', '2018-04-04'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[3,4)', datemultirange(daterange('2018-01-01', NULL))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES (NULL, datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[3,4)', NULL); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[3,4)', '{}'); + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +UPDATE temporal_mltrng +SET id = '[11,12)' +WHERE id = '[1,2)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_mltrng +SET valid_at = '{[2020-01-01,2021-01-01)}' +WHERE id = '[11,12)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_mltrng +SET id = '[21,22)', + valid_at = '{[2018-01-02,2018-02-03)}' +WHERE id = '[11,12)' +AND valid_at @> '2020-01-15'::date; + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +UPDATE temporal_mltrng +SET id = '[1,2)', + valid_at = datemultirange(daterange('2018-03-05', '2018-05-05')) +WHERE id = '[21,22)'; + +UPDATE temporal_mltrng +SET id = NULL, + valid_at = datemultirange(daterange('2018-03-05', '2018-05-05')) +WHERE id = '[21,22)'; + +UPDATE temporal_mltrng +SET id = '[1,2)', + valid_at = NULL +WHERE id = '[21,22)'; + +UPDATE temporal_mltrng +SET id = '[1,2)', + valid_at = '{}' +WHERE id = '[21,22)'; + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +CREATE TABLE temporal_mltrng3 ( + id int4range, + valid_at datemultirange +); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-02', '2018-02-03'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-03-03', '2018-04-04'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[3,4)', datemultirange(daterange('2018-01-01', NULL))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES (NULL, datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[3,4)', NULL); + +ALTER TABLE temporal_mltrng3 DROP CONSTRAINT temporal_mltrng3_uq; + +BEGIN; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +ROLLBACK; + +BEGIN; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[3,4)', '{}'); + +ROLLBACK; + +DELETE FROM temporal_mltrng3; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-02', '2018-02-03'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-03-03', '2018-04-04'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[3,4)', datemultirange(daterange('2018-01-01', NULL))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES (NULL, datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[3,4)', NULL); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-01-01', '2018-01-05'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[3,4)', '{}'); + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +UPDATE temporal_mltrng3 +SET id = '[11,12)' +WHERE id = '[1,2)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_mltrng3 +SET valid_at = '{[2020-01-01,2021-01-01)}' +WHERE id = '[11,12)' +AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_mltrng3 +SET id = '[21,22)', + valid_at = '{[2018-01-02,2018-02-03)}' +WHERE id = '[11,12)' +AND valid_at @> '2020-01-15'::date; + +UPDATE temporal_mltrng3 +SET id = NULL, + valid_at = datemultirange(daterange('2020-01-01', '2021-01-01')) +WHERE id = '[21,22)'; + +UPDATE temporal_mltrng3 +SET id = '[1,2)', + valid_at = NULL +WHERE id IS NULL AND valid_at @> '2020-06-01'::date; + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +UPDATE temporal_mltrng3 +SET valid_at = datemultirange(daterange('2018-03-01', '2018-05-05')) +WHERE id = '[1,2)' AND valid_at IS NULL; + +UPDATE temporal_mltrng3 +SET valid_at = '{}' +WHERE id = '[1,2)' AND valid_at IS NULL; + +UPDATE temporal_mltrng3 +SET id = NULL, + valid_at = '{}' +WHERE id = '[1,2)' AND valid_at IS NULL; + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +DROP TABLE temporal_mltrng3; + +INSERT INTO temporal3 (id, valid_at, id2, name) + VALUES + ('[1,2)', daterange('2000-01-01', '2010-01-01'), '[7,8)', 'foo'), + ('[2,3)', daterange('2000-01-01', '2010-01-01'), '[9,10)', 'bar') +; + +DROP TABLE temporal3; + +ALTER TABLE temporal3 ALTER COLUMN valid_at DROP NOT NULL; + +ALTER TABLE temporal3 ALTER COLUMN valid_at TYPE tstzrange USING tstzrange(lower(valid_at), upper(valid_at)); + +ALTER TABLE temporal3 RENAME COLUMN valid_at TO valid_thru; + +ALTER TABLE temporal3 DROP COLUMN valid_thru; + +DROP TABLE temporal3; + +CREATE TABLE tp1 PARTITION OF temporal_partitioned FOR VALUES IN ('[1,2)', '[2,3)'); + +CREATE TABLE tp2 PARTITION OF temporal_partitioned FOR VALUES IN ('[3,4)', '[4,5)'); + +INSERT INTO temporal_partitioned (id, valid_at, name) VALUES + ('[1,2)', daterange('2000-01-01', '2000-02-01'), 'one'), + ('[1,2)', daterange('2000-02-01', '2000-03-01'), 'one'), + ('[3,4)', daterange('2000-01-01', '2010-01-01'), 'three'); + +SELECT * FROM temporal_partitioned ORDER BY id, valid_at; + +SELECT * FROM tp1 ORDER BY id, valid_at; + +SELECT * FROM tp2 ORDER BY id, valid_at; + +DROP TABLE temporal_partitioned; + +CREATE TABLE tp1 PARTITION OF temporal_partitioned FOR VALUES IN ('[1,2)', '[2,3)'); + +CREATE TABLE tp2 PARTITION OF temporal_partitioned FOR VALUES IN ('[3,4)', '[4,5)'); + +INSERT INTO temporal_partitioned (id, valid_at, name) VALUES + ('[1,2)', daterange('2000-01-01', '2000-02-01'), 'one'), + ('[1,2)', daterange('2000-02-01', '2000-03-01'), 'one'), + ('[3,4)', daterange('2000-01-01', '2010-01-01'), 'three'); + +SELECT * FROM temporal_partitioned ORDER BY id, valid_at; + +SELECT * FROM tp1 ORDER BY id, valid_at; + +SELECT * FROM tp2 ORDER BY id, valid_at; + +DROP TABLE temporal_partitioned; + +ALTER TABLE temporal_rng REPLICA IDENTITY USING INDEX temporal_rng_pk; + +TRUNCATE temporal_rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT DO NOTHING; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT DO NOTHING; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT DO NOTHING; + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +TRUNCATE temporal_rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO NOTHING; + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +TRUNCATE temporal_rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal_rng_pk DO NOTHING; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT ON CONSTRAINT temporal_rng_pk DO NOTHING; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal_rng_pk DO NOTHING; + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +TRUNCATE temporal_rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +TRUNCATE temporal_rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal_rng_pk DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT ON CONSTRAINT temporal_rng_pk DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal_rng_pk DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal_rng ORDER BY id, valid_at; + +TRUNCATE temporal3; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT DO NOTHING; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT DO NOTHING; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT DO NOTHING; + +SELECT * FROM temporal3 ORDER BY id, valid_at; + +TRUNCATE temporal3; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO NOTHING; + +SELECT * FROM temporal3 ORDER BY id, valid_at; + +TRUNCATE temporal3; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal3_uq DO NOTHING; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT ON CONSTRAINT temporal3_uq DO NOTHING; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal3_uq DO NOTHING; + +SELECT * FROM temporal3 ORDER BY id, valid_at; + +TRUNCATE temporal3; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal3 ORDER BY id, valid_at; + +TRUNCATE temporal3; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2000-01-01', '2010-01-01')); + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal3_uq DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[1,2)', daterange('2010-01-01', '2020-01-01')) ON CONFLICT ON CONSTRAINT temporal3_uq DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal3 (id, valid_at) VALUES ('[2,3)', daterange('2005-01-01', '2006-01-01')) ON CONFLICT ON CONSTRAINT temporal3_uq DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal3 ORDER BY id, valid_at; + +DROP TABLE temporal3; + +TRUNCATE temporal_mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT DO NOTHING; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT DO NOTHING; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT DO NOTHING; + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO NOTHING; + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng_pk DO NOTHING; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng_pk DO NOTHING; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng_pk DO NOTHING; + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng_pk DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng_pk DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng_pk DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal_mltrng ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng3; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT DO NOTHING; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT DO NOTHING; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT DO NOTHING; + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng3; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT (id, valid_at) DO NOTHING; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO NOTHING; + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng3; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng3_uq DO NOTHING; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng3_uq DO NOTHING; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng3_uq DO NOTHING; + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng3; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT (id, valid_at) DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +TRUNCATE temporal_mltrng3; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2000-01-01', '2010-01-01'))); + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng3_uq DO UPDATE SET id = EXCLUDED.id + '[2,3)'; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2010-01-01', '2020-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng3_uq DO UPDATE SET id = EXCLUDED.id + '[3,4)'; + +INSERT INTO temporal_mltrng3 (id, valid_at) VALUES ('[2,3)', datemultirange(daterange('2005-01-01', '2006-01-01'))) ON CONFLICT ON CONSTRAINT temporal_mltrng3_uq DO UPDATE SET id = EXCLUDED.id + '[4,5)'; + +SELECT * FROM temporal_mltrng3 ORDER BY id, valid_at; + +DROP TABLE temporal_mltrng3; + +ALTER TABLE temporal3 DROP COLUMN valid_at; + +ALTER TABLE temporal3 DROP COLUMN valid_at CASCADE; + +DROP TABLE temporal_fk_rng2rng; + +DROP TABLE temporal3; + +DROP TABLE temporal_rng; + +CREATE TABLE temporal_rng (id int4range, valid_at daterange); + +DROP TABLE temporal_fk_rng2rng; + +DROP TABLE temporal_fk_rng2rng; + +DROP TABLE temporal_rng2; + +DROP TABLE temporal_fk2_rng2rng; + +ALTER TABLE temporal_fk_rng2rng + DROP CONSTRAINT temporal_fk_rng2rng_fk, + ALTER COLUMN valid_at TYPE tsrange USING tsrange(lower(valid_at), upper(valid_at)); + +ALTER TABLE temporal_fk_rng2rng + ALTER COLUMN valid_at TYPE daterange USING daterange(lower(valid_at)::date, upper(valid_at)::date); + +DELETE FROM temporal_fk_rng2rng; + +DELETE FROM temporal_rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES + ('[1,2)', daterange('2018-01-02', '2018-02-03')), + ('[1,2)', daterange('2018-03-03', '2018-04-04')), + ('[2,3)', daterange('2018-01-01', '2018-01-05')), + ('[3,4)', daterange('2018-01-01', NULL)); + +ALTER TABLE temporal_fk_rng2rng + DROP CONSTRAINT temporal_fk_rng2rng_fk; + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[1,2)', daterange('2018-01-02', '2018-02-01'), '[1,2)'); + +ALTER TABLE temporal_fk_rng2rng + DROP CONSTRAINT temporal_fk_rng2rng_fk; + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[2,3)', daterange('2018-01-02', '2018-04-01'), '[1,2)'); + +DELETE FROM temporal_fk_rng2rng; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_fk_rng2rng_fk'; + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[1,2)', daterange('2018-01-02', '2018-02-01'), '[1,2)'); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[2,3)', daterange('2018-01-02', '2018-04-01'), '[1,2)'); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[1,2)', daterange('2018-02-03', '2018-03-03')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[2,3)', daterange('2018-01-02', '2018-04-01'), '[1,2)'); + +UPDATE temporal_fk_rng2rng SET valid_at = daterange('2018-01-02', '2018-02-20') WHERE id = '[1,2)'; + +UPDATE temporal_fk_rng2rng SET valid_at = daterange('2018-01-02', '2018-05-01') WHERE id = '[1,2)'; + +UPDATE temporal_fk_rng2rng SET parent_id = '[8,9)' WHERE id = '[1,2)'; + +BEGIN; + +INSERT INTO temporal_rng (id, valid_at) VALUES + ('[5,6)', daterange('2018-01-01', '2018-02-01')), + ('[5,6)', daterange('2018-02-01', '2018-03-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[3,4)', daterange('2018-01-05', '2018-01-10'), '[5,6)'); + +ALTER TABLE temporal_fk_rng2rng + ALTER CONSTRAINT temporal_fk_rng2rng_fk + DEFERRABLE INITIALLY DEFERRED; + +DELETE FROM temporal_rng WHERE id = '[5,6)'; + +COMMIT; + +TRUNCATE temporal_rng, temporal_fk_rng2rng; + +ALTER TABLE temporal_fk_rng2rng + DROP CONSTRAINT temporal_fk_rng2rng_fk; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01')); + +UPDATE temporal_rng SET valid_at = daterange('2016-01-01', '2016-02-01') WHERE id = '[5,6)'; + +DELETE FROM temporal_rng WHERE id = '[5,6)'; + +INSERT INTO temporal_rng (id, valid_at) VALUES + ('[5,6)', daterange('2018-01-01', '2018-02-01')), + ('[5,6)', daterange('2018-02-01', '2018-03-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) + VALUES ('[3,4)', daterange('2018-01-05', '2018-01-10'), '[5,6)'); + +UPDATE temporal_rng SET valid_at = daterange('2016-02-01', '2016-03-01') + WHERE id = '[5,6)' AND valid_at = daterange('2018-02-01', '2018-03-01'); + +INSERT INTO temporal_rng (id, valid_at) VALUES + ('[6,7)', daterange('2018-01-01', '2018-02-01')), + ('[6,7)', daterange('2018-02-01', '2018-03-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[4,5)', daterange('2018-01-15', '2018-02-15'), '[6,7)'); + +UPDATE temporal_rng + SET valid_at = CASE WHEN lower(valid_at) = '2018-01-01' THEN daterange('2018-01-01', '2018-01-05') + WHEN lower(valid_at) = '2018-02-01' THEN daterange('2018-01-05', '2018-03-01') END + WHERE id = '[6,7)'; + +INSERT INTO temporal_rng (id, valid_at) VALUES + ('[1,2)', daterange('2018-01-01', '2018-03-01')), + ('[1,2)', daterange('2018-03-01', '2018-06-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[1,2)', daterange('2018-01-15', '2018-02-01'), '[1,2)'), + ('[2,3)', daterange('2018-01-15', '2018-05-01'), '[1,2)'); + +UPDATE temporal_rng SET valid_at = daterange('2018-01-15', '2018-03-01') + WHERE id = '[1,2)' AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_rng SET valid_at = daterange('2018-01-01', '2018-03-01') + WHERE id = '[1,2)' AND valid_at @> '2018-01-25'::date; + +UPDATE temporal_rng SET id = '[2,3)', valid_at = daterange('2018-01-15', '2018-03-01') + WHERE id = '[1,2)' AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_rng SET id = '[2,3)' + WHERE id = '[1,2)' AND valid_at @> '2018-01-15'::date; + +INSERT INTO temporal_rng (id, valid_at) VALUES + ('[2,3)', daterange('2018-01-01', '2018-03-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[5,6)', daterange('2018-01-15', '2018-02-01'), '[2,3)'); + +UPDATE temporal_rng SET valid_at = daterange('2018-01-15', '2018-02-15') + WHERE id = '[2,3)'; + +UPDATE temporal_rng SET valid_at = daterange('2016-01-01', '2016-02-01') + WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +BEGIN; + +ALTER TABLE temporal_fk_rng2rng + ALTER CONSTRAINT temporal_fk_rng2rng_fk + DEFERRABLE INITIALLY DEFERRED; + +UPDATE temporal_rng SET valid_at = daterange('2016-01-01', '2016-02-01') + WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +COMMIT; + +UPDATE temporal_rng SET id = '[7,8)' + WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +DELETE FROM temporal_fk_rng2rng WHERE id = '[3,4)'; + +UPDATE temporal_rng SET valid_at = daterange('2016-01-01', '2016-02-01') + WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +TRUNCATE temporal_rng, temporal_fk_rng2rng; + +ALTER TABLE temporal_fk_rng2rng + DROP CONSTRAINT temporal_fk_rng2rng_fk; + +TRUNCATE temporal_rng, temporal_fk_rng2rng; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01')); + +DELETE FROM temporal_rng WHERE id = '[5,6)'; + +INSERT INTO temporal_rng (id, valid_at) VALUES + ('[5,6)', daterange('2018-01-01', '2018-02-01')), + ('[5,6)', daterange('2018-02-01', '2018-03-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[3,4)', daterange('2018-01-05', '2018-01-10'), '[5,6)'); + +DELETE FROM temporal_rng WHERE id = '[5,6)' AND valid_at = daterange('2018-02-01', '2018-03-01'); + +DELETE FROM temporal_rng WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +BEGIN; + +ALTER TABLE temporal_fk_rng2rng + ALTER CONSTRAINT temporal_fk_rng2rng_fk + DEFERRABLE INITIALLY DEFERRED; + +DELETE FROM temporal_rng WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +COMMIT; + +DELETE FROM temporal_fk_rng2rng WHERE id = '[3,4)'; + +DELETE FROM temporal_rng WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +TRUNCATE temporal_rng, temporal_fk_rng2rng; + +ALTER TABLE temporal_fk_rng2rng + DROP CONSTRAINT temporal_fk_rng2rng_fk; + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[6,7)', daterange('2018-01-01', '2021-01-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[4,5)', daterange('2018-01-01', '2021-01-01'), '[6,7)'); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[9,10)', daterange('2018-01-01', '2021-01-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[6,7)', daterange('2018-01-01', '2021-01-01'), '[9,10)'); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[-1,-1]', daterange(null, null)); + +INSERT INTO temporal_rng (id, valid_at) VALUES ('[12,13)', daterange('2018-01-01', '2021-01-01')); + +INSERT INTO temporal_fk_rng2rng (id, valid_at, parent_id) VALUES ('[8,9)', daterange('2018-01-01', '2021-01-01'), '[12,13)'); + +DROP TABLE temporal_mltrng; + +CREATE TABLE temporal_mltrng ( id int4range, valid_at datemultirange); + +DROP TABLE temporal_fk_mltrng2mltrng; + +DROP TABLE temporal_fk_mltrng2mltrng; + +DROP TABLE temporal_mltrng2; + +DROP TABLE temporal_fk2_mltrng2mltrng; + +DELETE FROM temporal_fk_mltrng2mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES + ('[1,2)', datemultirange(daterange('2018-01-02', '2018-02-03'))), + ('[1,2)', datemultirange(daterange('2018-03-03', '2018-04-04'))), + ('[2,3)', datemultirange(daterange('2018-01-01', '2018-01-05'))), + ('[3,4)', datemultirange(daterange('2018-01-01', NULL))); + +ALTER TABLE temporal_fk_mltrng2mltrng + DROP CONSTRAINT temporal_fk_mltrng2mltrng_fk; + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[1,2)', datemultirange(daterange('2018-01-02', '2018-02-01')), '[1,2)'); + +ALTER TABLE temporal_fk_mltrng2mltrng + DROP CONSTRAINT temporal_fk_mltrng2mltrng_fk; + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[2,3)', datemultirange(daterange('2018-01-02', '2018-04-01')), '[1,2)'); + +DELETE FROM temporal_fk_mltrng2mltrng; + +SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'temporal_fk_mltrng2mltrng_fk'; + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[1,2)', datemultirange(daterange('2018-01-02', '2018-02-01')), '[1,2)'); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[2,3)', datemultirange(daterange('2018-01-02', '2018-04-01')), '[1,2)'); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[1,2)', datemultirange(daterange('2018-02-03', '2018-03-03'))); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[2,3)', datemultirange(daterange('2018-01-02', '2018-04-01')), '[1,2)'); + +UPDATE temporal_fk_mltrng2mltrng SET valid_at = datemultirange(daterange('2018-01-02', '2018-02-20')) WHERE id = '[1,2)'; + +UPDATE temporal_fk_mltrng2mltrng SET valid_at = datemultirange(daterange('2018-01-02', '2018-05-01')) WHERE id = '[1,2)'; + +UPDATE temporal_fk_mltrng2mltrng SET parent_id = '[8,9)' WHERE id = '[1,2)'; + +BEGIN; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES + ('[5,6)', datemultirange(daterange('2018-01-01', '2018-02-01'))), + ('[5,6)', datemultirange(daterange('2018-02-01', '2018-03-01'))); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[3,4)', datemultirange(daterange('2018-01-05', '2018-01-10')), '[5,6)'); + +ALTER TABLE temporal_fk_mltrng2mltrng + ALTER CONSTRAINT temporal_fk_mltrng2mltrng_fk + DEFERRABLE INITIALLY DEFERRED; + +DELETE FROM temporal_mltrng WHERE id = '[5,6)'; + +COMMIT; + +TRUNCATE temporal_mltrng, temporal_fk_mltrng2mltrng; + +ALTER TABLE temporal_fk_mltrng2mltrng + DROP CONSTRAINT temporal_fk_mltrng2mltrng_fk; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[5,6)', datemultirange(daterange('2018-01-01', '2018-02-01'))); + +UPDATE temporal_mltrng SET valid_at = datemultirange(daterange('2016-01-01', '2016-02-01')) WHERE id = '[5,6)'; + +DELETE FROM temporal_mltrng WHERE id = '[5,6)'; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES + ('[5,6)', datemultirange(daterange('2018-01-01', '2018-02-01'))), + ('[5,6)', datemultirange(daterange('2018-02-01', '2018-03-01'))); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[3,4)', datemultirange(daterange('2018-01-05', '2018-01-10')), '[5,6)'); + +UPDATE temporal_mltrng SET valid_at = datemultirange(daterange('2016-02-01', '2016-03-01')) + WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-02-01', '2018-03-01')); + +INSERT INTO temporal_mltrng (id, valid_at) VALUES + ('[6,7)', datemultirange(daterange('2018-01-01', '2018-02-01'))), + ('[6,7)', datemultirange(daterange('2018-02-01', '2018-03-01'))); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[4,5)', datemultirange(daterange('2018-01-15', '2018-02-15')), '[6,7)'); + +UPDATE temporal_mltrng + SET valid_at = CASE WHEN lower(valid_at) = '2018-01-01' THEN datemultirange(daterange('2018-01-01', '2018-01-05')) + WHEN lower(valid_at) = '2018-02-01' THEN datemultirange(daterange('2018-01-05', '2018-03-01')) END + WHERE id = '[6,7)'; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES + ('[1,2)', datemultirange(daterange('2018-01-01', '2018-03-01'))), + ('[1,2)', datemultirange(daterange('2018-03-01', '2018-06-01'))); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[1,2)', datemultirange(daterange('2018-01-15', '2018-02-01')), '[1,2)'), + ('[2,3)', datemultirange(daterange('2018-01-15', '2018-05-01')), '[1,2)'); + +UPDATE temporal_mltrng SET valid_at = datemultirange(daterange('2018-01-15', '2018-03-01')) + WHERE id = '[1,2)' AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_mltrng SET valid_at = datemultirange(daterange('2018-01-01', '2018-03-01')) + WHERE id = '[1,2)' AND valid_at @> '2018-01-25'::date; + +UPDATE temporal_mltrng SET id = '[2,3)', valid_at = datemultirange(daterange('2018-01-15', '2018-03-01')) + WHERE id = '[1,2)' AND valid_at @> '2018-01-15'::date; + +UPDATE temporal_mltrng SET id = '[2,3)' + WHERE id = '[1,2)' AND valid_at @> '2018-01-15'::date; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES + ('[2,3)', datemultirange(daterange('2018-01-01', '2018-03-01'))); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[5,6)', datemultirange(daterange('2018-01-15', '2018-02-01')), '[2,3)'); + +UPDATE temporal_mltrng SET valid_at = datemultirange(daterange('2018-01-15', '2018-02-15')) + WHERE id = '[2,3)'; + +UPDATE temporal_mltrng SET valid_at = datemultirange(daterange('2016-01-01', '2016-02-01')) + WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')); + +BEGIN; + +ALTER TABLE temporal_fk_mltrng2mltrng + ALTER CONSTRAINT temporal_fk_mltrng2mltrng_fk + DEFERRABLE INITIALLY DEFERRED; + +UPDATE temporal_mltrng SET valid_at = datemultirange(daterange('2016-01-01', '2016-02-01')) + WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')); + +COMMIT; + +UPDATE temporal_mltrng SET id = '[7,8)' + WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')); + +TRUNCATE temporal_mltrng, temporal_fk_mltrng2mltrng; + +ALTER TABLE temporal_fk_mltrng2mltrng + DROP CONSTRAINT temporal_fk_mltrng2mltrng_fk; + +TRUNCATE temporal_mltrng, temporal_fk_mltrng2mltrng; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES ('[5,6)', datemultirange(daterange('2018-01-01', '2018-02-01'))); + +DELETE FROM temporal_mltrng WHERE id = '[5,6)'; + +INSERT INTO temporal_mltrng (id, valid_at) VALUES + ('[5,6)', datemultirange(daterange('2018-01-01', '2018-02-01'))), + ('[5,6)', datemultirange(daterange('2018-02-01', '2018-03-01'))); + +INSERT INTO temporal_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[3,4)', datemultirange(daterange('2018-01-05', '2018-01-10')), '[5,6)'); + +DELETE FROM temporal_mltrng WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-02-01', '2018-03-01')); + +DELETE FROM temporal_mltrng WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')); + +BEGIN; + +ALTER TABLE temporal_fk_mltrng2mltrng + ALTER CONSTRAINT temporal_fk_mltrng2mltrng_fk + DEFERRABLE INITIALLY DEFERRED; + +DELETE FROM temporal_mltrng WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')); + +COMMIT; + +CREATE TABLE tp1 partition OF temporal_partitioned_rng FOR VALUES IN ('[1,2)', '[3,4)', '[5,6)', '[7,8)', '[9,10)', '[11,12)'); + +CREATE TABLE tp2 partition OF temporal_partitioned_rng FOR VALUES IN ('[2,3)', '[4,5)', '[6,7)', '[8,9)', '[10,11)', '[12,13)'); + +INSERT INTO temporal_partitioned_rng (id, valid_at, name) VALUES + ('[1,2)', daterange('2000-01-01', '2000-02-01'), 'one'), + ('[1,2)', daterange('2000-02-01', '2000-03-01'), 'one'), + ('[2,3)', daterange('2000-01-01', '2010-01-01'), 'two'); + +CREATE TABLE tfkp1 partition OF temporal_partitioned_fk_rng2rng FOR VALUES IN ('[1,2)', '[3,4)', '[5,6)', '[7,8)', '[9,10)', '[11,12)'); + +CREATE TABLE tfkp2 partition OF temporal_partitioned_fk_rng2rng FOR VALUES IN ('[2,3)', '[4,5)', '[6,7)', '[8,9)', '[10,11)', '[12,13)'); + +INSERT INTO temporal_partitioned_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[1,2)', daterange('2000-01-01', '2000-02-15'), '[1,2)'), + ('[1,2)', daterange('2001-01-01', '2002-01-01'), '[2,3)'), + ('[2,3)', daterange('2000-01-01', '2000-02-15'), '[1,2)'); + +INSERT INTO temporal_partitioned_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[3,4)', daterange('2010-01-01', '2010-02-15'), '[1,2)'); + +INSERT INTO temporal_partitioned_fk_rng2rng (id, valid_at, parent_id) VALUES + ('[3,4)', daterange('2000-01-01', '2000-02-15'), '[3,4)'); + +UPDATE temporal_partitioned_fk_rng2rng SET valid_at = daterange('2000-01-01', '2000-02-13') WHERE id = '[2,3)'; + +UPDATE temporal_partitioned_fk_rng2rng SET id = '[4,5)' WHERE id = '[1,2)'; + +UPDATE temporal_partitioned_fk_rng2rng SET id = '[1,2)' WHERE id = '[4,5)'; + +UPDATE temporal_partitioned_fk_rng2rng SET valid_at = daterange('2000-01-01', '2000-04-01') WHERE id = '[1,2)'; + +TRUNCATE temporal_partitioned_rng, temporal_partitioned_fk_rng2rng; + +INSERT INTO temporal_partitioned_rng (id, valid_at) VALUES ('[5,6)', daterange('2016-01-01', '2016-02-01')); + +UPDATE temporal_partitioned_rng SET valid_at = daterange('2018-01-01', '2018-02-01') WHERE id = '[5,6)'; + +INSERT INTO temporal_partitioned_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-02-01', '2018-03-01')); + +INSERT INTO temporal_partitioned_fk_rng2rng (id, valid_at, parent_id) VALUES ('[3,4)', daterange('2018-01-05', '2018-01-10'), '[5,6)'); + +UPDATE temporal_partitioned_rng SET valid_at = daterange('2016-02-01', '2016-03-01') + WHERE id = '[5,6)' AND valid_at = daterange('2018-02-01', '2018-03-01'); + +UPDATE temporal_partitioned_rng SET valid_at = daterange('2016-01-01', '2016-02-01') + WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +TRUNCATE temporal_partitioned_rng, temporal_partitioned_fk_rng2rng; + +INSERT INTO temporal_partitioned_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-01-01', '2018-02-01')); + +INSERT INTO temporal_partitioned_rng (id, valid_at) VALUES ('[5,6)', daterange('2018-02-01', '2018-03-01')); + +INSERT INTO temporal_partitioned_fk_rng2rng (id, valid_at, parent_id) VALUES ('[3,4)', daterange('2018-01-05', '2018-01-10'), '[5,6)'); + +DELETE FROM temporal_partitioned_rng WHERE id = '[5,6)' AND valid_at = daterange('2018-02-01', '2018-03-01'); + +DELETE FROM temporal_partitioned_rng WHERE id = '[5,6)' AND valid_at = daterange('2018-01-01', '2018-02-01'); + +DROP TABLE temporal_partitioned_fk_rng2rng; + +DROP TABLE temporal_partitioned_rng; + +CREATE TABLE tp1 PARTITION OF temporal_partitioned_mltrng FOR VALUES IN ('[1,2)', '[3,4)', '[5,6)', '[7,8)', '[9,10)', '[11,12)', '[13,14)', '[15,16)', '[17,18)', '[19,20)', '[21,22)', '[23,24)'); + +CREATE TABLE tp2 PARTITION OF temporal_partitioned_mltrng FOR VALUES IN ('[0,1)', '[2,3)', '[4,5)', '[6,7)', '[8,9)', '[10,11)', '[12,13)', '[14,15)', '[16,17)', '[18,19)', '[20,21)', '[22,23)', '[24,25)'); + +INSERT INTO temporal_partitioned_mltrng (id, valid_at, name) VALUES + ('[1,2)', datemultirange(daterange('2000-01-01', '2000-02-01')), 'one'), + ('[1,2)', datemultirange(daterange('2000-02-01', '2000-03-01')), 'one'), + ('[2,3)', datemultirange(daterange('2000-01-01', '2010-01-01')), 'two'); + +CREATE TABLE tfkp1 PARTITION OF temporal_partitioned_fk_mltrng2mltrng FOR VALUES IN ('[1,2)', '[3,4)', '[5,6)', '[7,8)', '[9,10)', '[11,12)', '[13,14)', '[15,16)', '[17,18)', '[19,20)', '[21,22)', '[23,24)'); + +CREATE TABLE tfkp2 PARTITION OF temporal_partitioned_fk_mltrng2mltrng FOR VALUES IN ('[0,1)', '[2,3)', '[4,5)', '[6,7)', '[8,9)', '[10,11)', '[12,13)', '[14,15)', '[16,17)', '[18,19)', '[20,21)', '[22,23)', '[24,25)'); + +INSERT INTO temporal_partitioned_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[1,2)', datemultirange(daterange('2000-01-01', '2000-02-15')), '[1,2)'), + ('[1,2)', datemultirange(daterange('2001-01-01', '2002-01-01')), '[2,3)'), + ('[2,3)', datemultirange(daterange('2000-01-01', '2000-02-15')), '[1,2)'); + +INSERT INTO temporal_partitioned_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[3,4)', datemultirange(daterange('2010-01-01', '2010-02-15')), '[1,2)'); + +INSERT INTO temporal_partitioned_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES + ('[3,4)', datemultirange(daterange('2000-01-01', '2000-02-15')), '[3,4)'); + +UPDATE temporal_partitioned_fk_mltrng2mltrng SET valid_at = datemultirange(daterange('2000-01-01', '2000-02-13')) WHERE id = '[2,3)'; + +UPDATE temporal_partitioned_fk_mltrng2mltrng SET id = '[4,5)' WHERE id = '[1,2)'; + +UPDATE temporal_partitioned_fk_mltrng2mltrng SET id = '[1,2)' WHERE id = '[4,5)'; + +UPDATE temporal_partitioned_fk_mltrng2mltrng SET valid_at = datemultirange(daterange('2000-01-01', '2000-04-01')) WHERE id = '[1,2)'; + +TRUNCATE temporal_partitioned_mltrng, temporal_partitioned_fk_mltrng2mltrng; + +INSERT INTO temporal_partitioned_mltrng (id, valid_at) VALUES ('[5,6)', datemultirange(daterange('2016-01-01', '2016-02-01'))); + +UPDATE temporal_partitioned_mltrng SET valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')) WHERE id = '[5,6)'; + +INSERT INTO temporal_partitioned_mltrng (id, valid_at) VALUES ('[5,6)', datemultirange(daterange('2018-02-01', '2018-03-01'))); + +INSERT INTO temporal_partitioned_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[3,4)', datemultirange(daterange('2018-01-05', '2018-01-10')), '[5,6)'); + +UPDATE temporal_partitioned_mltrng SET valid_at = datemultirange(daterange('2016-02-01', '2016-03-01')) + WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-02-01', '2018-03-01')); + +UPDATE temporal_partitioned_mltrng SET valid_at = datemultirange(daterange('2016-01-01', '2016-02-01')) + WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')); + +TRUNCATE temporal_partitioned_mltrng, temporal_partitioned_fk_mltrng2mltrng; + +INSERT INTO temporal_partitioned_mltrng (id, valid_at) VALUES ('[5,6)', datemultirange(daterange('2018-01-01', '2018-02-01'))); + +INSERT INTO temporal_partitioned_mltrng (id, valid_at) VALUES ('[5,6)', datemultirange(daterange('2018-02-01', '2018-03-01'))); + +INSERT INTO temporal_partitioned_fk_mltrng2mltrng (id, valid_at, parent_id) VALUES ('[3,4)', datemultirange(daterange('2018-01-05', '2018-01-10')), '[5,6)'); + +DELETE FROM temporal_partitioned_mltrng WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-02-01', '2018-03-01')); + +DELETE FROM temporal_partitioned_mltrng WHERE id = '[5,6)' AND valid_at = datemultirange(daterange('2018-01-01', '2018-02-01')); + +DROP TABLE temporal_partitioned_fk_mltrng2mltrng; + +DROP TABLE temporal_partitioned_mltrng; + +RESET datestyle; diff --git a/crates/pgt_pretty_print/tests/data/multi/write_parallel_60.sql b/crates/pgt_pretty_print/tests/data/multi/write_parallel_60.sql new file mode 100644 index 000000000..a1af72897 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/write_parallel_60.sql @@ -0,0 +1,49 @@ +begin; + +set parallel_setup_cost=0; + +set parallel_tuple_cost=0; + +set min_parallel_table_scan_size=0; + +set max_parallel_workers_per_gather=4; + +create table parallel_write as + select length(stringu1) from tenk1 group by length(stringu1); + +create table parallel_write as + select length(stringu1) from tenk1 group by length(stringu1); + +drop table parallel_write; + +select length(stringu1) into parallel_write + from tenk1 group by length(stringu1); + +select length(stringu1) into parallel_write + from tenk1 group by length(stringu1); + +drop table parallel_write; + +create materialized view parallel_mat_view as + select length(stringu1) from tenk1 group by length(stringu1); + +create materialized view parallel_mat_view as + select length(stringu1) from tenk1 group by length(stringu1); + +create unique index on parallel_mat_view(length); + +refresh materialized view parallel_mat_view; + +refresh materialized view concurrently parallel_mat_view; + +drop materialized view parallel_mat_view; + +prepare prep_stmt as select length(stringu1) from tenk1 group by length(stringu1); + +create table parallel_write as execute prep_stmt; + +create table parallel_write as execute prep_stmt; + +drop table parallel_write; + +rollback; diff --git a/crates/pgt_pretty_print/tests/data/multi/xid_60.sql b/crates/pgt_pretty_print/tests/data/multi/xid_60.sql new file mode 100644 index 000000000..933772c83 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/xid_60.sql @@ -0,0 +1,196 @@ +select '010'::xid, + '42'::xid, + '0xffffffff'::xid, + '-1'::xid, + '010'::xid8, + '42'::xid8, + '0xffffffffffffffff'::xid8, + '-1'::xid8; + +select ''::xid; + +select 'asdf'::xid; + +select ''::xid8; + +select 'asdf'::xid8; + +SELECT pg_input_is_valid('42', 'xid'); + +SELECT pg_input_is_valid('asdf', 'xid'); + +SELECT * FROM pg_input_error_info('0xffffffffff', 'xid'); + +SELECT pg_input_is_valid('42', 'xid8'); + +SELECT pg_input_is_valid('asdf', 'xid8'); + +SELECT * FROM pg_input_error_info('0xffffffffffffffffffff', 'xid8'); + +select '1'::xid = '1'::xid; + +select '1'::xid != '1'::xid; + +select '1'::xid8 = '1'::xid8; + +select '1'::xid8 != '1'::xid8; + +select '1'::xid = '1'::xid8::xid; + +select '1'::xid != '1'::xid8::xid; + +select '1'::xid < '2'::xid; + +select '1'::xid <= '2'::xid; + +select '1'::xid > '2'::xid; + +select '1'::xid >= '2'::xid; + +select '1'::xid8 < '2'::xid8, '2'::xid8 < '2'::xid8, '2'::xid8 < '1'::xid8; + +select '1'::xid8 <= '2'::xid8, '2'::xid8 <= '2'::xid8, '2'::xid8 <= '1'::xid8; + +select '1'::xid8 > '2'::xid8, '2'::xid8 > '2'::xid8, '2'::xid8 > '1'::xid8; + +select '1'::xid8 >= '2'::xid8, '2'::xid8 >= '2'::xid8, '2'::xid8 >= '1'::xid8; + +select xid8cmp('1', '2'), xid8cmp('2', '2'), xid8cmp('2', '1'); + +create table xid8_t1 (x xid8); + +insert into xid8_t1 values ('0'), ('010'), ('42'), ('0xffffffffffffffff'), ('-1'); + +select min(x), max(x) from xid8_t1; + +create index on xid8_t1 using btree(x); + +create index on xid8_t1 using hash(x); + +drop table xid8_t1; + +select '12:13:'::pg_snapshot; + +select '12:18:14,16'::pg_snapshot; + +select '12:16:14,14'::pg_snapshot; + +select '31:12:'::pg_snapshot; + +select '0:1:'::pg_snapshot; + +select '12:13:0'::pg_snapshot; + +select '12:16:14,13'::pg_snapshot; + +select pg_input_is_valid('12:13:', 'pg_snapshot'); + +select pg_input_is_valid('31:12:', 'pg_snapshot'); + +select * from pg_input_error_info('31:12:', 'pg_snapshot'); + +select pg_input_is_valid('12:16:14,13', 'pg_snapshot'); + +select * from pg_input_error_info('12:16:14,13', 'pg_snapshot'); + +create temp table snapshot_test ( + nr integer, + snap pg_snapshot +); + +insert into snapshot_test values (1, '12:13:'); + +insert into snapshot_test values (2, '12:20:13,15,18'); + +insert into snapshot_test values (3, '100001:100009:100005,100007,100008'); + +insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131'); + +select snap from snapshot_test order by nr; + +select pg_snapshot_xmin(snap), + pg_snapshot_xmax(snap), + pg_snapshot_xip(snap) +from snapshot_test order by nr; + +select id, pg_visible_in_snapshot(id::text::xid8, snap) +from snapshot_test, generate_series(11, 21) id +where nr = 2; + +select id, pg_visible_in_snapshot(id::text::xid8, snap) +from snapshot_test, generate_series(90, 160) id +where nr = 4; + +select pg_current_xact_id() >= pg_snapshot_xmin(pg_current_snapshot()); + +select pg_visible_in_snapshot(pg_current_xact_id(), pg_current_snapshot()); + +select pg_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013'; + +select pg_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); + +select pg_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013'); + +SELECT pg_snapshot '1:9223372036854775807:3'; + +SELECT pg_snapshot '1:9223372036854775808:3'; + +BEGIN; + +SELECT pg_current_xact_id_if_assigned() IS NULL; + +SELECT pg_current_xact_id() ; + +SELECT pg_current_xact_id_if_assigned() IS NOT DISTINCT FROM xid8 'pg_current_xact_id'; + +COMMIT; + +BEGIN; + +SELECT pg_current_xact_id() AS committed ; + +COMMIT; + +BEGIN; + +SELECT pg_current_xact_id() AS rolledback ; + +ROLLBACK; + +BEGIN; + +SELECT pg_current_xact_id() AS inprogress ; + +SELECT pg_xact_status('committed'::text::xid8) AS committed; + +SELECT pg_xact_status('rolledback'::text::xid8) AS rolledback; + +SELECT pg_xact_status('inprogress'::text::xid8) AS inprogress; + +SELECT pg_xact_status('1'::xid8); + +SELECT pg_xact_status('2'::xid8); + +SELECT pg_xact_status('3'::xid8); + +COMMIT; + +BEGIN; + +CREATE FUNCTION test_future_xid_status(xid8) +RETURNS void +LANGUAGE plpgsql +AS +$$ +BEGIN + PERFORM pg_xact_status($1); + RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected'; +EXCEPTION + WHEN invalid_parameter_value THEN + RAISE NOTICE 'Got expected error for xid in the future'; +END; +$$; + +SELECT test_future_xid_status(('inprogress' + 10000)::text::xid8); + +ROLLBACK; diff --git a/crates/pgt_pretty_print/tests/data/multi/xml_60.sql b/crates/pgt_pretty_print/tests/data/multi/xml_60.sql new file mode 100644 index 000000000..8bc1e8420 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/xml_60.sql @@ -0,0 +1,793 @@ +CREATE TABLE xmltest ( + id int, + data xml +); + +INSERT INTO xmltest VALUES (1, 'one'); + +INSERT INTO xmltest VALUES (2, 'two'); + +INSERT INTO xmltest VALUES (3, 'one', 'xml'); + +SELECT pg_input_is_valid('oneone', 'xml'); + +SELECT message FROM pg_input_error_info('', 'xml'); + +SELECT xmlcomment('test'); + +SELECT xmlcomment('-test'); + +SELECT xmlcomment('test-'); + +SELECT xmlcomment('--test'); + +SELECT xmlcomment('te st'); + +SELECT xmlconcat(xmlcomment('hello'), + xmlelement(NAME qux, 'foo'), + xmlcomment('world')); + +SELECT xmlconcat('hello', 'you'); + +SELECT xmlconcat(1, 2); + +SELECT xmlconcat('bad', '', NULL, ''); + +SELECT xmlconcat('', NULL, ''); + +SELECT xmlconcat(NULL); + +SELECT xmlconcat(NULL, NULL); + +SELECT xmlelement(name element, + xmlattributes (1 as one, 'deuce' as two), + 'content'); + +SELECT xmlelement(name element, + xmlattributes ('unnamed and wrong')); + +SELECT xmlelement(name element, xmlelement(name nested, 'stuff')); + +SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp; + +SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a)); + +SELECT xmlelement(name num, 37); + +SELECT xmlelement(name foo, text 'bar'); + +SELECT xmlelement(name foo, xml 'bar'); + +SELECT xmlelement(name foo, text 'br'); + +SELECT xmlelement(name foo, xml 'br'); + +SELECT xmlelement(name foo, array[1, 2, 3]); + +SET xmlbinary TO base64; + +SELECT xmlelement(name foo, bytea 'bar'); + +SET xmlbinary TO hex; + +SELECT xmlelement(name foo, bytea 'bar'); + +SELECT xmlelement(name foo, xmlattributes(true as bar)); + +SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as bar)); + +SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar)); + +SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'br' as funnier)); + +SELECT xmlparse(content ''); + +SELECT xmlparse(content ' '); + +SELECT xmlparse(content 'abc'); + +SELECT xmlparse(content 'x'); + +SELECT xmlparse(content '&'); + +SELECT xmlparse(content '&idontexist;'); + +SELECT xmlparse(content ''); + +SELECT xmlparse(content ''); + +SELECT xmlparse(content '&idontexist;'); + +SELECT xmlparse(content ''); + +SELECT xmlparse(document ' '); + +SELECT xmlparse(document 'abc'); + +SELECT xmlparse(document 'x'); + +SELECT xmlparse(document '&'); + +SELECT xmlparse(document '&idontexist;'); + +SELECT xmlparse(document ''); + +SELECT xmlparse(document ''); + +SELECT xmlparse(document '&idontexist;'); + +SELECT xmlparse(document ''); + +SELECT xmlpi(name foo); + +SELECT xmlpi(name xml); + +SELECT xmlpi(name xmlstuff); + +SELECT xmlpi(name foo, 'bar'); + +SELECT xmlpi(name foo, 'in?>valid'); + +SELECT xmlpi(name foo, null); + +SELECT xmlpi(name xml, null); + +SELECT xmlpi(name xmlstuff, null); + +SELECT xmlpi(name "xml-stylesheet", 'href="mystyle.css" type="text/css"'); + +SELECT xmlpi(name foo, ' bar'); + +SELECT xmlroot(xml '', version no value, standalone no value); + +SELECT xmlroot(xml '', version '2.0'); + +SELECT xmlroot(xml '', version no value, standalone yes); + +SELECT xmlroot(xml '', version no value, standalone yes); + +SELECT xmlroot(xmlroot(xml '', version '1.0'), version '1.1', standalone no); + +SELECT xmlroot('', version no value, standalone no); + +SELECT xmlroot('', version no value, standalone no value); + +SELECT xmlroot('', version no value); + +SELECT xmlroot ( + xmlelement ( + name gazonk, + xmlattributes ( + 'val' AS name, + 1 + 1 AS num + ), + xmlelement ( + NAME qux, + 'foo' + ) + ), + version '1.0', + standalone yes +); + +SELECT xmlserialize(content data as character varying(20)) FROM xmltest; + +SELECT xmlserialize(content 'good' as char(10)); + +SELECT xmlserialize(document 'bad' as text); + +SELECT xmlserialize(DOCUMENT '42' AS text INDENT); + +SELECT xmlserialize(CONTENT '42' AS text INDENT); + +SELECT xmlserialize(DOCUMENT '42' AS text NO INDENT); + +SELECT xmlserialize(CONTENT '42' AS text NO INDENT); + +SELECT xmlserialize(DOCUMENT '7342' AS text INDENT); + +SELECT xmlserialize(CONTENT '7342' AS text INDENT); + +SELECT xmlserialize(DOCUMENT 'text node73text node42' AS text INDENT); + +SELECT xmlserialize(CONTENT 'text node73text node42' AS text INDENT); + +SELECT xmlserialize(DOCUMENT '42text node73' AS text INDENT); + +SELECT xmlserialize(CONTENT '42text node73' AS text INDENT); + +SELECT xmlserialize(DOCUMENT '' AS text INDENT); + +SELECT xmlserialize(CONTENT '' AS text INDENT); + +SELECT xmlserialize(DOCUMENT ' ' AS text INDENT); + +SELECT xmlserialize(CONTENT ' ' AS text INDENT); + +SELECT xmlserialize(DOCUMENT NULL AS text INDENT); + +SELECT xmlserialize(CONTENT NULL AS text INDENT); + +SELECT xmlserialize(DOCUMENT '73' AS text INDENT); + +SELECT xmlserialize(CONTENT '73' AS text INDENT); + +SELECT xmlserialize(DOCUMENT '' AS text INDENT); + +SELECT xmlserialize(CONTENT '' AS text INDENT); + +SELECT xmlserialize(DOCUMENT '' AS text INDENT); + +SELECT xmlserialize(CONTENT '' AS text INDENT); + +SELECT xmlserialize(DOCUMENT '42' AS text) = xmlserialize(DOCUMENT '42' AS text NO INDENT); + +SELECT xmlserialize(CONTENT '42' AS text) = xmlserialize(CONTENT '42' AS text NO INDENT); + +SELECT xmlserialize(DOCUMENT ' ' AS text INDENT); + +SELECT xmlserialize(CONTENT 'text node ' AS text INDENT); + +SELECT xml 'bar' IS DOCUMENT; + +SELECT xml 'barfoo' IS DOCUMENT; + +SELECT xml '' IS NOT DOCUMENT; + +SELECT xml 'abc' IS NOT DOCUMENT; + +SELECT '<>' IS NOT DOCUMENT; + +SELECT xmlagg(data) FROM xmltest; + +SELECT xmlagg(data) FROM xmltest WHERE id > 10; + +SELECT xmlelement(name employees, xmlagg(xmlelement(name name, name))) FROM emp; + +SELECT xmlpi(name ":::_xml_abc135.%-&_"); + +SELECT xmlpi(name "123"); + +PREPARE foo (xml) AS SELECT xmlconcat('', $1); + +SET XML OPTION DOCUMENT; + +EXECUTE foo (''); + +EXECUTE foo ('bad'); + +SELECT xml ''; + +SET XML OPTION CONTENT; + +EXECUTE foo (''); + +EXECUTE foo ('good'); + +SELECT xml ' '; + +SELECT xml ' '; + +SELECT xml ''; + +SELECT xml ' oops '; + +SELECT xml ' '; + +SELECT xml ''; + +CREATE VIEW xmlview1 AS SELECT xmlcomment('test'); + +CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you'); + +CREATE VIEW xmlview3 AS SELECT xmlelement(name element, xmlattributes (1 as ":one:", 'deuce' as two), 'content&'); + +CREATE VIEW xmlview4 AS SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp; + +CREATE VIEW xmlview5 AS SELECT xmlparse(content 'x'); + +CREATE VIEW xmlview6 AS SELECT xmlpi(name foo, 'bar'); + +CREATE VIEW xmlview7 AS SELECT xmlroot(xml '', version no value, standalone yes); + +CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10)); + +CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text); + +CREATE VIEW xmlview10 AS SELECT xmlserialize(document '42' AS text indent); + +CREATE VIEW xmlview11 AS SELECT xmlserialize(document '42' AS character varying no indent); + +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'xmlview%' ORDER BY 1; + +SELECT xpath('/value', data) FROM xmltest; + +SELECT xpath(NULL, NULL) IS NULL FROM xmltest; + +SELECT xpath('', ''); + +SELECT xpath('//text()', 'number one'); + +SELECT xpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); + +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); + +SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); + +SELECT xpath('//b', 'one two three etc'); + +SELECT xpath('//text()', '<'); + +SELECT xpath('//@value', ''); + +SELECT xpath('''<>''', ''); + +SELECT xpath('count(//*)', ''); + +SELECT xpath('count(//*)=0', ''); + +SELECT xpath('count(//*)=3', ''); + +SELECT xpath('name(/*)', ''); + +SELECT xpath('/nosuchtag', ''); + +SELECT xpath('root', ''); + +DO $$ +DECLARE + xml_declaration text := ''; + degree_symbol text; + res xml[]; +BEGIN + -- Per the documentation, except when the server encoding is UTF8, xpath() + -- may not work on non-ASCII data. The untranslatable_character and + -- undefined_function traps below, currently dead code, will become relevant + -- if we remove this limitation. + IF current_setting('server_encoding') <> 'UTF8' THEN + RAISE LOG 'skip: encoding % unsupported for xpath', + current_setting('server_encoding'); + RETURN; + END IF; + + degree_symbol := convert_from('\xc2b0', 'UTF8'); + res := xpath('text()', (xml_declaration || + '' || degree_symbol || '')::xml); + IF degree_symbol <> res[1]::text THEN + RAISE 'expected % (%), got % (%)', + degree_symbol, convert_to(degree_symbol, 'UTF8'), + res[1], convert_to(res[1]::text, 'UTF8'); + END IF; +EXCEPTION + -- character with byte sequence 0xc2 0xb0 in encoding "UTF8" has no equivalent in encoding "LATIN8" + WHEN untranslatable_character + -- default conversion function for encoding "UTF8" to "MULE_INTERNAL" does not exist + OR undefined_function + -- unsupported XML feature + OR feature_not_supported THEN + RAISE LOG 'skip: %', SQLERRM; +END +$$; + +SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF 'Bidford-on-AvonCwmbranBristol'); + +SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF 'Bidford-on-AvonCwmbranBristol'); + +SELECT xmlexists('count(/nosuchtag)' PASSING BY REF ''); + +SELECT xpath_exists('//town[text() = ''Toronto'']','Bidford-on-AvonCwmbranBristol'::xml); + +SELECT xpath_exists('//town[text() = ''Cwmbran'']','Bidford-on-AvonCwmbranBristol'::xml); + +SELECT xpath_exists('count(/nosuchtag)', ''::xml); + +INSERT INTO xmltest VALUES (4, 'BudvarfreeCarlinglots'::xml); + +INSERT INTO xmltest VALUES (5, 'MolsonfreeCarlinglots'::xml); + +INSERT INTO xmltest VALUES (6, 'BudvarfreeCarlinglots'::xml); + +INSERT INTO xmltest VALUES (7, 'MolsonfreeCarlinglots'::xml); + +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING data); + +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING BY REF data BY REF); + +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers' PASSING BY REF data); + +SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molson'']' PASSING BY REF data); + +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beer',data); + +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers',data); + +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers/name[text() = ''Molson'']',data); + +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beer',data,ARRAY[ARRAY['myns','http://myns.com']]); + +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers',data,ARRAY[ARRAY['myns','http://myns.com']]); + +SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers/myns:name[text() = ''Molson'']',data,ARRAY[ARRAY['myns','http://myns.com']]); + +CREATE TABLE query ( expr TEXT ); + +INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']'); + +SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data); + +SELECT xml_is_well_formed_document('bar'); + +SELECT xml_is_well_formed_document('abc'); + +SELECT xml_is_well_formed_content('bar'); + +SELECT xml_is_well_formed_content('abc'); + +SET xmloption TO DOCUMENT; + +SELECT xml_is_well_formed('abc'); + +SELECT xml_is_well_formed('<>'); + +SELECT xml_is_well_formed(''); + +SELECT xml_is_well_formed('bar'); + +SELECT xml_is_well_formed('barbaz'); + +SELECT xml_is_well_formed('number one'); + +SELECT xml_is_well_formed('bar'); + +SELECT xml_is_well_formed('bar'); + +SELECT xml_is_well_formed('&'); + +SELECT xml_is_well_formed('&idontexist;'); + +SELECT xml_is_well_formed(''); + +SELECT xml_is_well_formed(''); + +SELECT xml_is_well_formed('&idontexist;'); + +SET xmloption TO CONTENT; + +SELECT xml_is_well_formed('abc'); + +SELECT xpath('/*', ''); + +SELECT xpath('/*', ''); + +SELECT xpath('/*', ''); + +SELECT XMLPARSE(DOCUMENT ']>&c;'); + +SELECT XMLPARSE(DOCUMENT ']>&c;'); + +SELECT XMLPARSE(DOCUMENT ' '); + +CREATE TABLE xmldata(data xml); + +INSERT INTO xmldata VALUES(' + + AU + Australia + 3 + + + CN + China + 3 + + + HK + HongKong + 3 + + + IN + India + 3 + + + JP + Japan + 3Sinzo Abe + + + SG + Singapore + 3791 + +'); + +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); + +CREATE VIEW xmltableview1 AS SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); + +SELECT * FROM xmltableview1; + +SELECT * FROM xmltableview1; + +SELECT * FROM xmltableview1; + +SELECT * FROM XMLTABLE (ROW () PASSING null COLUMNS v1 timestamp) AS f (v1, v2); + +SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), + '/zz:rows/zz:row' + PASSING '10' + COLUMNS a int PATH 'zz:a'); + +CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"), + '/Zz:rows/Zz:row' + PASSING '10' + COLUMNS a int PATH 'Zz:a'); + +SELECT * FROM xmltableview2; + +SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), + '/rows/row' + PASSING '10' + COLUMNS a int PATH 'a'); + +SELECT * FROM XMLTABLE('.' + PASSING '' + COLUMNS a text PATH 'foo/namespace::node()'); + +PREPARE pp AS +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); + +EXECUTE pp; + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int); + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id FOR ORDINALITY, "COUNTRY_NAME" text, "REGION_ID" int); + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int); + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id'); + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id FOR ORDINALITY); + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int, rawdata xml PATH '.'); + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS id int PATH '@id', "COUNTRY_NAME" text, "REGION_ID" int, rawdata xml PATH './*'); + +SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text); + +SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text PATH 'element/text()'); + +select * from xmltable('d/r' passing ' &"<>!foo]]>2' columns c text); + +SELECT * FROM xmltable('/x/a' PASSING ''"&<>' COLUMNS ent text); + +SELECT * FROM xmltable('/x/a' PASSING ''"&<>' COLUMNS ent xml); + +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); + +SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) WHERE "COUNTRY_NAME" = 'Japan'; + +SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) AS f WHERE "COUNTRY_NAME" = 'Japan'; + +SELECT f.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" or COUNTRY_NAME="India"]' PASSING data COLUMNS "COUNTRY_NAME" text, "REGION_ID" int) AS f WHERE "COUNTRY_NAME" = 'Japan'; + +INSERT INTO xmldata VALUES(' + + CZ + Czech Republic + 2Milos Zeman + + + DE + Germany + 2 + + + FR + France + 2 + +'); + +INSERT INTO xmldata VALUES(' + + EG + Egypt + 1 + + + SD + Sudan + 1 + +'); + +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); + +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') + WHERE region_id = 2; + +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE', + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified') + WHERE region_id = 2; + +SELECT xmltable.* + FROM (SELECT data FROM xmldata) x, + LATERAL XMLTABLE('/ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + _id FOR ORDINALITY, + country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_id text PATH 'COUNTRY_ID', + region_id int PATH 'REGION_ID', + size float PATH 'SIZE' NOT NULL, + unit text PATH 'SIZE/@unit', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); + +WITH + x AS (SELECT proname, proowner, procost::numeric, pronargs, + array_to_string(proargnames,',') as proargnames, + case when proargtypes <> '' then array_to_string(proargtypes::oid[],',') end as proargtypes + FROM pg_proc WHERE proname = 'f_leak'), + y AS (SELECT xmlelement(name proc, + xmlforest(proname, proowner, + procost, pronargs, + proargnames, proargtypes)) as proc + FROM x), + z AS (SELECT xmltable.* + FROM y, + LATERAL xmltable('/proc' PASSING proc + COLUMNS proname name, + proowner oid, + procost float, + pronargs int, + proargnames text, + proargtypes text)) + SELECT * FROM z + EXCEPT SELECT * FROM x; + +WITH + x AS (SELECT proname, proowner, procost::numeric, pronargs, + array_to_string(proargnames,',') as proargnames, + case when proargtypes <> '' then array_to_string(proargtypes::oid[],',') end as proargtypes + FROM pg_proc), + y AS (SELECT xmlelement(name data, + xmlagg(xmlelement(name proc, + xmlforest(proname, proowner, procost, + pronargs, proargnames, proargtypes)))) as doc + FROM x), + z AS (SELECT xmltable.* + FROM y, + LATERAL xmltable('/data/proc' PASSING doc + COLUMNS proname name, + proowner oid, + procost float, + pronargs int, + proargnames text, + proargtypes text)) + SELECT * FROM z + EXCEPT SELECT * FROM x; + +CREATE TABLE xmltest2(x xml, _path text); + +INSERT INTO xmltest2 VALUES('1', 'A'); + +INSERT INTO xmltest2 VALUES('2', 'B'); + +INSERT INTO xmltest2 VALUES('3', 'C'); + +INSERT INTO xmltest2 VALUES('2', 'D'); + +SELECT xmltable.* FROM xmltest2, LATERAL xmltable('/d/r' PASSING x COLUMNS a int PATH '' || lower(_path) || 'c'); + +SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH '.'); + +SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH 'x' DEFAULT ascii(_path) - 54); + +SELECT * FROM XMLTABLE('*' PASSING 'a' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"', e integer PATH 'string-length(.)'); + +SELECT * FROM XMLTABLE('*' PASSING 'pre&deeppost' COLUMNS x xml PATH '/e/n2', y xml PATH '/'); + +SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '""', b xml PATH '""'); + +SELECT xmltext(NULL); + +SELECT xmltext(''); + +SELECT xmltext(' '); + +SELECT xmltext('foo `$_-+?=*^%!|/\()[]{}'); + +SELECT xmltext('foo & <"bar">'); + +SELECT xmltext('x'|| '

73

'::xml || .42 || true || 'j'::char); diff --git a/crates/pgt_pretty_print/tests/data/multi/xmlmap_60.sql b/crates/pgt_pretty_print/tests/data/multi/xmlmap_60.sql new file mode 100644 index 000000000..bc2430080 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/multi/xmlmap_60.sql @@ -0,0 +1,53 @@ +CREATE SCHEMA testxmlschema; + +CREATE TABLE testxmlschema.test1 (a int, b text); + +INSERT INTO testxmlschema.test1 VALUES (1, 'one'), (2, 'two'), (-1, null); + +CREATE DOMAIN testxmldomain AS varchar; + +CREATE TABLE testxmlschema.test2 (z int, y varchar(500), x char(6), + w numeric(9,2), v smallint, u bigint, t real, + s time, stz timetz, r timestamp, rtz timestamptz, q date, + p xml, o testxmldomain, n bool, m bytea, aaa text); + +ALTER TABLE testxmlschema.test2 DROP COLUMN aaa; + +INSERT INTO testxmlschema.test2 VALUES (55, 'abc', 'def', + 98.6, 2, 999, 0, + '21:07', '21:11 +05', '2009-06-08 21:07:30', '2009-06-08 21:07:30 -07', '2009-06-08', + NULL, 'ABC', true, 'XYZ'); + +SELECT table_to_xml('testxmlschema.test1', false, false, ''); + +SELECT table_to_xml('testxmlschema.test1', true, false, 'foo'); + +SELECT table_to_xml('testxmlschema.test1', false, true, ''); + +SELECT table_to_xml('testxmlschema.test1', true, true, ''); + +SELECT table_to_xml('testxmlschema.test2', false, false, ''); + +SELECT table_to_xmlschema('testxmlschema.test1', false, false, ''); + +SELECT table_to_xmlschema('testxmlschema.test1', true, false, ''); + +SELECT table_to_xmlschema('testxmlschema.test1', false, true, 'foo'); + +SELECT table_to_xmlschema('testxmlschema.test1', true, true, ''); + +SELECT table_to_xmlschema('testxmlschema.test2', false, false, ''); + +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, false, ''); + +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, false, ''); + +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', false, true, ''); + +SELECT table_to_xml_and_xmlschema('testxmlschema.test1', true, true, 'foo'); + +SELECT query_to_xml('SELECT * FROM testxmlschema.test1', false, false, ''); + +SELECT query_to_xmlschema('SELECT * FROM testxmlschema.test1', false, false, ''); + +SELECT query_to_xml_and_xmlschema('SELECT * FROM testxmlschema.test1', true, true, ''); diff --git a/crates/pgt_pretty_print/tests/data/single/aggref_0_60.sql b/crates/pgt_pretty_print/tests/data/single/aggref_0_60.sql new file mode 100644 index 000000000..8217dece0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/aggref_0_60.sql @@ -0,0 +1 @@ +SELECT COUNT(*) FROM users; diff --git a/crates/pgt_pretty_print/tests/data/single/alter_collation_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_collation_stmt_0_60.sql new file mode 100644 index 000000000..32c4ed696 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_collation_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER COLLATION myschema.mycollation REFRESH VERSION; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_database_refresh_coll_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_database_refresh_coll_stmt_0_60.sql new file mode 100644 index 000000000..48316fe73 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_database_refresh_coll_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER DATABASE mydb REFRESH COLLATION VERSION; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_database_set_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_database_set_stmt_0_60.sql new file mode 100644 index 000000000..fec7cdf29 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_database_set_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER DATABASE mydb SET search_path TO myschema; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_database_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_database_stmt_0_60.sql new file mode 100644 index 000000000..f3021849d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_database_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER DATABASE mydb CONNECTION LIMIT 100; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_default_privileges_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_default_privileges_stmt_0_60.sql new file mode 100644 index 000000000..b1709f40a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_default_privileges_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO reader; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_domain_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_domain_stmt_0_60.sql new file mode 100644 index 000000000..55dcc2b48 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_domain_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER DOMAIN myschema.mydomain DROP CONSTRAINT mycheck; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_event_trig_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_event_trig_stmt_0_60.sql new file mode 100644 index 000000000..8eacd2b84 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_event_trig_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER EVENT TRIGGER my_event_trigger ENABLE; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_extension_contents_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_extension_contents_stmt_0_60.sql new file mode 100644 index 000000000..eb105dee6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_extension_contents_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER EXTENSION hstore ADD FUNCTION hstore_in(cstring); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_extension_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_extension_stmt_0_60.sql new file mode 100644 index 000000000..bad504fb5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_extension_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER EXTENSION hstore UPDATE TO '1.8'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_fdw_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_fdw_stmt_0_60.sql new file mode 100644 index 000000000..0ab72f93f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_fdw_stmt_0_60.sql @@ -0,0 +1,2 @@ +ALTER FOREIGN DATA WRAPPER postgres_fdw +OPTIONS (host 'newhost.example.com'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_foreign_server_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_foreign_server_stmt_0_60.sql new file mode 100644 index 000000000..db890b19b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_foreign_server_stmt_0_60.sql @@ -0,0 +1,2 @@ +ALTER SERVER myserver VERSION '1.2' +OPTIONS (host 'new.example.com'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_function_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_function_stmt_0_60.sql new file mode 100644 index 000000000..a54441b31 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_function_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER FUNCTION my_function(integer) IMMUTABLE; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_object_depends_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_object_depends_stmt_0_60.sql new file mode 100644 index 000000000..61bb21305 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_object_depends_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER FUNCTION my_func(integer) DEPENDS ON EXTENSION btree_gist; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_object_schema_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_object_schema_stmt_0_60.sql new file mode 100644 index 000000000..d4539f54f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_object_schema_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TABLE users SET SCHEMA public; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_op_family_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_op_family_stmt_0_60.sql new file mode 100644 index 000000000..fe90b7cb7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_op_family_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER OPERATOR FAMILY myopfamily USING btree ADD OPERATOR 1 < (int4, int4); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_operator_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_operator_stmt_0_60.sql new file mode 100644 index 000000000..12e67219a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_operator_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER OPERATOR + (int4, int4) OWNER TO postgres; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_owner_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_owner_stmt_0_60.sql new file mode 100644 index 000000000..1de373c3a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_owner_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER DATABASE mydb OWNER TO postgres; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_policy_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_policy_stmt_0_60.sql new file mode 100644 index 000000000..ac8c4a0cd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_policy_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER POLICY mypolicy ON mytable TO PUBLIC; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_publication_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_publication_stmt_0_60.sql new file mode 100644 index 000000000..9c0cbb59c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_publication_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER PUBLICATION mypub SET TABLE mytable; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_role_set_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_role_set_stmt_0_60.sql new file mode 100644 index 000000000..8604e0829 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_role_set_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER ROLE admin SET search_path TO myschema, public; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_seq_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_seq_stmt_0_60.sql new file mode 100644 index 000000000..676823783 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_seq_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER SEQUENCE myseq RESTART WITH 100; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_stats_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_stats_stmt_0_60.sql new file mode 100644 index 000000000..5588c2206 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_stats_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER STATISTICS myschema.mystat SET STATISTICS 100; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_subscription_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_subscription_stmt_0_60.sql new file mode 100644 index 000000000..466ec4805 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_subscription_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER SUBSCRIPTION mysub SET PUBLICATION mypub; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_system_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_system_stmt_0_60.sql new file mode 100644 index 000000000..ee25b9686 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_system_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER SYSTEM SET max_connections TO 200; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_table_move_all_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_table_move_all_stmt_0_60.sql new file mode 100644 index 000000000..93bea04e3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_table_move_all_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TABLE ALL IN TABLESPACE myspace SET TABLESPACE newspace; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_table_owner_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_table_owner_0_60.sql new file mode 100644 index 000000000..9cc5d04d2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_table_owner_0_60.sql @@ -0,0 +1 @@ +ALTER TABLE users OWNER TO postgres; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_table_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_table_stmt_0_60.sql new file mode 100644 index 000000000..7b008ffda --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_table_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN email TEXT; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_tablespace_options_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_tablespace_options_stmt_0_60.sql new file mode 100644 index 000000000..a07993393 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_tablespace_options_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TABLESPACE myspace SET (seq_page_cost = 1.5); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_tsconfiguration_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_tsconfiguration_stmt_0_60.sql new file mode 100644 index 000000000..549f727c3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_tsconfiguration_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TEXT SEARCH CONFIGURATION myconfig ADD MAPPING FOR word WITH simple; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_tsdictionary_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_tsdictionary_stmt_0_60.sql new file mode 100644 index 000000000..443c1e90c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_tsdictionary_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TEXT SEARCH DICTIONARY my_dict (StopWords = 'russian', Language = 'russian'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_type_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_type_stmt_0_60.sql new file mode 100644 index 000000000..693e4be45 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_type_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TYPE mytype ADD VALUE 'newvalue'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/alter_user_mapping_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/alter_user_mapping_stmt_0_60.sql new file mode 100644 index 000000000..a98d51a3b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/alter_user_mapping_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER USER MAPPING FOR myuser SERVER myserver OPTIONS (ADD user 'newuser'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/array_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/array_expr_0_60.sql new file mode 100644 index 000000000..ee1dbbccd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/array_expr_0_60.sql @@ -0,0 +1 @@ +SELECT ARRAY[1, 2, 3]; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/bit_string_0_60.sql b/crates/pgt_pretty_print/tests/data/single/bit_string_0_60.sql new file mode 100644 index 000000000..1d462bd6b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/bit_string_0_60.sql @@ -0,0 +1 @@ +SELECT B'10101'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/bool_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/bool_expr_0_60.sql new file mode 100644 index 000000000..ef79e136b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/bool_expr_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM users WHERE active = true AND age >= 18; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/boolean_test_0_60.sql b/crates/pgt_pretty_print/tests/data/single/boolean_test_0_60.sql new file mode 100644 index 000000000..4117d7a7b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/boolean_test_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM users WHERE active IS TRUE; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/break_parent_test_80.sql b/crates/pgt_pretty_print/tests/data/single/break_parent_test_80.sql new file mode 100644 index 000000000..58fb488a8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/break_parent_test_80.sql @@ -0,0 +1 @@ +SELECT very_long_function_name(short_arg, other_arg) FROM test_table \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/call_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/call_stmt_0_60.sql new file mode 100644 index 000000000..1899561ef --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/call_stmt_0_60.sql @@ -0,0 +1 @@ +CALL my_procedure('test', 123); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/case_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/case_expr_0_60.sql new file mode 100644 index 000000000..a4acf620e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/case_expr_0_60.sql @@ -0,0 +1 @@ +SELECT CASE WHEN x = 1 THEN 'one' ELSE 'other' END; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/checkpoint_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/checkpoint_stmt_0_60.sql new file mode 100644 index 000000000..1a3ffce1a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/checkpoint_stmt_0_60.sql @@ -0,0 +1 @@ +CHECKPOINT; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/close_portal_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/close_portal_stmt_0_60.sql new file mode 100644 index 000000000..0ec6a86c9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/close_portal_stmt_0_60.sql @@ -0,0 +1 @@ +CLOSE mycursor; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/cluster_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/cluster_stmt_0_60.sql new file mode 100644 index 000000000..51b1de7bf --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/cluster_stmt_0_60.sql @@ -0,0 +1 @@ +CLUSTER users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/coalesce_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/coalesce_expr_0_60.sql new file mode 100644 index 000000000..53a91d007 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/coalesce_expr_0_60.sql @@ -0,0 +1 @@ +SELECT COALESCE(name, 'Anonymous'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/coerce_via_io_0_60.sql b/crates/pgt_pretty_print/tests/data/single/coerce_via_io_0_60.sql new file mode 100644 index 000000000..0b41251f8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/coerce_via_io_0_60.sql @@ -0,0 +1 @@ +SELECT '123'::integer \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/collate_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/collate_expr_0_60.sql new file mode 100644 index 000000000..ef38fcaaa --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/collate_expr_0_60.sql @@ -0,0 +1 @@ +SELECT name COLLATE "en_US" FROM users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/comment_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/comment_stmt_0_60.sql new file mode 100644 index 000000000..c17223ed1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/comment_stmt_0_60.sql @@ -0,0 +1 @@ +COMMENT ON TABLE customers IS 'Customer information'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_0_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_0_60.sql new file mode 100644 index 000000000..6d4d5fb6c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_0_60.sql @@ -0,0 +1,189 @@ +with recursive +pks_fks as ( + -- pk + fk referencing col + select + contype::text as contype, + conname, + array_length(conkey, 1) as ncol, + conrelid as resorigtbl, + col as resorigcol, + ord + from pg_constraint + left join lateral unnest(conkey) with ordinality as _(col, ord) on true + where contype IN ('p', 'f') + union + -- fk referenced col + select + concat(contype, '_ref') as contype, + conname, + array_length(confkey, 1) as ncol, + confrelid, + col, + ord + from pg_constraint + left join lateral unnest(confkey) with ordinality as _(col, ord) on true + where contype='f' +), +views as ( + select + c.oid as view_id, + n.nspname as view_schema, + c.relname as view_name, + r.ev_action as view_definition + from pg_class c + join pg_namespace n on n.oid = c.relnamespace + join pg_rewrite r on r.ev_class = c.oid + where c.relkind in ('v', 'm') +), +transform_json as ( + select + view_id, view_schema, view_name, + -- the following formatting is without indentation on purpose + -- to allow simple diffs, with less whitespace noise + replace( + replace( + replace( + replace( + replace( + replace( + replace( + regexp_replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + view_definition::text, + -- This conversion to json is heavily optimized for performance. + -- The general idea is to use as few regexp_replace() calls as possible. + -- Simple replace() is a lot faster, so we jump through some hoops + -- to be able to use regexp_replace() only once. + -- This has been tested against a huge schema with 250+ different views. + -- The unit tests do NOT reflect all possible inputs. Be careful when changing this! + -- ----------------------------------------------- + -- pattern | replacement | flags + -- ----------------------------------------------- + -- <> in pg_node_tree is the same as null in JSON, but due to very poor performance of json_typeof + -- we need to make this an empty array here to prevent json_array_elements from throwing an error + -- when the targetList is null. + -- We'll need to put it first, to make the node protection below work for node lists that start with + -- null: (<> ..., too. This is the case for coldefexprs, when the first column does not have a default value. + '<>' , '()' + -- , is not part of the pg_node_tree format, but used in the regex. + -- This removes all , that might be part of column names. + ), ',' , '' + -- The same applies for { and }, although those are used a lot in pg_node_tree. + -- We remove the escaped ones, which might be part of column names again. + ), E'\\\\{' , '' + ), E'\\\\}' , '' + -- The fields we need are formatted as json manually to protect them from the regex. + ), ' :targetList ' , ',"targetList":' + ), ' :resno ' , ',"resno":' + ), ' :resorigtbl ' , ',"resorigtbl":' + ), ' :resorigcol ' , ',"resorigcol":' + -- Make the regex also match the node type, e.g. \`{QUERY ...\`, to remove it in one pass. + ), '{' , '{ :' + -- Protect node lists, which start with \`({\` or \`((\` from the greedy regex. + -- The extra \`{\` is removed again later. + ), '((' , '{((' + ), '({' , '{({' + -- This regex removes all unused fields to avoid the need to format all of them correctly. + -- This leads to a smaller json result as well. + -- Removal stops at \`,\` for used fields (see above) and \`}\` for the end of the current node. + -- Nesting can't be parsed correctly with a regex, so we stop at \`{\` as well and + -- add an empty key for the followig node. + ), ' :[^}{,]+' , ',"":' , 'g' + -- For performance, the regex also added those empty keys when hitting a \`,\` or \`}\`. + -- Those are removed next. + ), ',"":}' , '}' + ), ',"":,' , ',' + -- This reverses the "node list protection" from above. + ), '{(' , '(' + -- Every key above has been added with a \`,\` so far. The first key in an object doesn't need it. + ), '{,' , '{' + -- pg_node_tree has \`()\` around lists, but JSON uses \`[]\` + ), '(' , '[' + ), ')' , ']' + -- pg_node_tree has \` \` between list items, but JSON uses \`,\` + ), ' ' , ',' + )::json as view_definition + from views +), +target_entries as( + select + view_id, view_schema, view_name, + json_array_elements(view_definition->0->'targetList') as entry + from transform_json +), +results as( + select + view_id, view_schema, view_name, + (entry->>'resno')::int as view_column, + (entry->>'resorigtbl')::oid as resorigtbl, + (entry->>'resorigcol')::int as resorigcol + from target_entries +), +-- CYCLE detection according to PG docs: https://www.postgresql.org/docs/current/queries-with.html#QUERIES-WITH-CYCLE +-- Can be replaced with CYCLE clause once PG v13 is EOL. +recursion(view_id, view_schema, view_name, view_column, resorigtbl, resorigcol, is_cycle, path) as( + select + r.*, + false, + ARRAY[resorigtbl] + from results r + where true + union all + select + view.view_id, + view.view_schema, + view.view_name, + view.view_column, + tab.resorigtbl, + tab.resorigcol, + tab.resorigtbl = ANY(path), + path || tab.resorigtbl + from recursion view + join results tab on view.resorigtbl=tab.view_id and view.resorigcol=tab.view_column + where not is_cycle +), +repeated_references as( + select + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol, + array_agg(attname) as view_columns + from recursion + join pg_attribute vcol on vcol.attrelid = view_id and vcol.attnum = view_column + group by + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol +) +select + sch.nspname as table_schema, + tbl.relname as table_name, + rep.view_schema, + rep.view_name, + pks_fks.conname as constraint_name, + pks_fks.contype as constraint_type, + jsonb_agg( + jsonb_build_object('table_column', col.attname, 'view_columns', view_columns) order by pks_fks.ord + ) as column_dependencies +from repeated_references rep +join pks_fks using (resorigtbl, resorigcol) +join pg_class tbl on tbl.oid = rep.resorigtbl +join pg_attribute col on col.attrelid = tbl.oid and col.attnum = rep.resorigcol +join pg_namespace sch on sch.oid = tbl.relnamespace +group by sch.nspname, tbl.relname, rep.view_schema, rep.view_name, pks_fks.conname, pks_fks.contype, pks_fks.ncol +-- make sure we only return key for which all columns are referenced in the view - no partial PKs or FKs +having ncol = array_length(array_agg(row(col.attname, view_columns) order by pks_fks.ord), 1) diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_0_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_0_60.sql new file mode 100644 index 000000000..5a61fae57 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_0_60.sql @@ -0,0 +1,24 @@ + -- pk + fk referencing col + select + contype::text as contype, + conname, + array_length(conkey, 1) as ncol, + conrelid as resorigtbl, + col as resorigcol, + ord + from pg_constraint + left join lateral unnest(conkey) with ordinality as _(col, ord) on true + where contype IN ('p', 'f') + union + -- fk referenced col + select + concat(contype, '_ref') as contype, + conname, + array_length(confkey, 1) as ncol, + confrelid, + col, + ord + from pg_constraint + left join lateral unnest(confkey) with ordinality as _(col, ord) on true + where contype='f' + diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_1_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_1_60.sql new file mode 100644 index 000000000..d646858d3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_1_60.sql @@ -0,0 +1,9 @@ + select + c.oid as view_id, + n.nspname as view_schema, + c.relname as view_name, + r.ev_action as view_definition + from pg_class c + join pg_namespace n on n.oid = c.relnamespace + join pg_rewrite r on r.ev_class = c.oid + where c.relkind in ('v', 'm') diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_2_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_2_60.sql new file mode 100644 index 000000000..4b2e666f7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_2_60.sql @@ -0,0 +1,78 @@ + select + view_id, view_schema, view_name, + -- the following formatting is without indentation on purpose + -- to allow simple diffs, with less whitespace noise + replace( + replace( + replace( + replace( + replace( + replace( + replace( + regexp_replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + view_definition::text, + -- This conversion to json is heavily optimized for performance. + -- The general idea is to use as few regexp_replace() calls as possible. + -- Simple replace() is a lot faster, so we jump through some hoops + -- to be able to use regexp_replace() only once. + -- This has been tested against a huge schema with 250+ different views. + -- The unit tests do NOT reflect all possible inputs. Be careful when changing this! + -- ----------------------------------------------- + -- pattern | replacement | flags + -- ----------------------------------------------- + -- <> in pg_node_tree is the same as null in JSON, but due to very poor performance of json_typeof + -- we need to make this an empty array here to prevent json_array_elements from throwing an error + -- when the targetList is null. + -- We'll need to put it first, to make the node protection below work for node lists that start with + -- null: (<> ..., too. This is the case for coldefexprs, when the first column does not have a default value. + '<>' , '()' + -- , is not part of the pg_node_tree format, but used in the regex. + -- This removes all , that might be part of column names. + ), ',' , '' + -- The same applies for { and }, although those are used a lot in pg_node_tree. + -- We remove the escaped ones, which might be part of column names again. + ), E'\\\\{' , '' + ), E'\\\\}' , '' + -- The fields we need are formatted as json manually to protect them from the regex. + ), ' :targetList ' , ',"targetList":' + ), ' :resno ' , ',"resno":' + ), ' :resorigtbl ' , ',"resorigtbl":' + ), ' :resorigcol ' , ',"resorigcol":' + -- Make the regex also match the node type, e.g. \`{QUERY ...\`, to remove it in one pass. + ), '{' , '{ :' + -- Protect node lists, which start with \`({\` or \`((\` from the greedy regex. + -- The extra \`{\` is removed again later. + ), '((' , '{((' + ), '({' , '{({' + -- This regex removes all unused fields to avoid the need to format all of them correctly. + -- This leads to a smaller json result as well. + -- Removal stops at \`,\` for used fields (see above) and \`}\` for the end of the current node. + -- Nesting can't be parsed correctly with a regex, so we stop at \`{\` as well and + -- add an empty key for the followig node. + ), ' :[^}{,]+' , ',"":' , 'g' + -- For performance, the regex also added those empty keys when hitting a \`,\` or \`}\`. + -- Those are removed next. + ), ',"":}' , '}' + ), ',"":,' , ',' + -- This reverses the "node list protection" from above. + ), '{(' , '(' + -- Every key above has been added with a \`,\` so far. The first key in an object doesn't need it. + ), '{,' , '{' + -- pg_node_tree has \`()\` around lists, but JSON uses \`[]\` + ), '(' , '[' + ), ')' , ']' + -- pg_node_tree has \` \` between list items, but JSON uses \`,\` + ), ' ' , ',' + )::json as view_definition + from views diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_3_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_3_60.sql new file mode 100644 index 000000000..ef2b338e3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_3_60.sql @@ -0,0 +1,4 @@ + select + view_id, view_schema, view_name, + json_array_elements(view_definition->0->'targetList') as entry + from transform_json diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_4_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_4_60.sql new file mode 100644 index 000000000..967b3be79 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_4_60.sql @@ -0,0 +1,6 @@ + select + view_id, view_schema, view_name, + (entry->>'resno')::int as view_column, + (entry->>'resorigtbl')::oid as resorigtbl, + (entry->>'resorigcol')::int as resorigcol + from target_entries diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_5_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_5_60.sql new file mode 100644 index 000000000..0d37ffbae --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_5_60.sql @@ -0,0 +1,19 @@ + select + r.*, + false, + ARRAY[resorigtbl] + from results r + where true + union all + select + view.view_id, + view.view_schema, + view.view_name, + view.view_column, + tab.resorigtbl, + tab.resorigcol, + tab.resorigtbl = ANY(path), + path || tab.resorigtbl + from recursion view + join results tab on view.resorigtbl=tab.view_id and view.resorigcol=tab.view_column + where not is_cycle diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_6_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_6_60.sql new file mode 100644 index 000000000..b86afb778 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_6_60.sql @@ -0,0 +1,15 @@ + select + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol, + array_agg(attname) as view_columns + from recursion + join pg_attribute vcol on vcol.attrelid = view_id and vcol.attnum = view_column + group by + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol diff --git a/crates/pgt_pretty_print/tests/data/single/complex_select_part_7_60.sql b/crates/pgt_pretty_print/tests/data/single/complex_select_part_7_60.sql new file mode 100644 index 000000000..c258256ff --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/complex_select_part_7_60.sql @@ -0,0 +1,18 @@ +select + sch.nspname as table_schema, + tbl.relname as table_name, + rep.view_schema, + rep.view_name, + pks_fks.conname as constraint_name, + pks_fks.contype as constraint_type, + jsonb_agg( + jsonb_build_object('table_column', col.attname, 'view_columns', view_columns) order by pks_fks.ord + ) as column_dependencies +from repeated_references rep +join pks_fks using (resorigtbl, resorigcol) +join pg_class tbl on tbl.oid = rep.resorigtbl +join pg_attribute col on col.attrelid = tbl.oid and col.attnum = rep.resorigcol +join pg_namespace sch on sch.oid = tbl.relnamespace +group by sch.nspname, tbl.relname, rep.view_schema, rep.view_name, pks_fks.conname, pks_fks.contype, pks_fks.ncol +-- make sure we only return key for which all columns are referenced in the view - no partial PKs or FKs +having ncol = array_length(array_agg(row(col.attname, view_columns) order by pks_fks.ord), 1) diff --git a/crates/pgt_pretty_print/tests/data/single/composite_type_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/composite_type_stmt_0_60.sql new file mode 100644 index 000000000..093b0e708 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/composite_type_stmt_0_60.sql @@ -0,0 +1,4 @@ +CREATE TYPE complex AS ( + r double precision, + i double precision +) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/constraints_set_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/constraints_set_stmt_0_60.sql new file mode 100644 index 000000000..6b453575c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/constraints_set_stmt_0_60.sql @@ -0,0 +1 @@ +SET CONSTRAINTS ALL DEFERRED; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/copy_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/copy_stmt_0_60.sql new file mode 100644 index 000000000..006052bca --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/copy_stmt_0_60.sql @@ -0,0 +1 @@ +COPY users TO '/tmp/users.csv' WITH CSV HEADER; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_am_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_am_stmt_0_60.sql new file mode 100644 index 000000000..7886e5de6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_am_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE ACCESS METHOD myam TYPE TABLE HANDLER amhandler; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_cast_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_cast_stmt_0_60.sql new file mode 100644 index 000000000..90633fee8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_cast_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE CAST (text AS integer) WITH FUNCTION int4(text); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_conversion_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_conversion_stmt_0_60.sql new file mode 100644 index 000000000..8ddc06a10 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_conversion_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM utf8_to_latin1; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_domain_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_domain_stmt_0_60.sql new file mode 100644 index 000000000..dc83bc0b4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_domain_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE DOMAIN myint AS integer; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_enum_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_enum_stmt_0_60.sql new file mode 100644 index 000000000..200b0110e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_enum_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy') \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_event_trig_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_event_trig_stmt_0_60.sql new file mode 100644 index 000000000..63853d1a4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_event_trig_stmt_0_60.sql @@ -0,0 +1,2 @@ +CREATE EVENT TRIGGER my_event_trigger ON ddl_command_start +EXECUTE FUNCTION my_event_function(); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_extension_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_extension_stmt_0_60.sql new file mode 100644 index 000000000..24a6d918e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_extension_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE EXTENSION IF NOT EXISTS pgcrypto; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_fdw_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_fdw_stmt_0_60.sql new file mode 100644 index 000000000..9518a80be --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_fdw_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE FOREIGN DATA WRAPPER postgres_fdw; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_foreign_table_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_foreign_table_stmt_0_60.sql new file mode 100644 index 000000000..7a38345eb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_foreign_table_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE FOREIGN TABLE foreign_users (id integer) SERVER myserver; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_function_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_function_stmt_0_60.sql new file mode 100644 index 000000000..a89b3cf40 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_function_stmt_0_60.sql @@ -0,0 +1,2 @@ +CREATE FUNCTION add(a integer, b integer) RETURNS integer +AS 'SELECT $1 + $2' LANGUAGE SQL; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_op_class_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_op_class_stmt_0_60.sql new file mode 100644 index 000000000..1c5977b03 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_op_class_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE OPERATOR CLASS myopclass FOR TYPE int4 USING btree AS OPERATOR 1 <; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_op_family_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_op_family_stmt_0_60.sql new file mode 100644 index 000000000..7c26104e2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_op_family_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE OPERATOR FAMILY myopfamily USING btree; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_plang_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_plang_stmt_0_60.sql new file mode 100644 index 000000000..d92798534 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_plang_stmt_0_60.sql @@ -0,0 +1,2 @@ +CREATE LANGUAGE plpython3u +HANDLER plpython3_handler; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_policy_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_policy_stmt_0_60.sql new file mode 100644 index 000000000..fef9d3dcc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_policy_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE POLICY mypolicy ON mytable FOR ALL TO PUBLIC; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_publication_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_publication_stmt_0_60.sql new file mode 100644 index 000000000..017b45ea8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_publication_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE PUBLICATION mypub FOR ALL TABLES; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_range_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_range_stmt_0_60.sql new file mode 100644 index 000000000..9ea9dcc4d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_range_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_role_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_role_stmt_0_60.sql new file mode 100644 index 000000000..8a9bb6722 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_role_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE ROLE admin WITH LOGIN PASSWORD 'secret'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_schema_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_schema_stmt_0_60.sql new file mode 100644 index 000000000..a087b3bc8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_schema_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE SCHEMA myschema; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_seq_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_seq_stmt_0_60.sql new file mode 100644 index 000000000..e6a27d7cd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_seq_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE SEQUENCE myschema.myseq; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_stats_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_stats_stmt_0_60.sql new file mode 100644 index 000000000..6d75c7e00 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_stats_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE STATISTICS s1 ON a, b FROM t1; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_stmt_0_60.sql new file mode 100644 index 000000000..4bc9d77d6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE TABLE users (id TEXT, name TEXT); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_subscription_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_subscription_stmt_0_60.sql new file mode 100644 index 000000000..47bd4399f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_subscription_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE SUBSCRIPTION mysub CONNECTION 'host=localhost dbname=postgres' PUBLICATION mypub; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_table_as_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_table_as_stmt_0_60.sql new file mode 100644 index 000000000..0f4ff6b94 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_table_as_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE TABLE foo AS SELECT 1 \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_tablespace_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_tablespace_stmt_0_60.sql new file mode 100644 index 000000000..b42c7cc6f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_tablespace_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE TABLESPACE myspace LOCATION '/data/postgres'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_transform_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_transform_stmt_0_60.sql new file mode 100644 index 000000000..d5b896513 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_transform_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE TRANSFORM FOR hstore LANGUAGE sql (FROM SQL WITH FUNCTION hstore_to_sql(internal), TO SQL WITH FUNCTION sql_to_hstore(internal)); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_trig_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_trig_stmt_0_60.sql new file mode 100644 index 000000000..3ed6e2986 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_trig_stmt_0_60.sql @@ -0,0 +1,4 @@ +CREATE TRIGGER my_trigger +AFTER INSERT ON my_table +FOR EACH ROW +EXECUTE FUNCTION my_function(); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/create_user_mapping_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/create_user_mapping_stmt_0_60.sql new file mode 100644 index 000000000..4f6964092 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/create_user_mapping_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE USER MAPPING FOR myuser SERVER myserver; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/createdb_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/createdb_stmt_0_60.sql new file mode 100644 index 000000000..7429bf026 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/createdb_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE DATABASE mydb; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/current_of_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/current_of_expr_0_60.sql new file mode 100644 index 000000000..16930643d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/current_of_expr_0_60.sql @@ -0,0 +1 @@ +DELETE FROM table_name WHERE CURRENT OF cursor_name; diff --git a/crates/pgt_pretty_print/tests/data/single/deallocate_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/deallocate_stmt_0_60.sql new file mode 100644 index 000000000..b094d8d41 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/deallocate_stmt_0_60.sql @@ -0,0 +1 @@ +DEALLOCATE my_insert; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/declare_cursor_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/declare_cursor_stmt_0_60.sql new file mode 100644 index 000000000..cd49ae5ef --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/declare_cursor_stmt_0_60.sql @@ -0,0 +1 @@ +DECLARE mycursor CURSOR FOR SELECT * FROM mytable; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/define_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/define_stmt_0_60.sql new file mode 100644 index 000000000..0c64a3388 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/define_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE COLLATION mycoll FROM "C"; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/delete_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/delete_stmt_0_60.sql new file mode 100644 index 000000000..cad242da0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/delete_stmt_0_60.sql @@ -0,0 +1 @@ +DELETE FROM users WHERE id = 1; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/discard_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/discard_stmt_0_60.sql new file mode 100644 index 000000000..3af51015c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/discard_stmt_0_60.sql @@ -0,0 +1 @@ +DISCARD ALL; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/distinct_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/distinct_expr_0_60.sql new file mode 100644 index 000000000..1eb04b38e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/distinct_expr_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM t WHERE a IS DISTINCT FROM b diff --git a/crates/pgt_pretty_print/tests/data/single/do_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/do_stmt_0_60.sql new file mode 100644 index 000000000..b6e104af8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/do_stmt_0_60.sql @@ -0,0 +1 @@ +DO LANGUAGE plpgsql 'BEGIN NULL; END'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/drop_owned_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/drop_owned_stmt_0_60.sql new file mode 100644 index 000000000..794867ab9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/drop_owned_stmt_0_60.sql @@ -0,0 +1 @@ +DROP OWNED BY myuser; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/drop_role_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/drop_role_stmt_0_60.sql new file mode 100644 index 000000000..f2396c91a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/drop_role_stmt_0_60.sql @@ -0,0 +1 @@ +DROP ROLE test_user; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/drop_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/drop_stmt_0_60.sql new file mode 100644 index 000000000..441087ad7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/drop_stmt_0_60.sql @@ -0,0 +1 @@ +DROP TABLE users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/drop_subscription_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/drop_subscription_stmt_0_60.sql new file mode 100644 index 000000000..95b16189b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/drop_subscription_stmt_0_60.sql @@ -0,0 +1 @@ +DROP SUBSCRIPTION mysub; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/drop_tablespace_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/drop_tablespace_stmt_0_60.sql new file mode 100644 index 000000000..b81295462 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/drop_tablespace_stmt_0_60.sql @@ -0,0 +1 @@ +DROP TABLESPACE myspace; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/drop_user_mapping_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/drop_user_mapping_stmt_0_60.sql new file mode 100644 index 000000000..ab2ad14f0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/drop_user_mapping_stmt_0_60.sql @@ -0,0 +1 @@ +DROP USER MAPPING FOR myuser SERVER myserver; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/dropdb_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/dropdb_stmt_0_60.sql new file mode 100644 index 000000000..57e1375ab --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/dropdb_stmt_0_60.sql @@ -0,0 +1 @@ +DROP DATABASE mydb; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/execute_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/execute_stmt_0_60.sql new file mode 100644 index 000000000..15748b4bc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/execute_stmt_0_60.sql @@ -0,0 +1 @@ +EXECUTE prepared_statement_name ('param1', 'param2'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/explain_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/explain_stmt_0_60.sql new file mode 100644 index 000000000..2949387fc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/explain_stmt_0_60.sql @@ -0,0 +1 @@ +EXPLAIN SELECT * FROM users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/fetch_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/fetch_stmt_0_60.sql new file mode 100644 index 000000000..224e438c1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/fetch_stmt_0_60.sql @@ -0,0 +1 @@ +FETCH NEXT FROM mycursor; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/field_select_0_60.sql b/crates/pgt_pretty_print/tests/data/single/field_select_0_60.sql new file mode 100644 index 000000000..c692c86f2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/field_select_0_60.sql @@ -0,0 +1 @@ +SELECT (row(1,2,3)).f1 \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/field_store_0_60.sql b/crates/pgt_pretty_print/tests/data/single/field_store_0_60.sql new file mode 100644 index 000000000..d8d73bdd2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/field_store_0_60.sql @@ -0,0 +1 @@ +UPDATE my_table SET composite_col.field1 = 'new_value'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/from_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/from_expr_0_60.sql new file mode 100644 index 000000000..1af880f16 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/from_expr_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM t1, t2 WHERE t1.id = t2.id; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/func_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/func_expr_0_60.sql new file mode 100644 index 000000000..ecfe81fcc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/func_expr_0_60.sql @@ -0,0 +1 @@ +SELECT lower('HELLO'), upper('world'), length('test'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/grant_role_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/grant_role_stmt_0_60.sql new file mode 100644 index 000000000..4a3051633 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/grant_role_stmt_0_60.sql @@ -0,0 +1 @@ +GRANT admin TO user1, user2; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/grant_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/grant_stmt_0_60.sql new file mode 100644 index 000000000..63b75ed01 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/grant_stmt_0_60.sql @@ -0,0 +1 @@ +GRANT SELECT ON TABLE users TO john; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/grouping_func_0_60.sql b/crates/pgt_pretty_print/tests/data/single/grouping_func_0_60.sql new file mode 100644 index 000000000..6c5110244 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/grouping_func_0_60.sql @@ -0,0 +1 @@ +SELECT category, GROUPING(category) FROM products GROUP BY ROLLUP (category); diff --git a/crates/pgt_pretty_print/tests/data/single/import_foreign_schema_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/import_foreign_schema_stmt_0_60.sql new file mode 100644 index 000000000..3ebfbce94 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/import_foreign_schema_stmt_0_60.sql @@ -0,0 +1 @@ +IMPORT FOREIGN SCHEMA remote_schema FROM SERVER myserver INTO local_schema; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/index_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/index_stmt_0_60.sql new file mode 100644 index 000000000..1fa683f3a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/index_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE INDEX idx_users_email ON users (email); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/insert_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/insert_stmt_0_60.sql new file mode 100644 index 000000000..2c9fdb7eb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/insert_stmt_0_60.sql @@ -0,0 +1 @@ +INSERT INTO users VALUES (1, 'John'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/insert_stmt_0_80.sql b/crates/pgt_pretty_print/tests/data/single/insert_stmt_0_80.sql new file mode 100644 index 000000000..56840417a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/insert_stmt_0_80.sql @@ -0,0 +1 @@ +INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/into_clause_0_60.sql b/crates/pgt_pretty_print/tests/data/single/into_clause_0_60.sql new file mode 100644 index 000000000..1e8aef5ce --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/into_clause_0_60.sql @@ -0,0 +1 @@ +SELECT * INTO new_table FROM old_table \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/join_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/join_expr_0_60.sql new file mode 100644 index 000000000..47f3d5fa0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/join_expr_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM users u INNER JOIN orders o ON u.id = o.user_id; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/json_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/json_expr_0_60.sql new file mode 100644 index 000000000..f3fc17e6c --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/json_expr_0_60.sql @@ -0,0 +1 @@ +SELECT JSON_EXISTS(data, '$.name') \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/json_is_predicate_0_60.sql b/crates/pgt_pretty_print/tests/data/single/json_is_predicate_0_60.sql new file mode 100644 index 000000000..c3228594f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/json_is_predicate_0_60.sql @@ -0,0 +1 @@ +SELECT * WHERE data IS JSON \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/json_scalar_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/json_scalar_expr_0_60.sql new file mode 100644 index 000000000..2f6588204 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/json_scalar_expr_0_60.sql @@ -0,0 +1 @@ +SELECT JSON_SCALAR(123); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/listen_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/listen_stmt_0_60.sql new file mode 100644 index 000000000..90f8f4daa --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/listen_stmt_0_60.sql @@ -0,0 +1 @@ +LISTEN mytable_updated; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/load_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/load_stmt_0_60.sql new file mode 100644 index 000000000..3638481c8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/load_stmt_0_60.sql @@ -0,0 +1 @@ +LOAD 'plpgsql' \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/lock_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/lock_stmt_0_60.sql new file mode 100644 index 000000000..4104bf837 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/lock_stmt_0_60.sql @@ -0,0 +1 @@ +LOCK TABLE users IN ACCESS EXCLUSIVE MODE; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/long_columns_0_60.sql b/crates/pgt_pretty_print/tests/data/single/long_columns_0_60.sql new file mode 100644 index 000000000..56b6b2d76 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/long_columns_0_60.sql @@ -0,0 +1 @@ +SELECT customer_id, customer_name, customer_email, customer_phone FROM customer_table; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/long_select_0_60.sql b/crates/pgt_pretty_print/tests/data/single/long_select_0_60.sql new file mode 100644 index 000000000..7d5ce765a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/long_select_0_60.sql @@ -0,0 +1 @@ +SELECT first_name, last_name, email, phone_number, address FROM customers WHERE city = 'New York'; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/long_select_should_break_40.sql b/crates/pgt_pretty_print/tests/data/single/long_select_should_break_40.sql new file mode 100644 index 000000000..422af5661 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/long_select_should_break_40.sql @@ -0,0 +1 @@ +SELECT very_long_column_name_one, very_long_column_name_two FROM long_table_name \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/long_select_should_break_80.sql b/crates/pgt_pretty_print/tests/data/single/long_select_should_break_80.sql new file mode 100644 index 000000000..3fe39f035 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/long_select_should_break_80.sql @@ -0,0 +1 @@ +SELECT very_long_column_name_one, very_long_column_name_two, very_long_column_name_three FROM long_table_name \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/merge_action_0_60.sql b/crates/pgt_pretty_print/tests/data/single/merge_action_0_60.sql new file mode 100644 index 000000000..baf0569cb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/merge_action_0_60.sql @@ -0,0 +1,7 @@ +MERGE INTO products AS p +USING new_products AS np +ON p.product_id = np.product_id +WHEN MATCHED THEN + UPDATE SET price = np.price +WHEN NOT MATCHED THEN + INSERT (product_id, price) VALUES (np.product_id, np.price); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/merge_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/merge_stmt_0_60.sql new file mode 100644 index 000000000..1f14d4353 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/merge_stmt_0_60.sql @@ -0,0 +1,4 @@ +MERGE INTO target_table AS t +USING source_table AS s ON t.id = s.id +WHEN MATCHED THEN UPDATE SET value = s.value +WHEN NOT MATCHED THEN INSERT (id, value) VALUES (s.id, s.value); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/merge_support_func_0_60.sql b/crates/pgt_pretty_print/tests/data/single/merge_support_func_0_60.sql new file mode 100644 index 000000000..bf1d26dc4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/merge_support_func_0_60.sql @@ -0,0 +1,5 @@ +MERGE INTO products p +USING new_products np +ON p.product_id = np.product_id +WHEN MATCHED THEN UPDATE SET price = np.price +WHEN NOT MATCHED THEN INSERT VALUES (np.product_id, np.price); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/min_max_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/min_max_expr_0_60.sql new file mode 100644 index 000000000..2dbb49a11 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/min_max_expr_0_60.sql @@ -0,0 +1 @@ +SELECT GREATEST(1, 2, 3), LEAST(10, 20, 5); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/minimal_120.sql b/crates/pgt_pretty_print/tests/data/single/minimal_120.sql new file mode 100644 index 000000000..a69bea203 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/minimal_120.sql @@ -0,0 +1 @@ +SELECT a FROM t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/minimal_80.sql b/crates/pgt_pretty_print/tests/data/single/minimal_80.sql new file mode 100644 index 000000000..a69bea203 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/minimal_80.sql @@ -0,0 +1 @@ +SELECT a FROM t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/nested_column_refs_80.sql b/crates/pgt_pretty_print/tests/data/single/nested_column_refs_80.sql new file mode 100644 index 000000000..aa3fd5518 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/nested_column_refs_80.sql @@ -0,0 +1 @@ +SELECT schema.table.column FROM schema.table \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/null_test_0_60.sql b/crates/pgt_pretty_print/tests/data/single/null_test_0_60.sql new file mode 100644 index 000000000..889c16df2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/null_test_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM users WHERE email IS NULL; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/nullif_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/nullif_expr_0_60.sql new file mode 100644 index 000000000..d6e2263f3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/nullif_expr_0_60.sql @@ -0,0 +1 @@ +SELECT NULLIF(name, 'John') FROM users diff --git a/crates/pgt_pretty_print/tests/data/single/on_conflict_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/on_conflict_expr_0_60.sql new file mode 100644 index 000000000..da73bc120 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/on_conflict_expr_0_60.sql @@ -0,0 +1 @@ +INSERT INTO users (id, name) VALUES (1, 'John') ON CONFLICT (id) DO NOTHING; diff --git a/crates/pgt_pretty_print/tests/data/single/op_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/op_expr_0_60.sql new file mode 100644 index 000000000..d6065a6c0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/op_expr_0_60.sql @@ -0,0 +1 @@ +SELECT 1 + 2; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/param_0_60.sql b/crates/pgt_pretty_print/tests/data/single/param_0_60.sql new file mode 100644 index 000000000..861edbaac --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/param_0_60.sql @@ -0,0 +1 @@ +SELECT $1; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/partition_bound_spec_0_60.sql b/crates/pgt_pretty_print/tests/data/single/partition_bound_spec_0_60.sql new file mode 100644 index 000000000..ac522ab09 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/partition_bound_spec_0_60.sql @@ -0,0 +1,4 @@ +CREATE TABLE measurement ( + id integer, + logdate date +) PARTITION BY RANGE (logdate) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/partition_elem_0_60.sql b/crates/pgt_pretty_print/tests/data/single/partition_elem_0_60.sql new file mode 100644 index 000000000..fe9531515 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/partition_elem_0_60.sql @@ -0,0 +1,4 @@ +CREATE TABLE measurement ( + city_id int, + logdate date +) PARTITION BY RANGE (logdate) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/pl_assign_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/pl_assign_stmt_0_60.sql new file mode 100644 index 000000000..259560bf3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/pl_assign_stmt_0_60.sql @@ -0,0 +1,6 @@ +DO $$ +DECLARE + x integer; +BEGIN + x := 42; +END $$; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/prepare_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/prepare_stmt_0_60.sql new file mode 100644 index 000000000..6d7888150 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/prepare_stmt_0_60.sql @@ -0,0 +1,2 @@ +PREPARE my_insert (int, text) AS +INSERT INTO users (id, name) VALUES ($1, $2); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/query_0_60.sql b/crates/pgt_pretty_print/tests/data/single/query_0_60.sql new file mode 100644 index 000000000..89db9babd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/query_0_60.sql @@ -0,0 +1 @@ +(SELECT 1) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/query_subselect_0_60.sql b/crates/pgt_pretty_print/tests/data/single/query_subselect_0_60.sql new file mode 100644 index 000000000..334ec8d37 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/query_subselect_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM (SELECT 1) AS subq \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/range_function_0_60.sql b/crates/pgt_pretty_print/tests/data/single/range_function_0_60.sql new file mode 100644 index 000000000..cf8ac8b26 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/range_function_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM generate_series(1, 10); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/range_subselect_0_60.sql b/crates/pgt_pretty_print/tests/data/single/range_subselect_0_60.sql new file mode 100644 index 000000000..83b790cc4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/range_subselect_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM (SELECT id, name FROM users WHERE active = true) AS active_users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/range_table_func_0_60.sql b/crates/pgt_pretty_print/tests/data/single/range_table_func_0_60.sql new file mode 100644 index 000000000..c3a19423e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/range_table_func_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM xmltable('/root' passing 'value' columns item text path 'item') \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/range_table_sample_0_60.sql b/crates/pgt_pretty_print/tests/data/single/range_table_sample_0_60.sql new file mode 100644 index 000000000..96508c506 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/range_table_sample_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM employees TABLESAMPLE SYSTEM (10) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/range_tbl_ref_0_60.sql b/crates/pgt_pretty_print/tests/data/single/range_tbl_ref_0_60.sql new file mode 100644 index 000000000..a202133b6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/range_tbl_ref_0_60.sql @@ -0,0 +1 @@ +SELECT t1.a FROM t1, t2; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/reassign_owned_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/reassign_owned_stmt_0_60.sql new file mode 100644 index 000000000..e8a661d4b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/reassign_owned_stmt_0_60.sql @@ -0,0 +1 @@ +REASSIGN OWNED BY olduser TO newuser; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/refresh_mat_view_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/refresh_mat_view_stmt_0_60.sql new file mode 100644 index 000000000..2a3fdd089 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/refresh_mat_view_stmt_0_60.sql @@ -0,0 +1 @@ +REFRESH MATERIALIZED VIEW myview \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/reindex_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/reindex_stmt_0_60.sql new file mode 100644 index 000000000..da2b1410f --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/reindex_stmt_0_60.sql @@ -0,0 +1 @@ +REINDEX TABLE users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/relabel_type_0_60.sql b/crates/pgt_pretty_print/tests/data/single/relabel_type_0_60.sql new file mode 100644 index 000000000..a65ad6cdf --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/relabel_type_0_60.sql @@ -0,0 +1 @@ +SELECT 'hello'::text \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/rename_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/rename_stmt_0_60.sql new file mode 100644 index 000000000..3c2f27ac2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/rename_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TABLE users RENAME TO customers; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/replica_identity_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/replica_identity_stmt_0_60.sql new file mode 100644 index 000000000..f2a27662e --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/replica_identity_stmt_0_60.sql @@ -0,0 +1 @@ +ALTER TABLE mytable REPLICA IDENTITY FULL; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/return_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/return_stmt_0_60.sql new file mode 100644 index 000000000..ea88dca16 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/return_stmt_0_60.sql @@ -0,0 +1,4 @@ +DO $$ +BEGIN + RETURN; +END $$; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/row_compare_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/row_compare_expr_0_60.sql new file mode 100644 index 000000000..62012becd --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/row_compare_expr_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM employees WHERE (salary, bonus) > (50000, 10000) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/row_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/row_expr_0_60.sql new file mode 100644 index 000000000..b6cddfae8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/row_expr_0_60.sql @@ -0,0 +1 @@ +SELECT ROW(1, 2, 3); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/rule_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/rule_stmt_0_60.sql new file mode 100644 index 000000000..2d692ffe8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/rule_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE RULE notify_me AS ON UPDATE TO mytable DO NOTIFY mytable_updated; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/scalar_array_op_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/scalar_array_op_expr_0_60.sql new file mode 100644 index 000000000..d8568e51d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/scalar_array_op_expr_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM users WHERE id IN (1, 2, 3); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/select_with_alias_80.sql b/crates/pgt_pretty_print/tests/data/single/select_with_alias_80.sql new file mode 100644 index 000000000..6428e7151 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/select_with_alias_80.sql @@ -0,0 +1 @@ +SELECT a AS x, b AS y, c FROM t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/select_with_schema_80.sql b/crates/pgt_pretty_print/tests/data/single/select_with_schema_80.sql new file mode 100644 index 000000000..08d5f59e6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/select_with_schema_80.sql @@ -0,0 +1 @@ +SELECT public.t.a, t.b, c FROM public.t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/set_operation_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/set_operation_stmt_0_60.sql new file mode 100644 index 000000000..00d5283a7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/set_operation_stmt_0_60.sql @@ -0,0 +1 @@ +SELECT id, name FROM users UNION SELECT id, name FROM employees; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/set_to_default_0_60.sql b/crates/pgt_pretty_print/tests/data/single/set_to_default_0_60.sql new file mode 100644 index 000000000..2178cea74 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/set_to_default_0_60.sql @@ -0,0 +1 @@ +UPDATE t SET a = DEFAULT \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/short_select_stays_inline_80.sql b/crates/pgt_pretty_print/tests/data/single/short_select_stays_inline_80.sql new file mode 100644 index 000000000..a69bea203 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/short_select_stays_inline_80.sql @@ -0,0 +1 @@ +SELECT a FROM t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/simple_select_20.sql b/crates/pgt_pretty_print/tests/data/single/simple_select_20.sql new file mode 100644 index 000000000..9c497a60d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/simple_select_20.sql @@ -0,0 +1 @@ +SELECT a, b, c FROM t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/simple_select_80.sql b/crates/pgt_pretty_print/tests/data/single/simple_select_80.sql new file mode 100644 index 000000000..9c497a60d --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/simple_select_80.sql @@ -0,0 +1 @@ +SELECT a, b, c FROM t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/sql_value_function_0_60.sql b/crates/pgt_pretty_print/tests/data/single/sql_value_function_0_60.sql new file mode 100644 index 000000000..895f56e5a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/sql_value_function_0_60.sql @@ -0,0 +1 @@ +SELECT CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER diff --git a/crates/pgt_pretty_print/tests/data/single/sub_link_0_60.sql b/crates/pgt_pretty_print/tests/data/single/sub_link_0_60.sql new file mode 100644 index 000000000..75109ffce --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/sub_link_0_60.sql @@ -0,0 +1 @@ +SELECT * FROM users WHERE EXISTS (SELECT 1 FROM orders); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/table_func_0_60.sql b/crates/pgt_pretty_print/tests/data/single/table_func_0_60.sql new file mode 100644 index 000000000..c5fd358fc --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/table_func_0_60.sql @@ -0,0 +1,9 @@ +SELECT * +FROM JSON_TABLE( + '{"employees":[{"name":"John","age":30},{"name":"Jane","age":25}]}'::jsonb, + '$.employees[*]' + COLUMNS ( + name text PATH '$.name', + age int PATH '$.age' + ) +) AS jt; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/table_like_clause_0_60.sql b/crates/pgt_pretty_print/tests/data/single/table_like_clause_0_60.sql new file mode 100644 index 000000000..458994d02 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/table_like_clause_0_60.sql @@ -0,0 +1 @@ +CREATE TABLE new_table (LIKE old_table INCLUDING ALL) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/target_entry_0_60.sql b/crates/pgt_pretty_print/tests/data/single/target_entry_0_60.sql new file mode 100644 index 000000000..a69bea203 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/target_entry_0_60.sql @@ -0,0 +1 @@ +SELECT a FROM t \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/transaction_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/transaction_stmt_0_60.sql new file mode 100644 index 000000000..58bfee118 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/transaction_stmt_0_60.sql @@ -0,0 +1 @@ +BEGIN; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/truncate_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/truncate_stmt_0_60.sql new file mode 100644 index 000000000..75e9657c2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/truncate_stmt_0_60.sql @@ -0,0 +1 @@ +TRUNCATE TABLE users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/type_cast_0_60.sql b/crates/pgt_pretty_print/tests/data/single/type_cast_0_60.sql new file mode 100644 index 000000000..0f4f23807 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/type_cast_0_60.sql @@ -0,0 +1 @@ +SELECT '123'::INTEGER; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/unlisten_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/unlisten_stmt_0_60.sql new file mode 100644 index 000000000..f3e0dab55 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/unlisten_stmt_0_60.sql @@ -0,0 +1 @@ +UNLISTEN mytable_updated; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/update_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/update_stmt_0_60.sql new file mode 100644 index 000000000..6e6e11159 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/update_stmt_0_60.sql @@ -0,0 +1 @@ +UPDATE users SET name = 'Jane Doe' WHERE id = 1; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/vacuum_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/vacuum_stmt_0_60.sql new file mode 100644 index 000000000..39e735c4a --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/vacuum_stmt_0_60.sql @@ -0,0 +1 @@ +VACUUM users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/var_0_60.sql b/crates/pgt_pretty_print/tests/data/single/var_0_60.sql new file mode 100644 index 000000000..d85e6c447 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/var_0_60.sql @@ -0,0 +1 @@ +SELECT a FROM t diff --git a/crates/pgt_pretty_print/tests/data/single/variable_set_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/variable_set_stmt_0_60.sql new file mode 100644 index 000000000..fb33528b8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/variable_set_stmt_0_60.sql @@ -0,0 +1 @@ +SET search_path TO myschema, public; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/variable_show_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/variable_show_stmt_0_60.sql new file mode 100644 index 000000000..c87f4a397 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/variable_show_stmt_0_60.sql @@ -0,0 +1 @@ +SHOW search_path; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/view_stmt_0_60.sql b/crates/pgt_pretty_print/tests/data/single/view_stmt_0_60.sql new file mode 100644 index 000000000..1d9b68158 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/view_stmt_0_60.sql @@ -0,0 +1 @@ +CREATE VIEW user_view AS SELECT id, name FROM users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/window_def_0_60.sql b/crates/pgt_pretty_print/tests/data/single/window_def_0_60.sql new file mode 100644 index 000000000..64218d794 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/window_def_0_60.sql @@ -0,0 +1 @@ +SELECT id, name, ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM employees; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/window_func_0_60.sql b/crates/pgt_pretty_print/tests/data/single/window_func_0_60.sql new file mode 100644 index 000000000..16e606e0b --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/window_func_0_60.sql @@ -0,0 +1 @@ +SELECT ROW_NUMBER() OVER (ORDER BY id) FROM users; diff --git a/crates/pgt_pretty_print/tests/data/single/xml_expr_0_60.sql b/crates/pgt_pretty_print/tests/data/single/xml_expr_0_60.sql new file mode 100644 index 000000000..6b194cc35 --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/xml_expr_0_60.sql @@ -0,0 +1 @@ +SELECT xmlelement(name foo, 'bar'); \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/data/single/xml_serialize_0_60.sql b/crates/pgt_pretty_print/tests/data/single/xml_serialize_0_60.sql new file mode 100644 index 000000000..cb947c4fb --- /dev/null +++ b/crates/pgt_pretty_print/tests/data/single/xml_serialize_0_60.sql @@ -0,0 +1 @@ +SELECT XMLSERIALIZE(CONTENT doc AS text) \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__advisory_lock_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__advisory_lock_60.snap new file mode 100644 index 000000000..4540eb370 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__advisory_lock_60.snap @@ -0,0 +1,455 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/advisory_lock_60.sql +snapshot_kind: text +--- +SELECT + oid AS datoid +FROM + pg_database +WHERE datname = current_database(); + +BEGIN; + +SELECT + pg_advisory_xact_lock( + 1 + ), + pg_advisory_xact_lock_shared( + 2 + ), + pg_advisory_xact_lock( + 1, + 1 + ), + pg_advisory_xact_lock_shared( + 2, + 2 + ); + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +SELECT pg_advisory_unlock_all(); + +SELECT + count(*) +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid'; + +SELECT + pg_advisory_unlock( + 1 + ), + pg_advisory_unlock_shared( + 2 + ), + pg_advisory_unlock( + 1, + 1 + ), + pg_advisory_unlock_shared( + 2, + 2 + ); + +COMMIT; + +SELECT + count(*) +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid'; + +BEGIN; + +SELECT + pg_advisory_xact_lock( + 1 + ), + pg_advisory_xact_lock_shared( + 2 + ), + pg_advisory_xact_lock( + 1, + 1 + ), + pg_advisory_xact_lock_shared( + 2, + 2 + ); + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +SELECT + pg_advisory_lock( + 1 + ), + pg_advisory_lock_shared( + 2 + ), + pg_advisory_lock( + 1, + 1 + ), + pg_advisory_lock_shared( + 2, + 2 + ); + +ROLLBACK; + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +SELECT + pg_advisory_unlock( + 1 + ), + pg_advisory_unlock( + 1 + ), + pg_advisory_unlock_shared( + 2 + ), + pg_advisory_unlock_shared( + 2 + ), + pg_advisory_unlock( + 1, + 1 + ), + pg_advisory_unlock( + 1, + 1 + ), + pg_advisory_unlock_shared( + 2, + 2 + ), + pg_advisory_unlock_shared( + 2, + 2 + ); + +SELECT + count(*) +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid'; + +BEGIN; + +SELECT + pg_advisory_lock( + 1 + ), + pg_advisory_lock_shared( + 2 + ), + pg_advisory_lock( + 1, + 1 + ), + pg_advisory_lock_shared( + 2, + 2 + ); + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +SELECT + pg_advisory_xact_lock( + 1 + ), + pg_advisory_xact_lock_shared( + 2 + ), + pg_advisory_xact_lock( + 1, + 1 + ), + pg_advisory_xact_lock_shared( + 2, + 2 + ); + +ROLLBACK; + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +SELECT pg_advisory_unlock_all(); + +SELECT + count(*) +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid'; + +BEGIN; + +SELECT + pg_advisory_xact_lock( + 1 + ), + pg_advisory_xact_lock( + 1 + ), + pg_advisory_xact_lock_shared( + 2 + ), + pg_advisory_xact_lock_shared( + 2 + ), + pg_advisory_xact_lock( + 1, + 1 + ), + pg_advisory_xact_lock( + 1, + 1 + ), + pg_advisory_xact_lock_shared( + 2, + 2 + ), + pg_advisory_xact_lock_shared( + 2, + 2 + ); + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +COMMIT; + +SELECT + count(*) +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid'; + +SELECT + pg_advisory_lock( + 1 + ), + pg_advisory_lock( + 1 + ), + pg_advisory_lock_shared( + 2 + ), + pg_advisory_lock_shared( + 2 + ), + pg_advisory_lock( + 1, + 1 + ), + pg_advisory_lock( + 1, + 1 + ), + pg_advisory_lock_shared( + 2, + 2 + ), + pg_advisory_lock_shared( + 2, + 2 + ); + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +SELECT + pg_advisory_unlock( + 1 + ), + pg_advisory_unlock( + 1 + ), + pg_advisory_unlock_shared( + 2 + ), + pg_advisory_unlock_shared( + 2 + ), + pg_advisory_unlock( + 1, + 1 + ), + pg_advisory_unlock( + 1, + 1 + ), + pg_advisory_unlock_shared( + 2, + 2 + ), + pg_advisory_unlock_shared( + 2, + 2 + ); + +SELECT + count(*) +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid'; + +SELECT + pg_advisory_lock( + 1 + ), + pg_advisory_lock( + 1 + ), + pg_advisory_lock_shared( + 2 + ), + pg_advisory_lock_shared( + 2 + ), + pg_advisory_lock( + 1, + 1 + ), + pg_advisory_lock( + 1, + 1 + ), + pg_advisory_lock_shared( + 2, + 2 + ), + pg_advisory_lock_shared( + 2, + 2 + ); + +SELECT + locktype, + classid, + objid, + objsubid, + mode, + granted +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid' +ORDER BY + classid, + objid, + objsubid; + +SELECT pg_advisory_unlock_all(); + +SELECT + count(*) +FROM + pg_locks +WHERE locktype = 'advisory' + AND database = 'datoid'; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__amutils_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__amutils_60.snap new file mode 100644 index 000000000..d17e9489f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__amutils_60.snap @@ -0,0 +1,268 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/amutils_60.sql +snapshot_kind: text +--- +SELECT + prop, + pg_indexam_has_property( + a.oid, + prop + ) AS "AM", + pg_index_has_property( + 'onek_hundred'::regclass, + prop + ) AS "Index", + pg_index_column_has_property( + 'onek_hundred'::regclass, + 1, + prop + ) AS "Column" +FROM + pg_am a, + unnest( + ARRAY['asc', + 'desc', + 'nulls_first', + 'nulls_last', + 'orderable', + 'distance_orderable', + 'returnable', + 'search_array', + 'search_nulls', + 'clusterable', + 'index_scan', + 'bitmap_scan', + 'backward_scan', + 'can_order', + 'can_unique', + 'can_multi_col', + 'can_exclude', + 'can_include', + 'bogus']::text[] + ) WITH ORDINALITY AS u(prop, ord) +WHERE a.amname = 'btree' +ORDER BY + ord; + +SELECT + prop, + pg_indexam_has_property( + a.oid, + prop + ) AS "AM", + pg_index_has_property( + 'gcircleind'::regclass, + prop + ) AS "Index", + pg_index_column_has_property( + 'gcircleind'::regclass, + 1, + prop + ) AS "Column" +FROM + pg_am a, + unnest( + ARRAY['asc', + 'desc', + 'nulls_first', + 'nulls_last', + 'orderable', + 'distance_orderable', + 'returnable', + 'search_array', + 'search_nulls', + 'clusterable', + 'index_scan', + 'bitmap_scan', + 'backward_scan', + 'can_order', + 'can_unique', + 'can_multi_col', + 'can_exclude', + 'can_include', + 'bogus']::text[] + ) WITH ORDINALITY AS u(prop, ord) +WHERE a.amname = 'gist' +ORDER BY + ord; + +SELECT + prop, + pg_index_column_has_property( + 'onek_hundred'::regclass, + 1, + prop + ) AS btree, + pg_index_column_has_property( + 'hash_i4_index'::regclass, + 1, + prop + ) AS hash, + pg_index_column_has_property( + 'gcircleind'::regclass, + 1, + prop + ) AS gist, + pg_index_column_has_property( + 'sp_radix_ind'::regclass, + 1, + prop + ) AS spgist_radix, + pg_index_column_has_property( + 'sp_quad_ind'::regclass, + 1, + prop + ) AS spgist_quad, + pg_index_column_has_property( + 'botharrayidx'::regclass, + 1, + prop + ) AS gin, + pg_index_column_has_property( + 'brinidx'::regclass, + 1, + prop + ) AS brin +FROM + unnest( + ARRAY['asc', + 'desc', + 'nulls_first', + 'nulls_last', + 'orderable', + 'distance_orderable', + 'returnable', + 'search_array', + 'search_nulls', + 'bogus']::text[] + ) WITH ORDINALITY AS u(prop, ord) +ORDER BY + ord; + +SELECT + prop, + pg_index_has_property( + 'onek_hundred'::regclass, + prop + ) AS btree, + pg_index_has_property( + 'hash_i4_index'::regclass, + prop + ) AS hash, + pg_index_has_property( + 'gcircleind'::regclass, + prop + ) AS gist, + pg_index_has_property( + 'sp_radix_ind'::regclass, + prop + ) AS spgist, + pg_index_has_property( + 'botharrayidx'::regclass, + prop + ) AS gin, + pg_index_has_property( + 'brinidx'::regclass, + prop + ) AS brin +FROM + unnest( + ARRAY['clusterable', + 'index_scan', + 'bitmap_scan', + 'backward_scan', + 'bogus']::text[] + ) WITH ORDINALITY AS u(prop, ord) +ORDER BY + ord; + +SELECT + amname, + prop, + pg_indexam_has_property( + a.oid, + prop + ) AS p +FROM + pg_am a, + unnest( + ARRAY['can_order', + 'can_unique', + 'can_multi_col', + 'can_exclude', + 'can_include', + 'bogus']::text[] + ) WITH ORDINALITY AS u(prop, ord) +WHERE amtype = 'i' +ORDER BY + amname, + ord; + +CREATE TEMP TABLE foo ( + f1 pg_catalog.int4, + f2 pg_catalog.int4, + f3 pg_catalog.int4, + f4 pg_catalog.int4 +); + +CREATE INDEX fooindex ON foo (f1 DESC, + f2 ASC, + f3 NULLS FIRST, + f4 NULLS LAST); + +SELECT + col, + prop, + pg_index_column_has_property( + o, + col, + prop + ) +FROM + (VALUES + ('fooindex'::regclass)) AS v1(o), + (VALUES + (1, 'orderable'), + (2, 'asc'), + (3, 'desc'), + (4, 'nulls_first'), + (5, 'nulls_last'), + (6, 'bogus')) AS v2(idx, prop), + generate_series( + 1, + 4 + ) AS col +ORDER BY + col, + idx; + +CREATE INDEX foocover ON foo (f1) INCLUDE (f2, f3); + +SELECT + col, + prop, + pg_index_column_has_property( + o, + col, + prop + ) +FROM + (VALUES + ('foocover'::regclass)) AS v1(o), + (VALUES + (1, 'orderable'), + (2, 'asc'), + (3, 'desc'), + (4, 'nulls_first'), + (5, 'nulls_last'), + (6, 'distance_orderable'), + (7, 'returnable'), + (8, 'bogus')) AS v2(idx, prop), + generate_series( + 1, + 3 + ) AS col +ORDER BY + col, + idx; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__circle_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__circle_60.snap new file mode 100644 index 000000000..021beace5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__circle_60.snap @@ -0,0 +1,64 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/circle_60.sql +snapshot_kind: text +--- +SET extra_float_digits TO -1; + +CREATE TABLE circle_tbl (f1 circle); + +INSERT INTO circle_tbl VALUES ('<(5,1),3>'); + +INSERT INTO circle_tbl VALUES ('((1,2),100)'); + +INSERT INTO circle_tbl VALUES (' 1 , 3 , 5 '); + +INSERT INTO circle_tbl VALUES (' ( ( 1 , 2 ) , 3 ) '); + +INSERT INTO circle_tbl VALUES (' ( 100 , 200 ) , 10 '); + +INSERT INTO circle_tbl VALUES (' < ( 100 , 1 ) , 115 > '); + +INSERT INTO circle_tbl VALUES ('<(3,5),0>'); + +INSERT INTO circle_tbl VALUES ('<(3,5),NaN>'); + +INSERT INTO circle_tbl VALUES ('<(-100,0),-100>'); + +INSERT INTO circle_tbl VALUES ('<(100,200),10'); + +INSERT INTO circle_tbl VALUES ('<(100,200),10> x'); + +INSERT INTO circle_tbl VALUES ('1abc,3,5'); + +INSERT INTO circle_tbl VALUES ('(3,(1,2),3)'); + +SELECT * FROM circle_tbl; + +SELECT center(f1) AS center FROM circle_tbl; + +SELECT radius(f1) AS radius FROM circle_tbl; + +SELECT diameter(f1) AS diameter FROM circle_tbl; + +SELECT f1 FROM circle_tbl WHERE radius(f1) < 5; + +SELECT f1 FROM circle_tbl WHERE diameter(f1) >= 10; + +SELECT + c1.f1 AS one, + c2.f1 AS two, + c1.f1 <-> c2.f1 AS distance +FROM + circle_tbl c1, + circle_tbl c2 +WHERE c1.f1 < c2.f1 + AND c1.f1 <-> c2.f1 > 0 +ORDER BY + distance, + area( + c1.f1 + ), + area( + c2.f1 + ); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__comments_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__comments_60.snap new file mode 100644 index 000000000..1eb3c3978 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__comments_60.snap @@ -0,0 +1,16 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/comments_60.sql +snapshot_kind: text +--- +SELECT 'trailing' AS first; + +SELECT 'embedded' AS second; + +SELECT 'both' AS third; + +SELECT 'before multi-line' AS fourth; + +SELECT 'after multi-line' AS fifth; + +SELECT 'deeply nested example' AS sixth; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__copyencoding_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__copyencoding_60.snap new file mode 100644 index 000000000..753a50000 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__copyencoding_60.snap @@ -0,0 +1,38 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/copyencoding_60.sql +snapshot_kind: text +--- +SELECT getdatabaseencoding() <> 'UTF8' AS skip_test; + +CREATE TABLE copy_encoding_tab (t text); + +COPY (SELECT 'あ') TO 'utf8_csv'; + +COPY copy_encoding_tab FROM 'utf8_csv'; + +SET client_encoding TO 'utf8'; + +COPY (SELECT 'あ') TO 'utf8_csv'; + +SET client_encoding TO 'latin1'; + +COPY copy_encoding_tab FROM 'utf8_csv'; + +RESET client_encoding; + +COPY (SELECT 'あ') TO 'utf8_csv'; + +COPY copy_encoding_tab FROM 'utf8_csv'; + +SET client_encoding TO 'utf8'; + +COPY (SELECT 'あ') TO 'utf8_csv'; + +SET client_encoding TO 'euc_jp'; + +COPY copy_encoding_tab FROM 'utf8_csv'; + +RESET client_encoding; + +DROP TABLE copy_encoding_tab; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__create_function_c_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__create_function_c_60.snap new file mode 100644 index 000000000..ba9e665bf --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__create_function_c_60.snap @@ -0,0 +1,34 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/create_function_c_60.sql +snapshot_kind: text +--- +LOAD 'regresslib'; + +CREATE FUNCTION test1 ( + pg_catalog.int4 +) +RETURNS pg_catalog.int4 +LANGUAGE c +AS 'nosuchfile'; + +CREATE FUNCTION test1 ( + pg_catalog.int4 +) +RETURNS pg_catalog.int4 +LANGUAGE c +AS 'regresslib', 'nosuchsymbol'; + +SELECT + regexp_replace( + 'LAST_ERROR_MESSAGE', + 'file ".*"', + 'file "..."' + ); + +CREATE FUNCTION test1 ( + pg_catalog.int4 +) +RETURNS pg_catalog.int4 +LANGUAGE internal +AS 'nosuch'; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__dbsize_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__dbsize_60.snap new file mode 100644 index 000000000..a1626876d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__dbsize_60.snap @@ -0,0 +1,199 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/dbsize_60.sql +snapshot_kind: text +--- +SELECT + size, + pg_size_pretty( + size + ), + pg_size_pretty( + -1 * size + ) +FROM + (VALUES + (10::pg_catalog.int8), + (1000::pg_catalog.int8), + (1000000::pg_catalog.int8), + (1000000000::pg_catalog.int8), + (1000000000000::pg_catalog.int8), + (1000000000000000::pg_catalog.int8)) AS x(size); + +SELECT + size, + pg_size_pretty( + size + ), + pg_size_pretty( + -1 * size + ) +FROM + (VALUES + (10::pg_catalog.numeric), + (1000::pg_catalog.numeric), + (1000000::pg_catalog.numeric), + (1000000000::pg_catalog.numeric), + (1000000000000::pg_catalog.numeric), + (1000000000000000::pg_catalog.numeric), + (10.5::pg_catalog.numeric), + (1000.5::pg_catalog.numeric), + (1000000.5::pg_catalog.numeric), + (1000000000.5::pg_catalog.numeric), + (1000000000000.5::pg_catalog.numeric), + (1000000000000000.5::pg_catalog.numeric)) AS x(size); + +SELECT + size, + pg_size_pretty( + size + ), + pg_size_pretty( + -1 * size + ) +FROM + (VALUES + (10239::pg_catalog.int8), + (10240::pg_catalog.int8), + (10485247::pg_catalog.int8), + (10485248::pg_catalog.int8), + (10736893951::pg_catalog.int8), + (10736893952::pg_catalog.int8), + (10994579406847::pg_catalog.int8), + (10994579406848::pg_catalog.int8), + (11258449312612351::pg_catalog.int8), + (11258449312612352::pg_catalog.int8)) AS x(size); + +SELECT + size, + pg_size_pretty( + size + ), + pg_size_pretty( + -1 * size + ) +FROM + (VALUES + (10239::pg_catalog.numeric), + (10240::pg_catalog.numeric), + (10485247::pg_catalog.numeric), + (10485248::pg_catalog.numeric), + (10736893951::pg_catalog.numeric), + (10736893952::pg_catalog.numeric), + (10994579406847::pg_catalog.numeric), + (10994579406848::pg_catalog.numeric), + (11258449312612351::pg_catalog.numeric), + (11258449312612352::pg_catalog.numeric), + (11528652096115048447::pg_catalog.numeric), + (11528652096115048448::pg_catalog.numeric)) AS x(size); + +SELECT + pg_size_pretty( + '-9223372036854775808'::pg_catalog.int8 + ), + pg_size_pretty( + '9223372036854775807'::pg_catalog.int8 + ); + +SELECT + size, + pg_size_bytes( + size + ) +FROM + (VALUES + ('1'), + ('123bytes'), + ('256 B'), + ('1kB'), + ('1MB'), + (' 1 GB'), + ('1.5 GB '), + ('1TB'), + ('3000 TB'), + ('1e6 MB'), + ('99 PB')) AS x(size); + +SELECT + size, + pg_size_bytes( + size + ) +FROM + (VALUES + ('1'), + ('123bYteS'), + ('1kb'), + ('1mb'), + (' 1 Gb'), + ('1.5 gB '), + ('1tb'), + ('3000 tb'), + ('1e6 mb'), + ('99 pb')) AS x(size); + +SELECT + size, + pg_size_bytes( + size + ) +FROM + (VALUES + ('-1'), + ('-123bytes'), + ('-1kb'), + ('-1mb'), + (' -1 Gb'), + ('-1.5 gB '), + ('-1tb'), + ('-3000 TB'), + ('-10e-1 MB'), + ('-99 PB')) AS x(size); + +SELECT + size, + pg_size_bytes( + size + ) +FROM + (VALUES + ('-1.'), + ('-1.kb'), + ('-1. kb'), + ('-0. gb'), + ('-.1'), + ('-.1kb'), + ('-.1 kb'), + ('-.0 gb')) AS x(size); + +SELECT pg_size_bytes('1 AB'); + +SELECT pg_size_bytes('1 AB A'); + +SELECT pg_size_bytes('1 AB A '); + +SELECT pg_size_bytes('9223372036854775807.9'); + +SELECT pg_size_bytes('1e100'); + +SELECT pg_size_bytes('1e1000000000000000000'); + +SELECT pg_size_bytes('1 byte'); + +SELECT pg_size_bytes(''); + +SELECT pg_size_bytes('kb'); + +SELECT pg_size_bytes('..'); + +SELECT pg_size_bytes('-.'); + +SELECT pg_size_bytes('-.kb'); + +SELECT pg_size_bytes('-. kb'); + +SELECT pg_size_bytes('.+912'); + +SELECT pg_size_bytes('+912+ kB'); + +SELECT pg_size_bytes('++123 kB'); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__delete_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__delete_60.snap new file mode 100644 index 000000000..65454a825 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__delete_60.snap @@ -0,0 +1,32 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/delete_60.sql +snapshot_kind: text +--- +CREATE TABLE delete_test ( + id serial PRIMARY KEY, + a pg_catalog.int4, + b text +); + +INSERT INTO delete_test (a) VALUES (10); + +INSERT INTO delete_test (a, b) VALUES + (50, repeat( + 'x', + 10000 + )); + +INSERT INTO delete_test (a) VALUES (100); + +DELETE FROM delete_test dt WHERE dt.a > 75; + +DELETE FROM delete_test dt WHERE delete_test.a > 25; + +SELECT id, a, char_length(b) FROM delete_test; + +DELETE FROM delete_test WHERE a > 25; + +SELECT id, a, char_length(b) FROM delete_test; + +DROP TABLE delete_test; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__drop_operator_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__drop_operator_60.snap new file mode 100644 index 000000000..d5c1ea70e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__drop_operator_60.snap @@ -0,0 +1,89 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/drop_operator_60.sql +snapshot_kind: text +--- +CREATE OPERATOR === ( + PROCEDURE = int8eq, + LEFTARG = pg_catalog.int8, + RIGHTARG = pg_catalog.int8, + COMMUTATOR = === +); + +CREATE OPERATOR !== ( + PROCEDURE = int8ne, + LEFTARG = pg_catalog.int8, + RIGHTARG = pg_catalog.int8, + NEGATOR = ===, + COMMUTATOR = !== +); + +DROP OPERATOR !==(pg_catalog.int8, pg_catalog.int8); + +SELECT + ctid, + oprcom +FROM + pg_catalog.pg_operator fk +WHERE oprcom <> 0 + AND NOT EXISTS (SELECT + 1 + FROM + pg_catalog.pg_operator pk + WHERE pk.oid = fk.oprcom); + +SELECT + ctid, + oprnegate +FROM + pg_catalog.pg_operator fk +WHERE oprnegate <> 0 + AND NOT EXISTS (SELECT + 1 + FROM + pg_catalog.pg_operator pk + WHERE pk.oid = fk.oprnegate); + +DROP OPERATOR ===(pg_catalog.int8, pg_catalog.int8); + +CREATE OPERATOR <| ( + PROCEDURE = int8lt, + LEFTARG = pg_catalog.int8, + RIGHTARG = pg_catalog.int8 +); + +CREATE OPERATOR |> ( + PROCEDURE = int8gt, + LEFTARG = pg_catalog.int8, + RIGHTARG = pg_catalog.int8, + NEGATOR = <|, + COMMUTATOR = <| +); + +DROP OPERATOR |>(pg_catalog.int8, pg_catalog.int8); + +SELECT + ctid, + oprcom +FROM + pg_catalog.pg_operator fk +WHERE oprcom <> 0 + AND NOT EXISTS (SELECT + 1 + FROM + pg_catalog.pg_operator pk + WHERE pk.oid = fk.oprcom); + +SELECT + ctid, + oprnegate +FROM + pg_catalog.pg_operator fk +WHERE oprnegate <> 0 + AND NOT EXISTS (SELECT + 1 + FROM + pg_catalog.pg_operator pk + WHERE pk.oid = fk.oprnegate); + +DROP OPERATOR <|(pg_catalog.int8, pg_catalog.int8); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__infinite_recurse_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__infinite_recurse_60.snap new file mode 100644 index 000000000..5cab6f143 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__infinite_recurse_60.snap @@ -0,0 +1,13 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/infinite_recurse_60.sql +snapshot_kind: text +--- +CREATE FUNCTION infinite_recurse () +RETURNS pg_catalog.int4 +AS 'select infinite_recurse()' +LANGUAGE sql; + +SELECT version() ~ 'powerpc64[^,]*-linux-gnu' AS skip_test; + +SELECT infinite_recurse(); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__init_privs_60.snap.new b/crates/pgt_pretty_print/tests/snapshots/multi/tests__init_privs_60.snap.new new file mode 100644 index 000000000..93dc08784 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__init_privs_60.snap.new @@ -0,0 +1,13 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +assertion_line: 161 +input_file: crates/pgt_pretty_print/tests/data/multi/init_privs_60.sql +--- +SELECT count(*) > 0 FROM pg_init_privs; + +GRANT SELECT ON TABLE pg_proc TO CURRENT_USER; + +GRANT SELECT (prosrc) ON TABLE pg_proc TO CURRENT_USER; + +GRANT SELECT (rolname, rolsuper) ON TABLE pg_authid +TO CURRENT_USER; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__line_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__line_60.snap new file mode 100644 index 000000000..32a334949 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__line_60.snap @@ -0,0 +1,90 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/line_60.sql +snapshot_kind: text +--- +CREATE TABLE line_tbl (s line); + +INSERT INTO line_tbl VALUES ('{0,-1,5}'); + +INSERT INTO line_tbl VALUES ('{1,0,5}'); + +INSERT INTO line_tbl VALUES ('{0,3,0}'); + +INSERT INTO line_tbl VALUES (' (0,0), (6,6)'); + +INSERT INTO line_tbl VALUES ('10,-10 ,-5,-4'); + +INSERT INTO line_tbl VALUES ('[-1e6,2e2,3e5, -4e1]'); + +INSERT INTO line_tbl VALUES ('{3,NaN,5}'); + +INSERT INTO line_tbl VALUES ('{NaN,NaN,NaN}'); + +INSERT INTO line_tbl VALUES ('[(1,3),(2,3)]'); + +INSERT INTO line_tbl VALUES + (line( + '(3,1)'::point, + '(3,2)'::point + )); + +INSERT INTO line_tbl VALUES ('{}'); + +INSERT INTO line_tbl VALUES ('{0'); + +INSERT INTO line_tbl VALUES ('{0,0}'); + +INSERT INTO line_tbl VALUES ('{0,0,1'); + +INSERT INTO line_tbl VALUES ('{0,0,1}'); + +INSERT INTO line_tbl VALUES ('{0,0,1} x'); + +INSERT INTO line_tbl VALUES ('(3asdf,2 ,3,4r2)'); + +INSERT INTO line_tbl VALUES ('[1,2,3, 4'); + +INSERT INTO line_tbl VALUES ('[(,2),(3,4)]'); + +INSERT INTO line_tbl VALUES ('[(1,2),(3,4)'); + +INSERT INTO line_tbl VALUES ('[(1,2),(1,2)]'); + +INSERT INTO line_tbl VALUES + (line( + '(1,0)'::point, + '(1,0)'::point + )); + +SELECT * FROM line_tbl; + +SELECT + '{nan, 1, nan}'::line = '{nan, 1, nan}'::line AS true, + '{nan, 1, nan}'::line = '{nan, 2, nan}'::line AS false; + +SELECT pg_input_is_valid('{1, 1}', 'line'); + +SELECT * FROM pg_input_error_info('{1, 1}', 'line'); + +SELECT pg_input_is_valid('{0, 0, 0}', 'line'); + +SELECT * FROM pg_input_error_info('{0, 0, 0}', 'line'); + +SELECT pg_input_is_valid('{1, 1, a}', 'line'); + +SELECT * FROM pg_input_error_info('{1, 1, a}', 'line'); + +SELECT pg_input_is_valid('{1, 1, 1e400}', 'line'); + +SELECT * FROM pg_input_error_info('{1, 1, 1e400}', 'line'); + +SELECT pg_input_is_valid('(1, 1), (1, 1e400)', 'line'); + +SELECT + * +FROM + pg_input_error_info( + '(1, 1), (1, 1e400)', + 'line' + ); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__lseg_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__lseg_60.snap new file mode 100644 index 000000000..3841fc88d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__lseg_60.snap @@ -0,0 +1,46 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/lseg_60.sql +snapshot_kind: text +--- +CREATE TABLE lseg_tbl (s lseg); + +INSERT INTO lseg_tbl VALUES ('[(1,2),(3,4)]'); + +INSERT INTO lseg_tbl VALUES ('(0,0),(6,6)'); + +INSERT INTO lseg_tbl VALUES ('10,-10 ,-3,-4'); + +INSERT INTO lseg_tbl VALUES ('[-1e6,2e2,3e5, -4e1]'); + +INSERT INTO lseg_tbl VALUES + (lseg( + point( + 11, + 22 + ), + point( + 33, + 44 + ) + )); + +INSERT INTO lseg_tbl VALUES ('[(-10,2),(-10,3)]'); + +INSERT INTO lseg_tbl VALUES ('[(0,-20),(30,-20)]'); + +INSERT INTO lseg_tbl VALUES ('[(NaN,1),(NaN,90)]'); + +INSERT INTO lseg_tbl VALUES ('(3asdf,2 ,3,4r2)'); + +INSERT INTO lseg_tbl VALUES ('[1,2,3, 4'); + +INSERT INTO lseg_tbl VALUES ('[(,2),(3,4)]'); + +INSERT INTO lseg_tbl VALUES ('[(1,2),(3,4)'); + +SELECT * FROM lseg_tbl; + +SELECT pg_input_is_valid('[(1,2),(3)]', 'lseg'); + +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'lseg'); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__numa_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__numa_60.snap new file mode 100644 index 000000000..ac333a630 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__numa_60.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/numa_60.sql +snapshot_kind: text +--- +SELECT NOT pg_numa_available() AS skip_test; + +SELECT count(*) = 0 AS ok FROM pg_shmem_allocations_numa; + +SELECT count(*) >= 0 AS ok FROM pg_shmem_allocations_numa; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__oid_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__oid_60.snap new file mode 100644 index 000000000..f06d7aefd --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__oid_60.snap @@ -0,0 +1,84 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/oid_60.sql +snapshot_kind: text +--- +CREATE TABLE oid_tbl (f1 oid); + +INSERT INTO oid_tbl (f1) VALUES ('1234'); + +INSERT INTO oid_tbl (f1) VALUES ('1235'); + +INSERT INTO oid_tbl (f1) VALUES ('987'); + +INSERT INTO oid_tbl (f1) VALUES ('-1040'); + +INSERT INTO oid_tbl (f1) VALUES ('99999999'); + +INSERT INTO oid_tbl (f1) VALUES ('5 '); + +INSERT INTO oid_tbl (f1) VALUES (' 10 '); + +INSERT INTO oid_tbl (f1) VALUES (' 15 '); + +INSERT INTO oid_tbl (f1) VALUES (''); + +INSERT INTO oid_tbl (f1) VALUES (' '); + +INSERT INTO oid_tbl (f1) VALUES ('asdfasd'); + +INSERT INTO oid_tbl (f1) VALUES ('99asdfasd'); + +INSERT INTO oid_tbl (f1) VALUES ('5 d'); + +INSERT INTO oid_tbl (f1) VALUES (' 5d'); + +INSERT INTO oid_tbl (f1) VALUES ('5 5'); + +INSERT INTO oid_tbl (f1) VALUES (' - 500'); + +INSERT INTO oid_tbl (f1) VALUES ('32958209582039852935'); + +INSERT INTO oid_tbl (f1) VALUES ('-23582358720398502385'); + +SELECT * FROM oid_tbl; + +SELECT pg_input_is_valid('1234', 'oid'); + +SELECT pg_input_is_valid('01XYZ', 'oid'); + +SELECT * FROM pg_input_error_info('01XYZ', 'oid'); + +SELECT pg_input_is_valid('9999999999', 'oid'); + +SELECT * FROM pg_input_error_info('9999999999', 'oid'); + +SELECT pg_input_is_valid(' 1 2 4 ', 'oidvector'); + +SELECT pg_input_is_valid('01 01XYZ', 'oidvector'); + +SELECT * FROM pg_input_error_info('01 01XYZ', 'oidvector'); + +SELECT pg_input_is_valid('01 9999999999', 'oidvector'); + +SELECT + * +FROM + pg_input_error_info( + '01 9999999999', + 'oidvector' + ); + +SELECT o.* FROM oid_tbl o WHERE o.f1 = 1234; + +SELECT o.* FROM oid_tbl o WHERE o.f1 <> '1234'; + +SELECT o.* FROM oid_tbl o WHERE o.f1 <= '1234'; + +SELECT o.* FROM oid_tbl o WHERE o.f1 < '1234'; + +SELECT o.* FROM oid_tbl o WHERE o.f1 >= '1234'; + +SELECT o.* FROM oid_tbl o WHERE o.f1 > '1234'; + +DROP TABLE oid_tbl; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__path_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__path_60.snap new file mode 100644 index 000000000..a12a127d5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__path_60.snap @@ -0,0 +1,56 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/path_60.sql +snapshot_kind: text +--- +CREATE TABLE path_tbl (f1 path); + +INSERT INTO path_tbl VALUES ('[(1,2),(3,4)]'); + +INSERT INTO path_tbl VALUES (' ( ( 1 , 2 ) , ( 3 , 4 ) ) '); + +INSERT INTO path_tbl VALUES ('[ (0,0),(3,0),(4,5),(1,6) ]'); + +INSERT INTO path_tbl VALUES ('((1,2) ,(3,4 ))'); + +INSERT INTO path_tbl VALUES ('1,2 ,3,4 '); + +INSERT INTO path_tbl VALUES (' [1,2,3, 4] '); + +INSERT INTO path_tbl VALUES ('((10,20))'); + +INSERT INTO path_tbl VALUES ('[ 11,12,13,14 ]'); + +INSERT INTO path_tbl VALUES ('( 11,12,13,14) '); + +INSERT INTO path_tbl VALUES ('[]'); + +INSERT INTO path_tbl VALUES ('[(,2),(3,4)]'); + +INSERT INTO path_tbl VALUES ('[(1,2),(3,4)'); + +INSERT INTO path_tbl VALUES ('(1,2,3,4'); + +INSERT INTO path_tbl VALUES ('(1,2),(3,4)]'); + +SELECT f1 AS open_path FROM path_tbl WHERE isopen(f1); + +SELECT f1 AS closed_path FROM path_tbl WHERE isclosed(f1); + +SELECT pclose(f1) AS closed_path FROM path_tbl; + +SELECT popen(f1) AS open_path FROM path_tbl; + +SELECT pg_input_is_valid('[(1,2),(3)]', 'path'); + +SELECT * FROM pg_input_error_info('[(1,2),(3)]', 'path'); + +SELECT pg_input_is_valid('[(1,2,6),(3,4,6)]', 'path'); + +SELECT + * +FROM + pg_input_error_info( + '[(1,2,6),(3,4,6)]', + 'path' + ); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__predicate_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__predicate_60.snap new file mode 100644 index 000000000..f13100c7d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__predicate_60.snap @@ -0,0 +1,254 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/predicate_60.sql +snapshot_kind: text +--- +CREATE TABLE pred_tab ( + a pg_catalog.int4 NOT NULL, + b pg_catalog.int4, + c pg_catalog.int4 NOT NULL +); + +SELECT * FROM pred_tab t WHERE t.a IS NOT NULL; + +SELECT * FROM pred_tab t WHERE t.b IS NOT NULL; + +SELECT * FROM pred_tab t WHERE t.a IS NULL; + +SELECT * FROM pred_tab t WHERE t.b IS NULL; + +SELECT * FROM pred_tab t WHERE t.a IS NOT NULL OR t.b = 1; + +SELECT * FROM pred_tab t WHERE t.b IS NOT NULL OR t.a = 1; + +SELECT * FROM pred_tab t WHERE t.a IS NULL OR t.c IS NULL; + +SELECT * FROM pred_tab t WHERE t.b IS NULL OR t.c IS NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON t1.a IS NOT NULL; + +SELECT + * +FROM + pred_tab t1 + FULL JOIN + pred_tab t2 ON t1.a = t2.a + LEFT JOIN + pred_tab t3 ON t2.a IS NOT NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON t1.a IS NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON t1.a = 1 + LEFT JOIN + pred_tab t3 ON t2.a IS NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON t1.a IS NOT NULL + OR t2.b = 1; + +SELECT + * +FROM + pred_tab t1 + FULL JOIN + pred_tab t2 ON t1.a = t2.a + LEFT JOIN + pred_tab t3 ON t2.a IS NOT NULL + OR t2.b = 1; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON t1.a IS NULL + OR t1.c IS NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON t1.a = 1 + LEFT JOIN + pred_tab t3 ON t2.a IS NULL + OR t2.c IS NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON EXISTS (SELECT + 1 + FROM + pred_tab t3, + pred_tab t4, + pred_tab t5, + pred_tab t6 + WHERE t1.a = t3.a + AND t6.a IS NOT NULL); + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON EXISTS (SELECT + 1 + FROM + pred_tab t3, + pred_tab t4, + pred_tab t5, + pred_tab t6 + WHERE t1.a = t3.a + AND t6.a IS NULL); + +DROP TABLE pred_tab; + +CREATE TABLE pred_parent (a pg_catalog.int4); + +CREATE TABLE pred_child () INHERITS (pred_parent); + +ALTER TABLE ONLY pred_parent ALTER COLUMN a SET NOT NULL; + +SELECT * FROM pred_parent WHERE a IS NOT NULL; + +SELECT * FROM pred_parent WHERE a IS NULL; + +ALTER TABLE pred_parent ALTER COLUMN a DROP NOT NULL; + +ALTER TABLE pred_child ALTER COLUMN a SET NOT NULL; + +SELECT * FROM pred_parent WHERE a IS NOT NULL; + +SELECT * FROM pred_parent WHERE a IS NULL; + +DROP TABLE pred_parent, pred_child; + +CREATE TABLE pred_tab ( + a pg_catalog.int4, + b pg_catalog.int4 +); + +CREATE TABLE pred_tab_notnull ( + a pg_catalog.int4, + b pg_catalog.int4 NOT NULL +); + +INSERT INTO pred_tab VALUES (1, 1); + +INSERT INTO pred_tab VALUES (2, 2); + +INSERT INTO pred_tab_notnull VALUES (2, 2); + +INSERT INTO pred_tab_notnull VALUES (3, 3); + +ANALYZE pred_tab; + +ANALYZE pred_tab_notnull; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON TRUE + LEFT JOIN + pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN + pred_tab t4 ON t3.b IS NOT NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON TRUE + LEFT JOIN + pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN + pred_tab t4 ON t3.b IS NOT NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON TRUE + LEFT JOIN + pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN + pred_tab t4 ON t3.b IS NULL + AND t3.a IS NOT NULL; + +SELECT + * +FROM + pred_tab t1 + LEFT JOIN + pred_tab t2 ON TRUE + LEFT JOIN + pred_tab_notnull t3 ON t2.a = t3.a + LEFT JOIN + pred_tab t4 ON t3.b IS NULL + AND t3.a IS NOT NULL; + +DROP TABLE pred_tab; + +DROP TABLE pred_tab_notnull; + +CREATE TABLE pred_tab1 ( + a pg_catalog.int4 NOT NULL, + b pg_catalog.int4, + CONSTRAINT check_tab1 CHECK (a IS NULL + OR b > 2) +); + +CREATE TABLE pred_tab2 ( + a pg_catalog.int4, + b pg_catalog.int4, + CONSTRAINT check_a CHECK (a IS NOT NULL) +); + +SET constraint_exclusion TO 'on'; + +SELECT + * +FROM + pred_tab1, + pred_tab2 +WHERE pred_tab2.a IS NULL; + +SELECT + * +FROM + pred_tab2, + pred_tab1 +WHERE pred_tab1.a IS NULL + OR pred_tab1.b < 2; + +RESET constraint_exclusion; + +DROP TABLE pred_tab1; + +DROP TABLE pred_tab2; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__regproc_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__regproc_60.snap new file mode 100644 index 000000000..668745d9e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__regproc_60.snap @@ -0,0 +1,396 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/regproc_60.sql +snapshot_kind: text +--- +CREATE ROLE regress_regrole_test; + +SELECT regoper('||/'); + +SELECT regoperator('+(int4,int4)'); + +SELECT regproc('now'); + +SELECT regprocedure('abs(numeric)'); + +SELECT regclass('pg_class'); + +SELECT regtype('int4'); + +SELECT regcollation('"POSIX"'); + +SELECT to_regoper('||/'); + +SELECT to_regoperator('+(int4,int4)'); + +SELECT to_regproc('now'); + +SELECT to_regprocedure('abs(numeric)'); + +SELECT to_regclass('pg_class'); + +SELECT to_regtype('int4'); + +SELECT to_regcollation('"POSIX"'); + +SELECT regoper('pg_catalog.||/'); + +SELECT regoperator('pg_catalog.+(int4,int4)'); + +SELECT regproc('pg_catalog.now'); + +SELECT regprocedure('pg_catalog.abs(numeric)'); + +SELECT regclass('pg_catalog.pg_class'); + +SELECT regtype('pg_catalog.int4'); + +SELECT regcollation('pg_catalog."POSIX"'); + +SELECT to_regoper('pg_catalog.||/'); + +SELECT to_regproc('pg_catalog.now'); + +SELECT to_regprocedure('pg_catalog.abs(numeric)'); + +SELECT to_regclass('pg_catalog.pg_class'); + +SELECT to_regtype('pg_catalog.int4'); + +SELECT to_regcollation('pg_catalog."POSIX"'); + +SELECT regrole('regress_regrole_test'); + +SELECT regrole('"regress_regrole_test"'); + +SELECT regnamespace('pg_catalog'); + +SELECT regnamespace('"pg_catalog"'); + +SELECT regdatabase('template1'); + +SELECT regdatabase('"template1"'); + +SELECT to_regrole('regress_regrole_test'); + +SELECT to_regrole('"regress_regrole_test"'); + +SELECT to_regnamespace('pg_catalog'); + +SELECT to_regnamespace('"pg_catalog"'); + +SELECT to_regdatabase('template1'); + +SELECT to_regdatabase('"template1"'); + +SELECT regproc('-')::oid; + +SELECT regprocedure('-')::oid; + +SELECT regclass('-')::oid; + +SELECT regcollation('-')::oid; + +SELECT regtype('-')::oid; + +SELECT regconfig('-')::oid; + +SELECT regdictionary('-')::oid; + +SELECT regrole('-')::oid; + +SELECT regnamespace('-')::oid; + +SELECT regdatabase('-')::oid; + +SELECT to_regproc('-')::oid; + +SELECT to_regprocedure('-')::oid; + +SELECT to_regclass('-')::oid; + +SELECT to_regcollation('-')::oid; + +SELECT to_regtype('-')::oid; + +SELECT to_regrole('-')::oid; + +SELECT to_regnamespace('-')::oid; + +SELECT to_regdatabase('-')::oid; + +CREATE TABLE regrole_test ( + rolid oid DEFAULT 'regress_regrole_test'::regrole +); + +CREATE TABLE regdatabase_test ( + datid oid DEFAULT 'template1'::regdatabase +); + +DROP ROLE regress_regrole_test; + +SELECT regoper('||//'); + +SELECT regoperator('++(int4,int4)'); + +SELECT regproc('know'); + +SELECT regprocedure('absinthe(numeric)'); + +SELECT regclass('pg_classes'); + +SELECT regtype('int3'); + +SELECT regoper('ng_catalog.||/'); + +SELECT regoperator('ng_catalog.+(int4,int4)'); + +SELECT regproc('ng_catalog.now'); + +SELECT regprocedure('ng_catalog.abs(numeric)'); + +SELECT regclass('ng_catalog.pg_class'); + +SELECT regtype('ng_catalog.int4'); + +SELECT regcollation('ng_catalog."POSIX"'); + +SELECT regrole('regress_regrole_test'); + +SELECT regrole('"regress_regrole_test"'); + +SELECT regrole('Nonexistent'); + +SELECT regrole('"Nonexistent"'); + +SELECT regrole('foo.bar'); + +SELECT regnamespace('Nonexistent'); + +SELECT regnamespace('"Nonexistent"'); + +SELECT regnamespace('foo.bar'); + +SELECT regdatabase('Nonexistent'); + +SELECT regdatabase('"Nonexistent"'); + +SELECT regdatabase('foo.bar'); + +SELECT to_regoper('||//'); + +SELECT to_regoperator('++(int4,int4)'); + +SELECT to_regproc('know'); + +SELECT to_regprocedure('absinthe(numeric)'); + +SELECT to_regclass('pg_classes'); + +SELECT to_regtype('int3'); + +SELECT to_regcollation('notacollation'); + +SELECT to_regoper('ng_catalog.||/'); + +SELECT to_regoperator('ng_catalog.+(int4,int4)'); + +SELECT to_regproc('ng_catalog.now'); + +SELECT to_regprocedure('ng_catalog.abs(numeric)'); + +SELECT to_regclass('ng_catalog.pg_class'); + +SELECT to_regtype('ng_catalog.int4'); + +SELECT to_regcollation('ng_catalog."POSIX"'); + +SELECT to_regrole('regress_regrole_test'); + +SELECT to_regrole('"regress_regrole_test"'); + +SELECT to_regrole('foo.bar'); + +SELECT to_regrole('Nonexistent'); + +SELECT to_regrole('"Nonexistent"'); + +SELECT to_regrole('foo.bar'); + +SELECT to_regnamespace('Nonexistent'); + +SELECT to_regnamespace('"Nonexistent"'); + +SELECT to_regnamespace('foo.bar'); + +SELECT to_regdatabase('Nonexistent'); + +SELECT to_regdatabase('"Nonexistent"'); + +SELECT to_regdatabase('foo.bar'); + +SELECT to_regtypemod('text'); + +SELECT to_regtypemod('timestamp(4)'); + +SELECT to_regtypemod('no_such_type(4)'); + +SELECT + format_type( + to_regtype( + 'varchar(32)' + ), + to_regtypemod( + 'varchar(32)' + ) + ); + +SELECT format_type(to_regtype('bit'), to_regtypemod('bit')); + +SELECT + format_type( + to_regtype( + '"bit"' + ), + to_regtypemod( + '"bit"' + ) + ); + +SELECT + * +FROM + pg_input_error_info( + 'ng_catalog.pg_class', + 'regclass' + ); + +SELECT + pg_input_is_valid( + 'ng_catalog."POSIX"', + 'regcollation' + ); + +SELECT + * +FROM + pg_input_error_info( + 'no_such_config', + 'regconfig' + ); + +SELECT + * +FROM + pg_input_error_info( + 'no_such_dictionary', + 'regdictionary' + ); + +SELECT + * +FROM + pg_input_error_info( + 'Nonexistent', + 'regnamespace' + ); + +SELECT + * +FROM + pg_input_error_info( + 'ng_catalog.||/', + 'regoper' + ); + +SELECT * FROM pg_input_error_info('-', 'regoper'); + +SELECT + * +FROM + pg_input_error_info( + 'ng_catalog.+(int4,int4)', + 'regoperator' + ); + +SELECT * FROM pg_input_error_info('-', 'regoperator'); + +SELECT + * +FROM + pg_input_error_info( + 'ng_catalog.now', + 'regproc' + ); + +SELECT + * +FROM + pg_input_error_info( + 'ng_catalog.abs(numeric)', + 'regprocedure' + ); + +SELECT + * +FROM + pg_input_error_info( + 'ng_catalog.abs(numeric', + 'regprocedure' + ); + +SELECT + * +FROM + pg_input_error_info( + 'regress_regrole_test', + 'regrole' + ); + +SELECT + * +FROM + pg_input_error_info( + 'no_such_type', + 'regtype' + ); + +SELECT + * +FROM + pg_input_error_info( + 'Nonexistent', + 'regdatabase' + ); + +SELECT + * +FROM + pg_input_error_info( + 'incorrect type name syntax', + 'regtype' + ); + +SELECT + * +FROM + pg_input_error_info( + 'numeric(1,2,3)', + 'regtype' + ); + +SELECT + * +FROM + pg_input_error_info( + 'way.too.many.names', + 'regtype' + ); + +SELECT + * +FROM + pg_input_error_info( + 'no_such_catalog.schema.name', + 'regtype' + ); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__reindex_catalog_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__reindex_catalog_60.snap new file mode 100644 index 000000000..ad65c52e6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__reindex_catalog_60.snap @@ -0,0 +1,44 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/reindex_catalog_60.sql +snapshot_kind: text +--- +REINDEX TABLE pg_class; + +REINDEX TABLE pg_index; + +REINDEX TABLE pg_operator; + +REINDEX TABLE pg_database; + +REINDEX TABLE pg_shdescription; + +REINDEX INDEX pg_class_oid_index; + +REINDEX INDEX pg_class_relname_nsp_index; + +REINDEX INDEX pg_index_indexrelid_index; + +REINDEX INDEX pg_index_indrelid_index; + +REINDEX INDEX pg_database_oid_index; + +REINDEX INDEX pg_shdescription_o_c_index; + +BEGIN; + +SET min_parallel_table_scan_size TO 0; + +REINDEX INDEX pg_class_oid_index; + +REINDEX INDEX pg_class_relname_nsp_index; + +REINDEX INDEX pg_index_indexrelid_index; + +REINDEX INDEX pg_index_indrelid_index; + +REINDEX INDEX pg_database_oid_index; + +REINDEX INDEX pg_shdescription_o_c_index; + +ROLLBACK; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__select_distinct_on_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__select_distinct_on_60.snap new file mode 100644 index 000000000..8367669be --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__select_distinct_on_60.snap @@ -0,0 +1,189 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/select_distinct_on_60.sql +snapshot_kind: text +--- +SELECT DISTINCT ON (string4) + string4, + two, + ten +FROM + onek +ORDER BY + string4 USING <, + two USING >, + ten USING <; + +SELECT DISTINCT ON (string4, ten) + string4, + two, + ten +FROM + onek +ORDER BY + string4 USING <, + two USING <, + ten USING <; + +SELECT DISTINCT ON (string4, ten) + string4, + ten, + two +FROM + onek +ORDER BY + string4 USING <, + ten USING >, + two USING <; + +SELECT DISTINCT ON (1) + floor( + random() + ) AS r, + f1 +FROM + int4_tbl +ORDER BY + 1, + 2; + +SELECT DISTINCT ON (four) + four, + two +FROM + tenk1 +WHERE four = 0 +ORDER BY + 1; + +SELECT DISTINCT ON (four) + four, + two +FROM + tenk1 +WHERE four = 0 +ORDER BY + 1; + +SELECT DISTINCT ON (four) + four, + two +FROM + tenk1 +WHERE four = 0 +ORDER BY + 1, + 2; + +SELECT DISTINCT ON (four) + four, + hundred +FROM + tenk1 +WHERE four = 0 +ORDER BY + 1, + 2; + +CREATE TABLE distinct_on_tbl ( + x pg_catalog.int4, + y pg_catalog.int4, + z pg_catalog.int4 +); + +INSERT INTO distinct_on_tbl SELECT + i % 10, + i % 10, + i % 10 +FROM + generate_series( + 1, + 1000 + ) AS i; + +CREATE INDEX distinct_on_tbl_x_y_idx ON distinct_on_tbl (x, + y); + +ANALYZE distinct_on_tbl; + +SET enable_hashagg TO 'off'; + +SELECT DISTINCT ON (y, x) x, y FROM distinct_on_tbl; + +SELECT DISTINCT ON (y, x) x, y FROM distinct_on_tbl; + +SELECT DISTINCT ON (y, x) + x, + y +FROM + (SELECT + * + FROM + distinct_on_tbl + ORDER BY + x) AS s; + +SELECT DISTINCT ON (y, x) + x, + y +FROM + (SELECT + * + FROM + distinct_on_tbl + ORDER BY + x) AS s; + +SELECT DISTINCT ON (y, x) + x, + y +FROM + distinct_on_tbl +ORDER BY + y; + +SELECT DISTINCT ON (y, x) + x, + y +FROM + distinct_on_tbl +ORDER BY + y; + +SELECT DISTINCT ON (y, x) + x, + y +FROM + (SELECT + * + FROM + distinct_on_tbl + ORDER BY + x, + z, + y) AS s +ORDER BY + y, + x, + z; + +SELECT DISTINCT ON (y, x) + x, + y +FROM + (SELECT + * + FROM + distinct_on_tbl + ORDER BY + x, + z, + y) AS s +ORDER BY + y, + x, + z; + +RESET enable_hashagg; + +DROP TABLE distinct_on_tbl; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__select_having_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__select_having_60.snap new file mode 100644 index 000000000..4947792c1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__select_having_60.snap @@ -0,0 +1,146 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/select_having_60.sql +snapshot_kind: text +--- +CREATE TABLE test_having ( + a pg_catalog.int4, + b pg_catalog.int4, + c pg_catalog.bpchar(8), + d pg_catalog.bpchar(1) +); + +INSERT INTO test_having VALUES (0, 1, 'XXXX', 'A'); + +INSERT INTO test_having VALUES (1, 2, 'AAAA', 'b'); + +INSERT INTO test_having VALUES (2, 2, 'AAAA', 'c'); + +INSERT INTO test_having VALUES (3, 3, 'BBBB', 'D'); + +INSERT INTO test_having VALUES (4, 3, 'BBBB', 'e'); + +INSERT INTO test_having VALUES (5, 3, 'bbbb', 'F'); + +INSERT INTO test_having VALUES (6, 4, 'cccc', 'g'); + +INSERT INTO test_having VALUES (7, 4, 'cccc', 'h'); + +INSERT INTO test_having VALUES (8, 4, 'CCCC', 'I'); + +INSERT INTO test_having VALUES (9, 4, 'CCCC', 'j'); + +SELECT + b, + c +FROM + test_having +GROUP BY + b, + c +HAVING count(*) = 1 +ORDER BY + b, + c; + +SELECT + b, + c +FROM + test_having +GROUP BY + b, + c +HAVING b = 3 +ORDER BY + b, + c; + +SELECT + lower( + c + ), + count( + c + ) +FROM + test_having +GROUP BY + lower( + c + ) +HAVING count(*) > 2 + OR min( + a + ) = max( + a + ) +ORDER BY + lower( + c + ); + +SELECT + c, + max( + a + ) +FROM + test_having +GROUP BY + c +HAVING count(*) > 2 + OR min( + a + ) = max( + a + ) +ORDER BY + c; + +SELECT + min( + a + ), + max( + a + ) +FROM + test_having +HAVING min( + a +) = max( + a +); + +SELECT + min( + a + ), + max( + a + ) +FROM + test_having +HAVING min( + a +) < max( + a +); + +SELECT a FROM test_having HAVING min(a) < max(a); + +SELECT 1 AS one FROM test_having HAVING a > 1; + +SELECT 1 AS one FROM test_having HAVING 1 > 2; + +SELECT 1 AS one FROM test_having HAVING 1 < 2; + +SELECT + 1 AS one +FROM + test_having +WHERE 1 / a = 1 +HAVING 1 < 2; + +DROP TABLE test_having; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__tid_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__tid_60.snap new file mode 100644 index 000000000..2da737282 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__tid_60.snap @@ -0,0 +1,100 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/tid_60.sql +snapshot_kind: text +--- +SELECT + '(0,0)'::tid AS tid00, + '(0,1)'::tid AS tid01, + '(-1,0)'::tid AS tidm10, + '(4294967295,65535)'::tid AS tidmax; + +SELECT '(4294967296,1)'::tid; + +SELECT '(1,65536)'::tid; + +SELECT pg_input_is_valid('(0)', 'tid'); + +SELECT * FROM pg_input_error_info('(0)', 'tid'); + +SELECT pg_input_is_valid('(0,-1)', 'tid'); + +SELECT * FROM pg_input_error_info('(0,-1)', 'tid'); + +CREATE TABLE tid_tab (a pg_catalog.int4); + +INSERT INTO tid_tab VALUES (1), (2); + +SELECT min(ctid) FROM tid_tab; + +SELECT max(ctid) FROM tid_tab; + +TRUNCATE TABLE tid_tab; + +CREATE MATERIALIZED VIEW tid_matview AS SELECT + a +FROM + tid_tab; + +SELECT currtid2('tid_matview'::text, '(0,1)'::tid); + +INSERT INTO tid_tab VALUES (1); + +REFRESH MATERIALIZED VIEW tid_matview; + +SELECT currtid2('tid_matview'::text, '(0,1)'::tid); + +DROP MATERIALIZED VIEW tid_matview; + +TRUNCATE TABLE tid_tab; + +CREATE SEQUENCE tid_seq; + +SELECT currtid2('tid_seq'::text, '(0,1)'::tid); + +DROP SEQUENCE tid_seq; + +CREATE INDEX tid_ind ON tid_tab (a); + +SELECT currtid2('tid_ind'::text, '(0,1)'::tid); + +DROP INDEX tid_ind; + +CREATE TABLE tid_part ( + a pg_catalog.int4 +) +PARTITION BY RANGE (a); + +SELECT currtid2('tid_part'::text, '(0,1)'::tid); + +DROP TABLE tid_part; + +CREATE VIEW tid_view_no_ctid AS SELECT a FROM tid_tab; + +SELECT currtid2('tid_view_no_ctid'::text, '(0,1)'::tid); + +DROP VIEW tid_view_no_ctid; + +CREATE VIEW tid_view_with_ctid AS SELECT + ctid, + a +FROM + tid_tab; + +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); + +INSERT INTO tid_tab VALUES (1); + +SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); + +DROP VIEW tid_view_with_ctid; + +TRUNCATE TABLE tid_tab; + +CREATE VIEW tid_view_fake_ctid AS SELECT 1 AS ctid, 2 AS a; + +SELECT currtid2('tid_view_fake_ctid'::text, '(0,1)'::tid); + +DROP VIEW tid_view_fake_ctid; + +DROP TABLE tid_tab CASCADE; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__tsdicts_60.snap.new b/crates/pgt_pretty_print/tests/snapshots/multi/tests__tsdicts_60.snap.new new file mode 100644 index 000000000..17ec17111 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__tsdicts_60.snap.new @@ -0,0 +1,245 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +assertion_line: 161 +input_file: crates/pgt_pretty_print/tests/data/multi/tsdicts_60.sql +--- +CREATE TEXT SEARCH DICTIONARY ispell ( + template = ispell, + dictfile = ispell_sample, + afffile = ispell_sample +); + +SELECT ts_lexize('ispell', 'skies'); + +SELECT ts_lexize('ispell', 'bookings'); + +SELECT ts_lexize('ispell', 'booking'); + +SELECT ts_lexize('ispell', 'foot'); + +SELECT ts_lexize('ispell', 'foots'); + +SELECT ts_lexize('ispell', 'rebookings'); + +SELECT ts_lexize('ispell', 'rebooking'); + +SELECT ts_lexize('ispell', 'rebook'); + +SELECT ts_lexize('ispell', 'unbookings'); + +SELECT ts_lexize('ispell', 'unbooking'); + +SELECT ts_lexize('ispell', 'unbook'); + +SELECT ts_lexize('ispell', 'footklubber'); + +SELECT ts_lexize('ispell', 'footballklubber'); + +SELECT ts_lexize('ispell', 'ballyklubber'); + +SELECT ts_lexize('ispell', 'footballyklubber'); + +CREATE TEXT SEARCH DICTIONARY hunspell ( + template = ispell, + dictfile = ispell_sample, + afffile = hunspell_sample +); + +SELECT ts_lexize('hunspell', 'skies'); + +SELECT ts_lexize('hunspell', 'bookings'); + +SELECT ts_lexize('hunspell', 'booking'); + +SELECT ts_lexize('hunspell', 'foot'); + +SELECT ts_lexize('hunspell', 'foots'); + +SELECT ts_lexize('hunspell', 'rebookings'); + +SELECT ts_lexize('hunspell', 'rebooking'); + +SELECT ts_lexize('hunspell', 'rebook'); + +SELECT ts_lexize('hunspell', 'unbookings'); + +SELECT ts_lexize('hunspell', 'unbooking'); + +SELECT ts_lexize('hunspell', 'unbook'); + +SELECT ts_lexize('hunspell', 'footklubber'); + +SELECT ts_lexize('hunspell', 'footballklubber'); + +SELECT ts_lexize('hunspell', 'ballyklubber'); + +SELECT ts_lexize('hunspell', 'footballyklubber'); + +CREATE TEXT SEARCH DICTIONARY hunspell_long ( + template = ispell, + dictfile = hunspell_sample_long, + afffile = hunspell_sample_long +); + +SELECT ts_lexize('hunspell_long', 'skies'); + +SELECT ts_lexize('hunspell_long', 'bookings'); + +SELECT ts_lexize('hunspell_long', 'booking'); + +SELECT ts_lexize('hunspell_long', 'foot'); + +SELECT ts_lexize('hunspell_long', 'foots'); + +SELECT ts_lexize('hunspell_long', 'rebookings'); + +SELECT ts_lexize('hunspell_long', 'rebooking'); + +SELECT ts_lexize('hunspell_long', 'rebook'); + +SELECT ts_lexize('hunspell_long', 'unbookings'); + +SELECT ts_lexize('hunspell_long', 'unbooking'); + +SELECT ts_lexize('hunspell_long', 'unbook'); + +SELECT ts_lexize('hunspell_long', 'booked'); + +SELECT ts_lexize('hunspell_long', 'footklubber'); + +SELECT ts_lexize('hunspell_long', 'footballklubber'); + +SELECT ts_lexize('hunspell_long', 'ballyklubber'); + +SELECT ts_lexize('hunspell_long', 'ballsklubber'); + +SELECT ts_lexize('hunspell_long', 'footballyklubber'); + +SELECT ts_lexize('hunspell_long', 'ex-machina'); + +CREATE TEXT SEARCH DICTIONARY hunspell_num ( + template = ispell, + dictfile = hunspell_sample_num, + afffile = hunspell_sample_num +); + +SELECT ts_lexize('hunspell_num', 'skies'); + +SELECT ts_lexize('hunspell_num', 'sk'); + +SELECT ts_lexize('hunspell_num', 'bookings'); + +SELECT ts_lexize('hunspell_num', 'booking'); + +SELECT ts_lexize('hunspell_num', 'foot'); + +SELECT ts_lexize('hunspell_num', 'foots'); + +SELECT ts_lexize('hunspell_num', 'rebookings'); + +SELECT ts_lexize('hunspell_num', 'rebooking'); + +SELECT ts_lexize('hunspell_num', 'rebook'); + +SELECT ts_lexize('hunspell_num', 'unbookings'); + +SELECT ts_lexize('hunspell_num', 'unbooking'); + +SELECT ts_lexize('hunspell_num', 'unbook'); + +SELECT ts_lexize('hunspell_num', 'booked'); + +SELECT ts_lexize('hunspell_num', 'footklubber'); + +SELECT ts_lexize('hunspell_num', 'footballklubber'); + +SELECT ts_lexize('hunspell_num', 'ballyklubber'); + +SELECT ts_lexize('hunspell_num', 'footballyklubber'); + +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + template = ispell, + dictfile = ispell_sample, + afffile = hunspell_sample_long +); + +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + template = ispell, + dictfile = ispell_sample, + afffile = hunspell_sample_num +); + +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 ( + template = ispell, + dictfile = hunspell_sample_long, + afffile = ispell_sample +); + +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 ( + template = ispell, + dictfile = hunspell_sample_long, + afffile = hunspell_sample_num +); + +CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 ( + template = ispell, + dictfile = hunspell_sample_num, + afffile = ispell_sample +); + +CREATE TEXT SEARCH DICTIONARY hunspell_err ( + template = ispell, + dictfile = hunspell_sample_num, + afffile = hunspell_sample_long +); + +CREATE TEXT SEARCH DICTIONARY synonym ( + template = synonym, + synonyms = synonym_sample +); + +SELECT ts_lexize('synonym', 'PoStGrEs'); + +SELECT ts_lexize('synonym', 'Gogle'); + +SELECT ts_lexize('synonym', 'indices'); + +SELECT + dictinitoption +FROM + pg_ts_dict +WHERE dictname = 'synonym'; + +ALTER TEXT SEARCH DICTIONARY synonym (casesensitive = 1); + +SELECT ts_lexize('synonym', 'PoStGrEs'); + +SELECT + dictinitoption +FROM + pg_ts_dict +WHERE dictname = 'synonym'; + +ALTER TEXT SEARCH DICTIONARY synonym (casesensitive = 2); + +ALTER TEXT SEARCH DICTIONARY synonym (casesensitive = off); + +SELECT ts_lexize('synonym', 'PoStGrEs'); + +SELECT + dictinitoption +FROM + pg_ts_dict +WHERE dictname = 'synonym'; + +CREATE TEXT SEARCH DICTIONARY thesaurus ( + template = thesaurus, + dictfile = thesaurus_sample, + dictionary = english_stem +); + +SELECT ts_lexize('thesaurus', 'one'); + +CREATE TEXT SEARCH CONFIGURATION ispell_tst ( + copy = english +); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__varchar_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__varchar_60.snap new file mode 100644 index 000000000..6ab3b7798 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__varchar_60.snap @@ -0,0 +1,48 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/varchar_60.sql +snapshot_kind: text +--- +CREATE TEMP TABLE varchar_tbl (f1 pg_catalog.varchar(1)); + +INSERT INTO varchar_tbl (f1) VALUES ('a'); + +INSERT INTO varchar_tbl (f1) VALUES ('A'); + +INSERT INTO varchar_tbl (f1) VALUES ('1'); + +INSERT INTO varchar_tbl (f1) VALUES (2); + +INSERT INTO varchar_tbl (f1) VALUES ('3'); + +INSERT INTO varchar_tbl (f1) VALUES (''); + +INSERT INTO varchar_tbl (f1) VALUES ('cd'); + +INSERT INTO varchar_tbl (f1) VALUES ('c '); + +SELECT * FROM varchar_tbl; + +SELECT c.* FROM varchar_tbl c WHERE c.f1 <> 'a'; + +SELECT c.* FROM varchar_tbl c WHERE c.f1 = 'a'; + +SELECT c.* FROM varchar_tbl c WHERE c.f1 < 'a'; + +SELECT c.* FROM varchar_tbl c WHERE c.f1 <= 'a'; + +SELECT c.* FROM varchar_tbl c WHERE c.f1 > 'a'; + +SELECT c.* FROM varchar_tbl c WHERE c.f1 >= 'a'; + +DROP TABLE varchar_tbl; + +INSERT INTO varchar_tbl (f1) VALUES ('abcde'); + +SELECT * FROM varchar_tbl; + +SELECT pg_input_is_valid('abcd ', 'varchar(4)'); + +SELECT pg_input_is_valid('abcde', 'varchar(4)'); + +SELECT * FROM pg_input_error_info('abcde', 'varchar(4)'); diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__write_parallel_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__write_parallel_60.snap new file mode 100644 index 000000000..9dd195fc6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__write_parallel_60.snap @@ -0,0 +1,112 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/write_parallel_60.sql +snapshot_kind: text +--- +BEGIN; + +SET parallel_setup_cost TO 0; + +SET parallel_tuple_cost TO 0; + +SET min_parallel_table_scan_size TO 0; + +SET max_parallel_workers_per_gather TO 4; + +CREATE TABLE parallel_write AS SELECT + length( + stringu1 + ) +FROM + tenk1 +GROUP BY + length( + stringu1 + ); + +CREATE TABLE parallel_write AS SELECT + length( + stringu1 + ) +FROM + tenk1 +GROUP BY + length( + stringu1 + ); + +DROP TABLE parallel_write; + +SELECT + length( + stringu1 + ) INTO parallel_write +FROM + tenk1 +GROUP BY + length( + stringu1 + ); + +SELECT + length( + stringu1 + ) INTO parallel_write +FROM + tenk1 +GROUP BY + length( + stringu1 + ); + +DROP TABLE parallel_write; + +CREATE MATERIALIZED VIEW parallel_mat_view AS SELECT + length( + stringu1 + ) +FROM + tenk1 +GROUP BY + length( + stringu1 + ); + +CREATE MATERIALIZED VIEW parallel_mat_view AS SELECT + length( + stringu1 + ) +FROM + tenk1 +GROUP BY + length( + stringu1 + ); + +CREATE UNIQUE INDEX ON parallel_mat_view (length); + +REFRESH MATERIALIZED VIEW parallel_mat_view; + +REFRESH MATERIALIZED VIEW CONCURRENTLY parallel_mat_view; + +DROP MATERIALIZED VIEW parallel_mat_view; + +PREPARE prep_stmt AS + SELECT + length( + stringu1 + ) + FROM + tenk1 + GROUP BY + length( + stringu1 + ); + +CREATE TABLE parallel_write AS EXECUTE prep_stmt; + +CREATE TABLE parallel_write AS EXECUTE prep_stmt; + +DROP TABLE parallel_write; + +ROLLBACK; diff --git a/crates/pgt_pretty_print/tests/snapshots/multi/tests__xmlmap_60.snap b/crates/pgt_pretty_print/tests/snapshots/multi/tests__xmlmap_60.snap new file mode 100644 index 000000000..4f5cc7547 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/multi/tests__xmlmap_60.snap @@ -0,0 +1,184 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/multi/xmlmap_60.sql +snapshot_kind: text +--- +CREATE SCHEMA testxmlschema; + +CREATE TABLE testxmlschema.test1 ( + a pg_catalog.int4, + b text +); + +INSERT INTO testxmlschema.test1 VALUES + (1, 'one'), + (2, 'two'), + (-1, NULL); + +CREATE DOMAIN testxmldomain AS pg_catalog.varchar; + +CREATE TABLE testxmlschema.test2 ( + z pg_catalog.int4, + y pg_catalog.varchar(500), + x pg_catalog.bpchar(6), + w pg_catalog.numeric(9, 2), + v pg_catalog.int2, + u pg_catalog.int8, + t pg_catalog.float4, + s pg_catalog.time, + stz timetz, + r pg_catalog.timestamp, + rtz timestamptz, + q date, + p xml, + o testxmldomain, + n bool, + m bytea, + aaa text +); + +ALTER TABLE testxmlschema.test2 DROP COLUMN aaa; + +INSERT INTO testxmlschema.test2 VALUES + ( + 55, + 'abc', + 'def', + 98.6, + 2, + 999, + 0, + '21:07', + '21:11 +05', + '2009-06-08 21:07:30', + '2009-06-08 21:07:30 -07', + '2009-06-08', + NULL, + 'ABC', + TRUE, + 'XYZ' + ); + +SELECT + table_to_xml( + 'testxmlschema.test1', + FALSE, + FALSE, + '' + ); + +SELECT + table_to_xml( + 'testxmlschema.test1', + TRUE, + FALSE, + 'foo' + ); + +SELECT table_to_xml('testxmlschema.test1', FALSE, TRUE, ''); + +SELECT table_to_xml('testxmlschema.test1', TRUE, TRUE, ''); + +SELECT + table_to_xml( + 'testxmlschema.test2', + FALSE, + FALSE, + '' + ); + +SELECT + table_to_xmlschema( + 'testxmlschema.test1', + FALSE, + FALSE, + '' + ); + +SELECT + table_to_xmlschema( + 'testxmlschema.test1', + TRUE, + FALSE, + '' + ); + +SELECT + table_to_xmlschema( + 'testxmlschema.test1', + FALSE, + TRUE, + 'foo' + ); + +SELECT + table_to_xmlschema( + 'testxmlschema.test1', + TRUE, + TRUE, + '' + ); + +SELECT + table_to_xmlschema( + 'testxmlschema.test2', + FALSE, + FALSE, + '' + ); + +SELECT + table_to_xml_and_xmlschema( + 'testxmlschema.test1', + FALSE, + FALSE, + '' + ); + +SELECT + table_to_xml_and_xmlschema( + 'testxmlschema.test1', + TRUE, + FALSE, + '' + ); + +SELECT + table_to_xml_and_xmlschema( + 'testxmlschema.test1', + FALSE, + TRUE, + '' + ); + +SELECT + table_to_xml_and_xmlschema( + 'testxmlschema.test1', + TRUE, + TRUE, + 'foo' + ); + +SELECT + query_to_xml( + 'SELECT * FROM testxmlschema.test1', + FALSE, + FALSE, + '' + ); + +SELECT + query_to_xmlschema( + 'SELECT * FROM testxmlschema.test1', + FALSE, + FALSE, + '' + ); + +SELECT + query_to_xml_and_xmlschema( + 'SELECT * FROM testxmlschema.test1', + TRUE, + TRUE, + '' + ); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__aggref_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__aggref_0_60.snap new file mode 100644 index 000000000..c6bf79fa5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__aggref_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/aggref_0_60.sql +snapshot_kind: text +--- +SELECT count(*) FROM users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__aggref_test_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__aggref_test_0_60.snap new file mode 100644 index 000000000..f04cfbce3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__aggref_test_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/aggref_test_0_60.sql +snapshot_kind: text +--- +SELECT count(*) FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__aindirection_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__aindirection_0_60.snap new file mode 100644 index 000000000..40752c133 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__aindirection_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/aindirection_0_60.sql +snapshot_kind: text +--- +SELECT arr[1], obj.field FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_collation_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_collation_stmt_0_60.snap new file mode 100644 index 000000000..0c752b0d0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_collation_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/single/alter_collation_stmt_0_60.sql +snapshot_kind: text +--- +ALTER COLLATION myschema.mycollation REFRESH VERSION; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_refresh_coll_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_refresh_coll_stmt_0_60.snap new file mode 100644 index 000000000..fdb5eb361 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_refresh_coll_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_database_refresh_coll_stmt_0_60.sql +snapshot_kind: text +--- +ALTER DATABASE mydb REFRESH COLLATION VERSION; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_set_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_set_stmt_0_60.snap new file mode 100644 index 000000000..c7b0a0494 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_set_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_database_set_stmt_0_60.sql +snapshot_kind: text +--- +ALTER DATABASE mydb SET search_path TO 'myschema'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_stmt_0_60.snap new file mode 100644 index 000000000..9fe51b1ca --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_database_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/single/alter_database_stmt_0_60.sql +snapshot_kind: text +--- +ALTER DATABASE mydb CONNECTION_LIMIT = 100; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_default_privileges_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_default_privileges_stmt_0_60.snap new file mode 100644 index 000000000..103c6d304 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_default_privileges_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_default_privileges_stmt_0_60.sql +snapshot_kind: text +--- +ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO reader; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_domain_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_domain_stmt_0_60.snap new file mode 100644 index 000000000..44cd78022 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_domain_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_domain_stmt_0_60.sql +snapshot_kind: text +--- +ALTER DOMAIN myschema.mydomain DROP CONSTRAINT mycheck; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_event_trig_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_event_trig_stmt_0_60.snap new file mode 100644 index 000000000..6809da9b6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_event_trig_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_event_trig_stmt_0_60.sql +snapshot_kind: text +--- +ALTER EVENT TRIGGER my_event_trigger ENABLE; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_extension_contents_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_extension_contents_stmt_0_60.snap new file mode 100644 index 000000000..8ae954a88 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_extension_contents_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_extension_contents_stmt_0_60.sql +snapshot_kind: text +--- +ALTER EXTENSION hstore ADD FUNCTION hstore_in(cstring); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_extension_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_extension_stmt_0_60.snap new file mode 100644 index 000000000..71c791a23 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_extension_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_extension_stmt_0_60.sql +snapshot_kind: text +--- +ALTER EXTENSION hstore UPDATE TO '1.8'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_fdw_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_fdw_stmt_0_60.snap new file mode 100644 index 000000000..12e146fc9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_fdw_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_fdw_stmt_0_60.sql +snapshot_kind: text +--- +ALTER FOREIGN DATA WRAPPER postgres_fdw + OPTIONS (host 'newhost.example.com'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_foreign_server_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_foreign_server_stmt_0_60.snap new file mode 100644 index 000000000..d09842a4a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_foreign_server_stmt_0_60.snap @@ -0,0 +1,8 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_foreign_server_stmt_0_60.sql +snapshot_kind: text +--- +ALTER SERVER myserver + VERSION '1.2' + OPTIONS (host 'new.example.com'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_function_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_function_stmt_0_60.snap new file mode 100644 index 000000000..da13ba18b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_function_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_function_stmt_0_60.sql +snapshot_kind: text +--- +ALTER FUNCTION my_function(pg_catalog.int4) IMMUTABLE; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_object_depends_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_object_depends_stmt_0_60.snap new file mode 100644 index 000000000..e60f26a85 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_object_depends_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_object_depends_stmt_0_60.sql +snapshot_kind: text +--- +ALTER FUNCTION my_func(pg_catalog.int4) + DEPENDS ON EXTENSION btree_gist; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_object_schema_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_object_schema_stmt_0_60.snap new file mode 100644 index 000000000..164008163 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_object_schema_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_object_schema_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TABLE users SET SCHEMA public; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_op_family_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_op_family_stmt_0_60.snap new file mode 100644 index 000000000..aa726e26b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_op_family_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_op_family_stmt_0_60.sql +snapshot_kind: text +--- +ALTER OPERATOR FAMILY myopfamily USING btree + ADD OPERATOR 1 <(int4, int4); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_operator_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_operator_stmt_0_60.snap new file mode 100644 index 000000000..aebef1fc8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_operator_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_operator_stmt_0_60.sql +snapshot_kind: text +--- +ALTER OPERATOR +(int4, int4) OWNER TO postgres; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_owner_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_owner_stmt_0_60.snap new file mode 100644 index 000000000..bc96785f1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_owner_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_owner_stmt_0_60.sql +snapshot_kind: text +--- +ALTER DATABASE mydb OWNER TO postgres; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_policy_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_policy_stmt_0_60.snap new file mode 100644 index 000000000..e5c288388 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_policy_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_policy_stmt_0_60.sql +snapshot_kind: text +--- +ALTER POLICY mypolicy ON mytable TO PUBLIC; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_publication_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_publication_stmt_0_60.snap new file mode 100644 index 000000000..c9ea12847 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_publication_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_publication_stmt_0_60.sql +snapshot_kind: text +--- +ALTER PUBLICATION mypub SET TABLE mytable; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_role_set_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_role_set_stmt_0_60.snap new file mode 100644 index 000000000..35f9e95fa --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_role_set_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_role_set_stmt_0_60.sql +snapshot_kind: text +--- +ALTER ROLE admin SET search_path TO 'myschema', 'public'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_seq_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_seq_stmt_0_60.snap new file mode 100644 index 000000000..27fc6de5b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_seq_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_seq_stmt_0_60.sql +snapshot_kind: text +--- +ALTER SEQUENCE myseq RESTART WITH 100; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_stats_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_stats_stmt_0_60.snap new file mode 100644 index 000000000..22e3b8b90 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_stats_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_stats_stmt_0_60.sql +snapshot_kind: text +--- +ALTER STATISTICS myschema.mystat SET STATISTICS 100; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_subscription_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_subscription_stmt_0_60.snap new file mode 100644 index 000000000..fa47a0045 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_subscription_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_subscription_stmt_0_60.sql +snapshot_kind: text +--- +ALTER SUBSCRIPTION mysub SET PUBLICATION mypub; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_system_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_system_stmt_0_60.snap new file mode 100644 index 000000000..d9142d721 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_system_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_system_stmt_0_60.sql +snapshot_kind: text +--- +ALTER SYSTEM SET max_connections TO 200; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_move_all_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_move_all_stmt_0_60.snap new file mode 100644 index 000000000..08db2fce9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_move_all_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_table_move_all_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TABLE ALL IN TABLESPACE myspace + SET TABLESPACE newspace; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_owner_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_owner_0_60.snap new file mode 100644 index 000000000..9d2f4ccfc --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_owner_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_table_owner_0_60.sql +snapshot_kind: text +--- +ALTER TABLE users OWNER TO postgres; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_stmt_0_60.snap new file mode 100644 index 000000000..746dab7f7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_table_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TABLE users ADD COLUMN email text; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_stmt_simple.snap new file mode 100644 index 000000000..545e285aa --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_table_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_table_stmt_simple.sql +snapshot_kind: text +--- +ALTER TABLE users ADD COLUMN email text; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tablespace_options_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tablespace_options_stmt_0_60.snap new file mode 100644 index 000000000..691488edd --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tablespace_options_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_tablespace_options_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TABLESPACE myspace SET (seq_page_cost = 1.5); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tsconfiguration_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tsconfiguration_stmt_0_60.snap new file mode 100644 index 000000000..1393aa40c --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tsconfiguration_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_tsconfiguration_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TEXT SEARCH CONFIGURATION myconfig + ADD MAPPING FOR word WITH simple; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tsdictionary_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tsdictionary_stmt_0_60.snap new file mode 100644 index 000000000..45c40b95a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_tsdictionary_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_tsdictionary_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TEXT SEARCH DICTIONARY my_dict + (stopwords = 'russian', language = 'russian'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_type_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_type_stmt_0_60.snap new file mode 100644 index 000000000..4e9292c7a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_type_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_type_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TYPE mytype ADD VALUE 'newvalue'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_user_mapping_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_user_mapping_stmt_0_60.snap new file mode 100644 index 000000000..abf1a9c6b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__alter_user_mapping_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/alter_user_mapping_stmt_0_60.sql +snapshot_kind: text +--- +ALTER USER MAPPING FOR myuser SERVER myserver + OPTIONS (ADD user 'newuser'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__array_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__array_expr_0_60.snap new file mode 100644 index 000000000..1aea7f68d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__array_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/array_expr_0_60.sql +snapshot_kind: text +--- +SELECT ARRAY[1, 2, 3]; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__bit_string_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__bit_string_0_60.snap new file mode 100644 index 000000000..acacd8565 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__bit_string_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/bit_string_0_60.sql +snapshot_kind: text +--- +SELECT B'10101'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__bool_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__bool_expr_0_60.snap new file mode 100644 index 000000000..9ba5514e8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__bool_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/bool_expr_0_60.sql +snapshot_kind: text +--- +SELECT * FROM users WHERE active = TRUE AND age >= 18; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__boolean_test_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__boolean_test_0_60.snap new file mode 100644 index 000000000..91555ad2b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__boolean_test_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/boolean_test_0_60.sql +snapshot_kind: text +--- +SELECT * FROM users WHERE active IS TRUE; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__break_parent_test_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__break_parent_test_80.snap new file mode 100644 index 000000000..2c2bece0d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__break_parent_test_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/break_parent_test_80.sql +snapshot_kind: text +--- +SELECT very_long_function_name(short_arg, other_arg) FROM test_table; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__call_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__call_stmt_0_60.snap new file mode 100644 index 000000000..efc280589 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__call_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/call_stmt_0_60.sql +snapshot_kind: text +--- +CALL my_procedure('test', 123); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__case_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__case_expr_0_60.snap new file mode 100644 index 000000000..c0a749983 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__case_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/case_expr_0_60.sql +snapshot_kind: text +--- +SELECT CASE WHEN x = 1 THEN 'one' ELSE 'other' END; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__checkpoint_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__checkpoint_stmt_0_60.snap new file mode 100644 index 000000000..266f96885 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__checkpoint_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/checkpoint_stmt_0_60.sql +snapshot_kind: text +--- +CHECKPOINT; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__close_portal_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__close_portal_stmt_0_60.snap new file mode 100644 index 000000000..49305a380 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__close_portal_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/close_portal_stmt_0_60.sql +snapshot_kind: text +--- +CLOSE mycursor; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__cluster_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__cluster_stmt_0_60.snap new file mode 100644 index 000000000..966b2453d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__cluster_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/cluster_stmt_0_60.sql +snapshot_kind: text +--- +CLUSTER users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__coalesce_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__coalesce_expr_0_60.snap new file mode 100644 index 000000000..711cb2493 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__coalesce_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/coalesce_expr_0_60.sql +snapshot_kind: text +--- +SELECT COALESCE(name, 'Anonymous'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__coerce_via_io_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__coerce_via_io_0_60.snap new file mode 100644 index 000000000..a4f692e58 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__coerce_via_io_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +assertion_line: 59 +input_file: crates/pgt_pretty_print/tests/data/coerce_via_io_0_60.sql +--- +SELECT '123'::pg_catalog.int4; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__collate_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__collate_expr_0_60.snap new file mode 100644 index 000000000..ad66b6bc9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__collate_expr_0_60.snap @@ -0,0 +1,5 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +expression: formatted_sql +--- +SELECT name COLLATE "en_US" FROM users; \ No newline at end of file diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__comment_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__comment_stmt_0_60.snap new file mode 100644 index 000000000..5a8eb33a9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__comment_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/comment_stmt_0_60.sql +snapshot_kind: text +--- +COMMENT ON TABLE customers IS 'Customer information'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_0_60.snap new file mode 100644 index 000000000..421685a1a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_0_60.snap @@ -0,0 +1,234 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_0_60.sql +snapshot_kind: text +--- +WITH RECURSIVE pks_fks AS (SELECT + contype::text AS contype, + conname, + array_length( + conkey, + 1 + ) AS ncol, + conrelid AS resorigtbl, + col AS resorigcol, + ord +FROM + pg_constraint + LEFT JOIN + LATERAL unnest( + conkey + ) WITH ORDINALITY AS _(col, ord) ON TRUE +WHERE contype IN ('p', 'f') +UNION +SELECT + concat( + contype, + '_ref' + ) AS contype, + conname, + array_length( + confkey, + 1 + ) AS ncol, + confrelid, + col, + ord +FROM + pg_constraint + LEFT JOIN + LATERAL unnest( + confkey + ) WITH ORDINALITY AS _(col, ord) ON TRUE +WHERE contype = 'f'), views AS (SELECT + c.oid AS view_id, + n.nspname AS view_schema, + c.relname AS view_name, + r.ev_action AS view_definition +FROM + pg_class c + INNER JOIN + pg_namespace n ON n.oid = c.relnamespace + INNER JOIN + pg_rewrite r ON r.ev_class = c.oid +WHERE c.relkind IN ('v', 'm')), transform_json AS (SELECT + view_id, + view_schema, + view_name, + replace( + replace( + replace( + replace( + replace( + replace( + replace( + regexp_replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + view_definition::text, + '<>', + '()' + ), + ',', + '' + ), + '\\{', + '' + ), + '\\}', + '' + ), + ' :targetList ', + ',"targetList":' + ), + ' :resno ', + ',"resno":' + ), + ' :resorigtbl ', + ',"resorigtbl":' + ), + ' :resorigcol ', + ',"resorigcol":' + ), + '{', + '{ :' + ), + '((', + '{((' + ), + '({', + '{({' + ), + ' :[^}{,]+', + ',"":', + 'g' + ), + ',"":}', + '}' + ), + ',"":,', + ',' + ), + '{(', + '(' + ), + '{,', + '{' + ), + '(', + '[' + ), + ')', + ']' + ), + ' ', + ',' + )::pg_catalog.json AS view_definition +FROM + views), target_entries AS (SELECT + view_id, + view_schema, + view_name, + json_array_elements( + view_definition -> 0 -> 'targetList' + ) AS entry +FROM + transform_json), results AS (SELECT + view_id, + view_schema, + view_name, + (entry ->> 'resno')::pg_catalog.int4 AS view_column, + (entry ->> 'resorigtbl')::oid AS resorigtbl, + (entry ->> 'resorigcol')::pg_catalog.int4 AS resorigcol +FROM + target_entries), recursion(view_id, view_schema, view_name, view_column, resorigtbl, resorigcol, is_cycle, path) AS (SELECT + r.*, + FALSE, + ARRAY[resorigtbl] +FROM + results r +WHERE TRUE +UNION ALL +SELECT + view.view_id, + view.view_schema, + view.view_name, + view.view_column, + tab.resorigtbl, + tab.resorigcol, + tab.resorigtbl = ANY(path), + path || tab.resorigtbl +FROM + recursion view + INNER JOIN + results tab ON view.resorigtbl = tab.view_id + AND view.resorigcol = tab.view_column +WHERE NOT is_cycle), repeated_references AS (SELECT + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol, + array_agg( + attname + ) AS view_columns +FROM + recursion + INNER JOIN + pg_attribute vcol ON vcol.attrelid = view_id + AND vcol.attnum = view_column +GROUP BY + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol) +SELECT + sch.nspname AS table_schema, + tbl.relname AS table_name, + rep.view_schema, + rep.view_name, + pks_fks.conname AS constraint_name, + pks_fks.contype AS constraint_type, + jsonb_agg( + jsonb_build_object( + 'table_column', + col.attname, + 'view_columns', + view_columns + ) ORDER BY pks_fks.ord + ) AS column_dependencies +FROM + repeated_references rep + INNER JOIN + pks_fks USING (resorigtbl, resorigcol) + INNER JOIN + pg_class tbl ON tbl.oid = rep.resorigtbl + INNER JOIN + pg_attribute col ON col.attrelid = tbl.oid + AND col.attnum = rep.resorigcol + INNER JOIN + pg_namespace sch ON sch.oid = tbl.relnamespace +GROUP BY + sch.nspname, + tbl.relname, + rep.view_schema, + rep.view_name, + pks_fks.conname, + pks_fks.contype, + pks_fks.ncol +HAVING ncol = array_length( + array_agg( + ROW(col.attname, view_columns) ORDER BY pks_fks.ord + ), + 1 +); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_0_60.snap new file mode 100644 index 000000000..46771c19c --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_0_60.snap @@ -0,0 +1,43 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_0_60.sql +snapshot_kind: text +--- +SELECT + contype::text AS contype, + conname, + array_length( + conkey, + 1 + ) AS ncol, + conrelid AS resorigtbl, + col AS resorigcol, + ord +FROM + pg_constraint + LEFT JOIN + LATERAL unnest( + conkey + ) WITH ORDINALITY AS _(col, ord) ON TRUE +WHERE contype IN ('p', 'f') +UNION +SELECT + concat( + contype, + '_ref' + ) AS contype, + conname, + array_length( + confkey, + 1 + ) AS ncol, + confrelid, + col, + ord +FROM + pg_constraint + LEFT JOIN + LATERAL unnest( + confkey + ) WITH ORDINALITY AS _(col, ord) ON TRUE +WHERE contype = 'f'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_1_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_1_60.snap new file mode 100644 index 000000000..6a51eb7dd --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_1_60.snap @@ -0,0 +1,17 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_1_60.sql +snapshot_kind: text +--- +SELECT + c.oid AS view_id, + n.nspname AS view_schema, + c.relname AS view_name, + r.ev_action AS view_definition +FROM + pg_class c + INNER JOIN + pg_namespace n ON n.oid = c.relnamespace + INNER JOIN + pg_rewrite r ON r.ev_class = c.oid +WHERE c.relkind IN ('v', 'm'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_2_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_2_60.snap new file mode 100644 index 000000000..2edc9306f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_2_60.snap @@ -0,0 +1,89 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_2_60.sql +snapshot_kind: text +--- +SELECT + view_id, + view_schema, + view_name, + replace( + replace( + replace( + replace( + replace( + replace( + replace( + regexp_replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + replace( + view_definition::text, + '<>', + '()' + ), + ',', + '' + ), + '\\{', + '' + ), + '\\}', + '' + ), + ' :targetList ', + ',"targetList":' + ), + ' :resno ', + ',"resno":' + ), + ' :resorigtbl ', + ',"resorigtbl":' + ), + ' :resorigcol ', + ',"resorigcol":' + ), + '{', + '{ :' + ), + '((', + '{((' + ), + '({', + '{({' + ), + ' :[^}{,]+', + ',"":', + 'g' + ), + ',"":}', + '}' + ), + ',"":,', + ',' + ), + '{(', + '(' + ), + '{,', + '{' + ), + '(', + '[' + ), + ')', + ']' + ), + ' ', + ',' + )::pg_catalog.json AS view_definition +FROM + views; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_3_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_3_60.snap new file mode 100644 index 000000000..b1f375fed --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_3_60.snap @@ -0,0 +1,14 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_3_60.sql +snapshot_kind: text +--- +SELECT + view_id, + view_schema, + view_name, + json_array_elements( + view_definition -> 0 -> 'targetList' + ) AS entry +FROM + transform_json; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_4_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_4_60.snap new file mode 100644 index 000000000..b1f3b7dbf --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_4_60.snap @@ -0,0 +1,14 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_4_60.sql +snapshot_kind: text +--- +SELECT + view_id, + view_schema, + view_name, + (entry ->> 'resno')::pg_catalog.int4 AS view_column, + (entry ->> 'resorigtbl')::oid AS resorigtbl, + (entry ->> 'resorigcol')::pg_catalog.int4 AS resorigcol +FROM + target_entries; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_5_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_5_60.snap new file mode 100644 index 000000000..20d375206 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_5_60.snap @@ -0,0 +1,28 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_5_60.sql +snapshot_kind: text +--- +SELECT + r.*, + FALSE, + ARRAY[resorigtbl] +FROM + results r +WHERE TRUE +UNION ALL +SELECT + view.view_id, + view.view_schema, + view.view_name, + view.view_column, + tab.resorigtbl, + tab.resorigcol, + tab.resorigtbl = ANY(path), + path || tab.resorigtbl +FROM + recursion view + INNER JOIN + results tab ON view.resorigtbl = tab.view_id + AND view.resorigcol = tab.view_column +WHERE NOT is_cycle; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_6_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_6_60.snap new file mode 100644 index 000000000..baa7e412f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_6_60.snap @@ -0,0 +1,25 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_6_60.sql +snapshot_kind: text +--- +SELECT + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol, + array_agg( + attname + ) AS view_columns +FROM + recursion + INNER JOIN + pg_attribute vcol ON vcol.attrelid = view_id + AND vcol.attnum = view_column +GROUP BY + view_id, + view_schema, + view_name, + resorigtbl, + resorigcol; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_7_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_7_60.snap new file mode 100644 index 000000000..47d633b1d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__complex_select_part_7_60.snap @@ -0,0 +1,45 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/complex_select_part_7_60.sql +snapshot_kind: text +--- +SELECT + sch.nspname AS table_schema, + tbl.relname AS table_name, + rep.view_schema, + rep.view_name, + pks_fks.conname AS constraint_name, + pks_fks.contype AS constraint_type, + jsonb_agg( + jsonb_build_object( + 'table_column', + col.attname, + 'view_columns', + view_columns + ) ORDER BY pks_fks.ord + ) AS column_dependencies +FROM + repeated_references rep + INNER JOIN + pks_fks USING (resorigtbl, resorigcol) + INNER JOIN + pg_class tbl ON tbl.oid = rep.resorigtbl + INNER JOIN + pg_attribute col ON col.attrelid = tbl.oid + AND col.attnum = rep.resorigcol + INNER JOIN + pg_namespace sch ON sch.oid = tbl.relnamespace +GROUP BY + sch.nspname, + tbl.relname, + rep.view_schema, + rep.view_name, + pks_fks.conname, + pks_fks.contype, + pks_fks.ncol +HAVING ncol = array_length( + array_agg( + ROW(col.attname, view_columns) ORDER BY pks_fks.ord + ), + 1 +); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__composite_type_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__composite_type_stmt_0_60.snap new file mode 100644 index 000000000..3aa164ef8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__composite_type_stmt_0_60.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/composite_type_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TYPE complex +AS ( + r pg_catalog.float8, + i pg_catalog.float8 +); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__constraints_set_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__constraints_set_stmt_0_60.snap new file mode 100644 index 000000000..f82830e94 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__constraints_set_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/constraints_set_stmt_0_60.sql +snapshot_kind: text +--- +SET CONSTRAINTS ALL DEFERRED; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__copy_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__copy_stmt_0_60.snap new file mode 100644 index 000000000..e44bd2302 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__copy_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/copy_stmt_0_60.sql +snapshot_kind: text +--- +COPY users TO '/tmp/users.csv' WITH CSV HEADER; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_am_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_am_stmt_0_60.snap new file mode 100644 index 000000000..57a1d1903 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_am_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_am_stmt_0_60.sql +snapshot_kind: text +--- +CREATE ACCESS METHOD myam TYPE TABLE HANDLER amhandler; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_cast_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_cast_stmt_0_60.snap new file mode 100644 index 000000000..5c51b5efb --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_cast_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_cast_stmt_0_60.sql +snapshot_kind: text +--- +CREATE CAST (text AS pg_catalog.int4) +WITH FUNCTION int4(text); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_conversion_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_conversion_stmt_0_60.snap new file mode 100644 index 000000000..4c0786f93 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_conversion_stmt_0_60.snap @@ -0,0 +1,8 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_conversion_stmt_0_60.sql +snapshot_kind: text +--- +CREATE CONVERSION myconv +FOR 'UTF8' TO 'LATIN1' +FROM utf8_to_latin1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_domain_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_domain_stmt_0_60.snap new file mode 100644 index 000000000..1fbc1bcc7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_domain_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_domain_stmt_0_60.sql +snapshot_kind: text +--- +CREATE DOMAIN myint AS pg_catalog.int4; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_enum_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_enum_stmt_0_60.snap new file mode 100644 index 000000000..5a371eff1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_enum_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_enum_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_event_trig_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_event_trig_stmt_0_60.snap new file mode 100644 index 000000000..d053116bd --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_event_trig_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_event_trig_stmt_0_60.sql +snapshot_kind: text +--- +CREATE EVENT TRIGGER my_event_trigger ON ddl_command_start +EXECUTE FUNCTION my_event_function(); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_extension_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_extension_stmt_0_60.snap new file mode 100644 index 000000000..52db413e2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_extension_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_extension_stmt_0_60.sql +snapshot_kind: text +--- +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_fdw_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_fdw_stmt_0_60.snap new file mode 100644 index 000000000..afed06cc3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_fdw_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_fdw_stmt_0_60.sql +snapshot_kind: text +--- +CREATE FOREIGN DATA WRAPPER postgres_fdw; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_foreign_table_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_foreign_table_stmt_0_60.snap new file mode 100644 index 000000000..a34a23cd3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_foreign_table_stmt_0_60.snap @@ -0,0 +1,9 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_foreign_table_stmt_0_60.sql +snapshot_kind: text +--- +CREATE FOREIGN TABLE foreign_users ( + id pg_catalog.int4 +) +SERVER myserver; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_function_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_function_stmt_0_60.snap new file mode 100644 index 000000000..f0707f8e8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_function_stmt_0_60.snap @@ -0,0 +1,12 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_function_stmt_0_60.sql +snapshot_kind: text +--- +CREATE FUNCTION add ( + a pg_catalog.int4, + b pg_catalog.int4 +) +RETURNS pg_catalog.int4 +AS 'SELECT $1 + $2' +LANGUAGE sql; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_op_class_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_op_class_stmt_0_60.snap new file mode 100644 index 000000000..79eaaa208 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_op_class_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_op_class_stmt_0_60.sql +snapshot_kind: text +--- +CREATE OPERATOR CLASS myopclass FOR TYPE int4 USING btree + AS OPERATOR 1 <; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_op_family_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_op_family_stmt_0_60.snap new file mode 100644 index 000000000..ed7589b60 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_op_family_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_op_family_stmt_0_60.sql +snapshot_kind: text +--- +CREATE OPERATOR FAMILY myopfamily USING btree; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_plang_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_plang_stmt_0_60.snap new file mode 100644 index 000000000..e932ef419 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_plang_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_plang_stmt_0_60.sql +snapshot_kind: text +--- +CREATE LANGUAGE plpython3u HANDLER plpython3_handler; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_policy_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_policy_stmt_0_60.snap new file mode 100644 index 000000000..41f4517c8 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_policy_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_policy_stmt_0_60.sql +snapshot_kind: text +--- +CREATE POLICY mypolicy ON mytable FOR ALL TO PUBLIC; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_publication_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_publication_stmt_0_60.snap new file mode 100644 index 000000000..579e2b304 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_publication_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_publication_stmt_0_60.sql +snapshot_kind: text +--- +CREATE PUBLICATION mypub FOR ALL TABLES; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_range_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_range_stmt_0_60.snap new file mode 100644 index 000000000..2ad9f1127 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_range_stmt_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_range_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TYPE float8_range AS RANGE + (subtype = float8, subtype_diff = float8mi); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_role_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_role_stmt_0_60.snap new file mode 100644 index 000000000..e1eeb7d99 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_role_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_role_stmt_0_60.sql +snapshot_kind: text +--- +CREATE ROLE admin WITH LOGIN PASSWORD 'secret'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_schema_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_schema_stmt_0_60.snap new file mode 100644 index 000000000..8a1a7d03a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_schema_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_schema_stmt_0_60.sql +snapshot_kind: text +--- +CREATE SCHEMA myschema; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_seq_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_seq_stmt_0_60.snap new file mode 100644 index 000000000..5d7b9a1c7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_seq_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_seq_stmt_0_60.sql +snapshot_kind: text +--- +CREATE SEQUENCE myschema.myseq; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stats_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stats_stmt_0_60.snap new file mode 100644 index 000000000..17d6c497e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stats_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_stats_stmt_0_60.sql +snapshot_kind: text +--- +CREATE STATISTICS s1 ON a, b FROM t1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stmt_0_60.snap new file mode 100644 index 000000000..d8310e4fd --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TABLE users (id text, name text); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stmt_simple.snap new file mode 100644 index 000000000..c23453000 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_stmt_simple.sql +snapshot_kind: text +--- +CREATE TABLE users (id text, name text); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_subscription_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_subscription_stmt_0_60.snap new file mode 100644 index 000000000..e22170b6b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_subscription_stmt_0_60.snap @@ -0,0 +1,8 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_subscription_stmt_0_60.sql +snapshot_kind: text +--- +CREATE SUBSCRIPTION mysub +CONNECTION 'host=localhost dbname=postgres' +PUBLICATION mypub; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_table_as_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_table_as_stmt_0_60.snap new file mode 100644 index 000000000..80321fa2b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_table_as_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_table_as_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TABLE foo AS SELECT 1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_tablespace_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_tablespace_stmt_0_60.snap new file mode 100644 index 000000000..1d7a87b36 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_tablespace_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_tablespace_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TABLESPACE myspace LOCATION '/data/postgres'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_transform_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_transform_stmt_0_60.snap new file mode 100644 index 000000000..3cfd99ed3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_transform_stmt_0_60.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_transform_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TRANSFORM FOR hstore LANGUAGE sql + ( + FROM SQL WITH FUNCTION hstore_to_sql(internal), + TO SQL WITH FUNCTION sql_to_hstore(internal) + ); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_trig_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_trig_stmt_0_60.snap new file mode 100644 index 000000000..0c2ffd256 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_trig_stmt_0_60.snap @@ -0,0 +1,9 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_trig_stmt_0_60.sql +snapshot_kind: text +--- +CREATE TRIGGER my_trigger +AFTER INSERT ON my_table +FOR EACH ROW +EXECUTE FUNCTION my_function(); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__create_user_mapping_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_user_mapping_stmt_0_60.snap new file mode 100644 index 000000000..647a6d660 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__create_user_mapping_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/create_user_mapping_stmt_0_60.sql +snapshot_kind: text +--- +CREATE USER MAPPING FOR myuser SERVER myserver; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__createdb_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__createdb_stmt_0_60.snap new file mode 100644 index 000000000..6ea2cbdff --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__createdb_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/createdb_stmt_0_60.sql +snapshot_kind: text +--- +CREATE DATABASE mydb; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__current_of_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__current_of_expr_0_60.snap new file mode 100644 index 000000000..8fa56469e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__current_of_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/current_of_expr_0_60.sql +snapshot_kind: text +--- +DELETE FROM table_name WHERE CURRENT OF cursor_name; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__deallocate_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__deallocate_stmt_0_60.snap new file mode 100644 index 000000000..a9a973384 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__deallocate_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/deallocate_stmt_0_60.sql +snapshot_kind: text +--- +DEALLOCATE my_insert; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__declare_cursor_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__declare_cursor_stmt_0_60.snap new file mode 100644 index 000000000..e5ac2820d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__declare_cursor_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/declare_cursor_stmt_0_60.sql +snapshot_kind: text +--- +DECLARE mycursor CURSOR FOR SELECT * FROM mytable; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__define_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__define_stmt_0_60.snap new file mode 100644 index 000000000..7671b78cc --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__define_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/define_stmt_0_60.sql +snapshot_kind: text +--- +CREATE COLLATION mycoll FROM "C"; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__delete_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__delete_stmt_0_60.snap new file mode 100644 index 000000000..f5fa1d961 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__delete_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/delete_stmt_0_60.sql +snapshot_kind: text +--- +DELETE FROM users WHERE id = 1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__delete_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__delete_stmt_simple.snap new file mode 100644 index 000000000..42dedca2e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__delete_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/delete_stmt_simple.sql +snapshot_kind: text +--- +DELETE FROM users WHERE id = 1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__discard_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__discard_stmt_0_60.snap new file mode 100644 index 000000000..b8db1b76f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__discard_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/discard_stmt_0_60.sql +snapshot_kind: text +--- +DISCARD ALL; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__distinct_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__distinct_expr_0_60.snap new file mode 100644 index 000000000..03342c7cb --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__distinct_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/distinct_expr_0_60.sql +snapshot_kind: text +--- +SELECT * FROM t WHERE a IS DISTINCT FROM b; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__distinctexpr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__distinctexpr_0_60.snap new file mode 100644 index 000000000..e20bf3424 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__distinctexpr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/distinctexpr_0_60.sql +snapshot_kind: text +--- +SELECT a IS DISTINCT FROM b; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__do_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__do_stmt_0_60.snap new file mode 100644 index 000000000..42da9797c --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__do_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/do_stmt_0_60.sql +snapshot_kind: text +--- +DO LANGUAGE plpgsql 'BEGIN NULL; END'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_owned_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_owned_stmt_0_60.snap new file mode 100644 index 000000000..5adaffb04 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_owned_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/drop_owned_stmt_0_60.sql +snapshot_kind: text +--- +DROP OWNED BY myuser RESTRICT; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_role_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_role_stmt_0_60.snap new file mode 100644 index 000000000..4b853ff69 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_role_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/drop_role_stmt_0_60.sql +snapshot_kind: text +--- +DROP ROLE test_user; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_stmt_0_60.snap new file mode 100644 index 000000000..e5ecf28b5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/drop_stmt_0_60.sql +snapshot_kind: text +--- +DROP TABLE users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_stmt_simple.snap new file mode 100644 index 000000000..c9fdfd85d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/drop_stmt_simple.sql +snapshot_kind: text +--- +DROP TABLE users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_subscription_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_subscription_stmt_0_60.snap new file mode 100644 index 000000000..6ee4a17ce --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_subscription_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/drop_subscription_stmt_0_60.sql +snapshot_kind: text +--- +DROP SUBSCRIPTION mysub; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_tablespace_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_tablespace_stmt_0_60.snap new file mode 100644 index 000000000..89e16eb01 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_tablespace_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/drop_tablespace_stmt_0_60.sql +snapshot_kind: text +--- +DROP TABLESPACE myspace; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_user_mapping_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_user_mapping_stmt_0_60.snap new file mode 100644 index 000000000..04d07fdce --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__drop_user_mapping_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/drop_user_mapping_stmt_0_60.sql +snapshot_kind: text +--- +DROP USER MAPPING FOR myuser SERVER myserver; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__dropdb_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__dropdb_stmt_0_60.snap new file mode 100644 index 000000000..227ab2386 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__dropdb_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/dropdb_stmt_0_60.sql +snapshot_kind: text +--- +DROP DATABASE mydb; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__execute_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__execute_stmt_0_60.snap new file mode 100644 index 000000000..e3f1c9f3b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__execute_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/execute_stmt_0_60.sql +snapshot_kind: text +--- +EXECUTE prepared_statement_name ('param1', 'param2'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__explain_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__explain_stmt_0_60.snap new file mode 100644 index 000000000..4f8613ffa --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__explain_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/explain_stmt_0_60.sql +snapshot_kind: text +--- +EXPLAIN SELECT * FROM users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__fetch_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__fetch_stmt_0_60.snap new file mode 100644 index 000000000..afe2f8172 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__fetch_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/fetch_stmt_0_60.sql +snapshot_kind: text +--- +FETCH NEXT FROM mycursor; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__field_select_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__field_select_0_60.snap new file mode 100644 index 000000000..91e885a4b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__field_select_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/field_select_0_60.sql +snapshot_kind: text +--- +SELECT (ROW(1, 2, 3)).f1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__field_store_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__field_store_0_60.snap new file mode 100644 index 000000000..5b766b359 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__field_store_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/field_store_0_60.sql +snapshot_kind: text +--- +UPDATE my_table SET composite_col.field1 = 'new_value'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__from_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__from_expr_0_60.snap new file mode 100644 index 000000000..0cdcc566c --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__from_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/from_expr_0_60.sql +snapshot_kind: text +--- +SELECT * FROM t1, t2 WHERE t1.id = t2.id; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__func_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__func_expr_0_60.snap new file mode 100644 index 000000000..19d30aada --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__func_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/func_expr_0_60.sql +snapshot_kind: text +--- +SELECT lower('HELLO'), upper('world'), length('test'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__grant_role_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__grant_role_stmt_0_60.snap new file mode 100644 index 000000000..e111994e9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__grant_role_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/grant_role_stmt_0_60.sql +snapshot_kind: text +--- +GRANT ADMIN TO user1, user2; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__grant_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__grant_stmt_0_60.snap new file mode 100644 index 000000000..32c19a9a6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__grant_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/grant_stmt_0_60.sql +snapshot_kind: text +--- +GRANT SELECT ON TABLE users TO john; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__grouping_func_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__grouping_func_0_60.snap new file mode 100644 index 000000000..64141aea2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__grouping_func_0_60.snap @@ -0,0 +1,12 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/grouping_func_0_60.sql +snapshot_kind: text +--- +SELECT + category, + grouping(category) +FROM + products +GROUP BY + ROLLUP(category); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__import_foreign_schema_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__import_foreign_schema_stmt_0_60.snap new file mode 100644 index 000000000..44359f542 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__import_foreign_schema_stmt_0_60.snap @@ -0,0 +1,8 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/import_foreign_schema_stmt_0_60.sql +snapshot_kind: text +--- +IMPORT FOREIGN SCHEMA remote_schema +FROM SERVER myserver +INTO local_schema; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__index_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__index_stmt_0_60.snap new file mode 100644 index 000000000..181fe7548 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__index_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/index_stmt_0_60.sql +snapshot_kind: text +--- +CREATE INDEX idx_users_email ON users (email); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_0_60.snap new file mode 100644 index 000000000..300f347f4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/insert_stmt_0_60.sql +snapshot_kind: text +--- +INSERT INTO users VALUES (1, 'John'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_0_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_0_80.snap new file mode 100644 index 000000000..f11069dcc --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_0_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/insert_stmt_0_80.sql +snapshot_kind: text +--- +INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_simple.snap new file mode 100644 index 000000000..50336e54e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__insert_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/insert_stmt_simple.sql +snapshot_kind: text +--- +INSERT INTO users VALUES (1, 'John'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__into_clause_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__into_clause_0_60.snap new file mode 100644 index 000000000..896aa858d --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__into_clause_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/into_clause_0_60.sql +snapshot_kind: text +--- +SELECT * INTO new_table FROM old_table; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__join_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__join_expr_0_60.snap new file mode 100644 index 000000000..ca178b85f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__join_expr_0_60.snap @@ -0,0 +1,11 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/join_expr_0_60.sql +snapshot_kind: text +--- +SELECT + * +FROM + users u + INNER JOIN + orders o ON u.id = o.user_id; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__json_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__json_expr_0_60.snap new file mode 100644 index 000000000..624ddf3c0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__json_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/json_expr_0_60.sql +snapshot_kind: text +--- +SELECT JSON_EXISTS(data, '$.name'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__json_is_predicate_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__json_is_predicate_0_60.snap new file mode 100644 index 000000000..21166bd28 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__json_is_predicate_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/json_is_predicate_0_60.sql +snapshot_kind: text +--- +SELECT * WHERE data IS JSON; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__json_scalar_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__json_scalar_expr_0_60.snap new file mode 100644 index 000000000..7de65f609 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__json_scalar_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/json_scalar_expr_0_60.sql +snapshot_kind: text +--- +SELECT JSON_SCALAR(123); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__listen_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__listen_stmt_0_60.snap new file mode 100644 index 000000000..9268f3706 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__listen_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/listen_stmt_0_60.sql +snapshot_kind: text +--- +LISTEN mytable_updated; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__load_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__load_stmt_0_60.snap new file mode 100644 index 000000000..cd3a9ebdb --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__load_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/load_stmt_0_60.sql +snapshot_kind: text +--- +LOAD 'plpgsql'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__lock_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__lock_stmt_0_60.snap new file mode 100644 index 000000000..b820f217a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__lock_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/lock_stmt_0_60.sql +snapshot_kind: text +--- +LOCK TABLE users IN ACCESS EXCLUSIVE MODE; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__locking_clause_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__locking_clause_0_60.snap new file mode 100644 index 000000000..e4caf8589 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__locking_clause_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/locking_clause_0_60.sql +snapshot_kind: text +--- +SELECT * FROM t FOR UPDATE; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__long_columns_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_columns_0_60.snap new file mode 100644 index 000000000..01bb1a7fa --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_columns_0_60.snap @@ -0,0 +1,12 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/long_columns_0_60.sql +snapshot_kind: text +--- +SELECT + customer_id, + customer_name, + customer_email, + customer_phone +FROM + customer_table; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_0_60.snap new file mode 100644 index 000000000..0c930bd49 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_0_60.snap @@ -0,0 +1,14 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/long_select_0_60.sql +snapshot_kind: text +--- +SELECT + first_name, + last_name, + email, + phone_number, + address +FROM + customers +WHERE city = 'New York'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_should_break_40.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_should_break_40.snap new file mode 100644 index 000000000..0178e1ca3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_should_break_40.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/long_select_should_break_40.sql +snapshot_kind: text +--- +SELECT + very_long_column_name_one, + very_long_column_name_two +FROM + long_table_name; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_should_break_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_should_break_80.snap new file mode 100644 index 000000000..0f51564e1 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__long_select_should_break_80.snap @@ -0,0 +1,11 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/long_select_should_break_80.sql +snapshot_kind: text +--- +SELECT + very_long_column_name_one, + very_long_column_name_two, + very_long_column_name_three +FROM + long_table_name; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_action_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_action_0_60.snap new file mode 100644 index 000000000..3dee1f6cc --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_action_0_60.snap @@ -0,0 +1,13 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/merge_action_0_60.sql +snapshot_kind: text +--- +MERGE INTO products p +USING new_products np ON p.product_id = np.product_id +WHEN MATCHED THEN + UPDATE SET + price = np.price +WHEN NOT MATCHED THEN + INSERT (product_id, price) + VALUES (np.product_id, np.price); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_stmt_0_60.snap new file mode 100644 index 000000000..d28e6af7b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_stmt_0_60.snap @@ -0,0 +1,13 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/merge_stmt_0_60.sql +snapshot_kind: text +--- +MERGE INTO target_table t +USING source_table s ON t.id = s.id +WHEN MATCHED THEN + UPDATE SET + value = s.value +WHEN NOT MATCHED THEN + INSERT (id, value) + VALUES (s.id, s.value); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_support_func_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_support_func_0_60.snap new file mode 100644 index 000000000..43550c1f0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__merge_support_func_0_60.snap @@ -0,0 +1,13 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/merge_support_func_0_60.sql +snapshot_kind: text +--- +MERGE INTO products p +USING new_products np ON p.product_id = np.product_id +WHEN MATCHED THEN + UPDATE SET + price = np.price +WHEN NOT MATCHED THEN + INSERT + VALUES (np.product_id, np.price); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__min_max_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__min_max_expr_0_60.snap new file mode 100644 index 000000000..333828574 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__min_max_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/min_max_expr_0_60.sql +snapshot_kind: text +--- +SELECT GREATEST(1, 2, 3), LEAST(10, 20, 5); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__minimal_120.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__minimal_120.snap new file mode 100644 index 000000000..9e1b86dd7 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__minimal_120.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/minimal_120.sql +snapshot_kind: text +--- +SELECT a FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__minimal_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__minimal_80.snap new file mode 100644 index 000000000..b14b3f0ad --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__minimal_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/minimal_80.sql +snapshot_kind: text +--- +SELECT a FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__nested_column_refs_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__nested_column_refs_80.snap new file mode 100644 index 000000000..f631f99fd --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__nested_column_refs_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/nested_column_refs_80.sql +snapshot_kind: text +--- +SELECT schema.table.column FROM schema.table; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__next_value_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__next_value_expr_0_60.snap new file mode 100644 index 000000000..b4f14fe7e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__next_value_expr_0_60.snap @@ -0,0 +1,9 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/next_value_expr_0_60.sql +snapshot_kind: text +--- +SELECT + nextval( + 'user_id_seq' + ); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__null_test_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__null_test_0_60.snap new file mode 100644 index 000000000..d5da99fe2 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__null_test_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/null_test_0_60.sql +snapshot_kind: text +--- +SELECT * FROM users WHERE email IS NULL; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__nullif_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__nullif_expr_0_60.snap new file mode 100644 index 000000000..fa41d7037 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__nullif_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/nullif_expr_0_60.sql +snapshot_kind: text +--- +SELECT NULLIF(name, 'John') FROM users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__nullifexpr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__nullifexpr_0_60.snap new file mode 100644 index 000000000..57e8a91b0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__nullifexpr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/nullifexpr_0_60.sql +snapshot_kind: text +--- +SELECT NULLIF(a, b); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__on_conflict_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__on_conflict_expr_0_60.snap new file mode 100644 index 000000000..076d24230 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__on_conflict_expr_0_60.snap @@ -0,0 +1,7 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/on_conflict_expr_0_60.sql +snapshot_kind: text +--- +INSERT INTO users (id, name) VALUES (1, 'John') +ON CONFLICT (id) DO NOTHING; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__op_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__op_expr_0_60.snap new file mode 100644 index 000000000..642e10307 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__op_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/op_expr_0_60.sql +snapshot_kind: text +--- +SELECT 1 + 2; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__param_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__param_0_60.snap new file mode 100644 index 000000000..a0d14d74e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__param_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/param_0_60.sql +snapshot_kind: text +--- +SELECT $1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__partition_bound_spec_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__partition_bound_spec_0_60.snap new file mode 100644 index 000000000..632fbc78b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__partition_bound_spec_0_60.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/partition_bound_spec_0_60.sql +snapshot_kind: text +--- +CREATE TABLE measurement ( + id pg_catalog.int4, + logdate date +) +PARTITION BY RANGE (logdate); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__partition_elem_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__partition_elem_0_60.snap new file mode 100644 index 000000000..8ab48e8a9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__partition_elem_0_60.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/partition_elem_0_60.sql +snapshot_kind: text +--- +CREATE TABLE measurement ( + city_id pg_catalog.int4, + logdate date +) +PARTITION BY RANGE (logdate); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__pl_assign_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__pl_assign_stmt_0_60.snap new file mode 100644 index 000000000..c3b9834df --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__pl_assign_stmt_0_60.snap @@ -0,0 +1,11 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/pl_assign_stmt_0_60.sql +snapshot_kind: text +--- +DO ' +DECLARE + x integer; +BEGIN + x := 42; +END '; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__prepare_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__prepare_stmt_0_60.snap new file mode 100644 index 000000000..0ce2b86d4 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__prepare_stmt_0_60.snap @@ -0,0 +1,8 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/single/prepare_stmt_0_60.sql +snapshot_kind: text +--- +PREPARE my_insert (pg_catalog.int4, text) AS + INSERT INTO users (id, name) VALUES + ($1, $2); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__query_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__query_0_60.snap new file mode 100644 index 000000000..cea0d10df --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__query_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/query_0_60.sql +snapshot_kind: text +--- +SELECT 1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__query_subselect_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__query_subselect_0_60.snap new file mode 100644 index 000000000..3cee096ba --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__query_subselect_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/query_subselect_0_60.sql +snapshot_kind: text +--- +SELECT * FROM (SELECT 1) AS subq; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__range_function_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_function_0_60.snap new file mode 100644 index 000000000..205613580 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_function_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/range_function_0_60.sql +snapshot_kind: text +--- +SELECT * FROM generate_series(1, 10); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__range_subselect_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_subselect_0_60.snap new file mode 100644 index 000000000..fa5243bec --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_subselect_0_60.snap @@ -0,0 +1,14 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/range_subselect_0_60.sql +snapshot_kind: text +--- +SELECT + * +FROM + (SELECT + id, + name + FROM + users + WHERE active = TRUE) AS active_users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__range_table_func_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_table_func_0_60.snap new file mode 100644 index 000000000..8dddf7447 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_table_func_0_60.snap @@ -0,0 +1,11 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/range_table_func_0_60.sql +snapshot_kind: text +--- +SELECT + * +FROM + xmltable('/root' + passing 'value' + columns item text path 'item'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__range_table_sample_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_table_sample_0_60.snap new file mode 100644 index 000000000..7f6520702 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_table_sample_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/range_table_sample_0_60.sql +snapshot_kind: text +--- +SELECT * FROM employees TABLESAMPLE system (10); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__range_tbl_ref_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_tbl_ref_0_60.snap new file mode 100644 index 000000000..0ba237586 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__range_tbl_ref_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/range_tbl_ref_0_60.sql +snapshot_kind: text +--- +SELECT t1.a FROM t1, t2; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__reassign_owned_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__reassign_owned_stmt_0_60.snap new file mode 100644 index 000000000..4122bbe95 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__reassign_owned_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/reassign_owned_stmt_0_60.sql +snapshot_kind: text +--- +REASSIGN OWNED BY olduser TO newuser; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__refresh_mat_view_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__refresh_mat_view_stmt_0_60.snap new file mode 100644 index 000000000..15a5d3552 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__refresh_mat_view_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/refresh_mat_view_stmt_0_60.sql +snapshot_kind: text +--- +REFRESH MATERIALIZED VIEW myview; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__reindex_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__reindex_stmt_0_60.snap new file mode 100644 index 000000000..d606fab8f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__reindex_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/reindex_stmt_0_60.sql +snapshot_kind: text +--- +REINDEX TABLE users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__relabel_type_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__relabel_type_0_60.snap new file mode 100644 index 000000000..1705751ad --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__relabel_type_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +assertion_line: 59 +input_file: crates/pgt_pretty_print/tests/data/relabel_type_0_60.sql +--- +SELECT 'hello'::text; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__rename_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__rename_stmt_0_60.snap new file mode 100644 index 000000000..32f247e4b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__rename_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/rename_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TABLE users RENAME TO customers; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__replica_identity_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__replica_identity_stmt_0_60.snap new file mode 100644 index 000000000..5bef8bd87 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__replica_identity_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/replica_identity_stmt_0_60.sql +snapshot_kind: text +--- +ALTER TABLE mytable REPLICA IDENTITY FULL; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__return_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__return_stmt_0_60.snap new file mode 100644 index 000000000..2951baf3c --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__return_stmt_0_60.snap @@ -0,0 +1,9 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/return_stmt_0_60.sql +snapshot_kind: text +--- +DO ' +BEGIN + RETURN; +END '; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__row_compare_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__row_compare_expr_0_60.snap new file mode 100644 index 000000000..3af36b494 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__row_compare_expr_0_60.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/row_compare_expr_0_60.sql +snapshot_kind: text +--- +SELECT + * +FROM + employees +WHERE ROW(salary, bonus) > ROW(50000, 10000); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__row_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__row_expr_0_60.snap new file mode 100644 index 000000000..5711fac74 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__row_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/row_expr_0_60.sql +snapshot_kind: text +--- +SELECT ROW(1, 2, 3); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__rule_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__rule_stmt_0_60.snap new file mode 100644 index 000000000..14ea3379a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__rule_stmt_0_60.snap @@ -0,0 +1,8 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/rule_stmt_0_60.sql +snapshot_kind: text +--- +CREATE RULE notify_me AS ON UPDATE + TO mytable + DO NOTIFY mytable_updated; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__scalar_array_op_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__scalar_array_op_expr_0_60.snap new file mode 100644 index 000000000..58e190814 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__scalar_array_op_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/scalar_array_op_expr_0_60.sql +snapshot_kind: text +--- +SELECT * FROM users WHERE id IN (1, 2, 3); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__select_with_alias_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__select_with_alias_80.snap new file mode 100644 index 000000000..333474087 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__select_with_alias_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/select_with_alias_80.sql +snapshot_kind: text +--- +SELECT a AS x, b AS y, c FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__select_with_schema_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__select_with_schema_80.snap new file mode 100644 index 000000000..2c2c11e43 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__select_with_schema_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/select_with_schema_80.sql +snapshot_kind: text +--- +SELECT public.t.a, t.b, c FROM public.t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__set_operation_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__set_operation_stmt_0_60.snap new file mode 100644 index 000000000..ba8e7f33a --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__set_operation_stmt_0_60.snap @@ -0,0 +1,16 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/set_operation_stmt_0_60.sql +snapshot_kind: text +--- +SELECT + id, + name +FROM + users +UNION +SELECT + id, + name +FROM + employees; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__set_to_default_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__set_to_default_0_60.snap new file mode 100644 index 000000000..b0b2c5751 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__set_to_default_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/set_to_default_0_60.sql +snapshot_kind: text +--- +UPDATE t SET a = DEFAULT; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__short_select_stays_inline_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__short_select_stays_inline_80.snap new file mode 100644 index 000000000..7ec2633e5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__short_select_stays_inline_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/short_select_stays_inline_80.sql +snapshot_kind: text +--- +SELECT a FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__simple_select_20.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__simple_select_20.snap new file mode 100644 index 000000000..30ef22cae --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__simple_select_20.snap @@ -0,0 +1,11 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/simple_select_20.sql +snapshot_kind: text +--- +SELECT + a, + b, + c +FROM + t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__simple_select_80.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__simple_select_80.snap new file mode 100644 index 000000000..062c912f3 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__simple_select_80.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/simple_select_80.sql +snapshot_kind: text +--- +SELECT a, b, c FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__sql_value_function_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__sql_value_function_0_60.snap new file mode 100644 index 000000000..4cd499757 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__sql_value_function_0_60.snap @@ -0,0 +1,10 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/sql_value_function_0_60.sql +snapshot_kind: text +--- +SELECT + CURRENT_DATE, + CURRENT_TIME, + CURRENT_TIMESTAMP, + CURRENT_USER; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__sub_link_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__sub_link_0_60.snap new file mode 100644 index 000000000..25f89c8cc --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__sub_link_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/sub_link_0_60.sql +snapshot_kind: text +--- +SELECT * FROM users WHERE EXISTS (SELECT 1 FROM orders); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__table_func_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__table_func_0_60.snap new file mode 100644 index 000000000..28d8cf1c9 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__table_func_0_60.snap @@ -0,0 +1,14 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/table_func_0_60.sql +snapshot_kind: text +--- +SELECT + * +FROM + JSON_TABLE('{"employees":[{"name":"John","age":30},{"name":"Jane","age":25}]}'::jsonb, + '$.employees[*]' + COLUMNS ( + name text PATH '$.name', + age pg_catalog.int4 PATH '$.age' + )) AS jt; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__table_like_clause_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__table_like_clause_0_60.snap new file mode 100644 index 000000000..b15855723 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__table_like_clause_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/table_like_clause_0_60.sql +snapshot_kind: text +--- +CREATE TABLE new_table (LIKE old_table INCLUDING ALL); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__target_entry_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__target_entry_0_60.snap new file mode 100644 index 000000000..360f3aefa --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__target_entry_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/target_entry_0_60.sql +snapshot_kind: text +--- +SELECT a FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__transaction_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__transaction_stmt_0_60.snap new file mode 100644 index 000000000..27d2c238b --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__transaction_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/transaction_stmt_0_60.sql +snapshot_kind: text +--- +BEGIN; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__truncate_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__truncate_stmt_0_60.snap new file mode 100644 index 000000000..14e45c9a6 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__truncate_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/truncate_stmt_0_60.sql +snapshot_kind: text +--- +TRUNCATE TABLE users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__truncate_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__truncate_stmt_simple.snap new file mode 100644 index 000000000..0678987df --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__truncate_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/truncate_stmt_simple.sql +snapshot_kind: text +--- +TRUNCATE TABLE users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__type_cast_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__type_cast_0_60.snap new file mode 100644 index 000000000..90c263afb --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__type_cast_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/type_cast_0_60.sql +snapshot_kind: text +--- +SELECT '123'::pg_catalog.int4; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__unlisten_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__unlisten_stmt_0_60.snap new file mode 100644 index 000000000..f8b57d899 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__unlisten_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/unlisten_stmt_0_60.sql +snapshot_kind: text +--- +UNLISTEN mytable_updated; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__update_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__update_stmt_0_60.snap new file mode 100644 index 000000000..fb93863e5 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__update_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/update_stmt_0_60.sql +snapshot_kind: text +--- +UPDATE users SET name = 'Jane Doe' WHERE id = 1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__update_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__update_stmt_simple.snap new file mode 100644 index 000000000..1f34cc1cd --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__update_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/update_stmt_simple.sql +snapshot_kind: text +--- +UPDATE users SET name = 'Jane Doe' WHERE id = 1; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__vacuum_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__vacuum_stmt_0_60.snap new file mode 100644 index 000000000..8d45b391f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__vacuum_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/vacuum_stmt_0_60.sql +snapshot_kind: text +--- +VACUUM users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__var_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__var_0_60.snap new file mode 100644 index 000000000..a227a64bc --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__var_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/var_0_60.sql +snapshot_kind: text +--- +SELECT a FROM t; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__variable_set_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__variable_set_stmt_0_60.snap new file mode 100644 index 000000000..9ab98ec31 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__variable_set_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/variable_set_stmt_0_60.sql +snapshot_kind: text +--- +SET search_path TO 'myschema', 'public'; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__variable_show_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__variable_show_stmt_0_60.snap new file mode 100644 index 000000000..e57b0d12e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__variable_show_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/variable_show_stmt_0_60.sql +snapshot_kind: text +--- +SHOW search_path; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__view_stmt_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__view_stmt_0_60.snap new file mode 100644 index 000000000..d5ed1f46f --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__view_stmt_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/view_stmt_0_60.sql +snapshot_kind: text +--- +CREATE VIEW user_view AS SELECT id, name FROM users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__view_stmt_simple.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__view_stmt_simple.snap new file mode 100644 index 000000000..9350f4b8e --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__view_stmt_simple.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/view_stmt_simple.sql +snapshot_kind: text +--- +CREATE VIEW user_view AS SELECT id, name FROM users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__window_def_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__window_def_0_60.snap new file mode 100644 index 000000000..4f1fa84b0 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__window_def_0_60.snap @@ -0,0 +1,11 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/window_def_0_60.sql +snapshot_kind: text +--- +SELECT + id, + name, + row_number() OVER (PARTITION BY dept ORDER BY salary DESC) +FROM + employees; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__window_func_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__window_func_0_60.snap new file mode 100644 index 000000000..cc5a872cf --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__window_func_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/window_func_0_60.sql +snapshot_kind: text +--- +SELECT row_number() OVER (ORDER BY id) FROM users; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__with_clause_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__with_clause_0_60.snap new file mode 100644 index 000000000..543146418 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__with_clause_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/with_clause_0_60.sql +snapshot_kind: text +--- +WITH cte AS (SELECT 1) SELECT * FROM cte; diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__xml_expr_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__xml_expr_0_60.snap new file mode 100644 index 000000000..d49150133 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__xml_expr_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/xml_expr_0_60.sql +snapshot_kind: text +--- +SELECT XMLELEMENT(NAME foo, 'bar'); diff --git a/crates/pgt_pretty_print/tests/snapshots/single/tests__xml_serialize_0_60.snap b/crates/pgt_pretty_print/tests/snapshots/single/tests__xml_serialize_0_60.snap new file mode 100644 index 000000000..8309fb635 --- /dev/null +++ b/crates/pgt_pretty_print/tests/snapshots/single/tests__xml_serialize_0_60.snap @@ -0,0 +1,6 @@ +--- +source: crates/pgt_pretty_print/tests/tests.rs +input_file: crates/pgt_pretty_print/tests/data/xml_serialize_0_60.sql +snapshot_kind: text +--- +SELECT XMLSERIALIZE(CONTENT doc AS text); diff --git a/crates/pgt_pretty_print/tests/tests.rs b/crates/pgt_pretty_print/tests/tests.rs new file mode 100644 index 000000000..7daef68cc --- /dev/null +++ b/crates/pgt_pretty_print/tests/tests.rs @@ -0,0 +1,270 @@ +use camino::Utf8Path; +use dir_test::{Fixture, dir_test}; +use insta::{assert_snapshot, with_settings}; + +use pgt_pretty_print::{ + emitter::{EventEmitter, ToTokens}, + renderer::{IndentStyle, RenderConfig, Renderer}, +}; + +#[dir_test( + dir: "$CARGO_MANIFEST_DIR/tests/data/single/", + glob: "*.sql", +)] +fn test_single(fixture: Fixture<&str>) { + let content = fixture.content(); + + println!("Original content:\n{}", content); + + let absolute_fixture_path = Utf8Path::new(fixture.path()); + let input_file = absolute_fixture_path; + let test_name = absolute_fixture_path + .file_name() + .and_then(|x| x.strip_suffix(".sql")) + .unwrap(); + + // extract line length from filename (e.g., "simple_select_80" -> 80) + let max_line_length = test_name + .split('_') + .next_back() + .and_then(|s| s.parse::().ok()) + .unwrap_or(80); + + let parsed = pgt_query::parse(content).expect("Failed to parse SQL"); + let mut ast = parsed.into_root().expect("No root node found"); + + let mut emitter = EventEmitter::new(); + ast.to_tokens(&mut emitter); + + let mut output = String::new(); + let config = RenderConfig { + max_line_length, + indent_size: 2, + indent_style: IndentStyle::Spaces, + }; + let mut renderer = Renderer::new(&mut output, config); + renderer.render(emitter.events).expect("Failed to render"); + + println!("Formatted content:\n{}", output); + + for line in output.lines() { + assert!( + line.len() <= max_line_length, + "Line exceeds max length of {}: {}", + max_line_length, + line + ); + } + + let parsed_output = pgt_query::parse(&output).expect("Failed to parse SQL"); + let mut parsed_ast = parsed_output.into_root().expect("No root node found"); + + clear_location(&mut parsed_ast); + clear_location(&mut ast); + + assert_eq!(ast, parsed_ast); + + with_settings!({ + omit_expression => true, + input_file => input_file, + snapshot_path => "snapshots/single", + }, { + assert_snapshot!(test_name, output); + }); +} + +#[dir_test( + dir: "$CARGO_MANIFEST_DIR/tests/data/multi/", + glob: "*.sql", +)] +fn test_multi(fixture: Fixture<&str>) { + let content = fixture.content(); + + let absolute_fixture_path = Utf8Path::new(fixture.path()); + let input_file = absolute_fixture_path; + let test_name = absolute_fixture_path + .file_name() + .and_then(|x| x.strip_suffix(".sql")) + .unwrap(); + + // extract line length from filename (e.g., "advisory_lock_60" -> 60) + let max_line_length = test_name + .split('_') + .next_back() + .and_then(|s| s.parse::().ok()) + .unwrap_or(60); + + // Split the content into statements + let split_result = pgt_statement_splitter::split(content); + let mut formatted_statements = Vec::new(); + + for range in &split_result.ranges { + let statement = &content[usize::from(range.start())..usize::from(range.end())]; + let trimmed = statement.trim(); + + if trimmed.is_empty() { + continue; + } + + let parsed = pgt_query::parse(trimmed).expect("Failed to parse SQL"); + let mut ast = parsed.into_root().expect("No root node found"); + + let mut emitter = EventEmitter::new(); + ast.to_tokens(&mut emitter); + + let mut output = String::new(); + let config = RenderConfig { + max_line_length, + indent_size: 2, + indent_style: IndentStyle::Spaces, + }; + let mut renderer = Renderer::new(&mut output, config); + renderer.render(emitter.events).expect("Failed to render"); + + // Verify line length + for line in output.lines() { + assert!( + line.len() <= max_line_length, + "Line exceeds max length of {}: {}", + max_line_length, + line + ); + } + + // Verify AST equality + let parsed_output = pgt_query::parse(&output).unwrap_or_else(|e| { + eprintln!("Failed to parse formatted SQL. Error: {:?}", e); + eprintln!("Statement index: {}", range.start()); + eprintln!("Formatted SQL:\n{}", output); + panic!("Failed to parse formatted SQL: {:?}", e); + }); + let mut parsed_ast = parsed_output.into_root().expect("No root node found"); + + clear_location(&mut parsed_ast); + clear_location(&mut ast); + + assert_eq!(ast, parsed_ast); + + formatted_statements.push(output); + } + + // Join all formatted statements with double newline + let final_output = formatted_statements.join("\n\n"); + + println!("Formatted multi-statement content:\n{}", final_output); + + with_settings!({ + omit_expression => true, + input_file => input_file, + snapshot_path => "snapshots/multi", + }, { + assert_snapshot!(test_name, final_output); + }); +} + +fn clear_location(node: &mut pgt_query::NodeEnum) { + unsafe { + node.iter_mut().for_each(|n| match n { + pgt_query::NodeMut::ColumnRef(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::ParamRef(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::AExpr(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::JoinExpr(n) => { + (*n).rtindex = 0; + } + pgt_query::NodeMut::TypeCast(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::CollateClause(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::FuncCall(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::AArrayExpr(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::ResTarget(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::SortBy(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::WindowDef(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::TypeName(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::PartitionSpec(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::PartitionElem(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::SqlvalueFunction(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::ColumnDef(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::DefElem(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::XmlSerialize(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::AConst(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::RangeVar(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::RoleSpec(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::RangeTableFunc(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::RangeTableFuncCol(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::RowExpr(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::BoolExpr(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::GroupingFunc(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::GroupingSet(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::CommonTableExpr(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::SubLink(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::NullTest(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::Constraint(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::CaseWhen(n) => { + (*n).location = 0; + } + pgt_query::NodeMut::CaseExpr(n) => { + (*n).location = 0; + } + _ => {} + }); + } +} diff --git a/crates/pgt_pretty_print_codegen/Cargo.toml b/crates/pgt_pretty_print_codegen/Cargo.toml new file mode 100644 index 000000000..79b7aeec5 --- /dev/null +++ b/crates/pgt_pretty_print_codegen/Cargo.toml @@ -0,0 +1,25 @@ +[package] +authors.workspace = true +categories.workspace = true +description = "" +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +name = "pgt_pretty_print_codegen" +repository.workspace = true +version = "0.0.0" + +[dependencies] +anyhow = { workspace = true } +convert_case = { workspace = true } +proc-macro2.workspace = true +prost-reflect = { workspace = true } +protox = { workspace = true } +quote.workspace = true + +[build-dependencies] +ureq = "2.9" + +[lib] +proc-macro = true diff --git a/crates/pgt_pretty_print_codegen/README.md b/crates/pgt_pretty_print_codegen/README.md new file mode 100644 index 000000000..57bdaa340 --- /dev/null +++ b/crates/pgt_pretty_print_codegen/README.md @@ -0,0 +1 @@ +Heavily inspired by and copied from [squawk_parser](https://github.com/sbdchd/squawk/tree/9acfecbbb7f3c7eedcbaf060e7b25f9afa136db3/crates/squawk_parser). Thanks for making all the hard work MIT-licensed! diff --git a/crates/pgt_pretty_print_codegen/build.rs b/crates/pgt_pretty_print_codegen/build.rs new file mode 100644 index 000000000..c4bb1a740 --- /dev/null +++ b/crates/pgt_pretty_print_codegen/build.rs @@ -0,0 +1,80 @@ +use std::env; +use std::fs; +use std::io::Write; +use std::path::PathBuf; + +// TODO make this selectable via feature flags +static LIBPG_QUERY_TAG: &str = "17-6.1.0"; + +/// Downloads the `kwlist.h` file from the specified version of `libpg_query` +fn main() -> Result<(), Box> { + let version = LIBPG_QUERY_TAG.to_string(); + + let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?); + let postgres_dir = manifest_dir.join("postgres").join(&version); + let kwlist_path = postgres_dir.join("kwlist.h"); + let proto_path = postgres_dir.join("pg_query.proto"); + + if !postgres_dir.exists() { + fs::create_dir_all(&postgres_dir)?; + } + + if !kwlist_path.exists() { + println!( + "cargo:warning=Downloading kwlist.h for libpg_query {}", + version + ); + + let kwlist_url = format!( + "https://raw.githubusercontent.com/pganalyze/libpg_query/{}/src/postgres/include/parser/kwlist.h", + version + ); + + let response = ureq::get(&kwlist_url).call()?; + let content = response.into_string()?; + + let mut file = fs::File::create(&kwlist_path)?; + file.write_all(content.as_bytes())?; + + println!("cargo:warning=Successfully downloaded kwlist.h"); + } + + if !proto_path.exists() { + println!( + "cargo:warning=Downloading pg_query.proto for libpg_query {}", + version + ); + + let proto_url = format!( + "https://raw.githubusercontent.com/pganalyze/libpg_query/{}/protobuf/pg_query.proto", + version + ); + + let response = ureq::get(&proto_url).call()?; + let proto_content = response.into_string()?; + + let mut file = fs::File::create(&proto_path)?; + file.write_all(proto_content.as_bytes())?; + + println!( + "cargo:warning=Successfully downloaded pg_query.proto to {}", + proto_path.display() + ); + } + + println!( + "cargo:rustc-env=PG_QUERY_KWLIST_PATH={}", + kwlist_path.display() + ); + + println!( + "cargo:rustc-env=PG_QUERY_PROTO_PATH={}", + proto_path.display() + ); + + println!("cargo:rerun-if-changed={}", kwlist_path.display()); + + println!("cargo:rerun-if-changed={}", proto_path.display()); + + Ok(()) +} diff --git a/crates/pgt_pretty_print_codegen/postgres/17-6.1.0/kwlist.h b/crates/pgt_pretty_print_codegen/postgres/17-6.1.0/kwlist.h new file mode 100644 index 000000000..658d7ff6a --- /dev/null +++ b/crates/pgt_pretty_print_codegen/postgres/17-6.1.0/kwlist.h @@ -0,0 +1,518 @@ +/*------------------------------------------------------------------------- + * + * kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/parser/kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* there is deliberately not an #ifndef KWLIST_H here */ + +/* + * List of keyword (name, token-value, category, bare-label-status) entries. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value, category, is-bare-label */ +PG_KEYWORD("abort", ABORT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("absent", ABSENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("absolute", ABSOLUTE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("access", ACCESS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("add", ADD_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("admin", ADMIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("after", AFTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("aggregate", AGGREGATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("all", ALL, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("also", ALSO, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("alter", ALTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("always", ALWAYS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("analyse", ANALYSE, RESERVED_KEYWORD, BARE_LABEL) /* British spelling */ +PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("and", AND, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("any", ANY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("array", ARRAY, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("as", AS, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("asc", ASC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("asensitive", ASENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("assertion", ASSERTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("assignment", ASSIGNMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("asymmetric", ASYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("at", AT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("atomic", ATOMIC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("attach", ATTACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("attribute", ATTRIBUTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("authorization", AUTHORIZATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("backward", BACKWARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("before", BEFORE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("begin", BEGIN_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("between", BETWEEN, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("bigint", BIGINT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("binary", BINARY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("bit", BIT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("boolean", BOOLEAN_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("both", BOTH, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("breadth", BREADTH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("by", BY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cache", CACHE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("call", CALL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("called", CALLED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cascade", CASCADE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cascaded", CASCADED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("case", CASE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cast", CAST, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("catalog", CATALOG_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("chain", CHAIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("char", CHAR_P, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("character", CHARACTER, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("characteristics", CHARACTERISTICS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("check", CHECK, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("checkpoint", CHECKPOINT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("class", CLASS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("close", CLOSE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cluster", CLUSTER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("coalesce", COALESCE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("collation", COLLATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("columns", COLUMNS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("compression", COMPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("conditional", CONDITIONAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("constraint", CONSTRAINT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("constraints", CONSTRAINTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("content", CONTENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("continue", CONTINUE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("conversion", CONVERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("copy", COPY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cost", COST, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("create", CREATE, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("cross", CROSS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("csv", CSV, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cube", CUBE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current", CURRENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_catalog", CURRENT_CATALOG, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_date", CURRENT_DATE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_role", CURRENT_ROLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_schema", CURRENT_SCHEMA, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_time", CURRENT_TIME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("current_user", CURRENT_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cursor", CURSOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("cycle", CYCLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("data", DATA_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("database", DATABASE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("day", DAY_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("deallocate", DEALLOCATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("dec", DEC, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("decimal", DECIMAL_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("declare", DECLARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("default", DEFAULT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("defaults", DEFAULTS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("deferrable", DEFERRABLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("deferred", DEFERRED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("depends", DEPENDS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("depth", DEPTH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("desc", DESC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("detach", DETACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("do", DO, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("document", DOCUMENT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("else", ELSE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("empty", EMPTY_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("encoding", ENCODING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("end", END_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("error", ERROR_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("expression", EXPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("family", FAMILY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("fetch", FETCH, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("filter", FILTER, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("finalize", FINALIZE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("first", FIRST_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("float", FLOAT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("following", FOLLOWING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("for", FOR, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("force", FORCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("foreign", FOREIGN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("format", FORMAT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("forward", FORWARD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("from", FROM, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("grouping", GROUPING, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("groups", GROUPS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("handler", HANDLER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("having", HAVING, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("header", HEADER_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("implicit", IMPLICIT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("import", IMPORT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("in", IN_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("include", INCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("including", INCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("increment", INCREMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("indent", INDENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("index", INDEX, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("indexes", INDEXES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inherit", INHERIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inherits", INHERITS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("initially", INITIALLY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inline", INLINE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("inner", INNER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("inout", INOUT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("input", INPUT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("insensitive", INSENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("insert", INSERT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("instead", INSTEAD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("int", INT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("integer", INTEGER, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("intersect", INTERSECT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("interval", INTERVAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("into", INTO, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("invoker", INVOKER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("is", IS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json", JSON, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_array", JSON_ARRAY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_arrayagg", JSON_ARRAYAGG, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_exists", JSON_EXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_object", JSON_OBJECT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_query", JSON_QUERY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_scalar", JSON_SCALAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_serialize", JSON_SERIALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_table", JSON_TABLE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("json_value", JSON_VALUE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("keep", KEEP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("keys", KEYS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("last", LAST_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("lateral", LATERAL_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("leading", LEADING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("leakproof", LEAKPROOF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("least", LEAST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("left", LEFT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("level", LEVEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("like", LIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("limit", LIMIT, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("listen", LISTEN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("load", LOAD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("local", LOCAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("localtime", LOCALTIME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("matched", MATCHED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("merge", MERGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("merge_action", MERGE_ACTION, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("mode", MODE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("month", MONTH_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("move", MOVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("name", NAME_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("names", NAMES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("national", NATIONAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("natural", NATURAL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nchar", NCHAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nested", NESTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("new", NEW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfc", NFC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfd", NFD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfkc", NFKC, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nfkd", NFKD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("no", NO, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("none", NONE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("normalize", NORMALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("normalized", NORMALIZED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("not", NOT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("nowait", NOWAIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("null", NULL_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("of", OF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("old", OLD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("omit", OMIT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("on", ON, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("only", ONLY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("option", OPTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("or", OR, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("order", ORDER, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("ordinality", ORDINALITY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("others", OTHERS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parallel", PARALLEL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parameter", PARAMETER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("path", PATH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("plan", PLAN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD, AS_LABEL) +PG_KEYWORD("prepare", PREPARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("prepared", PREPARED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("preserve", PRESERVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("primary", PRIMARY, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("prior", PRIOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("privileges", PRIVILEGES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("procedures", PROCEDURES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("quotes", QUOTES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("read", READ, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("real", REAL, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("return", RETURN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("returns", RETURNS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("revoke", REVOKE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("right", RIGHT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("role", ROLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rollback", ROLLBACK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rollup", ROLLUP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("routine", ROUTINE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("routines", ROUTINES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("row", ROW, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("scalar", SCALAR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("select", SELECT, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("serializable", SERIALIZABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("server", SERVER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("session", SESSION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("session_user", SESSION_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("set", SET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("setof", SETOF, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("sets", SETS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("share", SHARE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("show", SHOW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("simple", SIMPLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("skip", SKIP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("some", SOME, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("source", SOURCE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("start", START, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("statement", STATEMENT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("statistics", STATISTICS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stdin", STDIN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("stored", STORED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("string", STRING_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("support", SUPPORT, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("symmetric", SYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("system_user", SYSTEM_USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("table", TABLE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("tables", TABLES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("tablesample", TABLESAMPLE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("tablespace", TABLESPACE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("target", TARGET, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("template", TEMPLATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("temporary", TEMPORARY, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("text", TEXT_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("then", THEN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("ties", TIES, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("time", TIME, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("timestamp", TIMESTAMP, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("to", TO, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("trailing", TRAILING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("transaction", TRANSACTION, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("transform", TRANSFORM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("treat", TREAT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("trigger", TRIGGER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("trim", TRIM, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("true", TRUE_P, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("truncate", TRUNCATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("trusted", TRUSTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("type", TYPE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("uescape", UESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unconditional", UNCONDITIONAL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("union", UNION, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("unique", UNIQUE, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unknown", UNKNOWN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unlisten", UNLISTEN, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("unlogged", UNLOGGED, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("until", UNTIL, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("update", UPDATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("user", USER, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("using", USING, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("vacuum", VACUUM, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("valid", VALID, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("validate", VALIDATE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("validator", VALIDATOR, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("value", VALUE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("values", VALUES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("varchar", VARCHAR, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("variadic", VARIADIC, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("when", WHEN, RESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("where", WHERE, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("with", WITH, RESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlnamespaces", XMLNAMESPACES, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlparse", XMLPARSE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlpi", XMLPI, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlroot", XMLROOT, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("xmltable", XMLTABLE, COL_NAME_KEYWORD, BARE_LABEL) +PG_KEYWORD("year", YEAR_P, UNRESERVED_KEYWORD, AS_LABEL) +PG_KEYWORD("yes", YES_P, UNRESERVED_KEYWORD, BARE_LABEL) +PG_KEYWORD("zone", ZONE, UNRESERVED_KEYWORD, BARE_LABEL) diff --git a/crates/pgt_pretty_print_codegen/postgres/17-6.1.0/pg_query.proto b/crates/pgt_pretty_print_codegen/postgres/17-6.1.0/pg_query.proto new file mode 100644 index 000000000..24a8f14cd --- /dev/null +++ b/crates/pgt_pretty_print_codegen/postgres/17-6.1.0/pg_query.proto @@ -0,0 +1,4110 @@ +// This file is autogenerated by ./scripts/generate_protobuf_and_funcs.rb + +syntax = "proto3"; + +package pg_query; + +message ParseResult { + int32 version = 1; + repeated RawStmt stmts = 2; +} + +message ScanResult { + int32 version = 1; + repeated ScanToken tokens = 2; +} + +message Node { + oneof node { + Alias alias = 1 [json_name="Alias"]; + RangeVar range_var = 2 [json_name="RangeVar"]; + TableFunc table_func = 3 [json_name="TableFunc"]; + IntoClause into_clause = 4 [json_name="IntoClause"]; + Var var = 5 [json_name="Var"]; + Param param = 6 [json_name="Param"]; + Aggref aggref = 7 [json_name="Aggref"]; + GroupingFunc grouping_func = 8 [json_name="GroupingFunc"]; + WindowFunc window_func = 9 [json_name="WindowFunc"]; + WindowFuncRunCondition window_func_run_condition = 10 [json_name="WindowFuncRunCondition"]; + MergeSupportFunc merge_support_func = 11 [json_name="MergeSupportFunc"]; + SubscriptingRef subscripting_ref = 12 [json_name="SubscriptingRef"]; + FuncExpr func_expr = 13 [json_name="FuncExpr"]; + NamedArgExpr named_arg_expr = 14 [json_name="NamedArgExpr"]; + OpExpr op_expr = 15 [json_name="OpExpr"]; + DistinctExpr distinct_expr = 16 [json_name="DistinctExpr"]; + NullIfExpr null_if_expr = 17 [json_name="NullIfExpr"]; + ScalarArrayOpExpr scalar_array_op_expr = 18 [json_name="ScalarArrayOpExpr"]; + BoolExpr bool_expr = 19 [json_name="BoolExpr"]; + SubLink sub_link = 20 [json_name="SubLink"]; + SubPlan sub_plan = 21 [json_name="SubPlan"]; + AlternativeSubPlan alternative_sub_plan = 22 [json_name="AlternativeSubPlan"]; + FieldSelect field_select = 23 [json_name="FieldSelect"]; + FieldStore field_store = 24 [json_name="FieldStore"]; + RelabelType relabel_type = 25 [json_name="RelabelType"]; + CoerceViaIO coerce_via_io = 26 [json_name="CoerceViaIO"]; + ArrayCoerceExpr array_coerce_expr = 27 [json_name="ArrayCoerceExpr"]; + ConvertRowtypeExpr convert_rowtype_expr = 28 [json_name="ConvertRowtypeExpr"]; + CollateExpr collate_expr = 29 [json_name="CollateExpr"]; + CaseExpr case_expr = 30 [json_name="CaseExpr"]; + CaseWhen case_when = 31 [json_name="CaseWhen"]; + CaseTestExpr case_test_expr = 32 [json_name="CaseTestExpr"]; + ArrayExpr array_expr = 33 [json_name="ArrayExpr"]; + RowExpr row_expr = 34 [json_name="RowExpr"]; + RowCompareExpr row_compare_expr = 35 [json_name="RowCompareExpr"]; + CoalesceExpr coalesce_expr = 36 [json_name="CoalesceExpr"]; + MinMaxExpr min_max_expr = 37 [json_name="MinMaxExpr"]; + SQLValueFunction sqlvalue_function = 38 [json_name="SQLValueFunction"]; + XmlExpr xml_expr = 39 [json_name="XmlExpr"]; + JsonFormat json_format = 40 [json_name="JsonFormat"]; + JsonReturning json_returning = 41 [json_name="JsonReturning"]; + JsonValueExpr json_value_expr = 42 [json_name="JsonValueExpr"]; + JsonConstructorExpr json_constructor_expr = 43 [json_name="JsonConstructorExpr"]; + JsonIsPredicate json_is_predicate = 44 [json_name="JsonIsPredicate"]; + JsonBehavior json_behavior = 45 [json_name="JsonBehavior"]; + JsonExpr json_expr = 46 [json_name="JsonExpr"]; + JsonTablePath json_table_path = 47 [json_name="JsonTablePath"]; + JsonTablePathScan json_table_path_scan = 48 [json_name="JsonTablePathScan"]; + JsonTableSiblingJoin json_table_sibling_join = 49 [json_name="JsonTableSiblingJoin"]; + NullTest null_test = 50 [json_name="NullTest"]; + BooleanTest boolean_test = 51 [json_name="BooleanTest"]; + MergeAction merge_action = 52 [json_name="MergeAction"]; + CoerceToDomain coerce_to_domain = 53 [json_name="CoerceToDomain"]; + CoerceToDomainValue coerce_to_domain_value = 54 [json_name="CoerceToDomainValue"]; + SetToDefault set_to_default = 55 [json_name="SetToDefault"]; + CurrentOfExpr current_of_expr = 56 [json_name="CurrentOfExpr"]; + NextValueExpr next_value_expr = 57 [json_name="NextValueExpr"]; + InferenceElem inference_elem = 58 [json_name="InferenceElem"]; + TargetEntry target_entry = 59 [json_name="TargetEntry"]; + RangeTblRef range_tbl_ref = 60 [json_name="RangeTblRef"]; + JoinExpr join_expr = 61 [json_name="JoinExpr"]; + FromExpr from_expr = 62 [json_name="FromExpr"]; + OnConflictExpr on_conflict_expr = 63 [json_name="OnConflictExpr"]; + Query query = 64 [json_name="Query"]; + TypeName type_name = 65 [json_name="TypeName"]; + ColumnRef column_ref = 66 [json_name="ColumnRef"]; + ParamRef param_ref = 67 [json_name="ParamRef"]; + A_Expr a_expr = 68 [json_name="A_Expr"]; + TypeCast type_cast = 69 [json_name="TypeCast"]; + CollateClause collate_clause = 70 [json_name="CollateClause"]; + RoleSpec role_spec = 71 [json_name="RoleSpec"]; + FuncCall func_call = 72 [json_name="FuncCall"]; + A_Star a_star = 73 [json_name="A_Star"]; + A_Indices a_indices = 74 [json_name="A_Indices"]; + A_Indirection a_indirection = 75 [json_name="A_Indirection"]; + A_ArrayExpr a_array_expr = 76 [json_name="A_ArrayExpr"]; + ResTarget res_target = 77 [json_name="ResTarget"]; + MultiAssignRef multi_assign_ref = 78 [json_name="MultiAssignRef"]; + SortBy sort_by = 79 [json_name="SortBy"]; + WindowDef window_def = 80 [json_name="WindowDef"]; + RangeSubselect range_subselect = 81 [json_name="RangeSubselect"]; + RangeFunction range_function = 82 [json_name="RangeFunction"]; + RangeTableFunc range_table_func = 83 [json_name="RangeTableFunc"]; + RangeTableFuncCol range_table_func_col = 84 [json_name="RangeTableFuncCol"]; + RangeTableSample range_table_sample = 85 [json_name="RangeTableSample"]; + ColumnDef column_def = 86 [json_name="ColumnDef"]; + TableLikeClause table_like_clause = 87 [json_name="TableLikeClause"]; + IndexElem index_elem = 88 [json_name="IndexElem"]; + DefElem def_elem = 89 [json_name="DefElem"]; + LockingClause locking_clause = 90 [json_name="LockingClause"]; + XmlSerialize xml_serialize = 91 [json_name="XmlSerialize"]; + PartitionElem partition_elem = 92 [json_name="PartitionElem"]; + PartitionSpec partition_spec = 93 [json_name="PartitionSpec"]; + PartitionBoundSpec partition_bound_spec = 94 [json_name="PartitionBoundSpec"]; + PartitionRangeDatum partition_range_datum = 95 [json_name="PartitionRangeDatum"]; + SinglePartitionSpec single_partition_spec = 96 [json_name="SinglePartitionSpec"]; + PartitionCmd partition_cmd = 97 [json_name="PartitionCmd"]; + RangeTblEntry range_tbl_entry = 98 [json_name="RangeTblEntry"]; + RTEPermissionInfo rtepermission_info = 99 [json_name="RTEPermissionInfo"]; + RangeTblFunction range_tbl_function = 100 [json_name="RangeTblFunction"]; + TableSampleClause table_sample_clause = 101 [json_name="TableSampleClause"]; + WithCheckOption with_check_option = 102 [json_name="WithCheckOption"]; + SortGroupClause sort_group_clause = 103 [json_name="SortGroupClause"]; + GroupingSet grouping_set = 104 [json_name="GroupingSet"]; + WindowClause window_clause = 105 [json_name="WindowClause"]; + RowMarkClause row_mark_clause = 106 [json_name="RowMarkClause"]; + WithClause with_clause = 107 [json_name="WithClause"]; + InferClause infer_clause = 108 [json_name="InferClause"]; + OnConflictClause on_conflict_clause = 109 [json_name="OnConflictClause"]; + CTESearchClause ctesearch_clause = 110 [json_name="CTESearchClause"]; + CTECycleClause ctecycle_clause = 111 [json_name="CTECycleClause"]; + CommonTableExpr common_table_expr = 112 [json_name="CommonTableExpr"]; + MergeWhenClause merge_when_clause = 113 [json_name="MergeWhenClause"]; + TriggerTransition trigger_transition = 114 [json_name="TriggerTransition"]; + JsonOutput json_output = 115 [json_name="JsonOutput"]; + JsonArgument json_argument = 116 [json_name="JsonArgument"]; + JsonFuncExpr json_func_expr = 117 [json_name="JsonFuncExpr"]; + JsonTablePathSpec json_table_path_spec = 118 [json_name="JsonTablePathSpec"]; + JsonTable json_table = 119 [json_name="JsonTable"]; + JsonTableColumn json_table_column = 120 [json_name="JsonTableColumn"]; + JsonKeyValue json_key_value = 121 [json_name="JsonKeyValue"]; + JsonParseExpr json_parse_expr = 122 [json_name="JsonParseExpr"]; + JsonScalarExpr json_scalar_expr = 123 [json_name="JsonScalarExpr"]; + JsonSerializeExpr json_serialize_expr = 124 [json_name="JsonSerializeExpr"]; + JsonObjectConstructor json_object_constructor = 125 [json_name="JsonObjectConstructor"]; + JsonArrayConstructor json_array_constructor = 126 [json_name="JsonArrayConstructor"]; + JsonArrayQueryConstructor json_array_query_constructor = 127 [json_name="JsonArrayQueryConstructor"]; + JsonAggConstructor json_agg_constructor = 128 [json_name="JsonAggConstructor"]; + JsonObjectAgg json_object_agg = 129 [json_name="JsonObjectAgg"]; + JsonArrayAgg json_array_agg = 130 [json_name="JsonArrayAgg"]; + RawStmt raw_stmt = 131 [json_name="RawStmt"]; + InsertStmt insert_stmt = 132 [json_name="InsertStmt"]; + DeleteStmt delete_stmt = 133 [json_name="DeleteStmt"]; + UpdateStmt update_stmt = 134 [json_name="UpdateStmt"]; + MergeStmt merge_stmt = 135 [json_name="MergeStmt"]; + SelectStmt select_stmt = 136 [json_name="SelectStmt"]; + SetOperationStmt set_operation_stmt = 137 [json_name="SetOperationStmt"]; + ReturnStmt return_stmt = 138 [json_name="ReturnStmt"]; + PLAssignStmt plassign_stmt = 139 [json_name="PLAssignStmt"]; + CreateSchemaStmt create_schema_stmt = 140 [json_name="CreateSchemaStmt"]; + AlterTableStmt alter_table_stmt = 141 [json_name="AlterTableStmt"]; + ReplicaIdentityStmt replica_identity_stmt = 142 [json_name="ReplicaIdentityStmt"]; + AlterTableCmd alter_table_cmd = 143 [json_name="AlterTableCmd"]; + AlterCollationStmt alter_collation_stmt = 144 [json_name="AlterCollationStmt"]; + AlterDomainStmt alter_domain_stmt = 145 [json_name="AlterDomainStmt"]; + GrantStmt grant_stmt = 146 [json_name="GrantStmt"]; + ObjectWithArgs object_with_args = 147 [json_name="ObjectWithArgs"]; + AccessPriv access_priv = 148 [json_name="AccessPriv"]; + GrantRoleStmt grant_role_stmt = 149 [json_name="GrantRoleStmt"]; + AlterDefaultPrivilegesStmt alter_default_privileges_stmt = 150 [json_name="AlterDefaultPrivilegesStmt"]; + CopyStmt copy_stmt = 151 [json_name="CopyStmt"]; + VariableSetStmt variable_set_stmt = 152 [json_name="VariableSetStmt"]; + VariableShowStmt variable_show_stmt = 153 [json_name="VariableShowStmt"]; + CreateStmt create_stmt = 154 [json_name="CreateStmt"]; + Constraint constraint = 155 [json_name="Constraint"]; + CreateTableSpaceStmt create_table_space_stmt = 156 [json_name="CreateTableSpaceStmt"]; + DropTableSpaceStmt drop_table_space_stmt = 157 [json_name="DropTableSpaceStmt"]; + AlterTableSpaceOptionsStmt alter_table_space_options_stmt = 158 [json_name="AlterTableSpaceOptionsStmt"]; + AlterTableMoveAllStmt alter_table_move_all_stmt = 159 [json_name="AlterTableMoveAllStmt"]; + CreateExtensionStmt create_extension_stmt = 160 [json_name="CreateExtensionStmt"]; + AlterExtensionStmt alter_extension_stmt = 161 [json_name="AlterExtensionStmt"]; + AlterExtensionContentsStmt alter_extension_contents_stmt = 162 [json_name="AlterExtensionContentsStmt"]; + CreateFdwStmt create_fdw_stmt = 163 [json_name="CreateFdwStmt"]; + AlterFdwStmt alter_fdw_stmt = 164 [json_name="AlterFdwStmt"]; + CreateForeignServerStmt create_foreign_server_stmt = 165 [json_name="CreateForeignServerStmt"]; + AlterForeignServerStmt alter_foreign_server_stmt = 166 [json_name="AlterForeignServerStmt"]; + CreateForeignTableStmt create_foreign_table_stmt = 167 [json_name="CreateForeignTableStmt"]; + CreateUserMappingStmt create_user_mapping_stmt = 168 [json_name="CreateUserMappingStmt"]; + AlterUserMappingStmt alter_user_mapping_stmt = 169 [json_name="AlterUserMappingStmt"]; + DropUserMappingStmt drop_user_mapping_stmt = 170 [json_name="DropUserMappingStmt"]; + ImportForeignSchemaStmt import_foreign_schema_stmt = 171 [json_name="ImportForeignSchemaStmt"]; + CreatePolicyStmt create_policy_stmt = 172 [json_name="CreatePolicyStmt"]; + AlterPolicyStmt alter_policy_stmt = 173 [json_name="AlterPolicyStmt"]; + CreateAmStmt create_am_stmt = 174 [json_name="CreateAmStmt"]; + CreateTrigStmt create_trig_stmt = 175 [json_name="CreateTrigStmt"]; + CreateEventTrigStmt create_event_trig_stmt = 176 [json_name="CreateEventTrigStmt"]; + AlterEventTrigStmt alter_event_trig_stmt = 177 [json_name="AlterEventTrigStmt"]; + CreatePLangStmt create_plang_stmt = 178 [json_name="CreatePLangStmt"]; + CreateRoleStmt create_role_stmt = 179 [json_name="CreateRoleStmt"]; + AlterRoleStmt alter_role_stmt = 180 [json_name="AlterRoleStmt"]; + AlterRoleSetStmt alter_role_set_stmt = 181 [json_name="AlterRoleSetStmt"]; + DropRoleStmt drop_role_stmt = 182 [json_name="DropRoleStmt"]; + CreateSeqStmt create_seq_stmt = 183 [json_name="CreateSeqStmt"]; + AlterSeqStmt alter_seq_stmt = 184 [json_name="AlterSeqStmt"]; + DefineStmt define_stmt = 185 [json_name="DefineStmt"]; + CreateDomainStmt create_domain_stmt = 186 [json_name="CreateDomainStmt"]; + CreateOpClassStmt create_op_class_stmt = 187 [json_name="CreateOpClassStmt"]; + CreateOpClassItem create_op_class_item = 188 [json_name="CreateOpClassItem"]; + CreateOpFamilyStmt create_op_family_stmt = 189 [json_name="CreateOpFamilyStmt"]; + AlterOpFamilyStmt alter_op_family_stmt = 190 [json_name="AlterOpFamilyStmt"]; + DropStmt drop_stmt = 191 [json_name="DropStmt"]; + TruncateStmt truncate_stmt = 192 [json_name="TruncateStmt"]; + CommentStmt comment_stmt = 193 [json_name="CommentStmt"]; + SecLabelStmt sec_label_stmt = 194 [json_name="SecLabelStmt"]; + DeclareCursorStmt declare_cursor_stmt = 195 [json_name="DeclareCursorStmt"]; + ClosePortalStmt close_portal_stmt = 196 [json_name="ClosePortalStmt"]; + FetchStmt fetch_stmt = 197 [json_name="FetchStmt"]; + IndexStmt index_stmt = 198 [json_name="IndexStmt"]; + CreateStatsStmt create_stats_stmt = 199 [json_name="CreateStatsStmt"]; + StatsElem stats_elem = 200 [json_name="StatsElem"]; + AlterStatsStmt alter_stats_stmt = 201 [json_name="AlterStatsStmt"]; + CreateFunctionStmt create_function_stmt = 202 [json_name="CreateFunctionStmt"]; + FunctionParameter function_parameter = 203 [json_name="FunctionParameter"]; + AlterFunctionStmt alter_function_stmt = 204 [json_name="AlterFunctionStmt"]; + DoStmt do_stmt = 205 [json_name="DoStmt"]; + InlineCodeBlock inline_code_block = 206 [json_name="InlineCodeBlock"]; + CallStmt call_stmt = 207 [json_name="CallStmt"]; + CallContext call_context = 208 [json_name="CallContext"]; + RenameStmt rename_stmt = 209 [json_name="RenameStmt"]; + AlterObjectDependsStmt alter_object_depends_stmt = 210 [json_name="AlterObjectDependsStmt"]; + AlterObjectSchemaStmt alter_object_schema_stmt = 211 [json_name="AlterObjectSchemaStmt"]; + AlterOwnerStmt alter_owner_stmt = 212 [json_name="AlterOwnerStmt"]; + AlterOperatorStmt alter_operator_stmt = 213 [json_name="AlterOperatorStmt"]; + AlterTypeStmt alter_type_stmt = 214 [json_name="AlterTypeStmt"]; + RuleStmt rule_stmt = 215 [json_name="RuleStmt"]; + NotifyStmt notify_stmt = 216 [json_name="NotifyStmt"]; + ListenStmt listen_stmt = 217 [json_name="ListenStmt"]; + UnlistenStmt unlisten_stmt = 218 [json_name="UnlistenStmt"]; + TransactionStmt transaction_stmt = 219 [json_name="TransactionStmt"]; + CompositeTypeStmt composite_type_stmt = 220 [json_name="CompositeTypeStmt"]; + CreateEnumStmt create_enum_stmt = 221 [json_name="CreateEnumStmt"]; + CreateRangeStmt create_range_stmt = 222 [json_name="CreateRangeStmt"]; + AlterEnumStmt alter_enum_stmt = 223 [json_name="AlterEnumStmt"]; + ViewStmt view_stmt = 224 [json_name="ViewStmt"]; + LoadStmt load_stmt = 225 [json_name="LoadStmt"]; + CreatedbStmt createdb_stmt = 226 [json_name="CreatedbStmt"]; + AlterDatabaseStmt alter_database_stmt = 227 [json_name="AlterDatabaseStmt"]; + AlterDatabaseRefreshCollStmt alter_database_refresh_coll_stmt = 228 [json_name="AlterDatabaseRefreshCollStmt"]; + AlterDatabaseSetStmt alter_database_set_stmt = 229 [json_name="AlterDatabaseSetStmt"]; + DropdbStmt dropdb_stmt = 230 [json_name="DropdbStmt"]; + AlterSystemStmt alter_system_stmt = 231 [json_name="AlterSystemStmt"]; + ClusterStmt cluster_stmt = 232 [json_name="ClusterStmt"]; + VacuumStmt vacuum_stmt = 233 [json_name="VacuumStmt"]; + VacuumRelation vacuum_relation = 234 [json_name="VacuumRelation"]; + ExplainStmt explain_stmt = 235 [json_name="ExplainStmt"]; + CreateTableAsStmt create_table_as_stmt = 236 [json_name="CreateTableAsStmt"]; + RefreshMatViewStmt refresh_mat_view_stmt = 237 [json_name="RefreshMatViewStmt"]; + CheckPointStmt check_point_stmt = 238 [json_name="CheckPointStmt"]; + DiscardStmt discard_stmt = 239 [json_name="DiscardStmt"]; + LockStmt lock_stmt = 240 [json_name="LockStmt"]; + ConstraintsSetStmt constraints_set_stmt = 241 [json_name="ConstraintsSetStmt"]; + ReindexStmt reindex_stmt = 242 [json_name="ReindexStmt"]; + CreateConversionStmt create_conversion_stmt = 243 [json_name="CreateConversionStmt"]; + CreateCastStmt create_cast_stmt = 244 [json_name="CreateCastStmt"]; + CreateTransformStmt create_transform_stmt = 245 [json_name="CreateTransformStmt"]; + PrepareStmt prepare_stmt = 246 [json_name="PrepareStmt"]; + ExecuteStmt execute_stmt = 247 [json_name="ExecuteStmt"]; + DeallocateStmt deallocate_stmt = 248 [json_name="DeallocateStmt"]; + DropOwnedStmt drop_owned_stmt = 249 [json_name="DropOwnedStmt"]; + ReassignOwnedStmt reassign_owned_stmt = 250 [json_name="ReassignOwnedStmt"]; + AlterTSDictionaryStmt alter_tsdictionary_stmt = 251 [json_name="AlterTSDictionaryStmt"]; + AlterTSConfigurationStmt alter_tsconfiguration_stmt = 252 [json_name="AlterTSConfigurationStmt"]; + PublicationTable publication_table = 253 [json_name="PublicationTable"]; + PublicationObjSpec publication_obj_spec = 254 [json_name="PublicationObjSpec"]; + CreatePublicationStmt create_publication_stmt = 255 [json_name="CreatePublicationStmt"]; + AlterPublicationStmt alter_publication_stmt = 256 [json_name="AlterPublicationStmt"]; + CreateSubscriptionStmt create_subscription_stmt = 257 [json_name="CreateSubscriptionStmt"]; + AlterSubscriptionStmt alter_subscription_stmt = 258 [json_name="AlterSubscriptionStmt"]; + DropSubscriptionStmt drop_subscription_stmt = 259 [json_name="DropSubscriptionStmt"]; + Integer integer = 260 [json_name="Integer"]; + Float float = 261 [json_name="Float"]; + Boolean boolean = 262 [json_name="Boolean"]; + String string = 263 [json_name="String"]; + BitString bit_string = 264 [json_name="BitString"]; + List list = 265 [json_name="List"]; + IntList int_list = 266 [json_name="IntList"]; + OidList oid_list = 267 [json_name="OidList"]; + A_Const a_const = 268 [json_name="A_Const"]; + } +} + +message Integer +{ + int32 ival = 1; /* machine integer */ +} + +message Float +{ + string fval = 1; /* string */ +} + +message Boolean +{ + bool boolval = 1; +} + +message String +{ + string sval = 1; /* string */ +} + +message BitString +{ + string bsval = 1; /* string */ +} + +message List +{ + repeated Node items = 1; +} + +message OidList +{ + repeated Node items = 1; +} + +message IntList +{ + repeated Node items = 1; +} + +message A_Const +{ + oneof val { + Integer ival = 1; + Float fval = 2; + Boolean boolval = 3; + String sval = 4; + BitString bsval = 5; + } + bool isnull = 10; + int32 location = 11; +} + +message Alias +{ + string aliasname = 1 [json_name="aliasname"]; + repeated Node colnames = 2 [json_name="colnames"]; +} + +message RangeVar +{ + string catalogname = 1 [json_name="catalogname"]; + string schemaname = 2 [json_name="schemaname"]; + string relname = 3 [json_name="relname"]; + bool inh = 4 [json_name="inh"]; + string relpersistence = 5 [json_name="relpersistence"]; + Alias alias = 6 [json_name="alias"]; + int32 location = 7 [json_name="location"]; +} + +message TableFunc +{ + TableFuncType functype = 1 [json_name="functype"]; + repeated Node ns_uris = 2 [json_name="ns_uris"]; + repeated Node ns_names = 3 [json_name="ns_names"]; + Node docexpr = 4 [json_name="docexpr"]; + Node rowexpr = 5 [json_name="rowexpr"]; + repeated Node colnames = 6 [json_name="colnames"]; + repeated Node coltypes = 7 [json_name="coltypes"]; + repeated Node coltypmods = 8 [json_name="coltypmods"]; + repeated Node colcollations = 9 [json_name="colcollations"]; + repeated Node colexprs = 10 [json_name="colexprs"]; + repeated Node coldefexprs = 11 [json_name="coldefexprs"]; + repeated Node colvalexprs = 12 [json_name="colvalexprs"]; + repeated Node passingvalexprs = 13 [json_name="passingvalexprs"]; + repeated uint64 notnulls = 14 [json_name="notnulls"]; + Node plan = 15 [json_name="plan"]; + int32 ordinalitycol = 16 [json_name="ordinalitycol"]; + int32 location = 17 [json_name="location"]; +} + +message IntoClause +{ + RangeVar rel = 1 [json_name="rel"]; + repeated Node col_names = 2 [json_name="colNames"]; + string access_method = 3 [json_name="accessMethod"]; + repeated Node options = 4 [json_name="options"]; + OnCommitAction on_commit = 5 [json_name="onCommit"]; + string table_space_name = 6 [json_name="tableSpaceName"]; + Node view_query = 7 [json_name="viewQuery"]; + bool skip_data = 8 [json_name="skipData"]; +} + +message Var +{ + Node xpr = 1 [json_name="xpr"]; + int32 varno = 2 [json_name="varno"]; + int32 varattno = 3 [json_name="varattno"]; + uint32 vartype = 4 [json_name="vartype"]; + int32 vartypmod = 5 [json_name="vartypmod"]; + uint32 varcollid = 6 [json_name="varcollid"]; + repeated uint64 varnullingrels = 7 [json_name="varnullingrels"]; + uint32 varlevelsup = 8 [json_name="varlevelsup"]; + int32 location = 9 [json_name="location"]; +} + +message Param +{ + Node xpr = 1 [json_name="xpr"]; + ParamKind paramkind = 2 [json_name="paramkind"]; + int32 paramid = 3 [json_name="paramid"]; + uint32 paramtype = 4 [json_name="paramtype"]; + int32 paramtypmod = 5 [json_name="paramtypmod"]; + uint32 paramcollid = 6 [json_name="paramcollid"]; + int32 location = 7 [json_name="location"]; +} + +message Aggref +{ + Node xpr = 1 [json_name="xpr"]; + uint32 aggfnoid = 2 [json_name="aggfnoid"]; + uint32 aggtype = 3 [json_name="aggtype"]; + uint32 aggcollid = 4 [json_name="aggcollid"]; + uint32 inputcollid = 5 [json_name="inputcollid"]; + repeated Node aggargtypes = 6 [json_name="aggargtypes"]; + repeated Node aggdirectargs = 7 [json_name="aggdirectargs"]; + repeated Node args = 8 [json_name="args"]; + repeated Node aggorder = 9 [json_name="aggorder"]; + repeated Node aggdistinct = 10 [json_name="aggdistinct"]; + Node aggfilter = 11 [json_name="aggfilter"]; + bool aggstar = 12 [json_name="aggstar"]; + bool aggvariadic = 13 [json_name="aggvariadic"]; + string aggkind = 14 [json_name="aggkind"]; + uint32 agglevelsup = 15 [json_name="agglevelsup"]; + AggSplit aggsplit = 16 [json_name="aggsplit"]; + int32 aggno = 17 [json_name="aggno"]; + int32 aggtransno = 18 [json_name="aggtransno"]; + int32 location = 19 [json_name="location"]; +} + +message GroupingFunc +{ + Node xpr = 1 [json_name="xpr"]; + repeated Node args = 2 [json_name="args"]; + repeated Node refs = 3 [json_name="refs"]; + uint32 agglevelsup = 4 [json_name="agglevelsup"]; + int32 location = 5 [json_name="location"]; +} + +message WindowFunc +{ + Node xpr = 1 [json_name="xpr"]; + uint32 winfnoid = 2 [json_name="winfnoid"]; + uint32 wintype = 3 [json_name="wintype"]; + uint32 wincollid = 4 [json_name="wincollid"]; + uint32 inputcollid = 5 [json_name="inputcollid"]; + repeated Node args = 6 [json_name="args"]; + Node aggfilter = 7 [json_name="aggfilter"]; + repeated Node run_condition = 8 [json_name="runCondition"]; + uint32 winref = 9 [json_name="winref"]; + bool winstar = 10 [json_name="winstar"]; + bool winagg = 11 [json_name="winagg"]; + int32 location = 12 [json_name="location"]; +} + +message WindowFuncRunCondition +{ + Node xpr = 1 [json_name="xpr"]; + uint32 opno = 2 [json_name="opno"]; + uint32 inputcollid = 3 [json_name="inputcollid"]; + bool wfunc_left = 4 [json_name="wfunc_left"]; + Node arg = 5 [json_name="arg"]; +} + +message MergeSupportFunc +{ + Node xpr = 1 [json_name="xpr"]; + uint32 msftype = 2 [json_name="msftype"]; + uint32 msfcollid = 3 [json_name="msfcollid"]; + int32 location = 4 [json_name="location"]; +} + +message SubscriptingRef +{ + Node xpr = 1 [json_name="xpr"]; + uint32 refcontainertype = 2 [json_name="refcontainertype"]; + uint32 refelemtype = 3 [json_name="refelemtype"]; + uint32 refrestype = 4 [json_name="refrestype"]; + int32 reftypmod = 5 [json_name="reftypmod"]; + uint32 refcollid = 6 [json_name="refcollid"]; + repeated Node refupperindexpr = 7 [json_name="refupperindexpr"]; + repeated Node reflowerindexpr = 8 [json_name="reflowerindexpr"]; + Node refexpr = 9 [json_name="refexpr"]; + Node refassgnexpr = 10 [json_name="refassgnexpr"]; +} + +message FuncExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 funcid = 2 [json_name="funcid"]; + uint32 funcresulttype = 3 [json_name="funcresulttype"]; + bool funcretset = 4 [json_name="funcretset"]; + bool funcvariadic = 5 [json_name="funcvariadic"]; + CoercionForm funcformat = 6 [json_name="funcformat"]; + uint32 funccollid = 7 [json_name="funccollid"]; + uint32 inputcollid = 8 [json_name="inputcollid"]; + repeated Node args = 9 [json_name="args"]; + int32 location = 10 [json_name="location"]; +} + +message NamedArgExpr +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + string name = 3 [json_name="name"]; + int32 argnumber = 4 [json_name="argnumber"]; + int32 location = 5 [json_name="location"]; +} + +message OpExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 opno = 2 [json_name="opno"]; + uint32 opresulttype = 3 [json_name="opresulttype"]; + bool opretset = 4 [json_name="opretset"]; + uint32 opcollid = 5 [json_name="opcollid"]; + uint32 inputcollid = 6 [json_name="inputcollid"]; + repeated Node args = 7 [json_name="args"]; + int32 location = 8 [json_name="location"]; +} + +message DistinctExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 opno = 2 [json_name="opno"]; + uint32 opresulttype = 3 [json_name="opresulttype"]; + bool opretset = 4 [json_name="opretset"]; + uint32 opcollid = 5 [json_name="opcollid"]; + uint32 inputcollid = 6 [json_name="inputcollid"]; + repeated Node args = 7 [json_name="args"]; + int32 location = 8 [json_name="location"]; +} + +message NullIfExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 opno = 2 [json_name="opno"]; + uint32 opresulttype = 3 [json_name="opresulttype"]; + bool opretset = 4 [json_name="opretset"]; + uint32 opcollid = 5 [json_name="opcollid"]; + uint32 inputcollid = 6 [json_name="inputcollid"]; + repeated Node args = 7 [json_name="args"]; + int32 location = 8 [json_name="location"]; +} + +message ScalarArrayOpExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 opno = 2 [json_name="opno"]; + bool use_or = 3 [json_name="useOr"]; + uint32 inputcollid = 4 [json_name="inputcollid"]; + repeated Node args = 5 [json_name="args"]; + int32 location = 6 [json_name="location"]; +} + +message BoolExpr +{ + Node xpr = 1 [json_name="xpr"]; + BoolExprType boolop = 2 [json_name="boolop"]; + repeated Node args = 3 [json_name="args"]; + int32 location = 4 [json_name="location"]; +} + +message SubLink +{ + Node xpr = 1 [json_name="xpr"]; + SubLinkType sub_link_type = 2 [json_name="subLinkType"]; + int32 sub_link_id = 3 [json_name="subLinkId"]; + Node testexpr = 4 [json_name="testexpr"]; + repeated Node oper_name = 5 [json_name="operName"]; + Node subselect = 6 [json_name="subselect"]; + int32 location = 7 [json_name="location"]; +} + +message SubPlan +{ + Node xpr = 1 [json_name="xpr"]; + SubLinkType sub_link_type = 2 [json_name="subLinkType"]; + Node testexpr = 3 [json_name="testexpr"]; + repeated Node param_ids = 4 [json_name="paramIds"]; + int32 plan_id = 5 [json_name="plan_id"]; + string plan_name = 6 [json_name="plan_name"]; + uint32 first_col_type = 7 [json_name="firstColType"]; + int32 first_col_typmod = 8 [json_name="firstColTypmod"]; + uint32 first_col_collation = 9 [json_name="firstColCollation"]; + bool use_hash_table = 10 [json_name="useHashTable"]; + bool unknown_eq_false = 11 [json_name="unknownEqFalse"]; + bool parallel_safe = 12 [json_name="parallel_safe"]; + repeated Node set_param = 13 [json_name="setParam"]; + repeated Node par_param = 14 [json_name="parParam"]; + repeated Node args = 15 [json_name="args"]; + double startup_cost = 16 [json_name="startup_cost"]; + double per_call_cost = 17 [json_name="per_call_cost"]; +} + +message AlternativeSubPlan +{ + Node xpr = 1 [json_name="xpr"]; + repeated Node subplans = 2 [json_name="subplans"]; +} + +message FieldSelect +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + int32 fieldnum = 3 [json_name="fieldnum"]; + uint32 resulttype = 4 [json_name="resulttype"]; + int32 resulttypmod = 5 [json_name="resulttypmod"]; + uint32 resultcollid = 6 [json_name="resultcollid"]; +} + +message FieldStore +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + repeated Node newvals = 3 [json_name="newvals"]; + repeated Node fieldnums = 4 [json_name="fieldnums"]; + uint32 resulttype = 5 [json_name="resulttype"]; +} + +message RelabelType +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + uint32 resulttype = 3 [json_name="resulttype"]; + int32 resulttypmod = 4 [json_name="resulttypmod"]; + uint32 resultcollid = 5 [json_name="resultcollid"]; + CoercionForm relabelformat = 6 [json_name="relabelformat"]; + int32 location = 7 [json_name="location"]; +} + +message CoerceViaIO +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + uint32 resulttype = 3 [json_name="resulttype"]; + uint32 resultcollid = 4 [json_name="resultcollid"]; + CoercionForm coerceformat = 5 [json_name="coerceformat"]; + int32 location = 6 [json_name="location"]; +} + +message ArrayCoerceExpr +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + Node elemexpr = 3 [json_name="elemexpr"]; + uint32 resulttype = 4 [json_name="resulttype"]; + int32 resulttypmod = 5 [json_name="resulttypmod"]; + uint32 resultcollid = 6 [json_name="resultcollid"]; + CoercionForm coerceformat = 7 [json_name="coerceformat"]; + int32 location = 8 [json_name="location"]; +} + +message ConvertRowtypeExpr +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + uint32 resulttype = 3 [json_name="resulttype"]; + CoercionForm convertformat = 4 [json_name="convertformat"]; + int32 location = 5 [json_name="location"]; +} + +message CollateExpr +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + uint32 coll_oid = 3 [json_name="collOid"]; + int32 location = 4 [json_name="location"]; +} + +message CaseExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 casetype = 2 [json_name="casetype"]; + uint32 casecollid = 3 [json_name="casecollid"]; + Node arg = 4 [json_name="arg"]; + repeated Node args = 5 [json_name="args"]; + Node defresult = 6 [json_name="defresult"]; + int32 location = 7 [json_name="location"]; +} + +message CaseWhen +{ + Node xpr = 1 [json_name="xpr"]; + Node expr = 2 [json_name="expr"]; + Node result = 3 [json_name="result"]; + int32 location = 4 [json_name="location"]; +} + +message CaseTestExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 type_id = 2 [json_name="typeId"]; + int32 type_mod = 3 [json_name="typeMod"]; + uint32 collation = 4 [json_name="collation"]; +} + +message ArrayExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 array_typeid = 2 [json_name="array_typeid"]; + uint32 array_collid = 3 [json_name="array_collid"]; + uint32 element_typeid = 4 [json_name="element_typeid"]; + repeated Node elements = 5 [json_name="elements"]; + bool multidims = 6 [json_name="multidims"]; + int32 location = 7 [json_name="location"]; +} + +message RowExpr +{ + Node xpr = 1 [json_name="xpr"]; + repeated Node args = 2 [json_name="args"]; + uint32 row_typeid = 3 [json_name="row_typeid"]; + CoercionForm row_format = 4 [json_name="row_format"]; + repeated Node colnames = 5 [json_name="colnames"]; + int32 location = 6 [json_name="location"]; +} + +message RowCompareExpr +{ + Node xpr = 1 [json_name="xpr"]; + RowCompareType rctype = 2 [json_name="rctype"]; + repeated Node opnos = 3 [json_name="opnos"]; + repeated Node opfamilies = 4 [json_name="opfamilies"]; + repeated Node inputcollids = 5 [json_name="inputcollids"]; + repeated Node largs = 6 [json_name="largs"]; + repeated Node rargs = 7 [json_name="rargs"]; +} + +message CoalesceExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 coalescetype = 2 [json_name="coalescetype"]; + uint32 coalescecollid = 3 [json_name="coalescecollid"]; + repeated Node args = 4 [json_name="args"]; + int32 location = 5 [json_name="location"]; +} + +message MinMaxExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 minmaxtype = 2 [json_name="minmaxtype"]; + uint32 minmaxcollid = 3 [json_name="minmaxcollid"]; + uint32 inputcollid = 4 [json_name="inputcollid"]; + MinMaxOp op = 5 [json_name="op"]; + repeated Node args = 6 [json_name="args"]; + int32 location = 7 [json_name="location"]; +} + +message SQLValueFunction +{ + Node xpr = 1 [json_name="xpr"]; + SQLValueFunctionOp op = 2 [json_name="op"]; + uint32 type = 3 [json_name="type"]; + int32 typmod = 4 [json_name="typmod"]; + int32 location = 5 [json_name="location"]; +} + +message XmlExpr +{ + Node xpr = 1 [json_name="xpr"]; + XmlExprOp op = 2 [json_name="op"]; + string name = 3 [json_name="name"]; + repeated Node named_args = 4 [json_name="named_args"]; + repeated Node arg_names = 5 [json_name="arg_names"]; + repeated Node args = 6 [json_name="args"]; + XmlOptionType xmloption = 7 [json_name="xmloption"]; + bool indent = 8 [json_name="indent"]; + uint32 type = 9 [json_name="type"]; + int32 typmod = 10 [json_name="typmod"]; + int32 location = 11 [json_name="location"]; +} + +message JsonFormat +{ + JsonFormatType format_type = 1 [json_name="format_type"]; + JsonEncoding encoding = 2 [json_name="encoding"]; + int32 location = 3 [json_name="location"]; +} + +message JsonReturning +{ + JsonFormat format = 1 [json_name="format"]; + uint32 typid = 2 [json_name="typid"]; + int32 typmod = 3 [json_name="typmod"]; +} + +message JsonValueExpr +{ + Node raw_expr = 1 [json_name="raw_expr"]; + Node formatted_expr = 2 [json_name="formatted_expr"]; + JsonFormat format = 3 [json_name="format"]; +} + +message JsonConstructorExpr +{ + Node xpr = 1 [json_name="xpr"]; + JsonConstructorType type = 2 [json_name="type"]; + repeated Node args = 3 [json_name="args"]; + Node func = 4 [json_name="func"]; + Node coercion = 5 [json_name="coercion"]; + JsonReturning returning = 6 [json_name="returning"]; + bool absent_on_null = 7 [json_name="absent_on_null"]; + bool unique = 8 [json_name="unique"]; + int32 location = 9 [json_name="location"]; +} + +message JsonIsPredicate +{ + Node expr = 1 [json_name="expr"]; + JsonFormat format = 2 [json_name="format"]; + JsonValueType item_type = 3 [json_name="item_type"]; + bool unique_keys = 4 [json_name="unique_keys"]; + int32 location = 5 [json_name="location"]; +} + +message JsonBehavior +{ + JsonBehaviorType btype = 1 [json_name="btype"]; + Node expr = 2 [json_name="expr"]; + bool coerce = 3 [json_name="coerce"]; + int32 location = 4 [json_name="location"]; +} + +message JsonExpr +{ + Node xpr = 1 [json_name="xpr"]; + JsonExprOp op = 2 [json_name="op"]; + string column_name = 3 [json_name="column_name"]; + Node formatted_expr = 4 [json_name="formatted_expr"]; + JsonFormat format = 5 [json_name="format"]; + Node path_spec = 6 [json_name="path_spec"]; + JsonReturning returning = 7 [json_name="returning"]; + repeated Node passing_names = 8 [json_name="passing_names"]; + repeated Node passing_values = 9 [json_name="passing_values"]; + JsonBehavior on_empty = 10 [json_name="on_empty"]; + JsonBehavior on_error = 11 [json_name="on_error"]; + bool use_io_coercion = 12 [json_name="use_io_coercion"]; + bool use_json_coercion = 13 [json_name="use_json_coercion"]; + JsonWrapper wrapper = 14 [json_name="wrapper"]; + bool omit_quotes = 15 [json_name="omit_quotes"]; + uint32 collation = 16 [json_name="collation"]; + int32 location = 17 [json_name="location"]; +} + +message JsonTablePath +{ + string name = 1 [json_name="name"]; +} + +message JsonTablePathScan +{ + Node plan = 1 [json_name="plan"]; + JsonTablePath path = 2 [json_name="path"]; + bool error_on_error = 3 [json_name="errorOnError"]; + Node child = 4 [json_name="child"]; + int32 col_min = 5 [json_name="colMin"]; + int32 col_max = 6 [json_name="colMax"]; +} + +message JsonTableSiblingJoin +{ + Node plan = 1 [json_name="plan"]; + Node lplan = 2 [json_name="lplan"]; + Node rplan = 3 [json_name="rplan"]; +} + +message NullTest +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + NullTestType nulltesttype = 3 [json_name="nulltesttype"]; + bool argisrow = 4 [json_name="argisrow"]; + int32 location = 5 [json_name="location"]; +} + +message BooleanTest +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + BoolTestType booltesttype = 3 [json_name="booltesttype"]; + int32 location = 4 [json_name="location"]; +} + +message MergeAction +{ + MergeMatchKind match_kind = 1 [json_name="matchKind"]; + CmdType command_type = 2 [json_name="commandType"]; + OverridingKind override = 3 [json_name="override"]; + Node qual = 4 [json_name="qual"]; + repeated Node target_list = 5 [json_name="targetList"]; + repeated Node update_colnos = 6 [json_name="updateColnos"]; +} + +message CoerceToDomain +{ + Node xpr = 1 [json_name="xpr"]; + Node arg = 2 [json_name="arg"]; + uint32 resulttype = 3 [json_name="resulttype"]; + int32 resulttypmod = 4 [json_name="resulttypmod"]; + uint32 resultcollid = 5 [json_name="resultcollid"]; + CoercionForm coercionformat = 6 [json_name="coercionformat"]; + int32 location = 7 [json_name="location"]; +} + +message CoerceToDomainValue +{ + Node xpr = 1 [json_name="xpr"]; + uint32 type_id = 2 [json_name="typeId"]; + int32 type_mod = 3 [json_name="typeMod"]; + uint32 collation = 4 [json_name="collation"]; + int32 location = 5 [json_name="location"]; +} + +message SetToDefault +{ + Node xpr = 1 [json_name="xpr"]; + uint32 type_id = 2 [json_name="typeId"]; + int32 type_mod = 3 [json_name="typeMod"]; + uint32 collation = 4 [json_name="collation"]; + int32 location = 5 [json_name="location"]; +} + +message CurrentOfExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 cvarno = 2 [json_name="cvarno"]; + string cursor_name = 3 [json_name="cursor_name"]; + int32 cursor_param = 4 [json_name="cursor_param"]; +} + +message NextValueExpr +{ + Node xpr = 1 [json_name="xpr"]; + uint32 seqid = 2 [json_name="seqid"]; + uint32 type_id = 3 [json_name="typeId"]; +} + +message InferenceElem +{ + Node xpr = 1 [json_name="xpr"]; + Node expr = 2 [json_name="expr"]; + uint32 infercollid = 3 [json_name="infercollid"]; + uint32 inferopclass = 4 [json_name="inferopclass"]; +} + +message TargetEntry +{ + Node xpr = 1 [json_name="xpr"]; + Node expr = 2 [json_name="expr"]; + int32 resno = 3 [json_name="resno"]; + string resname = 4 [json_name="resname"]; + uint32 ressortgroupref = 5 [json_name="ressortgroupref"]; + uint32 resorigtbl = 6 [json_name="resorigtbl"]; + int32 resorigcol = 7 [json_name="resorigcol"]; + bool resjunk = 8 [json_name="resjunk"]; +} + +message RangeTblRef +{ + int32 rtindex = 1 [json_name="rtindex"]; +} + +message JoinExpr +{ + JoinType jointype = 1 [json_name="jointype"]; + bool is_natural = 2 [json_name="isNatural"]; + Node larg = 3 [json_name="larg"]; + Node rarg = 4 [json_name="rarg"]; + repeated Node using_clause = 5 [json_name="usingClause"]; + Alias join_using_alias = 6 [json_name="join_using_alias"]; + Node quals = 7 [json_name="quals"]; + Alias alias = 8 [json_name="alias"]; + int32 rtindex = 9 [json_name="rtindex"]; +} + +message FromExpr +{ + repeated Node fromlist = 1 [json_name="fromlist"]; + Node quals = 2 [json_name="quals"]; +} + +message OnConflictExpr +{ + OnConflictAction action = 1 [json_name="action"]; + repeated Node arbiter_elems = 2 [json_name="arbiterElems"]; + Node arbiter_where = 3 [json_name="arbiterWhere"]; + uint32 constraint = 4 [json_name="constraint"]; + repeated Node on_conflict_set = 5 [json_name="onConflictSet"]; + Node on_conflict_where = 6 [json_name="onConflictWhere"]; + int32 excl_rel_index = 7 [json_name="exclRelIndex"]; + repeated Node excl_rel_tlist = 8 [json_name="exclRelTlist"]; +} + +message Query +{ + CmdType command_type = 1 [json_name="commandType"]; + QuerySource query_source = 2 [json_name="querySource"]; + bool can_set_tag = 3 [json_name="canSetTag"]; + Node utility_stmt = 4 [json_name="utilityStmt"]; + int32 result_relation = 5 [json_name="resultRelation"]; + bool has_aggs = 6 [json_name="hasAggs"]; + bool has_window_funcs = 7 [json_name="hasWindowFuncs"]; + bool has_target_srfs = 8 [json_name="hasTargetSRFs"]; + bool has_sub_links = 9 [json_name="hasSubLinks"]; + bool has_distinct_on = 10 [json_name="hasDistinctOn"]; + bool has_recursive = 11 [json_name="hasRecursive"]; + bool has_modifying_cte = 12 [json_name="hasModifyingCTE"]; + bool has_for_update = 13 [json_name="hasForUpdate"]; + bool has_row_security = 14 [json_name="hasRowSecurity"]; + bool is_return = 15 [json_name="isReturn"]; + repeated Node cte_list = 16 [json_name="cteList"]; + repeated Node rtable = 17 [json_name="rtable"]; + repeated Node rteperminfos = 18 [json_name="rteperminfos"]; + FromExpr jointree = 19 [json_name="jointree"]; + repeated Node merge_action_list = 20 [json_name="mergeActionList"]; + int32 merge_target_relation = 21 [json_name="mergeTargetRelation"]; + Node merge_join_condition = 22 [json_name="mergeJoinCondition"]; + repeated Node target_list = 23 [json_name="targetList"]; + OverridingKind override = 24 [json_name="override"]; + OnConflictExpr on_conflict = 25 [json_name="onConflict"]; + repeated Node returning_list = 26 [json_name="returningList"]; + repeated Node group_clause = 27 [json_name="groupClause"]; + bool group_distinct = 28 [json_name="groupDistinct"]; + repeated Node grouping_sets = 29 [json_name="groupingSets"]; + Node having_qual = 30 [json_name="havingQual"]; + repeated Node window_clause = 31 [json_name="windowClause"]; + repeated Node distinct_clause = 32 [json_name="distinctClause"]; + repeated Node sort_clause = 33 [json_name="sortClause"]; + Node limit_offset = 34 [json_name="limitOffset"]; + Node limit_count = 35 [json_name="limitCount"]; + LimitOption limit_option = 36 [json_name="limitOption"]; + repeated Node row_marks = 37 [json_name="rowMarks"]; + Node set_operations = 38 [json_name="setOperations"]; + repeated Node constraint_deps = 39 [json_name="constraintDeps"]; + repeated Node with_check_options = 40 [json_name="withCheckOptions"]; + int32 stmt_location = 41 [json_name="stmt_location"]; + int32 stmt_len = 42 [json_name="stmt_len"]; +} + +message TypeName +{ + repeated Node names = 1 [json_name="names"]; + uint32 type_oid = 2 [json_name="typeOid"]; + bool setof = 3 [json_name="setof"]; + bool pct_type = 4 [json_name="pct_type"]; + repeated Node typmods = 5 [json_name="typmods"]; + int32 typemod = 6 [json_name="typemod"]; + repeated Node array_bounds = 7 [json_name="arrayBounds"]; + int32 location = 8 [json_name="location"]; +} + +message ColumnRef +{ + repeated Node fields = 1 [json_name="fields"]; + int32 location = 2 [json_name="location"]; +} + +message ParamRef +{ + int32 number = 1 [json_name="number"]; + int32 location = 2 [json_name="location"]; +} + +message A_Expr +{ + A_Expr_Kind kind = 1 [json_name="kind"]; + repeated Node name = 2 [json_name="name"]; + Node lexpr = 3 [json_name="lexpr"]; + Node rexpr = 4 [json_name="rexpr"]; + int32 location = 5 [json_name="location"]; +} + +message TypeCast +{ + Node arg = 1 [json_name="arg"]; + TypeName type_name = 2 [json_name="typeName"]; + int32 location = 3 [json_name="location"]; +} + +message CollateClause +{ + Node arg = 1 [json_name="arg"]; + repeated Node collname = 2 [json_name="collname"]; + int32 location = 3 [json_name="location"]; +} + +message RoleSpec +{ + RoleSpecType roletype = 1 [json_name="roletype"]; + string rolename = 2 [json_name="rolename"]; + int32 location = 3 [json_name="location"]; +} + +message FuncCall +{ + repeated Node funcname = 1 [json_name="funcname"]; + repeated Node args = 2 [json_name="args"]; + repeated Node agg_order = 3 [json_name="agg_order"]; + Node agg_filter = 4 [json_name="agg_filter"]; + WindowDef over = 5 [json_name="over"]; + bool agg_within_group = 6 [json_name="agg_within_group"]; + bool agg_star = 7 [json_name="agg_star"]; + bool agg_distinct = 8 [json_name="agg_distinct"]; + bool func_variadic = 9 [json_name="func_variadic"]; + CoercionForm funcformat = 10 [json_name="funcformat"]; + int32 location = 11 [json_name="location"]; +} + +message A_Star +{ +} + +message A_Indices +{ + bool is_slice = 1 [json_name="is_slice"]; + Node lidx = 2 [json_name="lidx"]; + Node uidx = 3 [json_name="uidx"]; +} + +message A_Indirection +{ + Node arg = 1 [json_name="arg"]; + repeated Node indirection = 2 [json_name="indirection"]; +} + +message A_ArrayExpr +{ + repeated Node elements = 1 [json_name="elements"]; + int32 location = 2 [json_name="location"]; +} + +message ResTarget +{ + string name = 1 [json_name="name"]; + repeated Node indirection = 2 [json_name="indirection"]; + Node val = 3 [json_name="val"]; + int32 location = 4 [json_name="location"]; +} + +message MultiAssignRef +{ + Node source = 1 [json_name="source"]; + int32 colno = 2 [json_name="colno"]; + int32 ncolumns = 3 [json_name="ncolumns"]; +} + +message SortBy +{ + Node node = 1 [json_name="node"]; + SortByDir sortby_dir = 2 [json_name="sortby_dir"]; + SortByNulls sortby_nulls = 3 [json_name="sortby_nulls"]; + repeated Node use_op = 4 [json_name="useOp"]; + int32 location = 5 [json_name="location"]; +} + +message WindowDef +{ + string name = 1 [json_name="name"]; + string refname = 2 [json_name="refname"]; + repeated Node partition_clause = 3 [json_name="partitionClause"]; + repeated Node order_clause = 4 [json_name="orderClause"]; + int32 frame_options = 5 [json_name="frameOptions"]; + Node start_offset = 6 [json_name="startOffset"]; + Node end_offset = 7 [json_name="endOffset"]; + int32 location = 8 [json_name="location"]; +} + +message RangeSubselect +{ + bool lateral = 1 [json_name="lateral"]; + Node subquery = 2 [json_name="subquery"]; + Alias alias = 3 [json_name="alias"]; +} + +message RangeFunction +{ + bool lateral = 1 [json_name="lateral"]; + bool ordinality = 2 [json_name="ordinality"]; + bool is_rowsfrom = 3 [json_name="is_rowsfrom"]; + repeated Node functions = 4 [json_name="functions"]; + Alias alias = 5 [json_name="alias"]; + repeated Node coldeflist = 6 [json_name="coldeflist"]; +} + +message RangeTableFunc +{ + bool lateral = 1 [json_name="lateral"]; + Node docexpr = 2 [json_name="docexpr"]; + Node rowexpr = 3 [json_name="rowexpr"]; + repeated Node namespaces = 4 [json_name="namespaces"]; + repeated Node columns = 5 [json_name="columns"]; + Alias alias = 6 [json_name="alias"]; + int32 location = 7 [json_name="location"]; +} + +message RangeTableFuncCol +{ + string colname = 1 [json_name="colname"]; + TypeName type_name = 2 [json_name="typeName"]; + bool for_ordinality = 3 [json_name="for_ordinality"]; + bool is_not_null = 4 [json_name="is_not_null"]; + Node colexpr = 5 [json_name="colexpr"]; + Node coldefexpr = 6 [json_name="coldefexpr"]; + int32 location = 7 [json_name="location"]; +} + +message RangeTableSample +{ + Node relation = 1 [json_name="relation"]; + repeated Node method = 2 [json_name="method"]; + repeated Node args = 3 [json_name="args"]; + Node repeatable = 4 [json_name="repeatable"]; + int32 location = 5 [json_name="location"]; +} + +message ColumnDef +{ + string colname = 1 [json_name="colname"]; + TypeName type_name = 2 [json_name="typeName"]; + string compression = 3 [json_name="compression"]; + int32 inhcount = 4 [json_name="inhcount"]; + bool is_local = 5 [json_name="is_local"]; + bool is_not_null = 6 [json_name="is_not_null"]; + bool is_from_type = 7 [json_name="is_from_type"]; + string storage = 8 [json_name="storage"]; + string storage_name = 9 [json_name="storage_name"]; + Node raw_default = 10 [json_name="raw_default"]; + Node cooked_default = 11 [json_name="cooked_default"]; + string identity = 12 [json_name="identity"]; + RangeVar identity_sequence = 13 [json_name="identitySequence"]; + string generated = 14 [json_name="generated"]; + CollateClause coll_clause = 15 [json_name="collClause"]; + uint32 coll_oid = 16 [json_name="collOid"]; + repeated Node constraints = 17 [json_name="constraints"]; + repeated Node fdwoptions = 18 [json_name="fdwoptions"]; + int32 location = 19 [json_name="location"]; +} + +message TableLikeClause +{ + RangeVar relation = 1 [json_name="relation"]; + uint32 options = 2 [json_name="options"]; + uint32 relation_oid = 3 [json_name="relationOid"]; +} + +message IndexElem +{ + string name = 1 [json_name="name"]; + Node expr = 2 [json_name="expr"]; + string indexcolname = 3 [json_name="indexcolname"]; + repeated Node collation = 4 [json_name="collation"]; + repeated Node opclass = 5 [json_name="opclass"]; + repeated Node opclassopts = 6 [json_name="opclassopts"]; + SortByDir ordering = 7 [json_name="ordering"]; + SortByNulls nulls_ordering = 8 [json_name="nulls_ordering"]; +} + +message DefElem +{ + string defnamespace = 1 [json_name="defnamespace"]; + string defname = 2 [json_name="defname"]; + Node arg = 3 [json_name="arg"]; + DefElemAction defaction = 4 [json_name="defaction"]; + int32 location = 5 [json_name="location"]; +} + +message LockingClause +{ + repeated Node locked_rels = 1 [json_name="lockedRels"]; + LockClauseStrength strength = 2 [json_name="strength"]; + LockWaitPolicy wait_policy = 3 [json_name="waitPolicy"]; +} + +message XmlSerialize +{ + XmlOptionType xmloption = 1 [json_name="xmloption"]; + Node expr = 2 [json_name="expr"]; + TypeName type_name = 3 [json_name="typeName"]; + bool indent = 4 [json_name="indent"]; + int32 location = 5 [json_name="location"]; +} + +message PartitionElem +{ + string name = 1 [json_name="name"]; + Node expr = 2 [json_name="expr"]; + repeated Node collation = 3 [json_name="collation"]; + repeated Node opclass = 4 [json_name="opclass"]; + int32 location = 5 [json_name="location"]; +} + +message PartitionSpec +{ + PartitionStrategy strategy = 1 [json_name="strategy"]; + repeated Node part_params = 2 [json_name="partParams"]; + int32 location = 3 [json_name="location"]; +} + +message PartitionBoundSpec +{ + string strategy = 1 [json_name="strategy"]; + bool is_default = 2 [json_name="is_default"]; + int32 modulus = 3 [json_name="modulus"]; + int32 remainder = 4 [json_name="remainder"]; + repeated Node listdatums = 5 [json_name="listdatums"]; + repeated Node lowerdatums = 6 [json_name="lowerdatums"]; + repeated Node upperdatums = 7 [json_name="upperdatums"]; + int32 location = 8 [json_name="location"]; +} + +message PartitionRangeDatum +{ + PartitionRangeDatumKind kind = 1 [json_name="kind"]; + Node value = 2 [json_name="value"]; + int32 location = 3 [json_name="location"]; +} + +message SinglePartitionSpec +{ +} + +message PartitionCmd +{ + RangeVar name = 1 [json_name="name"]; + PartitionBoundSpec bound = 2 [json_name="bound"]; + bool concurrent = 3 [json_name="concurrent"]; +} + +message RangeTblEntry +{ + Alias alias = 1 [json_name="alias"]; + Alias eref = 2 [json_name="eref"]; + RTEKind rtekind = 3 [json_name="rtekind"]; + uint32 relid = 4 [json_name="relid"]; + bool inh = 5 [json_name="inh"]; + string relkind = 6 [json_name="relkind"]; + int32 rellockmode = 7 [json_name="rellockmode"]; + uint32 perminfoindex = 8 [json_name="perminfoindex"]; + TableSampleClause tablesample = 9 [json_name="tablesample"]; + Query subquery = 10 [json_name="subquery"]; + bool security_barrier = 11 [json_name="security_barrier"]; + JoinType jointype = 12 [json_name="jointype"]; + int32 joinmergedcols = 13 [json_name="joinmergedcols"]; + repeated Node joinaliasvars = 14 [json_name="joinaliasvars"]; + repeated Node joinleftcols = 15 [json_name="joinleftcols"]; + repeated Node joinrightcols = 16 [json_name="joinrightcols"]; + Alias join_using_alias = 17 [json_name="join_using_alias"]; + repeated Node functions = 18 [json_name="functions"]; + bool funcordinality = 19 [json_name="funcordinality"]; + TableFunc tablefunc = 20 [json_name="tablefunc"]; + repeated Node values_lists = 21 [json_name="values_lists"]; + string ctename = 22 [json_name="ctename"]; + uint32 ctelevelsup = 23 [json_name="ctelevelsup"]; + bool self_reference = 24 [json_name="self_reference"]; + repeated Node coltypes = 25 [json_name="coltypes"]; + repeated Node coltypmods = 26 [json_name="coltypmods"]; + repeated Node colcollations = 27 [json_name="colcollations"]; + string enrname = 28 [json_name="enrname"]; + double enrtuples = 29 [json_name="enrtuples"]; + bool lateral = 30 [json_name="lateral"]; + bool in_from_cl = 31 [json_name="inFromCl"]; + repeated Node security_quals = 32 [json_name="securityQuals"]; +} + +message RTEPermissionInfo +{ + uint32 relid = 1 [json_name="relid"]; + bool inh = 2 [json_name="inh"]; + uint64 required_perms = 3 [json_name="requiredPerms"]; + uint32 check_as_user = 4 [json_name="checkAsUser"]; + repeated uint64 selected_cols = 5 [json_name="selectedCols"]; + repeated uint64 inserted_cols = 6 [json_name="insertedCols"]; + repeated uint64 updated_cols = 7 [json_name="updatedCols"]; +} + +message RangeTblFunction +{ + Node funcexpr = 1 [json_name="funcexpr"]; + int32 funccolcount = 2 [json_name="funccolcount"]; + repeated Node funccolnames = 3 [json_name="funccolnames"]; + repeated Node funccoltypes = 4 [json_name="funccoltypes"]; + repeated Node funccoltypmods = 5 [json_name="funccoltypmods"]; + repeated Node funccolcollations = 6 [json_name="funccolcollations"]; + repeated uint64 funcparams = 7 [json_name="funcparams"]; +} + +message TableSampleClause +{ + uint32 tsmhandler = 1 [json_name="tsmhandler"]; + repeated Node args = 2 [json_name="args"]; + Node repeatable = 3 [json_name="repeatable"]; +} + +message WithCheckOption +{ + WCOKind kind = 1 [json_name="kind"]; + string relname = 2 [json_name="relname"]; + string polname = 3 [json_name="polname"]; + Node qual = 4 [json_name="qual"]; + bool cascaded = 5 [json_name="cascaded"]; +} + +message SortGroupClause +{ + uint32 tle_sort_group_ref = 1 [json_name="tleSortGroupRef"]; + uint32 eqop = 2 [json_name="eqop"]; + uint32 sortop = 3 [json_name="sortop"]; + bool nulls_first = 4 [json_name="nulls_first"]; + bool hashable = 5 [json_name="hashable"]; +} + +message GroupingSet +{ + GroupingSetKind kind = 1 [json_name="kind"]; + repeated Node content = 2 [json_name="content"]; + int32 location = 3 [json_name="location"]; +} + +message WindowClause +{ + string name = 1 [json_name="name"]; + string refname = 2 [json_name="refname"]; + repeated Node partition_clause = 3 [json_name="partitionClause"]; + repeated Node order_clause = 4 [json_name="orderClause"]; + int32 frame_options = 5 [json_name="frameOptions"]; + Node start_offset = 6 [json_name="startOffset"]; + Node end_offset = 7 [json_name="endOffset"]; + uint32 start_in_range_func = 8 [json_name="startInRangeFunc"]; + uint32 end_in_range_func = 9 [json_name="endInRangeFunc"]; + uint32 in_range_coll = 10 [json_name="inRangeColl"]; + bool in_range_asc = 11 [json_name="inRangeAsc"]; + bool in_range_nulls_first = 12 [json_name="inRangeNullsFirst"]; + uint32 winref = 13 [json_name="winref"]; + bool copied_order = 14 [json_name="copiedOrder"]; +} + +message RowMarkClause +{ + uint32 rti = 1 [json_name="rti"]; + LockClauseStrength strength = 2 [json_name="strength"]; + LockWaitPolicy wait_policy = 3 [json_name="waitPolicy"]; + bool pushed_down = 4 [json_name="pushedDown"]; +} + +message WithClause +{ + repeated Node ctes = 1 [json_name="ctes"]; + bool recursive = 2 [json_name="recursive"]; + int32 location = 3 [json_name="location"]; +} + +message InferClause +{ + repeated Node index_elems = 1 [json_name="indexElems"]; + Node where_clause = 2 [json_name="whereClause"]; + string conname = 3 [json_name="conname"]; + int32 location = 4 [json_name="location"]; +} + +message OnConflictClause +{ + OnConflictAction action = 1 [json_name="action"]; + InferClause infer = 2 [json_name="infer"]; + repeated Node target_list = 3 [json_name="targetList"]; + Node where_clause = 4 [json_name="whereClause"]; + int32 location = 5 [json_name="location"]; +} + +message CTESearchClause +{ + repeated Node search_col_list = 1 [json_name="search_col_list"]; + bool search_breadth_first = 2 [json_name="search_breadth_first"]; + string search_seq_column = 3 [json_name="search_seq_column"]; + int32 location = 4 [json_name="location"]; +} + +message CTECycleClause +{ + repeated Node cycle_col_list = 1 [json_name="cycle_col_list"]; + string cycle_mark_column = 2 [json_name="cycle_mark_column"]; + Node cycle_mark_value = 3 [json_name="cycle_mark_value"]; + Node cycle_mark_default = 4 [json_name="cycle_mark_default"]; + string cycle_path_column = 5 [json_name="cycle_path_column"]; + int32 location = 6 [json_name="location"]; + uint32 cycle_mark_type = 7 [json_name="cycle_mark_type"]; + int32 cycle_mark_typmod = 8 [json_name="cycle_mark_typmod"]; + uint32 cycle_mark_collation = 9 [json_name="cycle_mark_collation"]; + uint32 cycle_mark_neop = 10 [json_name="cycle_mark_neop"]; +} + +message CommonTableExpr +{ + string ctename = 1 [json_name="ctename"]; + repeated Node aliascolnames = 2 [json_name="aliascolnames"]; + CTEMaterialize ctematerialized = 3 [json_name="ctematerialized"]; + Node ctequery = 4 [json_name="ctequery"]; + CTESearchClause search_clause = 5 [json_name="search_clause"]; + CTECycleClause cycle_clause = 6 [json_name="cycle_clause"]; + int32 location = 7 [json_name="location"]; + bool cterecursive = 8 [json_name="cterecursive"]; + int32 cterefcount = 9 [json_name="cterefcount"]; + repeated Node ctecolnames = 10 [json_name="ctecolnames"]; + repeated Node ctecoltypes = 11 [json_name="ctecoltypes"]; + repeated Node ctecoltypmods = 12 [json_name="ctecoltypmods"]; + repeated Node ctecolcollations = 13 [json_name="ctecolcollations"]; +} + +message MergeWhenClause +{ + MergeMatchKind match_kind = 1 [json_name="matchKind"]; + CmdType command_type = 2 [json_name="commandType"]; + OverridingKind override = 3 [json_name="override"]; + Node condition = 4 [json_name="condition"]; + repeated Node target_list = 5 [json_name="targetList"]; + repeated Node values = 6 [json_name="values"]; +} + +message TriggerTransition +{ + string name = 1 [json_name="name"]; + bool is_new = 2 [json_name="isNew"]; + bool is_table = 3 [json_name="isTable"]; +} + +message JsonOutput +{ + TypeName type_name = 1 [json_name="typeName"]; + JsonReturning returning = 2 [json_name="returning"]; +} + +message JsonArgument +{ + JsonValueExpr val = 1 [json_name="val"]; + string name = 2 [json_name="name"]; +} + +message JsonFuncExpr +{ + JsonExprOp op = 1 [json_name="op"]; + string column_name = 2 [json_name="column_name"]; + JsonValueExpr context_item = 3 [json_name="context_item"]; + Node pathspec = 4 [json_name="pathspec"]; + repeated Node passing = 5 [json_name="passing"]; + JsonOutput output = 6 [json_name="output"]; + JsonBehavior on_empty = 7 [json_name="on_empty"]; + JsonBehavior on_error = 8 [json_name="on_error"]; + JsonWrapper wrapper = 9 [json_name="wrapper"]; + JsonQuotes quotes = 10 [json_name="quotes"]; + int32 location = 11 [json_name="location"]; +} + +message JsonTablePathSpec +{ + Node string = 1 [json_name="string"]; + string name = 2 [json_name="name"]; + int32 name_location = 3 [json_name="name_location"]; + int32 location = 4 [json_name="location"]; +} + +message JsonTable +{ + JsonValueExpr context_item = 1 [json_name="context_item"]; + JsonTablePathSpec pathspec = 2 [json_name="pathspec"]; + repeated Node passing = 3 [json_name="passing"]; + repeated Node columns = 4 [json_name="columns"]; + JsonBehavior on_error = 5 [json_name="on_error"]; + Alias alias = 6 [json_name="alias"]; + bool lateral = 7 [json_name="lateral"]; + int32 location = 8 [json_name="location"]; +} + +message JsonTableColumn +{ + JsonTableColumnType coltype = 1 [json_name="coltype"]; + string name = 2 [json_name="name"]; + TypeName type_name = 3 [json_name="typeName"]; + JsonTablePathSpec pathspec = 4 [json_name="pathspec"]; + JsonFormat format = 5 [json_name="format"]; + JsonWrapper wrapper = 6 [json_name="wrapper"]; + JsonQuotes quotes = 7 [json_name="quotes"]; + repeated Node columns = 8 [json_name="columns"]; + JsonBehavior on_empty = 9 [json_name="on_empty"]; + JsonBehavior on_error = 10 [json_name="on_error"]; + int32 location = 11 [json_name="location"]; +} + +message JsonKeyValue +{ + Node key = 1 [json_name="key"]; + JsonValueExpr value = 2 [json_name="value"]; +} + +message JsonParseExpr +{ + JsonValueExpr expr = 1 [json_name="expr"]; + JsonOutput output = 2 [json_name="output"]; + bool unique_keys = 3 [json_name="unique_keys"]; + int32 location = 4 [json_name="location"]; +} + +message JsonScalarExpr +{ + Node expr = 1 [json_name="expr"]; + JsonOutput output = 2 [json_name="output"]; + int32 location = 3 [json_name="location"]; +} + +message JsonSerializeExpr +{ + JsonValueExpr expr = 1 [json_name="expr"]; + JsonOutput output = 2 [json_name="output"]; + int32 location = 3 [json_name="location"]; +} + +message JsonObjectConstructor +{ + repeated Node exprs = 1 [json_name="exprs"]; + JsonOutput output = 2 [json_name="output"]; + bool absent_on_null = 3 [json_name="absent_on_null"]; + bool unique = 4 [json_name="unique"]; + int32 location = 5 [json_name="location"]; +} + +message JsonArrayConstructor +{ + repeated Node exprs = 1 [json_name="exprs"]; + JsonOutput output = 2 [json_name="output"]; + bool absent_on_null = 3 [json_name="absent_on_null"]; + int32 location = 4 [json_name="location"]; +} + +message JsonArrayQueryConstructor +{ + Node query = 1 [json_name="query"]; + JsonOutput output = 2 [json_name="output"]; + JsonFormat format = 3 [json_name="format"]; + bool absent_on_null = 4 [json_name="absent_on_null"]; + int32 location = 5 [json_name="location"]; +} + +message JsonAggConstructor +{ + JsonOutput output = 1 [json_name="output"]; + Node agg_filter = 2 [json_name="agg_filter"]; + repeated Node agg_order = 3 [json_name="agg_order"]; + WindowDef over = 4 [json_name="over"]; + int32 location = 5 [json_name="location"]; +} + +message JsonObjectAgg +{ + JsonAggConstructor constructor = 1 [json_name="constructor"]; + JsonKeyValue arg = 2 [json_name="arg"]; + bool absent_on_null = 3 [json_name="absent_on_null"]; + bool unique = 4 [json_name="unique"]; +} + +message JsonArrayAgg +{ + JsonAggConstructor constructor = 1 [json_name="constructor"]; + JsonValueExpr arg = 2 [json_name="arg"]; + bool absent_on_null = 3 [json_name="absent_on_null"]; +} + +message RawStmt +{ + Node stmt = 1 [json_name="stmt"]; + int32 stmt_location = 2 [json_name="stmt_location"]; + int32 stmt_len = 3 [json_name="stmt_len"]; +} + +message InsertStmt +{ + RangeVar relation = 1 [json_name="relation"]; + repeated Node cols = 2 [json_name="cols"]; + Node select_stmt = 3 [json_name="selectStmt"]; + OnConflictClause on_conflict_clause = 4 [json_name="onConflictClause"]; + repeated Node returning_list = 5 [json_name="returningList"]; + WithClause with_clause = 6 [json_name="withClause"]; + OverridingKind override = 7 [json_name="override"]; +} + +message DeleteStmt +{ + RangeVar relation = 1 [json_name="relation"]; + repeated Node using_clause = 2 [json_name="usingClause"]; + Node where_clause = 3 [json_name="whereClause"]; + repeated Node returning_list = 4 [json_name="returningList"]; + WithClause with_clause = 5 [json_name="withClause"]; +} + +message UpdateStmt +{ + RangeVar relation = 1 [json_name="relation"]; + repeated Node target_list = 2 [json_name="targetList"]; + Node where_clause = 3 [json_name="whereClause"]; + repeated Node from_clause = 4 [json_name="fromClause"]; + repeated Node returning_list = 5 [json_name="returningList"]; + WithClause with_clause = 6 [json_name="withClause"]; +} + +message MergeStmt +{ + RangeVar relation = 1 [json_name="relation"]; + Node source_relation = 2 [json_name="sourceRelation"]; + Node join_condition = 3 [json_name="joinCondition"]; + repeated Node merge_when_clauses = 4 [json_name="mergeWhenClauses"]; + repeated Node returning_list = 5 [json_name="returningList"]; + WithClause with_clause = 6 [json_name="withClause"]; +} + +message SelectStmt +{ + repeated Node distinct_clause = 1 [json_name="distinctClause"]; + IntoClause into_clause = 2 [json_name="intoClause"]; + repeated Node target_list = 3 [json_name="targetList"]; + repeated Node from_clause = 4 [json_name="fromClause"]; + Node where_clause = 5 [json_name="whereClause"]; + repeated Node group_clause = 6 [json_name="groupClause"]; + bool group_distinct = 7 [json_name="groupDistinct"]; + Node having_clause = 8 [json_name="havingClause"]; + repeated Node window_clause = 9 [json_name="windowClause"]; + repeated Node values_lists = 10 [json_name="valuesLists"]; + repeated Node sort_clause = 11 [json_name="sortClause"]; + Node limit_offset = 12 [json_name="limitOffset"]; + Node limit_count = 13 [json_name="limitCount"]; + LimitOption limit_option = 14 [json_name="limitOption"]; + repeated Node locking_clause = 15 [json_name="lockingClause"]; + WithClause with_clause = 16 [json_name="withClause"]; + SetOperation op = 17 [json_name="op"]; + bool all = 18 [json_name="all"]; + SelectStmt larg = 19 [json_name="larg"]; + SelectStmt rarg = 20 [json_name="rarg"]; +} + +message SetOperationStmt +{ + SetOperation op = 1 [json_name="op"]; + bool all = 2 [json_name="all"]; + Node larg = 3 [json_name="larg"]; + Node rarg = 4 [json_name="rarg"]; + repeated Node col_types = 5 [json_name="colTypes"]; + repeated Node col_typmods = 6 [json_name="colTypmods"]; + repeated Node col_collations = 7 [json_name="colCollations"]; + repeated Node group_clauses = 8 [json_name="groupClauses"]; +} + +message ReturnStmt +{ + Node returnval = 1 [json_name="returnval"]; +} + +message PLAssignStmt +{ + string name = 1 [json_name="name"]; + repeated Node indirection = 2 [json_name="indirection"]; + int32 nnames = 3 [json_name="nnames"]; + SelectStmt val = 4 [json_name="val"]; + int32 location = 5 [json_name="location"]; +} + +message CreateSchemaStmt +{ + string schemaname = 1 [json_name="schemaname"]; + RoleSpec authrole = 2 [json_name="authrole"]; + repeated Node schema_elts = 3 [json_name="schemaElts"]; + bool if_not_exists = 4 [json_name="if_not_exists"]; +} + +message AlterTableStmt +{ + RangeVar relation = 1 [json_name="relation"]; + repeated Node cmds = 2 [json_name="cmds"]; + ObjectType objtype = 3 [json_name="objtype"]; + bool missing_ok = 4 [json_name="missing_ok"]; +} + +message ReplicaIdentityStmt +{ + string identity_type = 1 [json_name="identity_type"]; + string name = 2 [json_name="name"]; +} + +message AlterTableCmd +{ + AlterTableType subtype = 1 [json_name="subtype"]; + string name = 2 [json_name="name"]; + int32 num = 3 [json_name="num"]; + RoleSpec newowner = 4 [json_name="newowner"]; + Node def = 5 [json_name="def"]; + DropBehavior behavior = 6 [json_name="behavior"]; + bool missing_ok = 7 [json_name="missing_ok"]; + bool recurse = 8 [json_name="recurse"]; +} + +message AlterCollationStmt +{ + repeated Node collname = 1 [json_name="collname"]; +} + +message AlterDomainStmt +{ + string subtype = 1 [json_name="subtype"]; + repeated Node type_name = 2 [json_name="typeName"]; + string name = 3 [json_name="name"]; + Node def = 4 [json_name="def"]; + DropBehavior behavior = 5 [json_name="behavior"]; + bool missing_ok = 6 [json_name="missing_ok"]; +} + +message GrantStmt +{ + bool is_grant = 1 [json_name="is_grant"]; + GrantTargetType targtype = 2 [json_name="targtype"]; + ObjectType objtype = 3 [json_name="objtype"]; + repeated Node objects = 4 [json_name="objects"]; + repeated Node privileges = 5 [json_name="privileges"]; + repeated Node grantees = 6 [json_name="grantees"]; + bool grant_option = 7 [json_name="grant_option"]; + RoleSpec grantor = 8 [json_name="grantor"]; + DropBehavior behavior = 9 [json_name="behavior"]; +} + +message ObjectWithArgs +{ + repeated Node objname = 1 [json_name="objname"]; + repeated Node objargs = 2 [json_name="objargs"]; + repeated Node objfuncargs = 3 [json_name="objfuncargs"]; + bool args_unspecified = 4 [json_name="args_unspecified"]; +} + +message AccessPriv +{ + string priv_name = 1 [json_name="priv_name"]; + repeated Node cols = 2 [json_name="cols"]; +} + +message GrantRoleStmt +{ + repeated Node granted_roles = 1 [json_name="granted_roles"]; + repeated Node grantee_roles = 2 [json_name="grantee_roles"]; + bool is_grant = 3 [json_name="is_grant"]; + repeated Node opt = 4 [json_name="opt"]; + RoleSpec grantor = 5 [json_name="grantor"]; + DropBehavior behavior = 6 [json_name="behavior"]; +} + +message AlterDefaultPrivilegesStmt +{ + repeated Node options = 1 [json_name="options"]; + GrantStmt action = 2 [json_name="action"]; +} + +message CopyStmt +{ + RangeVar relation = 1 [json_name="relation"]; + Node query = 2 [json_name="query"]; + repeated Node attlist = 3 [json_name="attlist"]; + bool is_from = 4 [json_name="is_from"]; + bool is_program = 5 [json_name="is_program"]; + string filename = 6 [json_name="filename"]; + repeated Node options = 7 [json_name="options"]; + Node where_clause = 8 [json_name="whereClause"]; +} + +message VariableSetStmt +{ + VariableSetKind kind = 1 [json_name="kind"]; + string name = 2 [json_name="name"]; + repeated Node args = 3 [json_name="args"]; + bool is_local = 4 [json_name="is_local"]; +} + +message VariableShowStmt +{ + string name = 1 [json_name="name"]; +} + +message CreateStmt +{ + RangeVar relation = 1 [json_name="relation"]; + repeated Node table_elts = 2 [json_name="tableElts"]; + repeated Node inh_relations = 3 [json_name="inhRelations"]; + PartitionBoundSpec partbound = 4 [json_name="partbound"]; + PartitionSpec partspec = 5 [json_name="partspec"]; + TypeName of_typename = 6 [json_name="ofTypename"]; + repeated Node constraints = 7 [json_name="constraints"]; + repeated Node options = 8 [json_name="options"]; + OnCommitAction oncommit = 9 [json_name="oncommit"]; + string tablespacename = 10 [json_name="tablespacename"]; + string access_method = 11 [json_name="accessMethod"]; + bool if_not_exists = 12 [json_name="if_not_exists"]; +} + +message Constraint +{ + ConstrType contype = 1 [json_name="contype"]; + string conname = 2 [json_name="conname"]; + bool deferrable = 3 [json_name="deferrable"]; + bool initdeferred = 4 [json_name="initdeferred"]; + bool skip_validation = 5 [json_name="skip_validation"]; + bool initially_valid = 6 [json_name="initially_valid"]; + bool is_no_inherit = 7 [json_name="is_no_inherit"]; + Node raw_expr = 8 [json_name="raw_expr"]; + string cooked_expr = 9 [json_name="cooked_expr"]; + string generated_when = 10 [json_name="generated_when"]; + int32 inhcount = 11 [json_name="inhcount"]; + bool nulls_not_distinct = 12 [json_name="nulls_not_distinct"]; + repeated Node keys = 13 [json_name="keys"]; + repeated Node including = 14 [json_name="including"]; + repeated Node exclusions = 15 [json_name="exclusions"]; + repeated Node options = 16 [json_name="options"]; + string indexname = 17 [json_name="indexname"]; + string indexspace = 18 [json_name="indexspace"]; + bool reset_default_tblspc = 19 [json_name="reset_default_tblspc"]; + string access_method = 20 [json_name="access_method"]; + Node where_clause = 21 [json_name="where_clause"]; + RangeVar pktable = 22 [json_name="pktable"]; + repeated Node fk_attrs = 23 [json_name="fk_attrs"]; + repeated Node pk_attrs = 24 [json_name="pk_attrs"]; + string fk_matchtype = 25 [json_name="fk_matchtype"]; + string fk_upd_action = 26 [json_name="fk_upd_action"]; + string fk_del_action = 27 [json_name="fk_del_action"]; + repeated Node fk_del_set_cols = 28 [json_name="fk_del_set_cols"]; + repeated Node old_conpfeqop = 29 [json_name="old_conpfeqop"]; + uint32 old_pktable_oid = 30 [json_name="old_pktable_oid"]; + int32 location = 31 [json_name="location"]; +} + +message CreateTableSpaceStmt +{ + string tablespacename = 1 [json_name="tablespacename"]; + RoleSpec owner = 2 [json_name="owner"]; + string location = 3 [json_name="location"]; + repeated Node options = 4 [json_name="options"]; +} + +message DropTableSpaceStmt +{ + string tablespacename = 1 [json_name="tablespacename"]; + bool missing_ok = 2 [json_name="missing_ok"]; +} + +message AlterTableSpaceOptionsStmt +{ + string tablespacename = 1 [json_name="tablespacename"]; + repeated Node options = 2 [json_name="options"]; + bool is_reset = 3 [json_name="isReset"]; +} + +message AlterTableMoveAllStmt +{ + string orig_tablespacename = 1 [json_name="orig_tablespacename"]; + ObjectType objtype = 2 [json_name="objtype"]; + repeated Node roles = 3 [json_name="roles"]; + string new_tablespacename = 4 [json_name="new_tablespacename"]; + bool nowait = 5 [json_name="nowait"]; +} + +message CreateExtensionStmt +{ + string extname = 1 [json_name="extname"]; + bool if_not_exists = 2 [json_name="if_not_exists"]; + repeated Node options = 3 [json_name="options"]; +} + +message AlterExtensionStmt +{ + string extname = 1 [json_name="extname"]; + repeated Node options = 2 [json_name="options"]; +} + +message AlterExtensionContentsStmt +{ + string extname = 1 [json_name="extname"]; + int32 action = 2 [json_name="action"]; + ObjectType objtype = 3 [json_name="objtype"]; + Node object = 4 [json_name="object"]; +} + +message CreateFdwStmt +{ + string fdwname = 1 [json_name="fdwname"]; + repeated Node func_options = 2 [json_name="func_options"]; + repeated Node options = 3 [json_name="options"]; +} + +message AlterFdwStmt +{ + string fdwname = 1 [json_name="fdwname"]; + repeated Node func_options = 2 [json_name="func_options"]; + repeated Node options = 3 [json_name="options"]; +} + +message CreateForeignServerStmt +{ + string servername = 1 [json_name="servername"]; + string servertype = 2 [json_name="servertype"]; + string version = 3 [json_name="version"]; + string fdwname = 4 [json_name="fdwname"]; + bool if_not_exists = 5 [json_name="if_not_exists"]; + repeated Node options = 6 [json_name="options"]; +} + +message AlterForeignServerStmt +{ + string servername = 1 [json_name="servername"]; + string version = 2 [json_name="version"]; + repeated Node options = 3 [json_name="options"]; + bool has_version = 4 [json_name="has_version"]; +} + +message CreateForeignTableStmt +{ + CreateStmt base_stmt = 1 [json_name="base"]; + string servername = 2 [json_name="servername"]; + repeated Node options = 3 [json_name="options"]; +} + +message CreateUserMappingStmt +{ + RoleSpec user = 1 [json_name="user"]; + string servername = 2 [json_name="servername"]; + bool if_not_exists = 3 [json_name="if_not_exists"]; + repeated Node options = 4 [json_name="options"]; +} + +message AlterUserMappingStmt +{ + RoleSpec user = 1 [json_name="user"]; + string servername = 2 [json_name="servername"]; + repeated Node options = 3 [json_name="options"]; +} + +message DropUserMappingStmt +{ + RoleSpec user = 1 [json_name="user"]; + string servername = 2 [json_name="servername"]; + bool missing_ok = 3 [json_name="missing_ok"]; +} + +message ImportForeignSchemaStmt +{ + string server_name = 1 [json_name="server_name"]; + string remote_schema = 2 [json_name="remote_schema"]; + string local_schema = 3 [json_name="local_schema"]; + ImportForeignSchemaType list_type = 4 [json_name="list_type"]; + repeated Node table_list = 5 [json_name="table_list"]; + repeated Node options = 6 [json_name="options"]; +} + +message CreatePolicyStmt +{ + string policy_name = 1 [json_name="policy_name"]; + RangeVar table = 2 [json_name="table"]; + string cmd_name = 3 [json_name="cmd_name"]; + bool permissive = 4 [json_name="permissive"]; + repeated Node roles = 5 [json_name="roles"]; + Node qual = 6 [json_name="qual"]; + Node with_check = 7 [json_name="with_check"]; +} + +message AlterPolicyStmt +{ + string policy_name = 1 [json_name="policy_name"]; + RangeVar table = 2 [json_name="table"]; + repeated Node roles = 3 [json_name="roles"]; + Node qual = 4 [json_name="qual"]; + Node with_check = 5 [json_name="with_check"]; +} + +message CreateAmStmt +{ + string amname = 1 [json_name="amname"]; + repeated Node handler_name = 2 [json_name="handler_name"]; + string amtype = 3 [json_name="amtype"]; +} + +message CreateTrigStmt +{ + bool replace = 1 [json_name="replace"]; + bool isconstraint = 2 [json_name="isconstraint"]; + string trigname = 3 [json_name="trigname"]; + RangeVar relation = 4 [json_name="relation"]; + repeated Node funcname = 5 [json_name="funcname"]; + repeated Node args = 6 [json_name="args"]; + bool row = 7 [json_name="row"]; + int32 timing = 8 [json_name="timing"]; + int32 events = 9 [json_name="events"]; + repeated Node columns = 10 [json_name="columns"]; + Node when_clause = 11 [json_name="whenClause"]; + repeated Node transition_rels = 12 [json_name="transitionRels"]; + bool deferrable = 13 [json_name="deferrable"]; + bool initdeferred = 14 [json_name="initdeferred"]; + RangeVar constrrel = 15 [json_name="constrrel"]; +} + +message CreateEventTrigStmt +{ + string trigname = 1 [json_name="trigname"]; + string eventname = 2 [json_name="eventname"]; + repeated Node whenclause = 3 [json_name="whenclause"]; + repeated Node funcname = 4 [json_name="funcname"]; +} + +message AlterEventTrigStmt +{ + string trigname = 1 [json_name="trigname"]; + string tgenabled = 2 [json_name="tgenabled"]; +} + +message CreatePLangStmt +{ + bool replace = 1 [json_name="replace"]; + string plname = 2 [json_name="plname"]; + repeated Node plhandler = 3 [json_name="plhandler"]; + repeated Node plinline = 4 [json_name="plinline"]; + repeated Node plvalidator = 5 [json_name="plvalidator"]; + bool pltrusted = 6 [json_name="pltrusted"]; +} + +message CreateRoleStmt +{ + RoleStmtType stmt_type = 1 [json_name="stmt_type"]; + string role = 2 [json_name="role"]; + repeated Node options = 3 [json_name="options"]; +} + +message AlterRoleStmt +{ + RoleSpec role = 1 [json_name="role"]; + repeated Node options = 2 [json_name="options"]; + int32 action = 3 [json_name="action"]; +} + +message AlterRoleSetStmt +{ + RoleSpec role = 1 [json_name="role"]; + string database = 2 [json_name="database"]; + VariableSetStmt setstmt = 3 [json_name="setstmt"]; +} + +message DropRoleStmt +{ + repeated Node roles = 1 [json_name="roles"]; + bool missing_ok = 2 [json_name="missing_ok"]; +} + +message CreateSeqStmt +{ + RangeVar sequence = 1 [json_name="sequence"]; + repeated Node options = 2 [json_name="options"]; + uint32 owner_id = 3 [json_name="ownerId"]; + bool for_identity = 4 [json_name="for_identity"]; + bool if_not_exists = 5 [json_name="if_not_exists"]; +} + +message AlterSeqStmt +{ + RangeVar sequence = 1 [json_name="sequence"]; + repeated Node options = 2 [json_name="options"]; + bool for_identity = 3 [json_name="for_identity"]; + bool missing_ok = 4 [json_name="missing_ok"]; +} + +message DefineStmt +{ + ObjectType kind = 1 [json_name="kind"]; + bool oldstyle = 2 [json_name="oldstyle"]; + repeated Node defnames = 3 [json_name="defnames"]; + repeated Node args = 4 [json_name="args"]; + repeated Node definition = 5 [json_name="definition"]; + bool if_not_exists = 6 [json_name="if_not_exists"]; + bool replace = 7 [json_name="replace"]; +} + +message CreateDomainStmt +{ + repeated Node domainname = 1 [json_name="domainname"]; + TypeName type_name = 2 [json_name="typeName"]; + CollateClause coll_clause = 3 [json_name="collClause"]; + repeated Node constraints = 4 [json_name="constraints"]; +} + +message CreateOpClassStmt +{ + repeated Node opclassname = 1 [json_name="opclassname"]; + repeated Node opfamilyname = 2 [json_name="opfamilyname"]; + string amname = 3 [json_name="amname"]; + TypeName datatype = 4 [json_name="datatype"]; + repeated Node items = 5 [json_name="items"]; + bool is_default = 6 [json_name="isDefault"]; +} + +message CreateOpClassItem +{ + int32 itemtype = 1 [json_name="itemtype"]; + ObjectWithArgs name = 2 [json_name="name"]; + int32 number = 3 [json_name="number"]; + repeated Node order_family = 4 [json_name="order_family"]; + repeated Node class_args = 5 [json_name="class_args"]; + TypeName storedtype = 6 [json_name="storedtype"]; +} + +message CreateOpFamilyStmt +{ + repeated Node opfamilyname = 1 [json_name="opfamilyname"]; + string amname = 2 [json_name="amname"]; +} + +message AlterOpFamilyStmt +{ + repeated Node opfamilyname = 1 [json_name="opfamilyname"]; + string amname = 2 [json_name="amname"]; + bool is_drop = 3 [json_name="isDrop"]; + repeated Node items = 4 [json_name="items"]; +} + +message DropStmt +{ + repeated Node objects = 1 [json_name="objects"]; + ObjectType remove_type = 2 [json_name="removeType"]; + DropBehavior behavior = 3 [json_name="behavior"]; + bool missing_ok = 4 [json_name="missing_ok"]; + bool concurrent = 5 [json_name="concurrent"]; +} + +message TruncateStmt +{ + repeated Node relations = 1 [json_name="relations"]; + bool restart_seqs = 2 [json_name="restart_seqs"]; + DropBehavior behavior = 3 [json_name="behavior"]; +} + +message CommentStmt +{ + ObjectType objtype = 1 [json_name="objtype"]; + Node object = 2 [json_name="object"]; + string comment = 3 [json_name="comment"]; +} + +message SecLabelStmt +{ + ObjectType objtype = 1 [json_name="objtype"]; + Node object = 2 [json_name="object"]; + string provider = 3 [json_name="provider"]; + string label = 4 [json_name="label"]; +} + +message DeclareCursorStmt +{ + string portalname = 1 [json_name="portalname"]; + int32 options = 2 [json_name="options"]; + Node query = 3 [json_name="query"]; +} + +message ClosePortalStmt +{ + string portalname = 1 [json_name="portalname"]; +} + +message FetchStmt +{ + FetchDirection direction = 1 [json_name="direction"]; + int64 how_many = 2 [json_name="howMany"]; + string portalname = 3 [json_name="portalname"]; + bool ismove = 4 [json_name="ismove"]; +} + +message IndexStmt +{ + string idxname = 1 [json_name="idxname"]; + RangeVar relation = 2 [json_name="relation"]; + string access_method = 3 [json_name="accessMethod"]; + string table_space = 4 [json_name="tableSpace"]; + repeated Node index_params = 5 [json_name="indexParams"]; + repeated Node index_including_params = 6 [json_name="indexIncludingParams"]; + repeated Node options = 7 [json_name="options"]; + Node where_clause = 8 [json_name="whereClause"]; + repeated Node exclude_op_names = 9 [json_name="excludeOpNames"]; + string idxcomment = 10 [json_name="idxcomment"]; + uint32 index_oid = 11 [json_name="indexOid"]; + uint32 old_number = 12 [json_name="oldNumber"]; + uint32 old_create_subid = 13 [json_name="oldCreateSubid"]; + uint32 old_first_relfilelocator_subid = 14 [json_name="oldFirstRelfilelocatorSubid"]; + bool unique = 15 [json_name="unique"]; + bool nulls_not_distinct = 16 [json_name="nulls_not_distinct"]; + bool primary = 17 [json_name="primary"]; + bool isconstraint = 18 [json_name="isconstraint"]; + bool deferrable = 19 [json_name="deferrable"]; + bool initdeferred = 20 [json_name="initdeferred"]; + bool transformed = 21 [json_name="transformed"]; + bool concurrent = 22 [json_name="concurrent"]; + bool if_not_exists = 23 [json_name="if_not_exists"]; + bool reset_default_tblspc = 24 [json_name="reset_default_tblspc"]; +} + +message CreateStatsStmt +{ + repeated Node defnames = 1 [json_name="defnames"]; + repeated Node stat_types = 2 [json_name="stat_types"]; + repeated Node exprs = 3 [json_name="exprs"]; + repeated Node relations = 4 [json_name="relations"]; + string stxcomment = 5 [json_name="stxcomment"]; + bool transformed = 6 [json_name="transformed"]; + bool if_not_exists = 7 [json_name="if_not_exists"]; +} + +message StatsElem +{ + string name = 1 [json_name="name"]; + Node expr = 2 [json_name="expr"]; +} + +message AlterStatsStmt +{ + repeated Node defnames = 1 [json_name="defnames"]; + Node stxstattarget = 2 [json_name="stxstattarget"]; + bool missing_ok = 3 [json_name="missing_ok"]; +} + +message CreateFunctionStmt +{ + bool is_procedure = 1 [json_name="is_procedure"]; + bool replace = 2 [json_name="replace"]; + repeated Node funcname = 3 [json_name="funcname"]; + repeated Node parameters = 4 [json_name="parameters"]; + TypeName return_type = 5 [json_name="returnType"]; + repeated Node options = 6 [json_name="options"]; + Node sql_body = 7 [json_name="sql_body"]; +} + +message FunctionParameter +{ + string name = 1 [json_name="name"]; + TypeName arg_type = 2 [json_name="argType"]; + FunctionParameterMode mode = 3 [json_name="mode"]; + Node defexpr = 4 [json_name="defexpr"]; +} + +message AlterFunctionStmt +{ + ObjectType objtype = 1 [json_name="objtype"]; + ObjectWithArgs func = 2 [json_name="func"]; + repeated Node actions = 3 [json_name="actions"]; +} + +message DoStmt +{ + repeated Node args = 1 [json_name="args"]; +} + +message InlineCodeBlock +{ + string source_text = 1 [json_name="source_text"]; + uint32 lang_oid = 2 [json_name="langOid"]; + bool lang_is_trusted = 3 [json_name="langIsTrusted"]; + bool atomic = 4 [json_name="atomic"]; +} + +message CallStmt +{ + FuncCall funccall = 1 [json_name="funccall"]; + FuncExpr funcexpr = 2 [json_name="funcexpr"]; + repeated Node outargs = 3 [json_name="outargs"]; +} + +message CallContext +{ + bool atomic = 1 [json_name="atomic"]; +} + +message RenameStmt +{ + ObjectType rename_type = 1 [json_name="renameType"]; + ObjectType relation_type = 2 [json_name="relationType"]; + RangeVar relation = 3 [json_name="relation"]; + Node object = 4 [json_name="object"]; + string subname = 5 [json_name="subname"]; + string newname = 6 [json_name="newname"]; + DropBehavior behavior = 7 [json_name="behavior"]; + bool missing_ok = 8 [json_name="missing_ok"]; +} + +message AlterObjectDependsStmt +{ + ObjectType object_type = 1 [json_name="objectType"]; + RangeVar relation = 2 [json_name="relation"]; + Node object = 3 [json_name="object"]; + String extname = 4 [json_name="extname"]; + bool remove = 5 [json_name="remove"]; +} + +message AlterObjectSchemaStmt +{ + ObjectType object_type = 1 [json_name="objectType"]; + RangeVar relation = 2 [json_name="relation"]; + Node object = 3 [json_name="object"]; + string newschema = 4 [json_name="newschema"]; + bool missing_ok = 5 [json_name="missing_ok"]; +} + +message AlterOwnerStmt +{ + ObjectType object_type = 1 [json_name="objectType"]; + RangeVar relation = 2 [json_name="relation"]; + Node object = 3 [json_name="object"]; + RoleSpec newowner = 4 [json_name="newowner"]; +} + +message AlterOperatorStmt +{ + ObjectWithArgs opername = 1 [json_name="opername"]; + repeated Node options = 2 [json_name="options"]; +} + +message AlterTypeStmt +{ + repeated Node type_name = 1 [json_name="typeName"]; + repeated Node options = 2 [json_name="options"]; +} + +message RuleStmt +{ + RangeVar relation = 1 [json_name="relation"]; + string rulename = 2 [json_name="rulename"]; + Node where_clause = 3 [json_name="whereClause"]; + CmdType event = 4 [json_name="event"]; + bool instead = 5 [json_name="instead"]; + repeated Node actions = 6 [json_name="actions"]; + bool replace = 7 [json_name="replace"]; +} + +message NotifyStmt +{ + string conditionname = 1 [json_name="conditionname"]; + string payload = 2 [json_name="payload"]; +} + +message ListenStmt +{ + string conditionname = 1 [json_name="conditionname"]; +} + +message UnlistenStmt +{ + string conditionname = 1 [json_name="conditionname"]; +} + +message TransactionStmt +{ + TransactionStmtKind kind = 1 [json_name="kind"]; + repeated Node options = 2 [json_name="options"]; + string savepoint_name = 3 [json_name="savepoint_name"]; + string gid = 4 [json_name="gid"]; + bool chain = 5 [json_name="chain"]; + int32 location = 6 [json_name="location"]; +} + +message CompositeTypeStmt +{ + RangeVar typevar = 1 [json_name="typevar"]; + repeated Node coldeflist = 2 [json_name="coldeflist"]; +} + +message CreateEnumStmt +{ + repeated Node type_name = 1 [json_name="typeName"]; + repeated Node vals = 2 [json_name="vals"]; +} + +message CreateRangeStmt +{ + repeated Node type_name = 1 [json_name="typeName"]; + repeated Node params = 2 [json_name="params"]; +} + +message AlterEnumStmt +{ + repeated Node type_name = 1 [json_name="typeName"]; + string old_val = 2 [json_name="oldVal"]; + string new_val = 3 [json_name="newVal"]; + string new_val_neighbor = 4 [json_name="newValNeighbor"]; + bool new_val_is_after = 5 [json_name="newValIsAfter"]; + bool skip_if_new_val_exists = 6 [json_name="skipIfNewValExists"]; +} + +message ViewStmt +{ + RangeVar view = 1 [json_name="view"]; + repeated Node aliases = 2 [json_name="aliases"]; + Node query = 3 [json_name="query"]; + bool replace = 4 [json_name="replace"]; + repeated Node options = 5 [json_name="options"]; + ViewCheckOption with_check_option = 6 [json_name="withCheckOption"]; +} + +message LoadStmt +{ + string filename = 1 [json_name="filename"]; +} + +message CreatedbStmt +{ + string dbname = 1 [json_name="dbname"]; + repeated Node options = 2 [json_name="options"]; +} + +message AlterDatabaseStmt +{ + string dbname = 1 [json_name="dbname"]; + repeated Node options = 2 [json_name="options"]; +} + +message AlterDatabaseRefreshCollStmt +{ + string dbname = 1 [json_name="dbname"]; +} + +message AlterDatabaseSetStmt +{ + string dbname = 1 [json_name="dbname"]; + VariableSetStmt setstmt = 2 [json_name="setstmt"]; +} + +message DropdbStmt +{ + string dbname = 1 [json_name="dbname"]; + bool missing_ok = 2 [json_name="missing_ok"]; + repeated Node options = 3 [json_name="options"]; +} + +message AlterSystemStmt +{ + VariableSetStmt setstmt = 1 [json_name="setstmt"]; +} + +message ClusterStmt +{ + RangeVar relation = 1 [json_name="relation"]; + string indexname = 2 [json_name="indexname"]; + repeated Node params = 3 [json_name="params"]; +} + +message VacuumStmt +{ + repeated Node options = 1 [json_name="options"]; + repeated Node rels = 2 [json_name="rels"]; + bool is_vacuumcmd = 3 [json_name="is_vacuumcmd"]; +} + +message VacuumRelation +{ + RangeVar relation = 1 [json_name="relation"]; + uint32 oid = 2 [json_name="oid"]; + repeated Node va_cols = 3 [json_name="va_cols"]; +} + +message ExplainStmt +{ + Node query = 1 [json_name="query"]; + repeated Node options = 2 [json_name="options"]; +} + +message CreateTableAsStmt +{ + Node query = 1 [json_name="query"]; + IntoClause into = 2 [json_name="into"]; + ObjectType objtype = 3 [json_name="objtype"]; + bool is_select_into = 4 [json_name="is_select_into"]; + bool if_not_exists = 5 [json_name="if_not_exists"]; +} + +message RefreshMatViewStmt +{ + bool concurrent = 1 [json_name="concurrent"]; + bool skip_data = 2 [json_name="skipData"]; + RangeVar relation = 3 [json_name="relation"]; +} + +message CheckPointStmt +{ +} + +message DiscardStmt +{ + DiscardMode target = 1 [json_name="target"]; +} + +message LockStmt +{ + repeated Node relations = 1 [json_name="relations"]; + int32 mode = 2 [json_name="mode"]; + bool nowait = 3 [json_name="nowait"]; +} + +message ConstraintsSetStmt +{ + repeated Node constraints = 1 [json_name="constraints"]; + bool deferred = 2 [json_name="deferred"]; +} + +message ReindexStmt +{ + ReindexObjectType kind = 1 [json_name="kind"]; + RangeVar relation = 2 [json_name="relation"]; + string name = 3 [json_name="name"]; + repeated Node params = 4 [json_name="params"]; +} + +message CreateConversionStmt +{ + repeated Node conversion_name = 1 [json_name="conversion_name"]; + string for_encoding_name = 2 [json_name="for_encoding_name"]; + string to_encoding_name = 3 [json_name="to_encoding_name"]; + repeated Node func_name = 4 [json_name="func_name"]; + bool def = 5 [json_name="def"]; +} + +message CreateCastStmt +{ + TypeName sourcetype = 1 [json_name="sourcetype"]; + TypeName targettype = 2 [json_name="targettype"]; + ObjectWithArgs func = 3 [json_name="func"]; + CoercionContext context = 4 [json_name="context"]; + bool inout = 5 [json_name="inout"]; +} + +message CreateTransformStmt +{ + bool replace = 1 [json_name="replace"]; + TypeName type_name = 2 [json_name="type_name"]; + string lang = 3 [json_name="lang"]; + ObjectWithArgs fromsql = 4 [json_name="fromsql"]; + ObjectWithArgs tosql = 5 [json_name="tosql"]; +} + +message PrepareStmt +{ + string name = 1 [json_name="name"]; + repeated Node argtypes = 2 [json_name="argtypes"]; + Node query = 3 [json_name="query"]; +} + +message ExecuteStmt +{ + string name = 1 [json_name="name"]; + repeated Node params = 2 [json_name="params"]; +} + +message DeallocateStmt +{ + string name = 1 [json_name="name"]; + bool isall = 2 [json_name="isall"]; + int32 location = 3 [json_name="location"]; +} + +message DropOwnedStmt +{ + repeated Node roles = 1 [json_name="roles"]; + DropBehavior behavior = 2 [json_name="behavior"]; +} + +message ReassignOwnedStmt +{ + repeated Node roles = 1 [json_name="roles"]; + RoleSpec newrole = 2 [json_name="newrole"]; +} + +message AlterTSDictionaryStmt +{ + repeated Node dictname = 1 [json_name="dictname"]; + repeated Node options = 2 [json_name="options"]; +} + +message AlterTSConfigurationStmt +{ + AlterTSConfigType kind = 1 [json_name="kind"]; + repeated Node cfgname = 2 [json_name="cfgname"]; + repeated Node tokentype = 3 [json_name="tokentype"]; + repeated Node dicts = 4 [json_name="dicts"]; + bool override = 5 [json_name="override"]; + bool replace = 6 [json_name="replace"]; + bool missing_ok = 7 [json_name="missing_ok"]; +} + +message PublicationTable +{ + RangeVar relation = 1 [json_name="relation"]; + Node where_clause = 2 [json_name="whereClause"]; + repeated Node columns = 3 [json_name="columns"]; +} + +message PublicationObjSpec +{ + PublicationObjSpecType pubobjtype = 1 [json_name="pubobjtype"]; + string name = 2 [json_name="name"]; + PublicationTable pubtable = 3 [json_name="pubtable"]; + int32 location = 4 [json_name="location"]; +} + +message CreatePublicationStmt +{ + string pubname = 1 [json_name="pubname"]; + repeated Node options = 2 [json_name="options"]; + repeated Node pubobjects = 3 [json_name="pubobjects"]; + bool for_all_tables = 4 [json_name="for_all_tables"]; +} + +message AlterPublicationStmt +{ + string pubname = 1 [json_name="pubname"]; + repeated Node options = 2 [json_name="options"]; + repeated Node pubobjects = 3 [json_name="pubobjects"]; + bool for_all_tables = 4 [json_name="for_all_tables"]; + AlterPublicationAction action = 5 [json_name="action"]; +} + +message CreateSubscriptionStmt +{ + string subname = 1 [json_name="subname"]; + string conninfo = 2 [json_name="conninfo"]; + repeated Node publication = 3 [json_name="publication"]; + repeated Node options = 4 [json_name="options"]; +} + +message AlterSubscriptionStmt +{ + AlterSubscriptionType kind = 1 [json_name="kind"]; + string subname = 2 [json_name="subname"]; + string conninfo = 3 [json_name="conninfo"]; + repeated Node publication = 4 [json_name="publication"]; + repeated Node options = 5 [json_name="options"]; +} + +message DropSubscriptionStmt +{ + string subname = 1 [json_name="subname"]; + bool missing_ok = 2 [json_name="missing_ok"]; + DropBehavior behavior = 3 [json_name="behavior"]; +} + +enum QuerySource +{ + QUERY_SOURCE_UNDEFINED = 0; + QSRC_ORIGINAL = 1; + QSRC_PARSER = 2; + QSRC_INSTEAD_RULE = 3; + QSRC_QUAL_INSTEAD_RULE = 4; + QSRC_NON_INSTEAD_RULE = 5; +} + +enum SortByDir +{ + SORT_BY_DIR_UNDEFINED = 0; + SORTBY_DEFAULT = 1; + SORTBY_ASC = 2; + SORTBY_DESC = 3; + SORTBY_USING = 4; +} + +enum SortByNulls +{ + SORT_BY_NULLS_UNDEFINED = 0; + SORTBY_NULLS_DEFAULT = 1; + SORTBY_NULLS_FIRST = 2; + SORTBY_NULLS_LAST = 3; +} + +enum SetQuantifier +{ + SET_QUANTIFIER_UNDEFINED = 0; + SET_QUANTIFIER_DEFAULT = 1; + SET_QUANTIFIER_ALL = 2; + SET_QUANTIFIER_DISTINCT = 3; +} + +enum A_Expr_Kind +{ + A_EXPR_KIND_UNDEFINED = 0; + AEXPR_OP = 1; + AEXPR_OP_ANY = 2; + AEXPR_OP_ALL = 3; + AEXPR_DISTINCT = 4; + AEXPR_NOT_DISTINCT = 5; + AEXPR_NULLIF = 6; + AEXPR_IN = 7; + AEXPR_LIKE = 8; + AEXPR_ILIKE = 9; + AEXPR_SIMILAR = 10; + AEXPR_BETWEEN = 11; + AEXPR_NOT_BETWEEN = 12; + AEXPR_BETWEEN_SYM = 13; + AEXPR_NOT_BETWEEN_SYM = 14; +} + +enum RoleSpecType +{ + ROLE_SPEC_TYPE_UNDEFINED = 0; + ROLESPEC_CSTRING = 1; + ROLESPEC_CURRENT_ROLE = 2; + ROLESPEC_CURRENT_USER = 3; + ROLESPEC_SESSION_USER = 4; + ROLESPEC_PUBLIC = 5; +} + +enum TableLikeOption +{ + TABLE_LIKE_OPTION_UNDEFINED = 0; + CREATE_TABLE_LIKE_COMMENTS = 1; + CREATE_TABLE_LIKE_COMPRESSION = 2; + CREATE_TABLE_LIKE_CONSTRAINTS = 3; + CREATE_TABLE_LIKE_DEFAULTS = 4; + CREATE_TABLE_LIKE_GENERATED = 5; + CREATE_TABLE_LIKE_IDENTITY = 6; + CREATE_TABLE_LIKE_INDEXES = 7; + CREATE_TABLE_LIKE_STATISTICS = 8; + CREATE_TABLE_LIKE_STORAGE = 9; + CREATE_TABLE_LIKE_ALL = 10; +} + +enum DefElemAction +{ + DEF_ELEM_ACTION_UNDEFINED = 0; + DEFELEM_UNSPEC = 1; + DEFELEM_SET = 2; + DEFELEM_ADD = 3; + DEFELEM_DROP = 4; +} + +enum PartitionStrategy +{ + PARTITION_STRATEGY_UNDEFINED = 0; + PARTITION_STRATEGY_LIST = 1; + PARTITION_STRATEGY_RANGE = 2; + PARTITION_STRATEGY_HASH = 3; +} + +enum PartitionRangeDatumKind +{ + PARTITION_RANGE_DATUM_KIND_UNDEFINED = 0; + PARTITION_RANGE_DATUM_MINVALUE = 1; + PARTITION_RANGE_DATUM_VALUE = 2; + PARTITION_RANGE_DATUM_MAXVALUE = 3; +} + +enum RTEKind +{ + RTEKIND_UNDEFINED = 0; + RTE_RELATION = 1; + RTE_SUBQUERY = 2; + RTE_JOIN = 3; + RTE_FUNCTION = 4; + RTE_TABLEFUNC = 5; + RTE_VALUES = 6; + RTE_CTE = 7; + RTE_NAMEDTUPLESTORE = 8; + RTE_RESULT = 9; +} + +enum WCOKind +{ + WCOKIND_UNDEFINED = 0; + WCO_VIEW_CHECK = 1; + WCO_RLS_INSERT_CHECK = 2; + WCO_RLS_UPDATE_CHECK = 3; + WCO_RLS_CONFLICT_CHECK = 4; + WCO_RLS_MERGE_UPDATE_CHECK = 5; + WCO_RLS_MERGE_DELETE_CHECK = 6; +} + +enum GroupingSetKind +{ + GROUPING_SET_KIND_UNDEFINED = 0; + GROUPING_SET_EMPTY = 1; + GROUPING_SET_SIMPLE = 2; + GROUPING_SET_ROLLUP = 3; + GROUPING_SET_CUBE = 4; + GROUPING_SET_SETS = 5; +} + +enum CTEMaterialize +{ + CTEMATERIALIZE_UNDEFINED = 0; + CTEMaterializeDefault = 1; + CTEMaterializeAlways = 2; + CTEMaterializeNever = 3; +} + +enum JsonQuotes +{ + JSON_QUOTES_UNDEFINED = 0; + JS_QUOTES_UNSPEC = 1; + JS_QUOTES_KEEP = 2; + JS_QUOTES_OMIT = 3; +} + +enum JsonTableColumnType +{ + JSON_TABLE_COLUMN_TYPE_UNDEFINED = 0; + JTC_FOR_ORDINALITY = 1; + JTC_REGULAR = 2; + JTC_EXISTS = 3; + JTC_FORMATTED = 4; + JTC_NESTED = 5; +} + +enum SetOperation +{ + SET_OPERATION_UNDEFINED = 0; + SETOP_NONE = 1; + SETOP_UNION = 2; + SETOP_INTERSECT = 3; + SETOP_EXCEPT = 4; +} + +enum ObjectType +{ + OBJECT_TYPE_UNDEFINED = 0; + OBJECT_ACCESS_METHOD = 1; + OBJECT_AGGREGATE = 2; + OBJECT_AMOP = 3; + OBJECT_AMPROC = 4; + OBJECT_ATTRIBUTE = 5; + OBJECT_CAST = 6; + OBJECT_COLUMN = 7; + OBJECT_COLLATION = 8; + OBJECT_CONVERSION = 9; + OBJECT_DATABASE = 10; + OBJECT_DEFAULT = 11; + OBJECT_DEFACL = 12; + OBJECT_DOMAIN = 13; + OBJECT_DOMCONSTRAINT = 14; + OBJECT_EVENT_TRIGGER = 15; + OBJECT_EXTENSION = 16; + OBJECT_FDW = 17; + OBJECT_FOREIGN_SERVER = 18; + OBJECT_FOREIGN_TABLE = 19; + OBJECT_FUNCTION = 20; + OBJECT_INDEX = 21; + OBJECT_LANGUAGE = 22; + OBJECT_LARGEOBJECT = 23; + OBJECT_MATVIEW = 24; + OBJECT_OPCLASS = 25; + OBJECT_OPERATOR = 26; + OBJECT_OPFAMILY = 27; + OBJECT_PARAMETER_ACL = 28; + OBJECT_POLICY = 29; + OBJECT_PROCEDURE = 30; + OBJECT_PUBLICATION = 31; + OBJECT_PUBLICATION_NAMESPACE = 32; + OBJECT_PUBLICATION_REL = 33; + OBJECT_ROLE = 34; + OBJECT_ROUTINE = 35; + OBJECT_RULE = 36; + OBJECT_SCHEMA = 37; + OBJECT_SEQUENCE = 38; + OBJECT_SUBSCRIPTION = 39; + OBJECT_STATISTIC_EXT = 40; + OBJECT_TABCONSTRAINT = 41; + OBJECT_TABLE = 42; + OBJECT_TABLESPACE = 43; + OBJECT_TRANSFORM = 44; + OBJECT_TRIGGER = 45; + OBJECT_TSCONFIGURATION = 46; + OBJECT_TSDICTIONARY = 47; + OBJECT_TSPARSER = 48; + OBJECT_TSTEMPLATE = 49; + OBJECT_TYPE = 50; + OBJECT_USER_MAPPING = 51; + OBJECT_VIEW = 52; +} + +enum DropBehavior +{ + DROP_BEHAVIOR_UNDEFINED = 0; + DROP_RESTRICT = 1; + DROP_CASCADE = 2; +} + +enum AlterTableType +{ + ALTER_TABLE_TYPE_UNDEFINED = 0; + AT_AddColumn = 1; + AT_AddColumnToView = 2; + AT_ColumnDefault = 3; + AT_CookedColumnDefault = 4; + AT_DropNotNull = 5; + AT_SetNotNull = 6; + AT_SetExpression = 7; + AT_DropExpression = 8; + AT_CheckNotNull = 9; + AT_SetStatistics = 10; + AT_SetOptions = 11; + AT_ResetOptions = 12; + AT_SetStorage = 13; + AT_SetCompression = 14; + AT_DropColumn = 15; + AT_AddIndex = 16; + AT_ReAddIndex = 17; + AT_AddConstraint = 18; + AT_ReAddConstraint = 19; + AT_ReAddDomainConstraint = 20; + AT_AlterConstraint = 21; + AT_ValidateConstraint = 22; + AT_AddIndexConstraint = 23; + AT_DropConstraint = 24; + AT_ReAddComment = 25; + AT_AlterColumnType = 26; + AT_AlterColumnGenericOptions = 27; + AT_ChangeOwner = 28; + AT_ClusterOn = 29; + AT_DropCluster = 30; + AT_SetLogged = 31; + AT_SetUnLogged = 32; + AT_DropOids = 33; + AT_SetAccessMethod = 34; + AT_SetTableSpace = 35; + AT_SetRelOptions = 36; + AT_ResetRelOptions = 37; + AT_ReplaceRelOptions = 38; + AT_EnableTrig = 39; + AT_EnableAlwaysTrig = 40; + AT_EnableReplicaTrig = 41; + AT_DisableTrig = 42; + AT_EnableTrigAll = 43; + AT_DisableTrigAll = 44; + AT_EnableTrigUser = 45; + AT_DisableTrigUser = 46; + AT_EnableRule = 47; + AT_EnableAlwaysRule = 48; + AT_EnableReplicaRule = 49; + AT_DisableRule = 50; + AT_AddInherit = 51; + AT_DropInherit = 52; + AT_AddOf = 53; + AT_DropOf = 54; + AT_ReplicaIdentity = 55; + AT_EnableRowSecurity = 56; + AT_DisableRowSecurity = 57; + AT_ForceRowSecurity = 58; + AT_NoForceRowSecurity = 59; + AT_GenericOptions = 60; + AT_AttachPartition = 61; + AT_DetachPartition = 62; + AT_DetachPartitionFinalize = 63; + AT_AddIdentity = 64; + AT_SetIdentity = 65; + AT_DropIdentity = 66; + AT_ReAddStatistics = 67; +} + +enum GrantTargetType +{ + GRANT_TARGET_TYPE_UNDEFINED = 0; + ACL_TARGET_OBJECT = 1; + ACL_TARGET_ALL_IN_SCHEMA = 2; + ACL_TARGET_DEFAULTS = 3; +} + +enum VariableSetKind +{ + VARIABLE_SET_KIND_UNDEFINED = 0; + VAR_SET_VALUE = 1; + VAR_SET_DEFAULT = 2; + VAR_SET_CURRENT = 3; + VAR_SET_MULTI = 4; + VAR_RESET = 5; + VAR_RESET_ALL = 6; +} + +enum ConstrType +{ + CONSTR_TYPE_UNDEFINED = 0; + CONSTR_NULL = 1; + CONSTR_NOTNULL = 2; + CONSTR_DEFAULT = 3; + CONSTR_IDENTITY = 4; + CONSTR_GENERATED = 5; + CONSTR_CHECK = 6; + CONSTR_PRIMARY = 7; + CONSTR_UNIQUE = 8; + CONSTR_EXCLUSION = 9; + CONSTR_FOREIGN = 10; + CONSTR_ATTR_DEFERRABLE = 11; + CONSTR_ATTR_NOT_DEFERRABLE = 12; + CONSTR_ATTR_DEFERRED = 13; + CONSTR_ATTR_IMMEDIATE = 14; +} + +enum ImportForeignSchemaType +{ + IMPORT_FOREIGN_SCHEMA_TYPE_UNDEFINED = 0; + FDW_IMPORT_SCHEMA_ALL = 1; + FDW_IMPORT_SCHEMA_LIMIT_TO = 2; + FDW_IMPORT_SCHEMA_EXCEPT = 3; +} + +enum RoleStmtType +{ + ROLE_STMT_TYPE_UNDEFINED = 0; + ROLESTMT_ROLE = 1; + ROLESTMT_USER = 2; + ROLESTMT_GROUP = 3; +} + +enum FetchDirection +{ + FETCH_DIRECTION_UNDEFINED = 0; + FETCH_FORWARD = 1; + FETCH_BACKWARD = 2; + FETCH_ABSOLUTE = 3; + FETCH_RELATIVE = 4; +} + +enum FunctionParameterMode +{ + FUNCTION_PARAMETER_MODE_UNDEFINED = 0; + FUNC_PARAM_IN = 1; + FUNC_PARAM_OUT = 2; + FUNC_PARAM_INOUT = 3; + FUNC_PARAM_VARIADIC = 4; + FUNC_PARAM_TABLE = 5; + FUNC_PARAM_DEFAULT = 6; +} + +enum TransactionStmtKind +{ + TRANSACTION_STMT_KIND_UNDEFINED = 0; + TRANS_STMT_BEGIN = 1; + TRANS_STMT_START = 2; + TRANS_STMT_COMMIT = 3; + TRANS_STMT_ROLLBACK = 4; + TRANS_STMT_SAVEPOINT = 5; + TRANS_STMT_RELEASE = 6; + TRANS_STMT_ROLLBACK_TO = 7; + TRANS_STMT_PREPARE = 8; + TRANS_STMT_COMMIT_PREPARED = 9; + TRANS_STMT_ROLLBACK_PREPARED = 10; +} + +enum ViewCheckOption +{ + VIEW_CHECK_OPTION_UNDEFINED = 0; + NO_CHECK_OPTION = 1; + LOCAL_CHECK_OPTION = 2; + CASCADED_CHECK_OPTION = 3; +} + +enum DiscardMode +{ + DISCARD_MODE_UNDEFINED = 0; + DISCARD_ALL = 1; + DISCARD_PLANS = 2; + DISCARD_SEQUENCES = 3; + DISCARD_TEMP = 4; +} + +enum ReindexObjectType +{ + REINDEX_OBJECT_TYPE_UNDEFINED = 0; + REINDEX_OBJECT_INDEX = 1; + REINDEX_OBJECT_TABLE = 2; + REINDEX_OBJECT_SCHEMA = 3; + REINDEX_OBJECT_SYSTEM = 4; + REINDEX_OBJECT_DATABASE = 5; +} + +enum AlterTSConfigType +{ + ALTER_TSCONFIG_TYPE_UNDEFINED = 0; + ALTER_TSCONFIG_ADD_MAPPING = 1; + ALTER_TSCONFIG_ALTER_MAPPING_FOR_TOKEN = 2; + ALTER_TSCONFIG_REPLACE_DICT = 3; + ALTER_TSCONFIG_REPLACE_DICT_FOR_TOKEN = 4; + ALTER_TSCONFIG_DROP_MAPPING = 5; +} + +enum PublicationObjSpecType +{ + PUBLICATION_OBJ_SPEC_TYPE_UNDEFINED = 0; + PUBLICATIONOBJ_TABLE = 1; + PUBLICATIONOBJ_TABLES_IN_SCHEMA = 2; + PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA = 3; + PUBLICATIONOBJ_CONTINUATION = 4; +} + +enum AlterPublicationAction +{ + ALTER_PUBLICATION_ACTION_UNDEFINED = 0; + AP_AddObjects = 1; + AP_DropObjects = 2; + AP_SetObjects = 3; +} + +enum AlterSubscriptionType +{ + ALTER_SUBSCRIPTION_TYPE_UNDEFINED = 0; + ALTER_SUBSCRIPTION_OPTIONS = 1; + ALTER_SUBSCRIPTION_CONNECTION = 2; + ALTER_SUBSCRIPTION_SET_PUBLICATION = 3; + ALTER_SUBSCRIPTION_ADD_PUBLICATION = 4; + ALTER_SUBSCRIPTION_DROP_PUBLICATION = 5; + ALTER_SUBSCRIPTION_REFRESH = 6; + ALTER_SUBSCRIPTION_ENABLED = 7; + ALTER_SUBSCRIPTION_SKIP = 8; +} + +enum OverridingKind +{ + OVERRIDING_KIND_UNDEFINED = 0; + OVERRIDING_NOT_SET = 1; + OVERRIDING_USER_VALUE = 2; + OVERRIDING_SYSTEM_VALUE = 3; +} + +enum OnCommitAction +{ + ON_COMMIT_ACTION_UNDEFINED = 0; + ONCOMMIT_NOOP = 1; + ONCOMMIT_PRESERVE_ROWS = 2; + ONCOMMIT_DELETE_ROWS = 3; + ONCOMMIT_DROP = 4; +} + +enum TableFuncType +{ + TABLE_FUNC_TYPE_UNDEFINED = 0; + TFT_XMLTABLE = 1; + TFT_JSON_TABLE = 2; +} + +enum ParamKind +{ + PARAM_KIND_UNDEFINED = 0; + PARAM_EXTERN = 1; + PARAM_EXEC = 2; + PARAM_SUBLINK = 3; + PARAM_MULTIEXPR = 4; +} + +enum CoercionContext +{ + COERCION_CONTEXT_UNDEFINED = 0; + COERCION_IMPLICIT = 1; + COERCION_ASSIGNMENT = 2; + COERCION_PLPGSQL = 3; + COERCION_EXPLICIT = 4; +} + +enum CoercionForm +{ + COERCION_FORM_UNDEFINED = 0; + COERCE_EXPLICIT_CALL = 1; + COERCE_EXPLICIT_CAST = 2; + COERCE_IMPLICIT_CAST = 3; + COERCE_SQL_SYNTAX = 4; +} + +enum BoolExprType +{ + BOOL_EXPR_TYPE_UNDEFINED = 0; + AND_EXPR = 1; + OR_EXPR = 2; + NOT_EXPR = 3; +} + +enum SubLinkType +{ + SUB_LINK_TYPE_UNDEFINED = 0; + EXISTS_SUBLINK = 1; + ALL_SUBLINK = 2; + ANY_SUBLINK = 3; + ROWCOMPARE_SUBLINK = 4; + EXPR_SUBLINK = 5; + MULTIEXPR_SUBLINK = 6; + ARRAY_SUBLINK = 7; + CTE_SUBLINK = 8; +} + +enum RowCompareType +{ + ROW_COMPARE_TYPE_UNDEFINED = 0; + ROWCOMPARE_LT = 1; + ROWCOMPARE_LE = 2; + ROWCOMPARE_EQ = 3; + ROWCOMPARE_GE = 4; + ROWCOMPARE_GT = 5; + ROWCOMPARE_NE = 6; +} + +enum MinMaxOp +{ + MIN_MAX_OP_UNDEFINED = 0; + IS_GREATEST = 1; + IS_LEAST = 2; +} + +enum SQLValueFunctionOp +{ + SQLVALUE_FUNCTION_OP_UNDEFINED = 0; + SVFOP_CURRENT_DATE = 1; + SVFOP_CURRENT_TIME = 2; + SVFOP_CURRENT_TIME_N = 3; + SVFOP_CURRENT_TIMESTAMP = 4; + SVFOP_CURRENT_TIMESTAMP_N = 5; + SVFOP_LOCALTIME = 6; + SVFOP_LOCALTIME_N = 7; + SVFOP_LOCALTIMESTAMP = 8; + SVFOP_LOCALTIMESTAMP_N = 9; + SVFOP_CURRENT_ROLE = 10; + SVFOP_CURRENT_USER = 11; + SVFOP_USER = 12; + SVFOP_SESSION_USER = 13; + SVFOP_CURRENT_CATALOG = 14; + SVFOP_CURRENT_SCHEMA = 15; +} + +enum XmlExprOp +{ + XML_EXPR_OP_UNDEFINED = 0; + IS_XMLCONCAT = 1; + IS_XMLELEMENT = 2; + IS_XMLFOREST = 3; + IS_XMLPARSE = 4; + IS_XMLPI = 5; + IS_XMLROOT = 6; + IS_XMLSERIALIZE = 7; + IS_DOCUMENT = 8; +} + +enum XmlOptionType +{ + XML_OPTION_TYPE_UNDEFINED = 0; + XMLOPTION_DOCUMENT = 1; + XMLOPTION_CONTENT = 2; +} + +enum JsonEncoding +{ + JSON_ENCODING_UNDEFINED = 0; + JS_ENC_DEFAULT = 1; + JS_ENC_UTF8 = 2; + JS_ENC_UTF16 = 3; + JS_ENC_UTF32 = 4; +} + +enum JsonFormatType +{ + JSON_FORMAT_TYPE_UNDEFINED = 0; + JS_FORMAT_DEFAULT = 1; + JS_FORMAT_JSON = 2; + JS_FORMAT_JSONB = 3; +} + +enum JsonConstructorType +{ + JSON_CONSTRUCTOR_TYPE_UNDEFINED = 0; + JSCTOR_JSON_OBJECT = 1; + JSCTOR_JSON_ARRAY = 2; + JSCTOR_JSON_OBJECTAGG = 3; + JSCTOR_JSON_ARRAYAGG = 4; + JSCTOR_JSON_PARSE = 5; + JSCTOR_JSON_SCALAR = 6; + JSCTOR_JSON_SERIALIZE = 7; +} + +enum JsonValueType +{ + JSON_VALUE_TYPE_UNDEFINED = 0; + JS_TYPE_ANY = 1; + JS_TYPE_OBJECT = 2; + JS_TYPE_ARRAY = 3; + JS_TYPE_SCALAR = 4; +} + +enum JsonWrapper +{ + JSON_WRAPPER_UNDEFINED = 0; + JSW_UNSPEC = 1; + JSW_NONE = 2; + JSW_CONDITIONAL = 3; + JSW_UNCONDITIONAL = 4; +} + +enum JsonBehaviorType +{ + JSON_BEHAVIOR_TYPE_UNDEFINED = 0; + JSON_BEHAVIOR_NULL = 1; + JSON_BEHAVIOR_ERROR = 2; + JSON_BEHAVIOR_EMPTY = 3; + JSON_BEHAVIOR_TRUE = 4; + JSON_BEHAVIOR_FALSE = 5; + JSON_BEHAVIOR_UNKNOWN = 6; + JSON_BEHAVIOR_EMPTY_ARRAY = 7; + JSON_BEHAVIOR_EMPTY_OBJECT = 8; + JSON_BEHAVIOR_DEFAULT = 9; +} + +enum JsonExprOp +{ + JSON_EXPR_OP_UNDEFINED = 0; + JSON_EXISTS_OP = 1; + JSON_QUERY_OP = 2; + JSON_VALUE_OP = 3; + JSON_TABLE_OP = 4; +} + +enum NullTestType +{ + NULL_TEST_TYPE_UNDEFINED = 0; + IS_NULL = 1; + IS_NOT_NULL = 2; +} + +enum BoolTestType +{ + BOOL_TEST_TYPE_UNDEFINED = 0; + IS_TRUE = 1; + IS_NOT_TRUE = 2; + IS_FALSE = 3; + IS_NOT_FALSE = 4; + IS_UNKNOWN = 5; + IS_NOT_UNKNOWN = 6; +} + +enum MergeMatchKind +{ + MERGE_MATCH_KIND_UNDEFINED = 0; + MERGE_WHEN_MATCHED = 1; + MERGE_WHEN_NOT_MATCHED_BY_SOURCE = 2; + MERGE_WHEN_NOT_MATCHED_BY_TARGET = 3; +} + +enum CmdType +{ + CMD_TYPE_UNDEFINED = 0; + CMD_UNKNOWN = 1; + CMD_SELECT = 2; + CMD_UPDATE = 3; + CMD_INSERT = 4; + CMD_DELETE = 5; + CMD_MERGE = 6; + CMD_UTILITY = 7; + CMD_NOTHING = 8; +} + +enum JoinType +{ + JOIN_TYPE_UNDEFINED = 0; + JOIN_INNER = 1; + JOIN_LEFT = 2; + JOIN_FULL = 3; + JOIN_RIGHT = 4; + JOIN_SEMI = 5; + JOIN_ANTI = 6; + JOIN_RIGHT_ANTI = 7; + JOIN_UNIQUE_OUTER = 8; + JOIN_UNIQUE_INNER = 9; +} + +enum AggStrategy +{ + AGG_STRATEGY_UNDEFINED = 0; + AGG_PLAIN = 1; + AGG_SORTED = 2; + AGG_HASHED = 3; + AGG_MIXED = 4; +} + +enum AggSplit +{ + AGG_SPLIT_UNDEFINED = 0; + AGGSPLIT_SIMPLE = 1; + AGGSPLIT_INITIAL_SERIAL = 2; + AGGSPLIT_FINAL_DESERIAL = 3; +} + +enum SetOpCmd +{ + SET_OP_CMD_UNDEFINED = 0; + SETOPCMD_INTERSECT = 1; + SETOPCMD_INTERSECT_ALL = 2; + SETOPCMD_EXCEPT = 3; + SETOPCMD_EXCEPT_ALL = 4; +} + +enum SetOpStrategy +{ + SET_OP_STRATEGY_UNDEFINED = 0; + SETOP_SORTED = 1; + SETOP_HASHED = 2; +} + +enum OnConflictAction +{ + ON_CONFLICT_ACTION_UNDEFINED = 0; + ONCONFLICT_NONE = 1; + ONCONFLICT_NOTHING = 2; + ONCONFLICT_UPDATE = 3; +} + +enum LimitOption +{ + LIMIT_OPTION_UNDEFINED = 0; + LIMIT_OPTION_DEFAULT = 1; + LIMIT_OPTION_COUNT = 2; + LIMIT_OPTION_WITH_TIES = 3; +} + +enum LockClauseStrength +{ + LOCK_CLAUSE_STRENGTH_UNDEFINED = 0; + LCS_NONE = 1; + LCS_FORKEYSHARE = 2; + LCS_FORSHARE = 3; + LCS_FORNOKEYUPDATE = 4; + LCS_FORUPDATE = 5; +} + +enum LockWaitPolicy +{ + LOCK_WAIT_POLICY_UNDEFINED = 0; + LockWaitBlock = 1; + LockWaitSkip = 2; + LockWaitError = 3; +} + +enum LockTupleMode +{ + LOCK_TUPLE_MODE_UNDEFINED = 0; + LockTupleKeyShare = 1; + LockTupleShare = 2; + LockTupleNoKeyExclusive = 3; + LockTupleExclusive = 4; +} + +message ScanToken { + int32 start = 1; + int32 end = 2; + Token token = 4; + KeywordKind keyword_kind = 5; +} + +enum KeywordKind { + NO_KEYWORD = 0; + UNRESERVED_KEYWORD = 1; + COL_NAME_KEYWORD = 2; + TYPE_FUNC_NAME_KEYWORD = 3; + RESERVED_KEYWORD = 4; +} + +enum Token { + NUL = 0; + // Single-character tokens that are returned 1:1 (identical with "self" list in scan.l) + // Either supporting syntax, or single-character operators (some can be both) + // Also see https://www.postgresql.org/docs/12/sql-syntax-lexical.html#SQL-SYNTAX-SPECIAL-CHARS + ASCII_36 = 36; // "$" + ASCII_37 = 37; // "%" + ASCII_40 = 40; // "(" + ASCII_41 = 41; // ")" + ASCII_42 = 42; // "*" + ASCII_43 = 43; // "+" + ASCII_44 = 44; // "," + ASCII_45 = 45; // "-" + ASCII_46 = 46; // "." + ASCII_47 = 47; // "/" + ASCII_58 = 58; // ":" + ASCII_59 = 59; // ";" + ASCII_60 = 60; // "<" + ASCII_61 = 61; // "=" + ASCII_62 = 62; // ">" + ASCII_63 = 63; // "?" + ASCII_91 = 91; // "[" + ASCII_92 = 92; // "\" + ASCII_93 = 93; // "]" + ASCII_94 = 94; // "^" + // Named tokens in scan.l + IDENT = 258; + UIDENT = 259; + FCONST = 260; + SCONST = 261; + USCONST = 262; + BCONST = 263; + XCONST = 264; + Op = 265; + ICONST = 266; + PARAM = 267; + TYPECAST = 268; + DOT_DOT = 269; + COLON_EQUALS = 270; + EQUALS_GREATER = 271; + LESS_EQUALS = 272; + GREATER_EQUALS = 273; + NOT_EQUALS = 274; + SQL_COMMENT = 275; + C_COMMENT = 276; + ABORT_P = 277; + ABSENT = 278; + ABSOLUTE_P = 279; + ACCESS = 280; + ACTION = 281; + ADD_P = 282; + ADMIN = 283; + AFTER = 284; + AGGREGATE = 285; + ALL = 286; + ALSO = 287; + ALTER = 288; + ALWAYS = 289; + ANALYSE = 290; + ANALYZE = 291; + AND = 292; + ANY = 293; + ARRAY = 294; + AS = 295; + ASC = 296; + ASENSITIVE = 297; + ASSERTION = 298; + ASSIGNMENT = 299; + ASYMMETRIC = 300; + ATOMIC = 301; + AT = 302; + ATTACH = 303; + ATTRIBUTE = 304; + AUTHORIZATION = 305; + BACKWARD = 306; + BEFORE = 307; + BEGIN_P = 308; + BETWEEN = 309; + BIGINT = 310; + BINARY = 311; + BIT = 312; + BOOLEAN_P = 313; + BOTH = 314; + BREADTH = 315; + BY = 316; + CACHE = 317; + CALL = 318; + CALLED = 319; + CASCADE = 320; + CASCADED = 321; + CASE = 322; + CAST = 323; + CATALOG_P = 324; + CHAIN = 325; + CHAR_P = 326; + CHARACTER = 327; + CHARACTERISTICS = 328; + CHECK = 329; + CHECKPOINT = 330; + CLASS = 331; + CLOSE = 332; + CLUSTER = 333; + COALESCE = 334; + COLLATE = 335; + COLLATION = 336; + COLUMN = 337; + COLUMNS = 338; + COMMENT = 339; + COMMENTS = 340; + COMMIT = 341; + COMMITTED = 342; + COMPRESSION = 343; + CONCURRENTLY = 344; + CONDITIONAL = 345; + CONFIGURATION = 346; + CONFLICT = 347; + CONNECTION = 348; + CONSTRAINT = 349; + CONSTRAINTS = 350; + CONTENT_P = 351; + CONTINUE_P = 352; + CONVERSION_P = 353; + COPY = 354; + COST = 355; + CREATE = 356; + CROSS = 357; + CSV = 358; + CUBE = 359; + CURRENT_P = 360; + CURRENT_CATALOG = 361; + CURRENT_DATE = 362; + CURRENT_ROLE = 363; + CURRENT_SCHEMA = 364; + CURRENT_TIME = 365; + CURRENT_TIMESTAMP = 366; + CURRENT_USER = 367; + CURSOR = 368; + CYCLE = 369; + DATA_P = 370; + DATABASE = 371; + DAY_P = 372; + DEALLOCATE = 373; + DEC = 374; + DECIMAL_P = 375; + DECLARE = 376; + DEFAULT = 377; + DEFAULTS = 378; + DEFERRABLE = 379; + DEFERRED = 380; + DEFINER = 381; + DELETE_P = 382; + DELIMITER = 383; + DELIMITERS = 384; + DEPENDS = 385; + DEPTH = 386; + DESC = 387; + DETACH = 388; + DICTIONARY = 389; + DISABLE_P = 390; + DISCARD = 391; + DISTINCT = 392; + DO = 393; + DOCUMENT_P = 394; + DOMAIN_P = 395; + DOUBLE_P = 396; + DROP = 397; + EACH = 398; + ELSE = 399; + EMPTY_P = 400; + ENABLE_P = 401; + ENCODING = 402; + ENCRYPTED = 403; + END_P = 404; + ENUM_P = 405; + ERROR_P = 406; + ESCAPE = 407; + EVENT = 408; + EXCEPT = 409; + EXCLUDE = 410; + EXCLUDING = 411; + EXCLUSIVE = 412; + EXECUTE = 413; + EXISTS = 414; + EXPLAIN = 415; + EXPRESSION = 416; + EXTENSION = 417; + EXTERNAL = 418; + EXTRACT = 419; + FALSE_P = 420; + FAMILY = 421; + FETCH = 422; + FILTER = 423; + FINALIZE = 424; + FIRST_P = 425; + FLOAT_P = 426; + FOLLOWING = 427; + FOR = 428; + FORCE = 429; + FOREIGN = 430; + FORMAT = 431; + FORWARD = 432; + FREEZE = 433; + FROM = 434; + FULL = 435; + FUNCTION = 436; + FUNCTIONS = 437; + GENERATED = 438; + GLOBAL = 439; + GRANT = 440; + GRANTED = 441; + GREATEST = 442; + GROUP_P = 443; + GROUPING = 444; + GROUPS = 445; + HANDLER = 446; + HAVING = 447; + HEADER_P = 448; + HOLD = 449; + HOUR_P = 450; + IDENTITY_P = 451; + IF_P = 452; + ILIKE = 453; + IMMEDIATE = 454; + IMMUTABLE = 455; + IMPLICIT_P = 456; + IMPORT_P = 457; + IN_P = 458; + INCLUDE = 459; + INCLUDING = 460; + INCREMENT = 461; + INDENT = 462; + INDEX = 463; + INDEXES = 464; + INHERIT = 465; + INHERITS = 466; + INITIALLY = 467; + INLINE_P = 468; + INNER_P = 469; + INOUT = 470; + INPUT_P = 471; + INSENSITIVE = 472; + INSERT = 473; + INSTEAD = 474; + INT_P = 475; + INTEGER = 476; + INTERSECT = 477; + INTERVAL = 478; + INTO = 479; + INVOKER = 480; + IS = 481; + ISNULL = 482; + ISOLATION = 483; + JOIN = 484; + JSON = 485; + JSON_ARRAY = 486; + JSON_ARRAYAGG = 487; + JSON_EXISTS = 488; + JSON_OBJECT = 489; + JSON_OBJECTAGG = 490; + JSON_QUERY = 491; + JSON_SCALAR = 492; + JSON_SERIALIZE = 493; + JSON_TABLE = 494; + JSON_VALUE = 495; + KEEP = 496; + KEY = 497; + KEYS = 498; + LABEL = 499; + LANGUAGE = 500; + LARGE_P = 501; + LAST_P = 502; + LATERAL_P = 503; + LEADING = 504; + LEAKPROOF = 505; + LEAST = 506; + LEFT = 507; + LEVEL = 508; + LIKE = 509; + LIMIT = 510; + LISTEN = 511; + LOAD = 512; + LOCAL = 513; + LOCALTIME = 514; + LOCALTIMESTAMP = 515; + LOCATION = 516; + LOCK_P = 517; + LOCKED = 518; + LOGGED = 519; + MAPPING = 520; + MATCH = 521; + MATCHED = 522; + MATERIALIZED = 523; + MAXVALUE = 524; + MERGE = 525; + MERGE_ACTION = 526; + METHOD = 527; + MINUTE_P = 528; + MINVALUE = 529; + MODE = 530; + MONTH_P = 531; + MOVE = 532; + NAME_P = 533; + NAMES = 534; + NATIONAL = 535; + NATURAL = 536; + NCHAR = 537; + NESTED = 538; + NEW = 539; + NEXT = 540; + NFC = 541; + NFD = 542; + NFKC = 543; + NFKD = 544; + NO = 545; + NONE = 546; + NORMALIZE = 547; + NORMALIZED = 548; + NOT = 549; + NOTHING = 550; + NOTIFY = 551; + NOTNULL = 552; + NOWAIT = 553; + NULL_P = 554; + NULLIF = 555; + NULLS_P = 556; + NUMERIC = 557; + OBJECT_P = 558; + OF = 559; + OFF = 560; + OFFSET = 561; + OIDS = 562; + OLD = 563; + OMIT = 564; + ON = 565; + ONLY = 566; + OPERATOR = 567; + OPTION = 568; + OPTIONS = 569; + OR = 570; + ORDER = 571; + ORDINALITY = 572; + OTHERS = 573; + OUT_P = 574; + OUTER_P = 575; + OVER = 576; + OVERLAPS = 577; + OVERLAY = 578; + OVERRIDING = 579; + OWNED = 580; + OWNER = 581; + PARALLEL = 582; + PARAMETER = 583; + PARSER = 584; + PARTIAL = 585; + PARTITION = 586; + PASSING = 587; + PASSWORD = 588; + PATH = 589; + PLACING = 590; + PLAN = 591; + PLANS = 592; + POLICY = 593; + POSITION = 594; + PRECEDING = 595; + PRECISION = 596; + PRESERVE = 597; + PREPARE = 598; + PREPARED = 599; + PRIMARY = 600; + PRIOR = 601; + PRIVILEGES = 602; + PROCEDURAL = 603; + PROCEDURE = 604; + PROCEDURES = 605; + PROGRAM = 606; + PUBLICATION = 607; + QUOTE = 608; + QUOTES = 609; + RANGE = 610; + READ = 611; + REAL = 612; + REASSIGN = 613; + RECHECK = 614; + RECURSIVE = 615; + REF_P = 616; + REFERENCES = 617; + REFERENCING = 618; + REFRESH = 619; + REINDEX = 620; + RELATIVE_P = 621; + RELEASE = 622; + RENAME = 623; + REPEATABLE = 624; + REPLACE = 625; + REPLICA = 626; + RESET = 627; + RESTART = 628; + RESTRICT = 629; + RETURN = 630; + RETURNING = 631; + RETURNS = 632; + REVOKE = 633; + RIGHT = 634; + ROLE = 635; + ROLLBACK = 636; + ROLLUP = 637; + ROUTINE = 638; + ROUTINES = 639; + ROW = 640; + ROWS = 641; + RULE = 642; + SAVEPOINT = 643; + SCALAR = 644; + SCHEMA = 645; + SCHEMAS = 646; + SCROLL = 647; + SEARCH = 648; + SECOND_P = 649; + SECURITY = 650; + SELECT = 651; + SEQUENCE = 652; + SEQUENCES = 653; + SERIALIZABLE = 654; + SERVER = 655; + SESSION = 656; + SESSION_USER = 657; + SET = 658; + SETS = 659; + SETOF = 660; + SHARE = 661; + SHOW = 662; + SIMILAR = 663; + SIMPLE = 664; + SKIP = 665; + SMALLINT = 666; + SNAPSHOT = 667; + SOME = 668; + SOURCE = 669; + SQL_P = 670; + STABLE = 671; + STANDALONE_P = 672; + START = 673; + STATEMENT = 674; + STATISTICS = 675; + STDIN = 676; + STDOUT = 677; + STORAGE = 678; + STORED = 679; + STRICT_P = 680; + STRING_P = 681; + STRIP_P = 682; + SUBSCRIPTION = 683; + SUBSTRING = 684; + SUPPORT = 685; + SYMMETRIC = 686; + SYSID = 687; + SYSTEM_P = 688; + SYSTEM_USER = 689; + TABLE = 690; + TABLES = 691; + TABLESAMPLE = 692; + TABLESPACE = 693; + TARGET = 694; + TEMP = 695; + TEMPLATE = 696; + TEMPORARY = 697; + TEXT_P = 698; + THEN = 699; + TIES = 700; + TIME = 701; + TIMESTAMP = 702; + TO = 703; + TRAILING = 704; + TRANSACTION = 705; + TRANSFORM = 706; + TREAT = 707; + TRIGGER = 708; + TRIM = 709; + TRUE_P = 710; + TRUNCATE = 711; + TRUSTED = 712; + TYPE_P = 713; + TYPES_P = 714; + UESCAPE = 715; + UNBOUNDED = 716; + UNCONDITIONAL = 717; + UNCOMMITTED = 718; + UNENCRYPTED = 719; + UNION = 720; + UNIQUE = 721; + UNKNOWN = 722; + UNLISTEN = 723; + UNLOGGED = 724; + UNTIL = 725; + UPDATE = 726; + USER = 727; + USING = 728; + VACUUM = 729; + VALID = 730; + VALIDATE = 731; + VALIDATOR = 732; + VALUE_P = 733; + VALUES = 734; + VARCHAR = 735; + VARIADIC = 736; + VARYING = 737; + VERBOSE = 738; + VERSION_P = 739; + VIEW = 740; + VIEWS = 741; + VOLATILE = 742; + WHEN = 743; + WHERE = 744; + WHITESPACE_P = 745; + WINDOW = 746; + WITH = 747; + WITHIN = 748; + WITHOUT = 749; + WORK = 750; + WRAPPER = 751; + WRITE = 752; + XML_P = 753; + XMLATTRIBUTES = 754; + XMLCONCAT = 755; + XMLELEMENT = 756; + XMLEXISTS = 757; + XMLFOREST = 758; + XMLNAMESPACES = 759; + XMLPARSE = 760; + XMLPI = 761; + XMLROOT = 762; + XMLSERIALIZE = 763; + XMLTABLE = 764; + YEAR_P = 765; + YES_P = 766; + ZONE = 767; + FORMAT_LA = 768; + NOT_LA = 769; + NULLS_LA = 770; + WITH_LA = 771; + WITHOUT_LA = 772; + MODE_TYPE_NAME = 773; + MODE_PLPGSQL_EXPR = 774; + MODE_PLPGSQL_ASSIGN1 = 775; + MODE_PLPGSQL_ASSIGN2 = 776; + MODE_PLPGSQL_ASSIGN3 = 777; + UMINUS = 778; +} diff --git a/crates/pgt_pretty_print_codegen/src/group_kind.rs b/crates/pgt_pretty_print_codegen/src/group_kind.rs new file mode 100644 index 000000000..52fe25d00 --- /dev/null +++ b/crates/pgt_pretty_print_codegen/src/group_kind.rs @@ -0,0 +1,24 @@ +use quote::{format_ident, quote}; + +use crate::proto_analyser::ProtoAnalyzer; + +pub fn group_kind_mod(analyser: ProtoAnalyzer) -> proc_macro2::TokenStream { + let node_variants = analyser.enum_variants(); + + let mut node_enum_variants = Vec::new(); + + for variant in &node_variants { + let variant_ident = format_ident!("{}", &variant.name); + + node_enum_variants.push(quote! { + #variant_ident + }); + } + + quote! { + #[derive(Clone, PartialEq, Debug)] + pub enum GroupKind { + #(#node_enum_variants),*, + } + } +} diff --git a/crates/pgt_pretty_print_codegen/src/keywords.rs b/crates/pgt_pretty_print_codegen/src/keywords.rs new file mode 100644 index 000000000..f0104c8d3 --- /dev/null +++ b/crates/pgt_pretty_print_codegen/src/keywords.rs @@ -0,0 +1,43 @@ +// from https://github.com/sbdchd/squawk/blob/ac9f90c3b2be8d2c46fd5454eb48975afd268dbe/crates/xtask/src/keywords.rs +use anyhow::{Context, Ok, Result}; +use std::path; + +fn parse_header() -> Result> { + // use the environment variable set by the build script to locate the kwlist.h file + let kwlist_file = path::PathBuf::from(env!("PG_QUERY_KWLIST_PATH")); + let data = std::fs::read_to_string(kwlist_file).context("Failed to read kwlist.h")?; + + let mut keywords = Vec::new(); + + for line in data.lines() { + if line.starts_with("PG_KEYWORD") { + let line = line + .split(&['(', ')']) + .nth(1) + .context("Invalid kwlist.h structure")?; + + let row_items: Vec<&str> = line.split(',').collect(); + + match row_items[..] { + [name, _value, _category, _is_bare_label] => { + let name = name.trim().replace('\"', ""); + keywords.push(name); + } + _ => anyhow::bail!("Problem reading kwlist.h row"), + } + } + } + + Ok(keywords) +} + +pub(crate) struct KeywordKinds { + pub(crate) all_keywords: Vec, +} + +pub(crate) fn keyword_kinds() -> Result { + let mut all_keywords = parse_header()?; + all_keywords.sort(); + + Ok(KeywordKinds { all_keywords }) +} diff --git a/crates/pgt_pretty_print_codegen/src/lib.rs b/crates/pgt_pretty_print_codegen/src/lib.rs new file mode 100644 index 000000000..5df181b85 --- /dev/null +++ b/crates/pgt_pretty_print_codegen/src/lib.rs @@ -0,0 +1,24 @@ +mod group_kind; +mod keywords; +mod proto_analyser; +mod token_kind; + +use std::path; + +use proto_analyser::ProtoAnalyzer; +use token_kind::token_kind_mod; + +#[proc_macro] +pub fn token_kind_codegen(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { + token_kind_mod().into() +} + +#[proc_macro] +pub fn group_kind_codegen(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let analyser = ProtoAnalyzer::from(&proto_file_path()).unwrap(); + group_kind::group_kind_mod(analyser).into() +} + +fn proto_file_path() -> path::PathBuf { + path::PathBuf::from(env!("PG_QUERY_PROTO_PATH")) +} diff --git a/crates/pgt_pretty_print_codegen/src/proto_analyser.rs b/crates/pgt_pretty_print_codegen/src/proto_analyser.rs new file mode 100644 index 000000000..28abdf3e4 --- /dev/null +++ b/crates/pgt_pretty_print_codegen/src/proto_analyser.rs @@ -0,0 +1,52 @@ +use std::path::Path; + +use convert_case::{Case, Casing}; +use prost_reflect::{DescriptorError, DescriptorPool}; + +pub(crate) struct ProtoAnalyzer { + pool: DescriptorPool, +} + +pub(crate) struct EnumVariant { + pub name: String, +} + +impl ProtoAnalyzer { + pub fn from(proto_file: &Path) -> Result { + let include_path = proto_file + .parent() + .expect("Proto file must have a parent directory"); + + // protox::compile expects the proto file to be relative to the include path + let file_name = proto_file + .file_name() + .expect("Proto file must have a file name"); + + let pool = DescriptorPool::from_file_descriptor_set( + protox::compile([file_name], [include_path]).expect("unable to parse"), + )?; + + let analyzer = ProtoAnalyzer { pool }; + + Ok(analyzer) + } + + pub fn enum_variants(&self) -> Vec { + let node = self + .pool + .get_message_by_name(".pg_query.Node") + .expect("Node message not found"); + + let mut variants = Vec::new(); + for field in node.fields() { + // The prost-generated variant name is derived from the field name using snake_case to PascalCase conversion + // For example: ctesearch_clause -> CtesearchClause + let field_name = field.name(); + let variant_name = field_name.to_case(Case::Pascal); + + variants.push(EnumVariant { name: variant_name }); + } + + variants + } +} diff --git a/crates/pgt_pretty_print_codegen/src/token_kind.rs b/crates/pgt_pretty_print_codegen/src/token_kind.rs new file mode 100644 index 000000000..a2773ce3d --- /dev/null +++ b/crates/pgt_pretty_print_codegen/src/token_kind.rs @@ -0,0 +1,157 @@ +use convert_case::{Case, Casing}; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; + +use crate::keywords::{KeywordKinds, keyword_kinds}; + +const STRUCTURAL_PUNCT: &[(&str, &str)] = &[ + (";", "SEMICOLON"), // Statement terminator - structural + (",", "COMMA"), // List separator - structural + ("(", "L_PAREN"), // Grouping - structural + (")", "R_PAREN"), // Grouping - structural + ("[", "L_BRACK"), // Array indexing - structural + ("]", "R_BRACK"), // Array indexing - structural + (".", "DOT"), // Qualified names (schema.table) - structural +]; + +const PUNCT: &[(&str, &str)] = &[ + ("$", "DOLLAR"), // Positional parameters ($1, $2) - special parsing + ("::", "DOUBLE_COLON"), // Type cast operator - special syntax +]; + +const EXTRA: &[&str] = &["POSITIONAL_PARAM", "COMMENT"]; + +const LITERALS: &[&str] = &[ + "BIT_STRING", + "BYTE_STRING", + "DOLLAR_QUOTED_STRING", + "ESC_STRING", + "FLOAT_NUMBER", + "INT_NUMBER", + "NULL", + "STRING", + "IDENT", + "BOOLEAN", +]; + +const VARIANT_DATA: &[(&str, &str)] = &[ + ("STRING", "String"), + ("ESC_STRING", "String"), // E'hello\nworld' + ("DOLLAR_QUOTED_STRING", "String"), // $$hello world$$ + ("INT_NUMBER", "i64"), // 123, -456 + ("FLOAT_NUMBER", "f64"), // 123.45, 1.2e-3 + ("BIT_STRING", "String"), // B'1010', X'FF' + ("BYTE_STRING", "String"), // Similar to bit string + ("IDENT", "String"), // user_id, table_name + ("POSITIONAL_PARAM", "u32"), // $1, $2, $3 (the number matters!) + ("COMMENT", "String"), // /* comment text */ + ("BOOLEAN", "bool"), // true, false +]; + +pub fn token_kind_mod() -> proc_macro2::TokenStream { + let keywords = keyword_kinds().expect("Failed to get keyword kinds"); + + let KeywordKinds { all_keywords, .. } = keywords; + + let mut enum_variants: Vec = Vec::new(); + let mut from_kw_match_arms: Vec = Vec::new(); + let mut render_kw_match_arms: Vec = Vec::new(); + + // helper function to create a variant quote for enum + // used to handle variants with data types + let variant_quote = |name: &str| { + let variant_name = format_ident!("{}", name); + + if let Some((_, data_type)) = VARIANT_DATA.iter().find(|&&(n, _)| n == name) { + let data_type = format_ident!("{}", data_type); + quote! { #variant_name(#data_type) } + } else { + quote! { #variant_name } + } + }; + + // collect keywords + for kw in &all_keywords { + if kw.to_uppercase().contains("WHITESPACE") { + continue; // Skip whitespace as it is handled separately + } + + let kind_ident = format_ident!("{}_KW", kw.to_case(Case::UpperSnake)); + + enum_variants.push(quote! { #kind_ident }); + from_kw_match_arms.push(quote! { + #kw => Some(TokenKind::#kind_ident) + }); + render_kw_match_arms.push(quote! { + TokenKind::#kind_ident => #kw.to_uppercase() + }); + } + + // collect extra keywords + EXTRA.iter().for_each(|&name| { + enum_variants.push(variant_quote(name)); + }); + + // collect punctuations + STRUCTURAL_PUNCT.iter().for_each(|&(_ascii_name, variant)| { + let variant_name = format_ident!("{}", variant); + enum_variants.push(quote! { #variant_name }); + }); + PUNCT.iter().for_each(|&(_ascii_name, variant)| { + let variant_name = format_ident!("{}", variant); + enum_variants.push(quote! { #variant_name }); + }); + + // collect literals + LITERALS.iter().for_each(|&name| { + enum_variants.push(variant_quote(name)); + }); + + quote! { + #[derive(Clone, PartialEq, Debug)] + pub enum TokenKind { + #(#enum_variants),*, + } + + impl TokenKind { + pub(crate) fn from_keyword(ident: &str) -> Option { + let lower_ident = ident.to_ascii_lowercase(); + match lower_ident.as_str() { + #(#from_kw_match_arms),*, + _ => None + } + } + } + + impl TokenKind { + pub fn render(&self) -> String { + match self { + TokenKind::SEMICOLON => ";".to_string(), + TokenKind::COMMA => ",".to_string(), + TokenKind::L_PAREN => "(".to_string(), + TokenKind::R_PAREN => ")".to_string(), + TokenKind::L_BRACK => "[".to_string(), + TokenKind::R_BRACK => "]".to_string(), + TokenKind::DOT => ".".to_string(), + TokenKind::DOUBLE_COLON => "::".to_string(), + TokenKind::DOLLAR => "$".to_string(), + TokenKind::IDENT(ident) => ident.clone(), + TokenKind::STRING(s) => s.clone(), + TokenKind::ESC_STRING(s) => s.clone(), + TokenKind::DOLLAR_QUOTED_STRING(s) => s.clone(), + TokenKind::INT_NUMBER(n) => n.to_string(), + TokenKind::FLOAT_NUMBER(n) => n.to_string(), + TokenKind::BIT_STRING(s) => s.clone(), + TokenKind::BYTE_STRING(s) => s.clone(), + TokenKind::BOOLEAN(b) => match b { + true => "TRUE".to_string(), + false => "FALSE".to_string(), + }, + TokenKind::NULL => "NULL".to_string(), + #(#render_kw_match_arms),*, + _ => format!("{:?}", self), // Fallback for other variants + } + } + } + } +} diff --git a/justfile b/justfile index 18b4ed35d..f759d74b2 100644 --- a/justfile +++ b/justfile @@ -30,6 +30,33 @@ gen-lint: cargo run -p docs_codegen just format +# Fix cargo check issues using Claude +fix-cargo-check: + unset ANTHROPIC_API_KEY && claude --dangerously-skip-permissions -p "Please run cargo check and fix any issues. It is okay to remove things that are not fully implemented yet." + +# Run the autonomous pretty print implementation generator +pretty-print: fix-cargo-check + cargo xtask agentic + +# Run the autonomous pretty print implementation generator with infinite retry loop +pretty-print-forever: fix-cargo-check + #!/bin/bash + echo "Starting autonomous pretty print generator with error recovery..." + while true; do + echo "$(date): Starting agentic loop iteration..." + if cargo xtask agentic; then + echo "$(date): Agentic loop completed successfully!" + break + else + echo "$(date): Agentic loop failed, waiting 6 hours 1 minute before retry..." + sleep 3660 # 1 hour 1 minute = 1 * 60 * 60 + 1 * 60 = 3600 + 60 = 3660 seconds + echo "$(date): Resuming after 1-hour 1-minute wait..." + fi + done + +fix-and-push: fix-cargo-check + just quick-modify + # Creates a new lint rule in the given path, with the given name. Name has to be camel case. Group should be lowercase. new-lintrule group rulename severity="error": cargo run -p xtask_codegen -- new-lintrule --category=lint --name={{rulename}} --group={{group}} --severity={{severity}} @@ -146,6 +173,49 @@ quick-modify: git commit -m "progress" git push +# Run a claude agent with the given agentic prompt file. +# Commented out by default to avoid accidental usage that may incur costs. +agentic name: + unset ANTHROPIC_API_KEY && claude --dangerously-skip-permissions -p "please read agentic/{{name}}.md and follow the instructions closely" + +# Run agentic loop that breaks when task is complete +agentic-loop-forever name: + #!/usr/bin/env bash + while true; do + echo "$(date): Calling Claude..." + output=$(just agentic {{name}} 2>&1) + exit_code=$? + echo "$output" + + if [ $exit_code -ne 0 ]; then + echo "$(date): Error occurred, waiting 61 minutes before retry..." + sleep 3660 # 61 minutes + continue + fi + + if echo "$output" | grep -q "TASK COMPLETE"; then + echo "$(date): Task completed!" + break + fi + done + +agentic-loop name: + #!/usr/bin/env bash + while true; do + echo "$(date): Calling Claude..." + output=$(just agentic {{name}} 2>&1) + exit_code=$? + echo "$output" + if [ $exit_code -ne 0 ]; then + echo "$(date): Error occurred, exiting..." + exit $exit_code + fi + if echo "$output" | grep -q "TASK COMPLETE"; then + echo "$(date): Task completed!" + break + fi + done + # Make sure to set your PGT_LOG_PATH in your shell profile. # You can use the PGT_LOG_LEVEL to set your log level. # We recommend to install `bunyan` (npm i -g bunyan) and pipe the output through there for color-coding: diff --git a/xtask/agentic/Cargo.toml b/xtask/agentic/Cargo.toml new file mode 100644 index 000000000..dfc4fe57f --- /dev/null +++ b/xtask/agentic/Cargo.toml @@ -0,0 +1,17 @@ +[package] +description = "AI-powered development tasks using Claude" +edition = "2021" +name = "xtask_agentic" +publish = false +version = "0.0.0" + +[dependencies] +anyhow = { workspace = true } +bpaf = { workspace = true, features = ["derive"] } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +xtask = { path = '../', version = "0.0" } + +# Pretty print specific dependencies +pgt_pretty_print = { workspace = true } +pgt_query = { workspace = true } diff --git a/xtask/agentic/ast_nodes.txt b/xtask/agentic/ast_nodes.txt new file mode 100644 index 000000000..69bd44bd1 --- /dev/null +++ b/xtask/agentic/ast_nodes.txt @@ -0,0 +1,271 @@ +InsertStmt +DeleteStmt +UpdateStmt +MergeStmt +SelectStmt +SetOperationStmt +ReturnStmt +PlAssignStmt +CreateSchemaStmt +AlterTableStmt +ReplicaIdentityStmt +AlterCollationStmt +AlterDomainStmt +GrantStmt +GrantRoleStmt +AlterDefaultPrivilegesStmt +CopyStmt +VariableSetStmt +VariableShowStmt +CreateStmt +CreateTableSpaceStmt +DropTableSpaceStmt +AlterTableSpaceOptionsStmt +AlterTableMoveAllStmt +CreateExtensionStmt +AlterExtensionStmt +AlterExtensionContentsStmt +CreateFdwStmt +AlterFdwStmt +CreateForeignServerStmt +AlterForeignServerStmt +CreateForeignTableStmt +CreateUserMappingStmt +AlterUserMappingStmt +DropUserMappingStmt +ImportForeignSchemaStmt +CreatePolicyStmt +AlterPolicyStmt +CreateAmStmt +CreateTrigStmt +CreateEventTrigStmt +AlterEventTrigStmt +CreatePLangStmt +CreateRoleStmt +AlterRoleStmt +AlterRoleSetStmt +DropRoleStmt +CreateSeqStmt +AlterSeqStmt +DefineStmt +CreateDomainStmt +CreateOpClassStmt +CreateOpFamilyStmt +AlterOpFamilyStmt +DropStmt +TruncateStmt +CommentStmt +SecLabelStmt +DeclareCursorStmt +ClosePortalStmt +FetchStmt +IndexStmt +CreateStatsStmt +AlterStatsStmt +CreateFunctionStmt +AlterFunctionStmt +DoStmt +CallStmt +RenameStmt +AlterObjectDependsStmt +AlterObjectSchemaStmt +AlterOwnerStmt +AlterOperatorStmt +AlterTypeStmt +RuleStmt +NotifyStmt +ListenStmt +UnlistenStmt +TransactionStmt +CompositeTypeStmt +CreateEnumStmt +CreateRangeStmt +AlterEnumStmt +ViewStmt +LoadStmt +CreatedbStmt +AlterDatabaseStmt +AlterDatabaseRefreshCollStmt +AlterDatabaseSetStmt +DropdbStmt +AlterSystemStmt +ClusterStmt +VacuumStmt +ExplainStmt +CreateTableAsStmt +RefreshMatViewStmt +CheckPointStmt +DiscardStmt +LockStmt +ConstraintsSetStmt +ReindexStmt +CreateConversionStmt +CreateCastStmt +CreateTransformStmt +PrepareStmt +ExecuteStmt +DeallocateStmt +DropOwnedStmt +ReassignOwnedStmt +AlterTsDictionaryStmt +AlterTsConfigurationStmt +CreatePublicationStmt +AlterPublicationStmt +CreateSubscriptionStmt +AlterSubscriptionStmt +DropSubscriptionStmt +ParseResult +ScanResult +Node +Integer +Float +Boolean +String +BitString +List +OidList +IntList +AConst +Alias +RangeVar +TableFunc +IntoClause +Var +Param +Aggref +GroupingFunc +WindowFunc +WindowFuncRunCondition +MergeSupportFunc +SubscriptingRef +FuncExpr +NamedArgExpr +OpExpr +DistinctExpr +NullIfExpr +ScalarArrayOpExpr +BoolExpr +SubLink +SubPlan +AlternativeSubPlan +FieldSelect +FieldStore +RelabelType +CoerceViaIo +ArrayCoerceExpr +ConvertRowtypeExpr +CollateExpr +CaseExpr +CaseWhen +CaseTestExpr +ArrayExpr +RowExpr +RowCompareExpr +CoalesceExpr +MinMaxExpr +SqlValueFunction +XmlExpr +JsonFormat +JsonReturning +JsonValueExpr +JsonConstructorExpr +JsonIsPredicate +JsonBehavior +JsonExpr +JsonTablePath +JsonTablePathScan +JsonTableSiblingJoin +NullTest +BooleanTest +MergeAction +CoerceToDomain +CoerceToDomainValue +SetToDefault +CurrentOfExpr +NextValueExpr +InferenceElem +TargetEntry +RangeTblRef +JoinExpr +FromExpr +OnConflictExpr +Query +TypeName +ColumnRef +ParamRef +AExpr +TypeCast +CollateClause +RoleSpec +FuncCall +AStar +AIndices +AIndirection +AArrayExpr +ResTarget +MultiAssignRef +SortBy +WindowDef +RangeSubselect +RangeFunction +RangeTableFunc +RangeTableFuncCol +RangeTableSample +ColumnDef +TableLikeClause +IndexElem +DefElem +LockingClause +XmlSerialize +PartitionElem +PartitionSpec +PartitionBoundSpec +PartitionRangeDatum +SinglePartitionSpec +PartitionCmd +RangeTblEntry +RtePermissionInfo +RangeTblFunction +TableSampleClause +WithCheckOption +SortGroupClause +GroupingSet +WindowClause +RowMarkClause +WithClause +InferClause +OnConflictClause +CteSearchClause +CteCycleClause +CommonTableExpr +MergeWhenClause +TriggerTransition +JsonOutput +JsonArgument +JsonFuncExpr +JsonTablePathSpec +JsonTable +JsonTableColumn +JsonKeyValue +JsonParseExpr +JsonScalarExpr +JsonSerializeExpr +JsonObjectConstructor +JsonArrayConstructor +JsonArrayQueryConstructor +JsonAggConstructor +JsonObjectAgg +JsonArrayAgg +AlterTableCmd +ObjectWithArgs +AccessPriv +Constraint +CreateOpClassItem +StatsElem +FunctionParameter +InlineCodeBlock +CallContext +VacuumRelation +PublicationTable +PublicationObjSpec +ScanToken \ No newline at end of file diff --git a/xtask/agentic/src/autonomous_pretty_print.rs b/xtask/agentic/src/autonomous_pretty_print.rs new file mode 100644 index 000000000..7924e0b9a --- /dev/null +++ b/xtask/agentic/src/autonomous_pretty_print.rs @@ -0,0 +1,309 @@ +use anyhow::Result; +use std::fs; +use std::io::Write; +use xtask::project_root; + +use crate::claude_session::ClaudeSession; + +struct Logger { + file: std::fs::File, +} + +impl Logger { + fn new() -> Result { + let log_path = project_root().join("xtask/agentic/autonomous_agent.log"); + let file = std::fs::OpenOptions::new() + .create(true) + .append(true) + .open(log_path)?; + Ok(Self { file }) + } + + fn log(&mut self, message: &str) { + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + let log_line = format!("[{}] {}\n", timestamp, message); + let _ = self.file.write_all(log_line.as_bytes()); + let _ = self.file.flush(); + // Also print to console + print!("{}", log_line); + } +} + +pub struct AutonomousPrettyPrintGenerator { + logger: Logger, + claude_session: ClaudeSession, +} + +impl AutonomousPrettyPrintGenerator { + pub fn new() -> Result { + let logger = Logger::new()?; + let claude_session = ClaudeSession::new(); + + Ok(Self { + logger, + claude_session, + }) + } + + fn log(&mut self, message: &str) { + self.logger.log(message); + } + + pub fn run(&mut self) -> Result<()> { + self.log("Starting autonomous pretty print implementation generator..."); + + let result = self.run_loop(); + + match &result { + Ok(_) => self.log("Autonomous pretty print generator completed successfully!"), + Err(e) => self.log(&format!("ERROR: Autonomous generator failed: {}", e)), + } + + result + } + + fn run_loop(&mut self) -> Result<()> { + loop { + self.log("Starting new autonomous cycle..."); + + let prompt = match self.build_comprehensive_prompt() { + Ok(p) => p, + Err(e) => { + self.log(&format!("ERROR: Failed to build prompt: {}", e)); + return Err(e); + } + }; + + self.log("Sending comprehensive prompt to Claude..."); + let response = match self.claude_session.call_claude(&prompt, false) { + Ok(r) => r, + Err(e) => { + self.log(&format!("ERROR: Claude API call failed: {}", e)); + return Err(e); + } + }; + + self.log(&format!("Claude response: {}", response)); + + // Check if Claude indicates it's done + if response.contains("ALL_NODES_COMPLETED") { + self.log("Claude reports all nodes are completed!"); + break; + } + + // Small delay to prevent overwhelming + std::thread::sleep(std::time::Duration::from_secs(2)); + } + + Ok(()) + } + + fn build_comprehensive_prompt(&mut self) -> Result { + let ast_nodes_list = self.load_ast_nodes_list()?; + let nodes_file_path = project_root().join("crates/pgt_pretty_print/src/nodes.rs"); + let test_data_dir = project_root().join("crates/pgt_pretty_print/tests/data"); + + let prompt = format!( + r#"You are an autonomous Rust code generator building a PostgreSQL pretty printer by implementing ToTokens traits for AST nodes. + +## PROJECT CONTEXT: +This is a PostgreSQL pretty printer that takes parsed AST nodes and converts them back into well-formatted SQL code. Each AST node type needs a ToTokens implementation that defines how to reconstruct readable SQL from the parsed structure. + +Your goal is to continuously implement ToTokens for all unimplemented nodes until the pretty printer is complete. + +## YOUR INFINITE LOOP TASK: + +1. **Read the current nodes.rs file** to see what's already implemented +2. **Pick the next unimplemented node** from the AST nodes list +3. **Analyze the node structure** in crates/pgt_query/src/protobuf.rs +4. **Generate a minimal SQL test case** and write it to tests/data/ with filename format: `[node_name]_[index]_60.sql` (60 is the line width for proper formatting) +5. **Validate the SQL example** by running: cargo test -p pgt_pretty_print --test tests validate_test_data__[filename_without_sql] +6. **Implement the ToTokens trait** for the node +7. **Add the node to the match statement** if not already there +8. **Run compilation checks** with cargo check -p pgt_pretty_print +9. **Run the formatter tests** with cargo test -p pgt_pretty_print +10. **Validate AST round-trip** - Ensure the formatted SQL parses back to the same AST structure +11. **Check output snapshot** - Read the generated .snap file to verify the formatted output looks correct +12. **Fix any issues** that arise +13. **Repeat from step 1** until all nodes are implemented + +## CRITICAL RULES: + +- **ALWAYS use line width 60** in test filenames (e.g., `select_stmt_0_60.sql`) to ensure proper line breaking +- **NEVER EVER add comments to Rust code** - ZERO // comments, ZERO /* */ comments in implementations +- **NEVER manually implement nested nodes** - Always call .to_tokens(e) on child nodes, never implement their logic +- **Use existing ToTokens implementations** - If a node already has ToTokens, call it, don't reimplement +- **Start with simplest possible implementations** - use todo!() for complex fields initially +- **Incremental improvement** - come back to nodes later to add more fields +- **When tests fail**, analyze the AST diff and fix the missing ToTokens fields +- **Prioritize Stmt nodes first** (SelectStmt, InsertStmt, etc.) +- **ALWAYS use enum accessor methods** - Use `self.field()` NOT `EnumType::try_from(self.field).unwrap()` for enum fields + - Example: `self.jointype()` returns `JoinType` enum directly + - Example: `self.op()` returns the operation enum directly + - Never use manual try_from conversions for protobuf enum fields + +## GROUP AND CONTEXT SYSTEM: + +- **Complex nodes MUST create groups**: `e.group_start(GroupKind::NodeName, None, false);` and `e.group_end();` +- **Simple nodes NO groups**: String, AConst, and other leaf nodes emit tokens directly +- **Context-aware formatting**: Use `e.is_within_group(GroupKind::ParentType)` to adapt behavior +- **Semicolons for top-level statements**: Use `if e.is_top_level() {{ e.token(TokenKind::SEMICOLON); }}` +- **Never maintain explicit context state** - always introspect the event stream + +## FORBIDDEN PATTERNS: +- `// Handle XYZ formatting directly` - NEVER add explanatory comments +- `if let Some(node::Node::SomeType(inner)) = &node.node {{{{ /* manual implementation */ }}}}` - NEVER manually implement child nodes +- Always use: `child_node.to_tokens(e)` instead of manual implementations + +## FILE PATHS: +- Nodes to implement: {} +- Target file: {} +- Test directory: {} + +## AST NODES TO IMPLEMENT: +{} + +## TOOLS AVAILABLE: +- Read: Read any file +- Write: Create new files +- Edit/MultiEdit: Modify existing files +- Bash: Run commands like cargo check, cargo test +- Grep: Search for patterns in files +- ast-grep: Use ast-grep (https://ast-grep.github.io/) for advanced code pattern searching and analysis + +## VALIDATION PROCESS: +After creating a SQL file, validate it with: +```bash +cargo test -p pgt_pretty_print --test tests validate_test_data__[filename_without_sql] +``` +Example: For insert_stmt_0_60.sql, run: +```bash +cargo test -p pgt_pretty_print --test tests validate_test_data__insert_stmt_0_60 +``` +This ensures the SQL parses correctly and produces the expected AST node type. + +## OUTPUT VERIFICATION PROCESS: +After running formatter tests, check the quality by: +1. **Read the snapshot file**: `crates/pgt_pretty_print/tests/snapshots/tests__test_formatter__[filename].snap` +2. **Verify formatted output**: Check that the generated SQL looks properly formatted +3. **Validate round-trip**: Parse the formatted SQL and compare AST structure with original +4. **Look for common issues**: Missing whitespace, incorrect operator precedence, malformed syntax + +Example: For insert_stmt_0_60.sql, check: +`crates/pgt_pretty_print/tests/snapshots/tests__test_formatter__insert_stmt_0_60.snap` + +## RESPONSE FORMAT: +After each cycle, respond with just: +- "CONTINUING" to keep going +- "ALL_NODES_COMPLETED" when finished + +## CORRECT IMPLEMENTATION PATTERN: +```rust +// Complex node with group +impl ToTokens for SomeComplexNode {{ + fn to_tokens(&self, e: &mut EventEmitter) {{ + e.group_start(GroupKind::SomeComplexNode, None, false); + + // Using enum accessor methods - ALWAYS use this pattern + match self.jointype() {{ // ✅ CORRECT - use accessor method + JoinType::JoinInner => e.token(TokenKind::INNER_KW), + JoinType::JoinLeft => e.token(TokenKind::LEFT_KW), + _ => {{}} + }} + + e.token(TokenKind::KEYWORD("SELECT".to_string())); + if let Some(ref child) = self.some_child {{ + child.to_tokens(e); // ✅ CORRECT - delegate to existing ToTokens + }} + + if e.is_top_level() {{ + e.token(TokenKind::SEMICOLON); + }} + + e.group_end(); + }} +}} + +// Simple leaf node without group +impl ToTokens for SomeSimpleNode {{ + fn to_tokens(&self, e: &mut EventEmitter) {{ + e.token(TokenKind::IDENT(self.value.clone())); + }} +}} + +// Context-aware node +impl ToTokens for ContextSensitiveNode {{ + fn to_tokens(&self, e: &mut EventEmitter) {{ + e.group_start(GroupKind::ContextSensitiveNode, None, false); + + if e.is_within_group(GroupKind::UpdateStmt) {{ + // UPDATE SET formatting: column = value + }} else {{ + // SELECT formatting: value AS alias + }} + + e.group_end(); + }} +}} +``` + +## WRONG IMPLEMENTATION PATTERN (FORBIDDEN): +```rust +impl ToTokens for SomeNode {{ + fn to_tokens(&self, e: &mut EventEmitter) {{ + e.group_start(GroupKind::SomeNode, None, false); + + // ❌ FORBIDDEN - using try_from for enum conversion + match JoinType::try_from(self.jointype).unwrap() {{ + JoinType::JoinInner => e.token(TokenKind::INNER_KW), + _ => {{}} + }} + + if let Some(ref child) = self.some_child {{ + // Handle child formatting directly ❌ FORBIDDEN COMMENT + if let Some(node::Node::ChildType(inner)) = &child.node {{ + // ❌ FORBIDDEN - manual implementation of child + e.token(TokenKind::IDENT(inner.name.clone())); + }} + }} + + e.group_end(); + }} +}} +``` + +## ACTION PLAN: +Start by reading nodes.rs to see current state, then begin the implementation loop. Work systematically through the nodes list, implementing ToTokens for each one with proper error handling and testing. + +## KEY CONTEXT RULES: +- **Complex nodes** (statements, expressions, structured data) MUST use groups with GroupKind +- **Simple leaf nodes** (String, AConst) emit tokens directly without groups +- **Context-sensitive nodes** use `e.is_within_group(GroupKind::ParentType)` to adapt formatting +- **Top-level statements** use `e.is_top_level()` to add semicolons +- **Always delegate** to existing ToTokens implementations. NEVER add explanatory comments. + +Continue this loop indefinitely until all nodes are implemented and all tests pass. +"#, + "xtask/agentic/ast_nodes.txt", + nodes_file_path.display(), + test_data_dir.display(), + ast_nodes_list + ); + + Ok(prompt) + } + + fn load_ast_nodes_list(&self) -> Result { + let ast_nodes_path = project_root().join("xtask/agentic/ast_nodes.txt"); + fs::read_to_string(ast_nodes_path) + .map_err(|e| anyhow::anyhow!("Failed to read AST nodes: {}", e)) + } +} + +pub fn run_autonomous_pretty_print_generator() -> Result<()> { + let mut generator = AutonomousPrettyPrintGenerator::new()?; + generator.run() +} diff --git a/xtask/agentic/src/claude_session.rs b/xtask/agentic/src/claude_session.rs new file mode 100644 index 000000000..2ab46ca11 --- /dev/null +++ b/xtask/agentic/src/claude_session.rs @@ -0,0 +1,136 @@ +use anyhow::{Context, Result}; +use serde::{Deserialize, Serialize}; +use std::collections::{HashMap, HashSet}; +use std::fs; +use std::process::Command; +use xtask::project_root; + +#[derive(Debug, Serialize, Deserialize)] +pub struct AgenticState { + pub current_node: String, + pub completed_nodes: Vec, + pub errors: Vec, + pub in_progress_nodes: HashMap, // node -> iteration count + pub node_structure_cache: HashMap, // node -> structure analysis + pub node_match_updated: std::collections::HashSet, // nodes already added to match statement +} + +impl AgenticState { + pub fn new() -> Self { + Self { + current_node: String::new(), + completed_nodes: Vec::new(), + errors: Vec::new(), + in_progress_nodes: HashMap::new(), + node_structure_cache: HashMap::new(), + node_match_updated: HashSet::new(), + } + } + + pub fn load() -> Result { + let path = project_root().join("xtask/agentic/agentic_state.json"); + if path.exists() { + let content = fs::read_to_string(path)?; + Ok(serde_json::from_str(&content)?) + } else { + Ok(Self::new()) + } + } + + pub fn save(&self) -> Result<()> { + let path = project_root().join("xtask/agentic/agentic_state.json"); + let content = serde_json::to_string_pretty(self)?; + fs::write(path, content)?; + Ok(()) + } + + pub fn clear_node_structure_cache(&mut self) -> Result<()> { + eprintln!("Clearing node structure cache (e.g., after protobuf changes)"); + self.node_structure_cache.clear(); + self.save() + } +} + +pub struct ClaudeSession { + conversation_id: Option, +} + +impl ClaudeSession { + pub fn new() -> Self { + Self { + conversation_id: None, + } + } + + pub fn call_claude(&mut self, prompt: &str, new_conversation: bool) -> Result { + use std::io::Write; + use std::process::Stdio; + + let mut cmd = Command::new("claude"); + cmd.arg("--print") // Non-interactive mode + .arg("--output-format") + .arg("json") + .arg("--permission-mode") + .arg("acceptEdits") + .arg("--allowedTools") + .arg("Bash,Read,Write,Edit,MultiEdit,Grep,Glob,LS") + .env_remove("ANTHROPIC_API_KEY") // Unset API key to use CLI auth + .current_dir(project_root()) // Set working directory to monorepo root + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); + + // Reuse conversation if we have one and not explicitly starting new + if !new_conversation && self.conversation_id.is_some() { + if let Some(ref conv_id) = self.conversation_id { + cmd.arg("--resume").arg(conv_id); + } + } + + eprintln!( + "Calling Claude with prompt: {}", + &prompt.lines().next().unwrap_or("") + ); + + // Spawn the process + let mut child = cmd + .spawn() + .context("Failed to execute claude CLI. Make sure it's installed and in PATH")?; + + // Write prompt to stdin + if let Some(mut stdin) = child.stdin.take() { + stdin.write_all(prompt.as_bytes())?; + stdin.flush()?; + } + + // Wait for completion and collect output + let output = child.wait_with_output()?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + let _stdout = String::from_utf8_lossy(&output.stdout); + + return Err(anyhow::anyhow!("Claude CLI failed: {}", stderr)); + } + + let stdout = String::from_utf8_lossy(&output.stdout); + + // Parse JSON response to extract session ID and result + let json_response: serde_json::Value = serde_json::from_str(&stdout) + .context("Failed to parse JSON response from Claude CLI")?; + + // Extract session ID for future requests + if let Some(session_id) = json_response.get("session_id").and_then(|s| s.as_str()) { + self.conversation_id = Some(session_id.to_string()); + } + + // Extract the actual result content + let result = json_response + .get("result") + .and_then(|r| r.as_str()) + .unwrap_or("") + .to_string(); + + Ok(result) + } +} diff --git a/xtask/agentic/src/lib.rs b/xtask/agentic/src/lib.rs new file mode 100644 index 000000000..a7988293a --- /dev/null +++ b/xtask/agentic/src/lib.rs @@ -0,0 +1,4 @@ +pub mod autonomous_pretty_print; +pub mod claude_session; + +pub use autonomous_pretty_print::run_autonomous_pretty_print_generator; diff --git a/xtask/agentic/src/main.rs b/xtask/agentic/src/main.rs new file mode 100644 index 000000000..9213a7158 --- /dev/null +++ b/xtask/agentic/src/main.rs @@ -0,0 +1,6 @@ +use anyhow::Result; +use xtask_agentic::run_autonomous_pretty_print_generator; + +fn main() -> Result<()> { + run_autonomous_pretty_print_generator() +} diff --git a/xtask/download_regression_tests/Cargo.toml b/xtask/download_regression_tests/Cargo.toml new file mode 100644 index 000000000..35c3850cf --- /dev/null +++ b/xtask/download_regression_tests/Cargo.toml @@ -0,0 +1,15 @@ +[package] +description = "Download PostgreSQL regression tests" +edition = "2021" +name = "download_regression_tests" +publish = false +version = "0.0.0" + +[dependencies] +anyhow = { workspace = true } +camino.workspace = true +pgt_query = { workspace = true } +pgt_statement_splitter = { workspace = true } +regex.workspace = true +serde.workspace = true +serde_json.workspace = true diff --git a/xtask/download_regression_tests/src/lib.rs b/xtask/download_regression_tests/src/lib.rs new file mode 100644 index 000000000..759ead17d --- /dev/null +++ b/xtask/download_regression_tests/src/lib.rs @@ -0,0 +1,444 @@ +use anyhow::{bail, Result}; +use camino::Utf8PathBuf; +use regex::Regex; +use std::env; +use std::fs::{create_dir_all, remove_dir_all, File}; +use std::io::{BufRead, Cursor, Write}; +use std::process::Command; + +const OUTPUT_DIR: &str = "crates/pgt_pretty_print/tests/data/multi"; + +fn find_project_root() -> Result { + // Start from the current directory and walk up until we find Cargo.toml + let mut current_dir = Utf8PathBuf::try_from(env::current_dir()?)?; + loop { + if current_dir.join("Cargo.toml").exists() && current_dir.join("crates").exists() { + return Ok(current_dir); + } + if let Some(parent) = current_dir.parent() { + current_dir = parent.to_path_buf(); + } else { + bail!("Could not find project root"); + } + } +} + +pub fn download_regression_tests() -> Result<()> { + let project_root = find_project_root()?; + let target_dir = project_root.join(OUTPUT_DIR); + + if target_dir.exists() { + println!("cleaning target directory: {:?}", target_dir); + remove_dir_all(&target_dir)?; + } + + create_dir_all(&target_dir)?; + + let urls = fetch_download_urls()?; + let total_files = urls.len(); + + for (index, url) in urls.iter().enumerate() { + let filename = url.split('/').next_back().unwrap(); + if filename.contains("psql") { + // skipping this for now, we don't support psql + continue; + } + + println!( + "[{}/{}] Downloading {}... ", + index + 1, + total_files, + filename + ); + + let output = Command::new("curl").args(["-s", url]).output()?; + + if !output.status.success() { + let error_msg = String::from_utf8_lossy(&output.stderr); + bail!(anyhow::anyhow!( + "Failed to download '{}': {}", + url, + error_msg + )); + } + + let mut processed_content = Vec::new(); + + let cursor = Cursor::new(&output.stdout); + + if let Err(e) = preprocess_sql(cursor, &mut processed_content) { + eprintln!("Error: Failed to process file: {}", e); + continue; + } + + let content_str = std::str::from_utf8(&processed_content)?; + let split_result = pgt_statement_splitter::split(content_str); + + let mut valid_statements = Vec::new(); + + for (idx, range) in split_result.ranges.iter().enumerate() { + let statement = &content_str[usize::from(range.start())..usize::from(range.end())]; + let trimmed = statement.trim(); + + if trimmed.is_empty() { + continue; + } + + // Try to parse the statement + match pgt_query::parse(trimmed) { + Ok(parsed) => { + if parsed.root().is_none() { + eprintln!( + "Warning: Statement {} in {} has no root node, skipping", + idx + 1, + filename + ); + continue; + } + + // Add valid statement to the list + valid_statements.push(trimmed); + } + Err(e) => { + eprintln!( + "Warning: Failed to parse statement {} in {}: {}", + idx + 1, + filename, + e + ); + continue; + } + } + } + + // Write all valid statements to a single file + if !valid_statements.is_empty() { + let base_name = filename.strip_suffix(".sql").unwrap_or(filename); + let output_filename = format!("{}_60.sql", base_name); + let filepath = target_dir.join(output_filename); + + let mut dest = File::create(&filepath)?; + for (i, stmt) in valid_statements.iter().enumerate() { + if i > 0 { + write!(dest, "\n\n")?; + } + write!(dest, "{}", stmt)?; + } + writeln!(dest)?; // Final newline + } + } + + Ok(()) +} + +fn fetch_download_urls() -> Result> { + println!("Fetching SQL file URLs..."); + let output = Command::new("gh") + .args([ + "api", + "-H", + "Accept: application/vnd.github+json", + "/repos/postgres/postgres/contents/src/test/regress/sql", + ]) + .output()?; + + if !output.status.success() { + bail!(anyhow::anyhow!( + "Failed to fetch SQL files: {}", + String::from_utf8_lossy(&output.stderr) + )); + } + + let json_str = String::from_utf8(output.stdout)?; + let files: Vec = serde_json::from_str(&json_str)?; + + // extract download urls for sql files + let urls: Vec = files + .into_iter() + .filter(|file| { + file["name"] + .as_str() + .map(|name| name.ends_with(".sql")) + .unwrap_or(false) + }) + .filter_map(|file| file["download_url"].as_str().map(String::from)) + .collect(); + + if urls.is_empty() { + bail!(anyhow::anyhow!("No SQL files found")); + } + + Ok(urls) +} + +fn preprocess_sql(source: R, mut dest: W) -> Result<()> { + let mut skipping_copy_block = false; + + let template_vars_regex = Regex::new(r"^:'([^']+)'|^:([a-zA-Z_][a-zA-Z0-9_]*)").unwrap(); + + for (idx, line) in source.lines().enumerate() { + let mut line = line?; + + // Detect the start of the COPY block + if line.starts_with("COPY ") && line.to_lowercase().contains("from stdin") { + skipping_copy_block = true; + continue; + } + + // Detect the end of the COPY block + if skipping_copy_block && (line.starts_with("\\.") || line.is_empty()) { + skipping_copy_block = false; + continue; + } + + // Skip lines if inside a COPY block + if skipping_copy_block { + continue; + } + + if line.starts_with("\\") { + // Skip plpgsql commands (for now) + continue; + } + + // replace "\gset" with ";" + if line.contains("\\gset") { + line = line.replace("\\gset", ";"); + } + + // Replace template variables + let mut result = String::new(); + let mut i = 0; + let bytes = line.as_bytes(); + let mut in_single_quote = false; + let mut in_double_quote = false; + let mut in_array = false; + + while i < bytes.len() { + let c = bytes[i] as char; + + // Handle quote state transitions + match c { + '\'' => { + result.push(c); + i += 1; + in_single_quote = !in_single_quote; + continue; + } + '"' => { + result.push(c); + i += 1; + in_double_quote = !in_double_quote; + continue; + } + '[' => { + result.push(c); + i += 1; + in_array = true; + continue; + } + ']' => { + result.push(c); + i += 1; + in_array = false; + continue; + } + ':' if !in_single_quote && !in_double_quote && !in_array => { + // Skip type casts (e.g., ::text) + if i + 1 < bytes.len() && bytes[i + 1] as char == ':' { + result.push_str("::"); + i += 2; + continue; + } + + if i + 2 < bytes.len() && bytes[i + 1] as char == '=' { + result.push_str(":="); + i += 2; + continue; + } + + let remaining = &line[i..]; + if let Some(caps) = template_vars_regex.captures(remaining) { + let full = caps.get(0).unwrap(); + let m = caps.get(1).or_else(|| caps.get(2)).unwrap(); + let matched_var = &remaining[m.start()..m.end()]; + + println!("#{} Replacing template variable {}", idx, matched_var); + + result.push('\''); + result.push_str(matched_var); + result.push('\''); + + i += full.end(); + continue; + } + } + _ => {} + } + + result.push(c); + i += 1; + } + + // Write the cleaned line + writeln!(dest, "{}", result)?; + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn test_preprocess_sql(sql: &str) -> Result { + let input = sql.as_bytes(); + let cursor = Cursor::new(input); + let mut output = Vec::new(); + + preprocess_sql(cursor, &mut output)?; + + Ok(String::from_utf8(output)?) + } + + #[test] + fn test_replacement() { + let cases = [ + ( + "SELECT * FROM foo WHERE bar = :'foo' AND baz = :baz;", + "SELECT * FROM foo WHERE bar = 'foo' AND baz = 'baz';", + ), + ( + "select array_dims('{1,2,3}'::dia);", + "select array_dims('{1,2,3}'::dia);", + ), + ( + "SELECT to_char(now(), 'OF') as \"OF\", to_char(now(), 'TZH:TZM') as \"TZH:TZM\";", + "SELECT to_char(now(), 'OF') as \"OF\", to_char(now(), 'TZH:TZM') as \"TZH:TZM\";", + ), + ( + "SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][1:NULL][1];", + "SELECT ('{{{1},{2},{3}},{{4},{5},{6}}}'::int[])[1][1:NULL][1];", + ), + ( + "SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON);", + "SELECT JSON_OBJECT('foo': NULL::int FORMAT JSON);", + ), + ( + "ALTER DATABASE :\"datname\" REFRESH COLLATION VERSION;", + "ALTER DATABASE \"datname\" REFRESH COLLATION VERSION;", + ), + ]; + + for (input, expected) in &cases { + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, format!("{}\n", *expected)); + } + } + + #[test] + fn test_dollar_quoted_strings() { + let input = "CREATE FUNCTION test() RETURNS text AS $$SELECT 'test;';$$ LANGUAGE sql;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "CREATE FUNCTION test() RETURNS text AS $$SELECT 'test;';$$ LANGUAGE sql;\n" + ); + + let input = "CREATE FUNCTION test() RETURNS void AS $$\nBEGIN\n RAISE NOTICE 'Hello;';\nEND;\n$$ LANGUAGE plpgsql;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, "CREATE FUNCTION test() RETURNS void AS $$\nBEGIN\n RAISE NOTICE 'Hello;';\nEND;\n$$ LANGUAGE plpgsql;\n"); + + let input = + "CREATE FUNCTION test() RETURNS text AS $tag$SELECT 'test;';$tag$ LANGUAGE sql;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "CREATE FUNCTION test() RETURNS text AS $tag$SELECT 'test;';$tag$ LANGUAGE sql;\n" + ); + } + + #[test] + fn test_multiple_statements_on_one_line() { + let input = "begin; alter table alterlock alter column f2 set statistics 150;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "begin;\nalter table alterlock alter column f2 set statistics 150;\n" + ); + + let input = "select 1; select 2; select 3;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, "select 1;\nselect 2;\nselect 3;\n"); + } + + #[test] + fn test_semicolons_in_strings() { + let input = "SELECT 'hello; world' as test;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, "SELECT 'hello; world' as test;\n"); + + let input = "SELECT 'test;' as a; SELECT 'another; test' as b;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "SELECT 'test;' as a;\nSELECT 'another; test' as b;\n" + ); + + let input = "SELECT 'it''s; a test' as msg;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, "SELECT 'it''s; a test' as msg;\n"); + + let input = "BEGIN; UPDATE foo SET bar = 'hello; world'; COMMIT;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "BEGIN;\nUPDATE foo SET bar = 'hello; world';\nCOMMIT;\n" + ); + } + + #[test] + fn test_multiline_statements() { + // Test case that was failing + let input = "DROP INDEX onek_unique1_constraint;\nALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "DROP INDEX onek_unique1_constraint;\nALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo;\n" + ); + + // Test multiline statement without semicolon on first line + let input = "CREATE TABLE test\n (id INT PRIMARY KEY);"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, "CREATE TABLE test\n (id INT PRIMARY KEY);\n"); + } + + #[test] + fn test_multiline_comments() { + // Test semicolon inside multiline comment + let input = "/* This is a comment; with semicolon */ SELECT 1;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "/* This is a comment; with semicolon */ SELECT 1;\n" + ); + + // Test multiline comment spanning multiple lines + let input = "/* not run by default because it requires tr_TR system locale\nSET lc_time TO 'tr_TR'; */\nSELECT 2;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, "/* not run by default because it requires tr_TR system locale\nSET lc_time TO 'tr_TR'; */\nSELECT 2;\n"); + + // Test multiple statements with multiline comments + let input = "SELECT 1; /* comment; with; semicolons; */ SELECT 2;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!( + result, + "SELECT 1;\n/* comment; with; semicolons; */ SELECT 2;\n" + ); + + // Test statement after multiline comment + let input = "/* comment */ SELECT 3;"; + let result = test_preprocess_sql(input).unwrap(); + assert_eq!(result, "/* comment */ SELECT 3;\n"); + } +} diff --git a/xtask/download_regression_tests/src/main.rs b/xtask/download_regression_tests/src/main.rs new file mode 100644 index 000000000..8f4c5a03d --- /dev/null +++ b/xtask/download_regression_tests/src/main.rs @@ -0,0 +1,3 @@ +fn main() -> anyhow::Result<()> { + download_regression_tests::download_regression_tests() +} diff --git a/xtask/src/agentic.rs b/xtask/src/agentic.rs new file mode 100644 index 000000000..335573cf7 --- /dev/null +++ b/xtask/src/agentic.rs @@ -0,0 +1,14 @@ +use anyhow::Result; +use xshell::{cmd, Shell}; + +use crate::flags::Agentic; + +pub fn run(cmd: Agentic, sh: &Shell) -> Result<()> { + println!("Running autonomous pretty print implementation generator..."); + if cmd.forever { + cmd!(sh, "cargo run -p xtask_agentic -- --forever").run()?; + } else { + cmd!(sh, "cargo run -p xtask_agentic").run()?; + } + Ok(()) +} diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs index 4ed3da40b..9d6769c07 100644 --- a/xtask/src/flags.rs +++ b/xtask/src/flags.rs @@ -18,6 +18,12 @@ xflags::xflags! { /// Install only the language server. optional --server } + + /// Run autonomous pretty print implementation generator using Claude. + cmd agentic { + /// Run continuously, retrying after rate limits. + optional --forever + } } } @@ -32,6 +38,7 @@ pub struct Xtask { #[derive(Debug)] pub enum XtaskCmd { Install(Install), + Agentic(Agentic), } #[derive(Debug)] @@ -41,6 +48,11 @@ pub struct Install { pub server: bool, } +#[derive(Debug)] +pub struct Agentic { + pub forever: bool, +} + impl Xtask { #[allow(dead_code)] pub fn from_env_or_exit() -> Self { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 282470849..a75a4931a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -14,8 +14,8 @@ semicolon_in_expressions_from_macros )] +mod agentic; mod flags; - mod install; use std::{ @@ -32,6 +32,7 @@ fn main() -> anyhow::Result<()> { match flags.subcommand { flags::XtaskCmd::Install(cmd) => cmd.run(sh), + flags::XtaskCmd::Agentic(cmd) => agentic::run(cmd, sh), } }