← Back to Overview

src/backend/utils/adt/ruleutils.c

Coverage: 245/288 lines (85.1%)
Total Lines
288
modified
Covered
245
85.1%
Uncovered
43
14.9%
키보드 네비게이션
pg_get_propgraphdef() lines 1615-1649
Modified Lines Coverage: 20/21 lines (95.2%)
LineHitsSourceCommit
1615 118 pg_get_propgraphdef(PG_FUNCTION_ARGS) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1616 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1617 118 Oid pgrelid = PG_GETARG_OID(0); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1618 118 StringInfoData buf; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1619 118 HeapTuple classtup; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1620 118 Form_pg_class classform; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1621 118 char *name; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1622 118 char *nsp; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1623 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1624 118 initStringInfo(&buf); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1625 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1626 118 classtup = SearchSysCache1(RELOID, ObjectIdGetDatum(pgrelid)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1627 118 if (!HeapTupleIsValid(classtup)) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1628 0 PG_RETURN_NULL(); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1629 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1630 118 classform = (Form_pg_class) GETSTRUCT(classtup); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1631 118 name = NameStr(classform->relname); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1632 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1633 118 if (classform->relkind != RELKIND_PROPGRAPH) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1634 3 ereport(ERROR, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1635 - (errcode(ERRCODE_WRONG_OBJECT_TYPE), 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1636 - errmsg("\"%s\" is not a property graph", name))); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1637 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1638 115 nsp = get_namespace_name(classform->relnamespace); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1639 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1640 115 appendStringInfo(&buf, "CREATE PROPERTY GRAPH %s", 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1641 - quote_qualified_identifier(nsp, name)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1642 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1643 115 ReleaseSysCache(classtup); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1644 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1645 115 make_propgraphdef_elements(&buf, pgrelid, PGEKIND_VERTEX); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1646 115 make_propgraphdef_elements(&buf, pgrelid, PGEKIND_EDGE); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1647 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1648 115 PG_RETURN_TEXT_P(string_to_text(buf.data)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1649 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
make_propgraphdef_elements() lines 1657-1772
Modified Lines Coverage: 72/79 lines (91.1%)
LineHitsSourceCommit
1657 230 make_propgraphdef_elements(StringInfo buf, Oid pgrelid, char pgekind) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1658 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1659 230 Relation pgerel; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1660 230 ScanKeyData scankey[1]; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1661 230 SysScanDesc scan; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1662 230 bool first; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1663 230 HeapTuple tup; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1664 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1665 230 pgerel = table_open(PropgraphElementRelationId, AccessShareLock); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1666 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1667 230 ScanKeyInit(&scankey[0], 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1668 - Anum_pg_propgraph_element_pgepgid, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1669 - BTEqualStrategyNumber, F_OIDEQ, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1670 - ObjectIdGetDatum(pgrelid)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1671 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1672 230 scan = systable_beginscan(pgerel, PropgraphElementAliasIndexId, true, NULL, 1, scankey); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1673 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1674 230 first = true; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1675 940 while ((tup = systable_getnext(scan))) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1676 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1677 710 Form_pg_propgraph_element pgeform = (Form_pg_propgraph_element) GETSTRUCT(tup); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1678 710 char *relname; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1679 710 Datum datum; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1680 710 bool isnull; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1681 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1682 710 if (pgeform->pgekind != pgekind) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1683 355 continue; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1684 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1685 355 if (first) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1686 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1687 152 appendStringInfo(buf, "\n %s TABLES (\n", pgekind == PGEKIND_VERTEX ? "VERTEX" : "EDGE"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1688 152 first = false; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1689 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1690 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1691 203 appendStringInfo(buf, ",\n"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1692 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1693 355 relname = get_rel_name(pgeform->pgerelid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1694 355 if (relname && strcmp(relname, NameStr(pgeform->pgealias)) == 0) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1695 355 appendStringInfo(buf, " %s", 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1696 - generate_relation_name(pgeform->pgerelid, NIL)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1697 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1698 0 appendStringInfo(buf, " %s AS %s", 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1699 - generate_relation_name(pgeform->pgerelid, NIL), 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1700 0 NameStr(pgeform->pgealias)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1701 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1702 355 datum = heap_getattr(tup, Anum_pg_propgraph_element_pgekey, RelationGetDescr(pgerel), &isnull); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1703 355 if (!isnull) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1704 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1705 355 appendStringInfoString(buf, " KEY ("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1706 355 decompile_column_index_array(datum, pgeform->pgerelid, false, buf); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1707 355 appendStringInfoString(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1708 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1709 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1710 0 elog(ERROR, "null pgekey for element %u", pgeform->oid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1711 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1712 355 if (pgekind == PGEKIND_EDGE) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1713 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1714 156 Datum srckey; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1715 156 Datum srcref; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1716 156 Datum destkey; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1717 156 Datum destref; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1718 156 HeapTuple tup2; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1719 156 Form_pg_propgraph_element pgeform2; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1720 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1721 156 datum = heap_getattr(tup, Anum_pg_propgraph_element_pgesrckey, RelationGetDescr(pgerel), &isnull); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1722 156 srckey = isnull ? 0 : datum; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1723 156 datum = heap_getattr(tup, Anum_pg_propgraph_element_pgesrcref, RelationGetDescr(pgerel), &isnull); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1724 156 srcref = isnull ? 0 : datum; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1725 156 datum = heap_getattr(tup, Anum_pg_propgraph_element_pgedestkey, RelationGetDescr(pgerel), &isnull); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1726 156 destkey = isnull ? 0 : datum; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1727 156 datum = heap_getattr(tup, Anum_pg_propgraph_element_pgedestref, RelationGetDescr(pgerel), &isnull); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1728 156 destref = isnull ? 0 : datum; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1729 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1730 156 appendStringInfoString(buf, " SOURCE"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1731 156 tup2 = SearchSysCache1(PROPGRAPHELOID, ObjectIdGetDatum(pgeform->pgesrcvertexid)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1732 156 if (!tup2) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1733 0 elog(ERROR, "cache lookup failed for property graph element %u", pgeform->pgesrcvertexid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1734 156 pgeform2 = (Form_pg_propgraph_element) GETSTRUCT(tup2); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1735 156 if (srckey) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1736 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1737 156 appendStringInfoString(buf, " KEY ("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1738 156 decompile_column_index_array(srckey, pgeform->pgerelid, false, buf); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1739 156 appendStringInfo(buf, ") REFERENCES %s (", NameStr(pgeform2->pgealias)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1740 156 decompile_column_index_array(srcref, pgeform2->pgerelid, false, buf); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1741 156 appendStringInfoString(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1742 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1743 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1744 0 appendStringInfo(buf, " %s ", NameStr(pgeform2->pgealias)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1745 156 ReleaseSysCache(tup2); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1746 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1747 156 appendStringInfoString(buf, " DESTINATION"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1748 156 tup2 = SearchSysCache1(PROPGRAPHELOID, ObjectIdGetDatum(pgeform->pgedestvertexid)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1749 156 if (!tup2) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1750 0 elog(ERROR, "cache lookup failed for property graph element %u", pgeform->pgedestvertexid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1751 156 pgeform2 = (Form_pg_propgraph_element) GETSTRUCT(tup2); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1752 156 if (destkey) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1753 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1754 156 appendStringInfoString(buf, " KEY ("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1755 156 decompile_column_index_array(destkey, pgeform->pgerelid, false, buf); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1756 156 appendStringInfo(buf, ") REFERENCES %s (", NameStr(pgeform2->pgealias)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1757 156 decompile_column_index_array(destref, pgeform2->pgerelid, false, buf); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1758 156 appendStringInfoString(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1759 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1760 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1761 0 appendStringInfo(buf, " %s", NameStr(pgeform2->pgealias)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1762 156 ReleaseSysCache(tup2); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1763 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1764 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1765 355 make_propgraphdef_labels(buf, pgeform->oid, NameStr(pgeform->pgealias), pgeform->pgerelid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1766 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1767 230 if (!first) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1768 152 appendStringInfo(buf, "\n )"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1769 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1770 230 systable_endscan(scan); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1771 230 table_close(pgerel, AccessShareLock); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1772 230 } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
make_propgraphdef_labels() lines 1779-1826
Modified Lines Coverage: 26/26 lines (100.0%)
LineHitsSourceCommit
1779 355 make_propgraphdef_labels(StringInfo buf, Oid elid, const char *elalias, Oid elrelid) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1780 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1781 355 Relation pglrel; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1782 355 ScanKeyData scankey[1]; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1783 355 SysScanDesc scan; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1784 355 int count; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1785 355 HeapTuple tup; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1786 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1787 355 pglrel = table_open(PropgraphElementLabelRelationId, AccessShareLock); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1788 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1789 355 ScanKeyInit(&scankey[0], 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1790 - Anum_pg_propgraph_element_label_pgelelid, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1791 - BTEqualStrategyNumber, F_OIDEQ, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1792 - ObjectIdGetDatum(elid)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1793 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1794 355 count = 0; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1795 355 scan = systable_beginscan(pglrel, PropgraphElementLabelElementLabelIndexId, true, NULL, 1, scankey); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1796 812 while ((tup = systable_getnext(scan))) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1797 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1798 457 count++; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1799 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1800 355 systable_endscan(scan); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1801 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1802 355 scan = systable_beginscan(pglrel, PropgraphElementLabelElementLabelIndexId, true, NULL, 1, scankey); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1803 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1804 812 while ((tup = systable_getnext(scan))) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1805 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1806 457 Form_pg_propgraph_element_label pgelform = (Form_pg_propgraph_element_label) GETSTRUCT(tup); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1807 457 const char *labelname; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1808 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1809 457 labelname = get_propgraph_label_name(pgelform->pgellabelid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1810 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1811 457 if (strcmp(labelname, elalias) == 0) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1812 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1813 - /* If the default label is the only label, don't print anything. */ 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1814 243 if (count != 1) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1815 30 appendStringInfo(buf, " DEFAULT LABEL"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1816 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1817 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1818 214 appendStringInfo(buf, " LABEL %s", quote_identifier(labelname)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1819 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1820 457 make_propgraphdef_properties(buf, pgelform->oid, elrelid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1821 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1822 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1823 355 systable_endscan(scan); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1824 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1825 355 table_close(pglrel, AccessShareLock); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1826 355 } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
propdata_by_name_cmp() lines 1833-1841
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
1833 709 propdata_by_name_cmp(const ListCell *a, const ListCell *b) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1834 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1835 709 List *la = lfirst_node(List, a); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1836 709 List *lb = lfirst_node(List, b); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1837 709 char *pna = strVal(linitial(la)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1838 709 char *pnb = strVal(linitial(lb)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1839 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1840 709 return strcmp(pna, pnb); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1841 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
make_propgraphdef_properties() lines 1849-1928
Modified Lines Coverage: 44/44 lines (100.0%)
LineHitsSourceCommit
1849 457 make_propgraphdef_properties(StringInfo buf, Oid ellabelid, Oid elrelid) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1850 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1851 457 Relation plprel; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1852 457 ScanKeyData scankey[1]; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1853 457 SysScanDesc scan; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1854 457 HeapTuple tup; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1855 457 List *outlist = NIL; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1856 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1857 457 plprel = table_open(PropgraphLabelPropertyRelationId, AccessShareLock); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1858 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1859 457 ScanKeyInit(&scankey[0], 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1860 - Anum_pg_propgraph_label_property_plpellabelid, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1861 - BTEqualStrategyNumber, F_OIDEQ, 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1862 - ObjectIdGetDatum(ellabelid)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1863 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1864 - /* 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1865 - * We want to output the properties in a deterministic order. So we first 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1866 - * read all the data, then sort, then print it. 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1867 - */ 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1868 457 scan = systable_beginscan(plprel, PropgraphLabelPropertyLabelPropIndexId, true, NULL, 1, scankey); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1869 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1870 1484 while ((tup = systable_getnext(scan))) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1871 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1872 1027 Form_pg_propgraph_label_property plpform = (Form_pg_propgraph_label_property) GETSTRUCT(tup); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1873 1027 Datum exprDatum; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1874 1027 bool isnull; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1875 1027 char *tmp; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1876 1027 Node *expr; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1877 1027 char *propname; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1878 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1879 1027 exprDatum = heap_getattr(tup, Anum_pg_propgraph_label_property_plpexpr, RelationGetDescr(plprel), &isnull); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1880 1027 Assert(!isnull); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1881 1027 tmp = TextDatumGetCString(exprDatum); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1882 1027 expr = stringToNode(tmp); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1883 1027 pfree(tmp); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1884 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1885 1027 propname = get_propgraph_property_name(plpform->plppropid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1886 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1887 1027 outlist = lappend(outlist, list_make2(makeString(propname), expr)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1888 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1889 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1890 457 systable_endscan(scan); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1891 457 table_close(plprel, AccessShareLock); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1892 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1893 457 list_sort(outlist, propdata_by_name_cmp); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1894 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1895 457 if (outlist) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1896 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1897 449 List *context; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1898 449 ListCell *lc; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1899 449 bool first = true; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1900 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1901 449 context = deparse_context_for(get_relation_name(elrelid), elrelid); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1902 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1903 449 appendStringInfo(buf, " PROPERTIES ("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1904 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1905 1476 foreach(lc, outlist) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1906 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1907 1027 List *data = lfirst_node(List, lc); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1908 1027 char *propname = strVal(linitial(data)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1909 1027 Node *expr = lsecond(data); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1910 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1911 1027 if (first) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1912 - first = false; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1913 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1914 578 appendStringInfo(buf, ", "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1915 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1916 1027 if (IsA(expr, Var) && strcmp(propname, get_attname(elrelid, castNode(Var, expr)->varattno, false)) == 0) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1917 830 appendStringInfo(buf, "%s", propname); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1918 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1919 197 appendStringInfo(buf, "%s AS %s", 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1920 - deparse_expression_pretty(expr, context, false, false, 0, 0), 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1921 - propname); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1922 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1923 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1924 449 appendStringInfo(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1925 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1926 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1927 8 appendStringInfo(buf, " NO PROPERTIES"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1928 457 } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
get_graph_label_expr() lines 7923-7966
Modified Lines Coverage: 9/22 lines (40.9%)
LineHitsSourceCommit
7923 39 get_graph_label_expr(Node *label_expr, deparse_context *context) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7924 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7925 39 StringInfo buf = context->buf; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7926 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7927 39 check_stack_depth(); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7928 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7929 39 switch (nodeTag(label_expr)) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7930 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7931 39 case T_GraphLabelRef: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7932 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7933 39 GraphLabelRef *lref = (GraphLabelRef *) label_expr; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7934 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7935 39 appendStringInfoString(buf, quote_identifier(get_propgraph_label_name(lref->labelid))); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7936 39 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7937 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7938 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7939 0 case T_BoolExpr: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7940 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7941 0 BoolExpr *be = (BoolExpr *) label_expr; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7942 0 ListCell *lc; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7943 0 bool first = true; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7944 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7945 0 Assert(be->boolop == OR_EXPR); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7946 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7947 0 foreach(lc, be->args) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7948 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7949 0 if (!first) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7950 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7951 0 if (be->boolop == OR_EXPR) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7952 0 appendStringInfoString(buf, "|"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7953 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7954 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7955 - first = false; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7956 0 get_graph_label_expr(lfirst(lc), context); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7957 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7958 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7959 0 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7960 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7961 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7962 0 default: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7963 0 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(label_expr)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7964 - break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7965 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7966 39 } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
get_path_pattern_expr_def() lines 7972-8052
Modified Lines Coverage: 35/53 lines (66.0%)
LineHitsSourceCommit
7972 13 get_path_pattern_expr_def(List *path_pattern_expr, deparse_context *context) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7973 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7974 13 StringInfo buf = context->buf; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7975 13 ListCell *lc; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7976 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7977 52 foreach(lc, path_pattern_expr) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7978 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7979 39 GraphElementPattern *gep = lfirst_node(GraphElementPattern, lc); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7980 39 const char *sep = ""; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7981 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7982 39 switch (gep->kind) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7983 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7984 26 case VERTEX_PATTERN: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7985 26 appendStringInfoString(buf, "("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7986 26 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7987 0 case EDGE_PATTERN_LEFT: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7988 0 appendStringInfoString(buf, "<-["); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7989 0 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7990 13 case EDGE_PATTERN_RIGHT: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7991 - case EDGE_PATTERN_ANY: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7992 13 appendStringInfoString(buf, "-["); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7993 13 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7994 0 case PAREN_EXPR: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7995 0 appendStringInfoString(buf, "("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7996 0 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7997 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7998 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
7999 39 if (gep->variable) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8000 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8001 26 appendStringInfoString(buf, gep->variable); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8002 26 sep = " "; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8003 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8004 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8005 39 if (gep->labelexpr) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8006 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8007 39 appendStringInfoString(buf, sep); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8008 39 appendStringInfoString(buf, "IS "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8009 39 get_graph_label_expr(gep->labelexpr, context); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8010 39 sep = " "; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8011 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8012 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8013 39 if (gep->subexpr) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8014 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8015 0 appendStringInfoString(buf, sep); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8016 0 get_path_pattern_expr_def(gep->subexpr, context); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8017 0 sep = " "; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8018 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8019 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8020 39 if (gep->whereClause) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8021 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8022 13 appendStringInfoString(buf, sep); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8023 13 appendStringInfoString(buf, "WHERE "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8024 13 get_rule_expr(gep->whereClause, context, false); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8025 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8026 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8027 39 switch (gep->kind) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8028 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8029 26 case VERTEX_PATTERN: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8030 26 appendStringInfoString(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8031 26 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8032 0 case EDGE_PATTERN_LEFT: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8033 - case EDGE_PATTERN_ANY: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8034 0 appendStringInfoString(buf, "]-"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8035 0 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8036 13 case EDGE_PATTERN_RIGHT: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8037 13 appendStringInfoString(buf, "]->"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8038 13 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8039 0 case PAREN_EXPR: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8040 0 appendStringInfoString(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8041 0 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8042 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8043 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8044 39 if (gep->quantifier) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8045 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8046 0 int lower = linitial_int(gep->quantifier); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8047 0 int upper = lsecond_int(gep->quantifier); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8048 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8049 0 appendStringInfo(buf, "{%d,%d}", lower, upper); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8050 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8051 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8052 13 } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
get_graph_pattern_def() lines 8058-8081
Modified Lines Coverage: 10/13 lines (76.9%)
LineHitsSourceCommit
8058 13 get_graph_pattern_def(GraphPattern *graph_pattern, deparse_context *context) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8059 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8060 13 StringInfo buf = context->buf; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8061 13 ListCell *lc; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8062 13 bool first = true; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8063 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8064 26 foreach(lc, graph_pattern->path_pattern_list) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8065 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8066 13 List *path_pattern_expr = lfirst_node(List, lc); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8067 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8068 13 if (!first) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8069 0 appendStringInfoString(buf, ", "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8070 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8071 - first = false; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8072 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8073 13 get_path_pattern_expr_def(path_pattern_expr, context); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8074 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8075 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8076 13 if (graph_pattern->whereClause) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8077 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8078 0 appendStringInfoString(buf, "WHERE "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8079 0 get_rule_expr(graph_pattern->whereClause, context, false); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8080 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8081 13 } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
get_name_for_var_field() lines 8514-8942
Modified Lines Coverage: 0/0 lines (0.0%)
LineHitsSourceCommit
8514 - get_name_for_var_field(Var *var, int fieldno, -
8515 - int levelsup, deparse_context *context) -
8516 - { -
8517 - RangeTblEntry *rte; -
8518 - AttrNumber attnum; -
8519 - int netlevelsup; -
8520 - deparse_namespace *dpns; -
8521 - int varno; -
8522 - AttrNumber varattno; -
8523 - TupleDesc tupleDesc; -
8524 - Node *expr; -
8525 - -
8526 - /* -
8527 - * If it's a RowExpr that was expanded from a whole-row Var, use the -
8528 - * column names attached to it. (We could let get_expr_result_tupdesc() -
8529 - * handle this, but it's much cheaper to just pull out the name we need.) -
8530 - */ -
8531 - if (IsA(var, RowExpr)) -
8532 - { -
8533 - RowExpr *r = (RowExpr *) var; -
8534 - -
8535 - if (fieldno > 0 && fieldno <= list_length(r->colnames)) -
8536 - return strVal(list_nth(r->colnames, fieldno - 1)); -
8537 - } -
8538 - -
8539 - /* -
8540 - * If it's a Param of type RECORD, try to find what the Param refers to. -
8541 - */ -
8542 - if (IsA(var, Param)) -
8543 - { -
8544 - Param *param = (Param *) var; -
8545 - ListCell *ancestor_cell; -
8546 - -
8547 - expr = find_param_referent(param, context, &dpns, &ancestor_cell); -
8548 - if (expr) -
8549 - { -
8550 - /* Found a match, so recurse to decipher the field name */ -
8551 - deparse_namespace save_dpns; -
8552 - const char *result; -
8553 - -
8554 - push_ancestor_plan(dpns, ancestor_cell, &save_dpns); -
8555 - result = get_name_for_var_field((Var *) expr, fieldno, -
8556 - 0, context); -
8557 - pop_ancestor_plan(dpns, &save_dpns); -
8558 - return result; -
8559 - } -
8560 - } -
8561 - -
8562 - /* -
8563 - * If it's a Var of type RECORD, we have to find what the Var refers to; -
8564 - * if not, we can use get_expr_result_tupdesc(). -
8565 - */ -
8566 - if (!IsA(var, Var) || -
8567 - var->vartype != RECORDOID) -
8568 - { -
8569 - tupleDesc = get_expr_result_tupdesc((Node *) var, false); -
8570 - /* Got the tupdesc, so we can extract the field name */ -
8571 - Assert(fieldno >= 1 && fieldno <= tupleDesc->natts); -
8572 - return NameStr(TupleDescAttr(tupleDesc, fieldno - 1)->attname); -
8573 - } -
8574 - -
8575 - /* Find appropriate nesting depth */ -
8576 - netlevelsup = var->varlevelsup + levelsup; -
8577 - if (netlevelsup >= list_length(context->namespaces)) -
8578 - elog(ERROR, "bogus varlevelsup: %d offset %d", -
8579 - var->varlevelsup, levelsup); -
8580 - dpns = (deparse_namespace *) list_nth(context->namespaces, -
8581 - netlevelsup); -
8582 - -
8583 - /* -
8584 - * If we have a syntactic referent for the Var, and we're working from a -
8585 - * parse tree, prefer to use the syntactic referent. Otherwise, fall back -
8586 - * on the semantic referent. (See comments in get_variable().) -
8587 - */ -
8588 - if (var->varnosyn > 0 && dpns->plan == NULL) -
8589 - { -
8590 - varno = var->varnosyn; -
8591 - varattno = var->varattnosyn; -
8592 - } -
8593 - else -
8594 - { -
8595 - varno = var->varno; -
8596 - varattno = var->varattno; -
8597 - } -
8598 - -
8599 - /* -
8600 - * Try to find the relevant RTE in this rtable. In a plan tree, it's -
8601 - * likely that varno is OUTER_VAR or INNER_VAR, in which case we must dig -
8602 - * down into the subplans, or INDEX_VAR, which is resolved similarly. -
8603 - * -
8604 - * Note: unlike get_variable and resolve_special_varno, we need not worry -
8605 - * about inheritance mapping: a child Var should have the same datatype as -
8606 - * its parent, and here we're really only interested in the Var's type. -
8607 - */ -
8608 - if (varno >= 1 && varno <= list_length(dpns->rtable)) -
8609 - { -
8610 - rte = rt_fetch(varno, dpns->rtable); -
8611 - attnum = varattno; -
8612 - } -
8613 - else if (varno == OUTER_VAR && dpns->outer_tlist) -
8614 - { -
8615 - TargetEntry *tle; -
8616 - deparse_namespace save_dpns; -
8617 - const char *result; -
8618 - -
8619 - tle = get_tle_by_resno(dpns->outer_tlist, varattno); -
8620 - if (!tle) -
8621 - elog(ERROR, "bogus varattno for OUTER_VAR var: %d", varattno); -
8622 - -
8623 - Assert(netlevelsup == 0); -
8624 - push_child_plan(dpns, dpns->outer_plan, &save_dpns); -
8625 - -
8626 - result = get_name_for_var_field((Var *) tle->expr, fieldno, -
8627 - levelsup, context); -
8628 - -
8629 - pop_child_plan(dpns, &save_dpns); -
8630 - return result; -
8631 - } -
8632 - else if (varno == INNER_VAR && dpns->inner_tlist) -
8633 - { -
8634 - TargetEntry *tle; -
8635 - deparse_namespace save_dpns; -
8636 - const char *result; -
8637 - -
8638 - tle = get_tle_by_resno(dpns->inner_tlist, varattno); -
8639 - if (!tle) -
8640 - elog(ERROR, "bogus varattno for INNER_VAR var: %d", varattno); -
8641 - -
8642 - Assert(netlevelsup == 0); -
8643 - push_child_plan(dpns, dpns->inner_plan, &save_dpns); -
8644 - -
8645 - result = get_name_for_var_field((Var *) tle->expr, fieldno, -
8646 - levelsup, context); -
8647 - -
8648 - pop_child_plan(dpns, &save_dpns); -
8649 - return result; -
8650 - } -
8651 - else if (varno == INDEX_VAR && dpns->index_tlist) -
8652 - { -
8653 - TargetEntry *tle; -
8654 - const char *result; -
8655 - -
8656 - tle = get_tle_by_resno(dpns->index_tlist, varattno); -
8657 - if (!tle) -
8658 - elog(ERROR, "bogus varattno for INDEX_VAR var: %d", varattno); -
8659 - -
8660 - Assert(netlevelsup == 0); -
8661 - -
8662 - result = get_name_for_var_field((Var *) tle->expr, fieldno, -
8663 - levelsup, context); -
8664 - -
8665 - return result; -
8666 - } -
8667 - else -
8668 - { -
8669 - elog(ERROR, "bogus varno: %d", varno); -
8670 - return NULL; /* keep compiler quiet */ -
8671 - } -
8672 - -
8673 - if (attnum == InvalidAttrNumber) -
8674 - { -
8675 - /* Var is whole-row reference to RTE, so select the right field */ -
8676 - return get_rte_attribute_name(rte, fieldno); -
8677 - } -
8678 - -
8679 - /* -
8680 - * This part has essentially the same logic as the parser's -
8681 - * expandRecordVariable() function, but we are dealing with a different -
8682 - * representation of the input context, and we only need one field name -
8683 - * not a TupleDesc. Also, we need special cases for finding subquery and -
8684 - * CTE subplans when deparsing Plan trees. -
8685 - */ -
8686 - expr = (Node *) var; /* default if we can't drill down */ -
8687 - -
8688 - switch (rte->rtekind) -
8689 - { -
8690 - case RTE_RELATION: -
8691 - case RTE_VALUES: -
8692 - case RTE_NAMEDTUPLESTORE: -
8693 - case RTE_GRAPH_TABLE: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
8694 - case RTE_RESULT: -
8695 - -
8696 - /* -
8697 - * This case should not occur: a column of a table, values list, -
8698 - * or ENR shouldn't have type RECORD. Fall through and fail (most -
8699 - * likely) at the bottom. -
8700 - */ -
8701 - break; -
8702 - case RTE_SUBQUERY: -
8703 - /* Subselect-in-FROM: examine sub-select's output expr */ -
8704 - { -
8705 - if (rte->subquery) -
8706 - { -
8707 - TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList, -
8708 - attnum); -
8709 - -
8710 - if (ste == NULL || ste->resjunk) -
8711 - elog(ERROR, "subquery %s does not have attribute %d", -
8712 - rte->eref->aliasname, attnum); -
8713 - expr = (Node *) ste->expr; -
8714 - if (IsA(expr, Var)) -
8715 - { -
8716 - /* -
8717 - * Recurse into the sub-select to see what its Var -
8718 - * refers to. We have to build an additional level of -
8719 - * namespace to keep in step with varlevelsup in the -
8720 - * subselect; furthermore, the subquery RTE might be -
8721 - * from an outer query level, in which case the -
8722 - * namespace for the subselect must have that outer -
8723 - * level as parent namespace. -
8724 - */ -
8725 - List *save_nslist = context->namespaces; -
8726 - List *parent_namespaces; -
8727 - deparse_namespace mydpns; -
8728 - const char *result; -
8729 - -
8730 - parent_namespaces = list_copy_tail(context->namespaces, -
8731 - netlevelsup); -
8732 - -
8733 - set_deparse_for_query(&mydpns, rte->subquery, -
8734 - parent_namespaces); -
8735 - -
8736 - context->namespaces = lcons(&mydpns, parent_namespaces); -
8737 - -
8738 - result = get_name_for_var_field((Var *) expr, fieldno, -
8739 - 0, context); -
8740 - -
8741 - context->namespaces = save_nslist; -
8742 - -
8743 - return result; -
8744 - } -
8745 - /* else fall through to inspect the expression */ -
8746 - } -
8747 - else -
8748 - { -
8749 - /* -
8750 - * We're deparsing a Plan tree so we don't have complete -
8751 - * RTE entries (in particular, rte->subquery is NULL). But -
8752 - * the only place we'd normally see a Var directly -
8753 - * referencing a SUBQUERY RTE is in a SubqueryScan plan -
8754 - * node, and we can look into the child plan's tlist -
8755 - * instead. An exception occurs if the subquery was -
8756 - * proven empty and optimized away: then we'd find such a -
8757 - * Var in a childless Result node, and there's nothing in -
8758 - * the plan tree that would let us figure out what it had -
8759 - * originally referenced. In that case, fall back on -
8760 - * printing "fN", analogously to the default column names -
8761 - * for RowExprs. -
8762 - */ -
8763 - TargetEntry *tle; -
8764 - deparse_namespace save_dpns; -
8765 - const char *result; -
8766 - -
8767 - if (!dpns->inner_plan) -
8768 - { -
8769 - char *dummy_name = palloc(32); -
8770 - -
8771 - Assert(dpns->plan && IsA(dpns->plan, Result)); -
8772 - snprintf(dummy_name, 32, "f%d", fieldno); -
8773 - return dummy_name; -
8774 - } -
8775 - Assert(dpns->plan && IsA(dpns->plan, SubqueryScan)); -
8776 - -
8777 - tle = get_tle_by_resno(dpns->inner_tlist, attnum); -
8778 - if (!tle) -
8779 - elog(ERROR, "bogus varattno for subquery var: %d", -
8780 - attnum); -
8781 - Assert(netlevelsup == 0); -
8782 - push_child_plan(dpns, dpns->inner_plan, &save_dpns); -
8783 - -
8784 - result = get_name_for_var_field((Var *) tle->expr, fieldno, -
8785 - levelsup, context); -
8786 - -
8787 - pop_child_plan(dpns, &save_dpns); -
8788 - return result; -
8789 - } -
8790 - } -
8791 - break; -
8792 - case RTE_JOIN: -
8793 - /* Join RTE --- recursively inspect the alias variable */ -
8794 - if (rte->joinaliasvars == NIL) -
8795 - elog(ERROR, "cannot decompile join alias var in plan tree"); -
8796 - Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars)); -
8797 - expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1); -
8798 - Assert(expr != NULL); -
8799 - /* we intentionally don't strip implicit coercions here */ -
8800 - if (IsA(expr, Var)) -
8801 - return get_name_for_var_field((Var *) expr, fieldno, -
8802 - var->varlevelsup + levelsup, -
8803 - context); -
8804 - /* else fall through to inspect the expression */ -
8805 - break; -
8806 - case RTE_FUNCTION: -
8807 - case RTE_TABLEFUNC: -
8808 - -
8809 - /* -
8810 - * We couldn't get here unless a function is declared with one of -
8811 - * its result columns as RECORD, which is not allowed. -
8812 - */ -
8813 - break; -
8814 - case RTE_CTE: -
8815 - /* CTE reference: examine subquery's output expr */ -
8816 - { -
8817 - CommonTableExpr *cte = NULL; -
8818 - Index ctelevelsup; -
8819 - ListCell *lc; -
8820 - -
8821 - /* -
8822 - * Try to find the referenced CTE using the namespace stack. -
8823 - */ -
8824 - ctelevelsup = rte->ctelevelsup + netlevelsup; -
8825 - if (ctelevelsup >= list_length(context->namespaces)) -
8826 - lc = NULL; -
8827 - else -
8828 - { -
8829 - deparse_namespace *ctedpns; -
8830 - -
8831 - ctedpns = (deparse_namespace *) -
8832 - list_nth(context->namespaces, ctelevelsup); -
8833 - foreach(lc, ctedpns->ctes) -
8834 - { -
8835 - cte = (CommonTableExpr *) lfirst(lc); -
8836 - if (strcmp(cte->ctename, rte->ctename) == 0) -
8837 - break; -
8838 - } -
8839 - } -
8840 - if (lc != NULL) -
8841 - { -
8842 - Query *ctequery = (Query *) cte->ctequery; -
8843 - TargetEntry *ste = get_tle_by_resno(GetCTETargetList(cte), -
8844 - attnum); -
8845 - -
8846 - if (ste == NULL || ste->resjunk) -
8847 - elog(ERROR, "CTE %s does not have attribute %d", -
8848 - rte->eref->aliasname, attnum); -
8849 - expr = (Node *) ste->expr; -
8850 - if (IsA(expr, Var)) -
8851 - { -
8852 - /* -
8853 - * Recurse into the CTE to see what its Var refers to. -
8854 - * We have to build an additional level of namespace -
8855 - * to keep in step with varlevelsup in the CTE; -
8856 - * furthermore it could be an outer CTE (compare -
8857 - * SUBQUERY case above). -
8858 - */ -
8859 - List *save_nslist = context->namespaces; -
8860 - List *parent_namespaces; -
8861 - deparse_namespace mydpns; -
8862 - const char *result; -
8863 - -
8864 - parent_namespaces = list_copy_tail(context->namespaces, -
8865 - ctelevelsup); -
8866 - -
8867 - set_deparse_for_query(&mydpns, ctequery, -
8868 - parent_namespaces); -
8869 - -
8870 - context->namespaces = lcons(&mydpns, parent_namespaces); -
8871 - -
8872 - result = get_name_for_var_field((Var *) expr, fieldno, -
8873 - 0, context); -
8874 - -
8875 - context->namespaces = save_nslist; -
8876 - -
8877 - return result; -
8878 - } -
8879 - /* else fall through to inspect the expression */ -
8880 - } -
8881 - else -
8882 - { -
8883 - /* -
8884 - * We're deparsing a Plan tree so we don't have a CTE -
8885 - * list. But the only places we'd normally see a Var -
8886 - * directly referencing a CTE RTE are in CteScan or -
8887 - * WorkTableScan plan nodes. For those cases, -
8888 - * set_deparse_plan arranged for dpns->inner_plan to be -
8889 - * the plan node that emits the CTE or RecursiveUnion -
8890 - * result, and we can look at its tlist instead. As -
8891 - * above, this can fail if the CTE has been proven empty, -
8892 - * in which case fall back to "fN". -
8893 - */ -
8894 - TargetEntry *tle; -
8895 - deparse_namespace save_dpns; -
8896 - const char *result; -
8897 - -
8898 - if (!dpns->inner_plan) -
8899 - { -
8900 - char *dummy_name = palloc(32); -
8901 - -
8902 - Assert(dpns->plan && IsA(dpns->plan, Result)); -
8903 - snprintf(dummy_name, 32, "f%d", fieldno); -
8904 - return dummy_name; -
8905 - } -
8906 - Assert(dpns->plan && (IsA(dpns->plan, CteScan) || -
8907 - IsA(dpns->plan, WorkTableScan))); -
8908 - -
8909 - tle = get_tle_by_resno(dpns->inner_tlist, attnum); -
8910 - if (!tle) -
8911 - elog(ERROR, "bogus varattno for subquery var: %d", -
8912 - attnum); -
8913 - Assert(netlevelsup == 0); -
8914 - push_child_plan(dpns, dpns->inner_plan, &save_dpns); -
8915 - -
8916 - result = get_name_for_var_field((Var *) tle->expr, fieldno, -
8917 - levelsup, context); -
8918 - -
8919 - pop_child_plan(dpns, &save_dpns); -
8920 - return result; -
8921 - } -
8922 - } -
8923 - break; -
8924 - case RTE_GROUP: -
8925 - -
8926 - /* -
8927 - * We couldn't get here: any Vars that reference the RTE_GROUP RTE -
8928 - * should have been replaced with the underlying grouping -
8929 - * expressions. -
8930 - */ -
8931 - break; -
8932 - } -
8933 - -
8934 - /* -
8935 - * We now have an expression we can't expand any more, so see if -
8936 - * get_expr_result_tupdesc() can do anything with it. -
8937 - */ -
8938 - tupleDesc = get_expr_result_tupdesc(expr, false); -
8939 - /* Got the tupdesc, so we can extract the field name */ -
8940 - Assert(fieldno >= 1 && fieldno <= tupleDesc->natts); -
8941 - return NameStr(TupleDescAttr(tupleDesc, fieldno - 1)->attname); -
8942 - } -
get_rule_expr() lines 9758-11150
Modified Lines Coverage: 4/4 lines (100.0%)
LineHitsSourceCommit
9758 - get_rule_expr(Node *node, deparse_context *context, -
9759 - bool showimplicit) -
9760 - { -
9761 - StringInfo buf = context->buf; -
9762 - -
9763 - if (node == NULL) -
9764 - return; -
9765 - -
9766 - /* Guard against excessively long or deeply-nested queries */ -
9767 - CHECK_FOR_INTERRUPTS(); -
9768 - check_stack_depth(); -
9769 - -
9770 - /* -
9771 - * Each level of get_rule_expr must emit an indivisible term -
9772 - * (parenthesized if necessary) to ensure result is reparsed into the same -
9773 - * expression tree. The only exception is that when the input is a List, -
9774 - * we emit the component items comma-separated with no surrounding -
9775 - * decoration; this is convenient for most callers. -
9776 - */ -
9777 - switch (nodeTag(node)) -
9778 - { -
9779 - case T_Var: -
9780 - (void) get_variable((Var *) node, 0, false, context); -
9781 - break; -
9782 - -
9783 - case T_Const: -
9784 - get_const_expr((Const *) node, context, 0); -
9785 - break; -
9786 - -
9787 - case T_Param: -
9788 - get_parameter((Param *) node, context); -
9789 - break; -
9790 - -
9791 - case T_Aggref: -
9792 - get_agg_expr((Aggref *) node, context, (Aggref *) node); -
9793 - break; -
9794 - -
9795 - case T_GroupingFunc: -
9796 - { -
9797 - GroupingFunc *gexpr = (GroupingFunc *) node; -
9798 - -
9799 - appendStringInfoString(buf, "GROUPING("); -
9800 - get_rule_expr((Node *) gexpr->args, context, true); -
9801 - appendStringInfoChar(buf, ')'); -
9802 - } -
9803 - break; -
9804 - -
9805 - case T_WindowFunc: -
9806 - get_windowfunc_expr((WindowFunc *) node, context); -
9807 - break; -
9808 - -
9809 - case T_MergeSupportFunc: -
9810 - appendStringInfoString(buf, "MERGE_ACTION()"); -
9811 - break; -
9812 - -
9813 - case T_SubscriptingRef: -
9814 - { -
9815 - SubscriptingRef *sbsref = (SubscriptingRef *) node; -
9816 - bool need_parens; -
9817 - -
9818 - /* -
9819 - * If the argument is a CaseTestExpr, we must be inside a -
9820 - * FieldStore, ie, we are assigning to an element of an array -
9821 - * within a composite column. Since we already punted on -
9822 - * displaying the FieldStore's target information, just punt -
9823 - * here too, and display only the assignment source -
9824 - * expression. -
9825 - */ -
9826 - if (IsA(sbsref->refexpr, CaseTestExpr)) -
9827 - { -
9828 - Assert(sbsref->refassgnexpr); -
9829 - get_rule_expr((Node *) sbsref->refassgnexpr, -
9830 - context, showimplicit); -
9831 - break; -
9832 - } -
9833 - -
9834 - /* -
9835 - * Parenthesize the argument unless it's a simple Var or a -
9836 - * FieldSelect. (In particular, if it's another -
9837 - * SubscriptingRef, we *must* parenthesize to avoid -
9838 - * confusion.) -
9839 - */ -
9840 - need_parens = !IsA(sbsref->refexpr, Var) && -
9841 - !IsA(sbsref->refexpr, FieldSelect); -
9842 - if (need_parens) -
9843 - appendStringInfoChar(buf, '('); -
9844 - get_rule_expr((Node *) sbsref->refexpr, context, showimplicit); -
9845 - if (need_parens) -
9846 - appendStringInfoChar(buf, ')'); -
9847 - -
9848 - /* -
9849 - * If there's a refassgnexpr, we want to print the node in the -
9850 - * format "container[subscripts] := refassgnexpr". This is -
9851 - * not legal SQL, so decompilation of INSERT or UPDATE -
9852 - * statements should always use processIndirection as part of -
9853 - * the statement-level syntax. We should only see this when -
9854 - * EXPLAIN tries to print the targetlist of a plan resulting -
9855 - * from such a statement. -
9856 - */ -
9857 - if (sbsref->refassgnexpr) -
9858 - { -
9859 - Node *refassgnexpr; -
9860 - -
9861 - /* -
9862 - * Use processIndirection to print this node's subscripts -
9863 - * as well as any additional field selections or -
9864 - * subscripting in immediate descendants. It returns the -
9865 - * RHS expr that is actually being "assigned". -
9866 - */ -
9867 - refassgnexpr = processIndirection(node, context); -
9868 - appendStringInfoString(buf, " := "); -
9869 - get_rule_expr(refassgnexpr, context, showimplicit); -
9870 - } -
9871 - else -
9872 - { -
9873 - /* Just an ordinary container fetch, so print subscripts */ -
9874 - printSubscripts(sbsref, context); -
9875 - } -
9876 - } -
9877 - break; -
9878 - -
9879 - case T_FuncExpr: -
9880 - get_func_expr((FuncExpr *) node, context, showimplicit); -
9881 - break; -
9882 - -
9883 - case T_NamedArgExpr: -
9884 - { -
9885 - NamedArgExpr *na = (NamedArgExpr *) node; -
9886 - -
9887 - appendStringInfo(buf, "%s => ", quote_identifier(na->name)); -
9888 - get_rule_expr((Node *) na->arg, context, showimplicit); -
9889 - } -
9890 - break; -
9891 - -
9892 - case T_OpExpr: -
9893 - get_oper_expr((OpExpr *) node, context); -
9894 - break; -
9895 - -
9896 - case T_DistinctExpr: -
9897 - { -
9898 - DistinctExpr *expr = (DistinctExpr *) node; -
9899 - List *args = expr->args; -
9900 - Node *arg1 = (Node *) linitial(args); -
9901 - Node *arg2 = (Node *) lsecond(args); -
9902 - -
9903 - if (!PRETTY_PAREN(context)) -
9904 - appendStringInfoChar(buf, '('); -
9905 - get_rule_expr_paren(arg1, context, true, node); -
9906 - appendStringInfoString(buf, " IS DISTINCT FROM "); -
9907 - get_rule_expr_paren(arg2, context, true, node); -
9908 - if (!PRETTY_PAREN(context)) -
9909 - appendStringInfoChar(buf, ')'); -
9910 - } -
9911 - break; -
9912 - -
9913 - case T_NullIfExpr: -
9914 - { -
9915 - NullIfExpr *nullifexpr = (NullIfExpr *) node; -
9916 - -
9917 - appendStringInfoString(buf, "NULLIF("); -
9918 - get_rule_expr((Node *) nullifexpr->args, context, true); -
9919 - appendStringInfoChar(buf, ')'); -
9920 - } -
9921 - break; -
9922 - -
9923 - case T_ScalarArrayOpExpr: -
9924 - { -
9925 - ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; -
9926 - List *args = expr->args; -
9927 - Node *arg1 = (Node *) linitial(args); -
9928 - Node *arg2 = (Node *) lsecond(args); -
9929 - -
9930 - if (!PRETTY_PAREN(context)) -
9931 - appendStringInfoChar(buf, '('); -
9932 - get_rule_expr_paren(arg1, context, true, node); -
9933 - appendStringInfo(buf, " %s %s (", -
9934 - generate_operator_name(expr->opno, -
9935 - exprType(arg1), -
9936 - get_base_element_type(exprType(arg2))), -
9937 - expr->useOr ? "ANY" : "ALL"); -
9938 - get_rule_expr_paren(arg2, context, true, node); -
9939 - -
9940 - /* -
9941 - * There's inherent ambiguity in "x op ANY/ALL (y)" when y is -
9942 - * a bare sub-SELECT. Since we're here, the sub-SELECT must -
9943 - * be meant as a scalar sub-SELECT yielding an array value to -
9944 - * be used in ScalarArrayOpExpr; but the grammar will -
9945 - * preferentially interpret such a construct as an ANY/ALL -
9946 - * SubLink. To prevent misparsing the output that way, insert -
9947 - * a dummy coercion (which will be stripped by parse analysis, -
9948 - * so no inefficiency is added in dump and reload). This is -
9949 - * indeed most likely what the user wrote to get the construct -
9950 - * accepted in the first place. -
9951 - */ -
9952 - if (IsA(arg2, SubLink) && -
9953 - ((SubLink *) arg2)->subLinkType == EXPR_SUBLINK) -
9954 - appendStringInfo(buf, "::%s", -
9955 - format_type_with_typemod(exprType(arg2), -
9956 - exprTypmod(arg2))); -
9957 - appendStringInfoChar(buf, ')'); -
9958 - if (!PRETTY_PAREN(context)) -
9959 - appendStringInfoChar(buf, ')'); -
9960 - } -
9961 - break; -
9962 - -
9963 - case T_BoolExpr: -
9964 - { -
9965 - BoolExpr *expr = (BoolExpr *) node; -
9966 - Node *first_arg = linitial(expr->args); -
9967 - ListCell *arg; -
9968 - -
9969 - switch (expr->boolop) -
9970 - { -
9971 - case AND_EXPR: -
9972 - if (!PRETTY_PAREN(context)) -
9973 - appendStringInfoChar(buf, '('); -
9974 - get_rule_expr_paren(first_arg, context, -
9975 - false, node); -
9976 - for_each_from(arg, expr->args, 1) -
9977 - { -
9978 - appendStringInfoString(buf, " AND "); -
9979 - get_rule_expr_paren((Node *) lfirst(arg), context, -
9980 - false, node); -
9981 - } -
9982 - if (!PRETTY_PAREN(context)) -
9983 - appendStringInfoChar(buf, ')'); -
9984 - break; -
9985 - -
9986 - case OR_EXPR: -
9987 - if (!PRETTY_PAREN(context)) -
9988 - appendStringInfoChar(buf, '('); -
9989 - get_rule_expr_paren(first_arg, context, -
9990 - false, node); -
9991 - for_each_from(arg, expr->args, 1) -
9992 - { -
9993 - appendStringInfoString(buf, " OR "); -
9994 - get_rule_expr_paren((Node *) lfirst(arg), context, -
9995 - false, node); -
9996 - } -
9997 - if (!PRETTY_PAREN(context)) -
9998 - appendStringInfoChar(buf, ')'); -
9999 - break; -
10000 - -
10001 - case NOT_EXPR: -
10002 - if (!PRETTY_PAREN(context)) -
10003 - appendStringInfoChar(buf, '('); -
10004 - appendStringInfoString(buf, "NOT "); -
10005 - get_rule_expr_paren(first_arg, context, -
10006 - false, node); -
10007 - if (!PRETTY_PAREN(context)) -
10008 - appendStringInfoChar(buf, ')'); -
10009 - break; -
10010 - -
10011 - default: -
10012 - elog(ERROR, "unrecognized boolop: %d", -
10013 - (int) expr->boolop); -
10014 - } -
10015 - } -
10016 - break; -
10017 - -
10018 - case T_SubLink: -
10019 - get_sublink_expr((SubLink *) node, context); -
10020 - break; -
10021 - -
10022 - case T_SubPlan: -
10023 - { -
10024 - SubPlan *subplan = (SubPlan *) node; -
10025 - -
10026 - /* -
10027 - * We cannot see an already-planned subplan in rule deparsing, -
10028 - * only while EXPLAINing a query plan. We don't try to -
10029 - * reconstruct the original SQL, just reference the subplan -
10030 - * that appears elsewhere in EXPLAIN's result. It does seem -
10031 - * useful to show the subLinkType and testexpr (if any), and -
10032 - * we also note whether the subplan will be hashed. -
10033 - */ -
10034 - switch (subplan->subLinkType) -
10035 - { -
10036 - case EXISTS_SUBLINK: -
10037 - appendStringInfoString(buf, "EXISTS("); -
10038 - Assert(subplan->testexpr == NULL); -
10039 - break; -
10040 - case ALL_SUBLINK: -
10041 - appendStringInfoString(buf, "(ALL "); -
10042 - Assert(subplan->testexpr != NULL); -
10043 - break; -
10044 - case ANY_SUBLINK: -
10045 - appendStringInfoString(buf, "(ANY "); -
10046 - Assert(subplan->testexpr != NULL); -
10047 - break; -
10048 - case ROWCOMPARE_SUBLINK: -
10049 - /* Parenthesizing the testexpr seems sufficient */ -
10050 - appendStringInfoChar(buf, '('); -
10051 - Assert(subplan->testexpr != NULL); -
10052 - break; -
10053 - case EXPR_SUBLINK: -
10054 - /* No need to decorate these subplan references */ -
10055 - appendStringInfoChar(buf, '('); -
10056 - Assert(subplan->testexpr == NULL); -
10057 - break; -
10058 - case MULTIEXPR_SUBLINK: -
10059 - /* MULTIEXPR isn't executed in the normal way */ -
10060 - appendStringInfoString(buf, "(rescan "); -
10061 - Assert(subplan->testexpr == NULL); -
10062 - break; -
10063 - case ARRAY_SUBLINK: -
10064 - appendStringInfoString(buf, "ARRAY("); -
10065 - Assert(subplan->testexpr == NULL); -
10066 - break; -
10067 - case CTE_SUBLINK: -
10068 - /* This case is unreachable within expressions */ -
10069 - appendStringInfoString(buf, "CTE("); -
10070 - Assert(subplan->testexpr == NULL); -
10071 - break; -
10072 - } -
10073 - -
10074 - if (subplan->testexpr != NULL) -
10075 - { -
10076 - deparse_namespace *dpns; -
10077 - -
10078 - /* -
10079 - * Push SubPlan into ancestors list while deparsing -
10080 - * testexpr, so that we can handle PARAM_EXEC references -
10081 - * to the SubPlan's paramIds. (This makes it look like -
10082 - * the SubPlan is an "ancestor" of the current plan node, -
10083 - * which is a little weird, but it does no harm.) In this -
10084 - * path, we don't need to mention the SubPlan explicitly, -
10085 - * because the referencing Params will show its existence. -
10086 - */ -
10087 - dpns = (deparse_namespace *) linitial(context->namespaces); -
10088 - dpns->ancestors = lcons(subplan, dpns->ancestors); -
10089 - -
10090 - get_rule_expr(subplan->testexpr, context, showimplicit); -
10091 - appendStringInfoChar(buf, ')'); -
10092 - -
10093 - dpns->ancestors = list_delete_first(dpns->ancestors); -
10094 - } -
10095 - else -
10096 - { -
10097 - const char *nameprefix; -
10098 - -
10099 - /* No referencing Params, so show the SubPlan's name */ -
10100 - if (subplan->isInitPlan) -
10101 - nameprefix = "InitPlan "; -
10102 - else -
10103 - nameprefix = "SubPlan "; -
10104 - if (subplan->useHashTable) -
10105 - appendStringInfo(buf, "hashed %s%s)", -
10106 - nameprefix, subplan->plan_name); -
10107 - else -
10108 - appendStringInfo(buf, "%s%s)", -
10109 - nameprefix, subplan->plan_name); -
10110 - } -
10111 - } -
10112 - break; -
10113 - -
10114 - case T_AlternativeSubPlan: -
10115 - { -
10116 - AlternativeSubPlan *asplan = (AlternativeSubPlan *) node; -
10117 - ListCell *lc; -
10118 - -
10119 - /* -
10120 - * This case cannot be reached in normal usage, since no -
10121 - * AlternativeSubPlan can appear either in parsetrees or -
10122 - * finished plan trees. We keep it just in case somebody -
10123 - * wants to use this code to print planner data structures. -
10124 - */ -
10125 - appendStringInfoString(buf, "(alternatives: "); -
10126 - foreach(lc, asplan->subplans) -
10127 - { -
10128 - SubPlan *splan = lfirst_node(SubPlan, lc); -
10129 - const char *nameprefix; -
10130 - -
10131 - if (splan->isInitPlan) -
10132 - nameprefix = "InitPlan "; -
10133 - else -
10134 - nameprefix = "SubPlan "; -
10135 - if (splan->useHashTable) -
10136 - appendStringInfo(buf, "hashed %s%s", nameprefix, -
10137 - splan->plan_name); -
10138 - else -
10139 - appendStringInfo(buf, "%s%s", nameprefix, -
10140 - splan->plan_name); -
10141 - if (lnext(asplan->subplans, lc)) -
10142 - appendStringInfoString(buf, " or "); -
10143 - } -
10144 - appendStringInfoChar(buf, ')'); -
10145 - } -
10146 - break; -
10147 - -
10148 - case T_FieldSelect: -
10149 - { -
10150 - FieldSelect *fselect = (FieldSelect *) node; -
10151 - Node *arg = (Node *) fselect->arg; -
10152 - int fno = fselect->fieldnum; -
10153 - const char *fieldname; -
10154 - bool need_parens; -
10155 - -
10156 - /* -
10157 - * Parenthesize the argument unless it's an SubscriptingRef or -
10158 - * another FieldSelect. Note in particular that it would be -
10159 - * WRONG to not parenthesize a Var argument; simplicity is not -
10160 - * the issue here, having the right number of names is. -
10161 - */ -
10162 - need_parens = !IsA(arg, SubscriptingRef) && -
10163 - !IsA(arg, FieldSelect); -
10164 - if (need_parens) -
10165 - appendStringInfoChar(buf, '('); -
10166 - get_rule_expr(arg, context, true); -
10167 - if (need_parens) -
10168 - appendStringInfoChar(buf, ')'); -
10169 - -
10170 - /* -
10171 - * Get and print the field name. -
10172 - */ -
10173 - fieldname = get_name_for_var_field((Var *) arg, fno, -
10174 - 0, context); -
10175 - appendStringInfo(buf, ".%s", quote_identifier(fieldname)); -
10176 - } -
10177 - break; -
10178 - -
10179 - case T_FieldStore: -
10180 - { -
10181 - FieldStore *fstore = (FieldStore *) node; -
10182 - bool need_parens; -
10183 - -
10184 - /* -
10185 - * There is no good way to represent a FieldStore as real SQL, -
10186 - * so decompilation of INSERT or UPDATE statements should -
10187 - * always use processIndirection as part of the -
10188 - * statement-level syntax. We should only get here when -
10189 - * EXPLAIN tries to print the targetlist of a plan resulting -
10190 - * from such a statement. The plan case is even harder than -
10191 - * ordinary rules would be, because the planner tries to -
10192 - * collapse multiple assignments to the same field or subfield -
10193 - * into one FieldStore; so we can see a list of target fields -
10194 - * not just one, and the arguments could be FieldStores -
10195 - * themselves. We don't bother to try to print the target -
10196 - * field names; we just print the source arguments, with a -
10197 - * ROW() around them if there's more than one. This isn't -
10198 - * terribly complete, but it's probably good enough for -
10199 - * EXPLAIN's purposes; especially since anything more would be -
10200 - * either hopelessly confusing or an even poorer -
10201 - * representation of what the plan is actually doing. -
10202 - */ -
10203 - need_parens = (list_length(fstore->newvals) != 1); -
10204 - if (need_parens) -
10205 - appendStringInfoString(buf, "ROW("); -
10206 - get_rule_expr((Node *) fstore->newvals, context, showimplicit); -
10207 - if (need_parens) -
10208 - appendStringInfoChar(buf, ')'); -
10209 - } -
10210 - break; -
10211 - -
10212 - case T_RelabelType: -
10213 - { -
10214 - RelabelType *relabel = (RelabelType *) node; -
10215 - Node *arg = (Node *) relabel->arg; -
10216 - -
10217 - if (relabel->relabelformat == COERCE_IMPLICIT_CAST && -
10218 - !showimplicit) -
10219 - { -
10220 - /* don't show the implicit cast */ -
10221 - get_rule_expr_paren(arg, context, false, node); -
10222 - } -
10223 - else -
10224 - { -
10225 - get_coercion_expr(arg, context, -
10226 - relabel->resulttype, -
10227 - relabel->resulttypmod, -
10228 - node); -
10229 - } -
10230 - } -
10231 - break; -
10232 - -
10233 - case T_CoerceViaIO: -
10234 - { -
10235 - CoerceViaIO *iocoerce = (CoerceViaIO *) node; -
10236 - Node *arg = (Node *) iocoerce->arg; -
10237 - -
10238 - if (iocoerce->coerceformat == COERCE_IMPLICIT_CAST && -
10239 - !showimplicit) -
10240 - { -
10241 - /* don't show the implicit cast */ -
10242 - get_rule_expr_paren(arg, context, false, node); -
10243 - } -
10244 - else -
10245 - { -
10246 - get_coercion_expr(arg, context, -
10247 - iocoerce->resulttype, -
10248 - -1, -
10249 - node); -
10250 - } -
10251 - } -
10252 - break; -
10253 - -
10254 - case T_ArrayCoerceExpr: -
10255 - { -
10256 - ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node; -
10257 - Node *arg = (Node *) acoerce->arg; -
10258 - -
10259 - if (acoerce->coerceformat == COERCE_IMPLICIT_CAST && -
10260 - !showimplicit) -
10261 - { -
10262 - /* don't show the implicit cast */ -
10263 - get_rule_expr_paren(arg, context, false, node); -
10264 - } -
10265 - else -
10266 - { -
10267 - get_coercion_expr(arg, context, -
10268 - acoerce->resulttype, -
10269 - acoerce->resulttypmod, -
10270 - node); -
10271 - } -
10272 - } -
10273 - break; -
10274 - -
10275 - case T_ConvertRowtypeExpr: -
10276 - { -
10277 - ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node; -
10278 - Node *arg = (Node *) convert->arg; -
10279 - -
10280 - if (convert->convertformat == COERCE_IMPLICIT_CAST && -
10281 - !showimplicit) -
10282 - { -
10283 - /* don't show the implicit cast */ -
10284 - get_rule_expr_paren(arg, context, false, node); -
10285 - } -
10286 - else -
10287 - { -
10288 - get_coercion_expr(arg, context, -
10289 - convert->resulttype, -1, -
10290 - node); -
10291 - } -
10292 - } -
10293 - break; -
10294 - -
10295 - case T_CollateExpr: -
10296 - { -
10297 - CollateExpr *collate = (CollateExpr *) node; -
10298 - Node *arg = (Node *) collate->arg; -
10299 - -
10300 - if (!PRETTY_PAREN(context)) -
10301 - appendStringInfoChar(buf, '('); -
10302 - get_rule_expr_paren(arg, context, showimplicit, node); -
10303 - appendStringInfo(buf, " COLLATE %s", -
10304 - generate_collation_name(collate->collOid)); -
10305 - if (!PRETTY_PAREN(context)) -
10306 - appendStringInfoChar(buf, ')'); -
10307 - } -
10308 - break; -
10309 - -
10310 - case T_CaseExpr: -
10311 - { -
10312 - CaseExpr *caseexpr = (CaseExpr *) node; -
10313 - ListCell *temp; -
10314 - -
10315 - appendContextKeyword(context, "CASE", -
10316 - 0, PRETTYINDENT_VAR, 0); -
10317 - if (caseexpr->arg) -
10318 - { -
10319 - appendStringInfoChar(buf, ' '); -
10320 - get_rule_expr((Node *) caseexpr->arg, context, true); -
10321 - } -
10322 - foreach(temp, caseexpr->args) -
10323 - { -
10324 - CaseWhen *when = (CaseWhen *) lfirst(temp); -
10325 - Node *w = (Node *) when->expr; -
10326 - -
10327 - if (caseexpr->arg) -
10328 - { -
10329 - /* -
10330 - * The parser should have produced WHEN clauses of the -
10331 - * form "CaseTestExpr = RHS", possibly with an -
10332 - * implicit coercion inserted above the CaseTestExpr. -
10333 - * For accurate decompilation of rules it's essential -
10334 - * that we show just the RHS. However in an -
10335 - * expression that's been through the optimizer, the -
10336 - * WHEN clause could be almost anything (since the -
10337 - * equality operator could have been expanded into an -
10338 - * inline function). If we don't recognize the form -
10339 - * of the WHEN clause, just punt and display it as-is. -
10340 - */ -
10341 - if (IsA(w, OpExpr)) -
10342 - { -
10343 - List *args = ((OpExpr *) w)->args; -
10344 - -
10345 - if (list_length(args) == 2 && -
10346 - IsA(strip_implicit_coercions(linitial(args)), -
10347 - CaseTestExpr)) -
10348 - w = (Node *) lsecond(args); -
10349 - } -
10350 - } -
10351 - -
10352 - if (!PRETTY_INDENT(context)) -
10353 - appendStringInfoChar(buf, ' '); -
10354 - appendContextKeyword(context, "WHEN ", -
10355 - 0, 0, 0); -
10356 - get_rule_expr(w, context, false); -
10357 - appendStringInfoString(buf, " THEN "); -
10358 - get_rule_expr((Node *) when->result, context, true); -
10359 - } -
10360 - if (!PRETTY_INDENT(context)) -
10361 - appendStringInfoChar(buf, ' '); -
10362 - appendContextKeyword(context, "ELSE ", -
10363 - 0, 0, 0); -
10364 - get_rule_expr((Node *) caseexpr->defresult, context, true); -
10365 - if (!PRETTY_INDENT(context)) -
10366 - appendStringInfoChar(buf, ' '); -
10367 - appendContextKeyword(context, "END", -
10368 - -PRETTYINDENT_VAR, 0, 0); -
10369 - } -
10370 - break; -
10371 - -
10372 - case T_CaseTestExpr: -
10373 - { -
10374 - /* -
10375 - * Normally we should never get here, since for expressions -
10376 - * that can contain this node type we attempt to avoid -
10377 - * recursing to it. But in an optimized expression we might -
10378 - * be unable to avoid that (see comments for CaseExpr). If we -
10379 - * do see one, print it as CASE_TEST_EXPR. -
10380 - */ -
10381 - appendStringInfoString(buf, "CASE_TEST_EXPR"); -
10382 - } -
10383 - break; -
10384 - -
10385 - case T_ArrayExpr: -
10386 - { -
10387 - ArrayExpr *arrayexpr = (ArrayExpr *) node; -
10388 - -
10389 - appendStringInfoString(buf, "ARRAY["); -
10390 - get_rule_expr((Node *) arrayexpr->elements, context, true); -
10391 - appendStringInfoChar(buf, ']'); -
10392 - -
10393 - /* -
10394 - * If the array isn't empty, we assume its elements are -
10395 - * coerced to the desired type. If it's empty, though, we -
10396 - * need an explicit coercion to the array type. -
10397 - */ -
10398 - if (arrayexpr->elements == NIL) -
10399 - appendStringInfo(buf, "::%s", -
10400 - format_type_with_typemod(arrayexpr->array_typeid, -1)); -
10401 - } -
10402 - break; -
10403 - -
10404 - case T_RowExpr: -
10405 - { -
10406 - RowExpr *rowexpr = (RowExpr *) node; -
10407 - TupleDesc tupdesc = NULL; -
10408 - ListCell *arg; -
10409 - int i; -
10410 - char *sep; -
10411 - -
10412 - /* -
10413 - * If it's a named type and not RECORD, we may have to skip -
10414 - * dropped columns and/or claim there are NULLs for added -
10415 - * columns. -
10416 - */ -
10417 - if (rowexpr->row_typeid != RECORDOID) -
10418 - { -
10419 - tupdesc = lookup_rowtype_tupdesc(rowexpr->row_typeid, -1); -
10420 - Assert(list_length(rowexpr->args) <= tupdesc->natts); -
10421 - } -
10422 - -
10423 - /* -
10424 - * SQL99 allows "ROW" to be omitted when there is more than -
10425 - * one column, but for simplicity we always print it. -
10426 - */ -
10427 - appendStringInfoString(buf, "ROW("); -
10428 - sep = ""; -
10429 - i = 0; -
10430 - foreach(arg, rowexpr->args) -
10431 - { -
10432 - Node *e = (Node *) lfirst(arg); -
10433 - -
10434 - if (tupdesc == NULL || -
10435 - !TupleDescCompactAttr(tupdesc, i)->attisdropped) -
10436 - { -
10437 - appendStringInfoString(buf, sep); -
10438 - /* Whole-row Vars need special treatment here */ -
10439 - get_rule_expr_toplevel(e, context, true); -
10440 - sep = ", "; -
10441 - } -
10442 - i++; -
10443 - } -
10444 - if (tupdesc != NULL) -
10445 - { -
10446 - while (i < tupdesc->natts) -
10447 - { -
10448 - if (!TupleDescCompactAttr(tupdesc, i)->attisdropped) -
10449 - { -
10450 - appendStringInfoString(buf, sep); -
10451 - appendStringInfoString(buf, "NULL"); -
10452 - sep = ", "; -
10453 - } -
10454 - i++; -
10455 - } -
10456 - -
10457 - ReleaseTupleDesc(tupdesc); -
10458 - } -
10459 - appendStringInfoChar(buf, ')'); -
10460 - if (rowexpr->row_format == COERCE_EXPLICIT_CAST) -
10461 - appendStringInfo(buf, "::%s", -
10462 - format_type_with_typemod(rowexpr->row_typeid, -1)); -
10463 - } -
10464 - break; -
10465 - -
10466 - case T_RowCompareExpr: -
10467 - { -
10468 - RowCompareExpr *rcexpr = (RowCompareExpr *) node; -
10469 - -
10470 - /* -
10471 - * SQL99 allows "ROW" to be omitted when there is more than -
10472 - * one column, but for simplicity we always print it. Within -
10473 - * a ROW expression, whole-row Vars need special treatment, so -
10474 - * use get_rule_list_toplevel. -
10475 - */ -
10476 - appendStringInfoString(buf, "(ROW("); -
10477 - get_rule_list_toplevel(rcexpr->largs, context, true); -
10478 - -
10479 - /* -
10480 - * We assume that the name of the first-column operator will -
10481 - * do for all the rest too. This is definitely open to -
10482 - * failure, eg if some but not all operators were renamed -
10483 - * since the construct was parsed, but there seems no way to -
10484 - * be perfect. -
10485 - */ -
10486 - appendStringInfo(buf, ") %s ROW(", -
10487 - generate_operator_name(linitial_oid(rcexpr->opnos), -
10488 - exprType(linitial(rcexpr->largs)), -
10489 - exprType(linitial(rcexpr->rargs)))); -
10490 - get_rule_list_toplevel(rcexpr->rargs, context, true); -
10491 - appendStringInfoString(buf, "))"); -
10492 - } -
10493 - break; -
10494 - -
10495 - case T_CoalesceExpr: -
10496 - { -
10497 - CoalesceExpr *coalesceexpr = (CoalesceExpr *) node; -
10498 - -
10499 - appendStringInfoString(buf, "COALESCE("); -
10500 - get_rule_expr((Node *) coalesceexpr->args, context, true); -
10501 - appendStringInfoChar(buf, ')'); -
10502 - } -
10503 - break; -
10504 - -
10505 - case T_MinMaxExpr: -
10506 - { -
10507 - MinMaxExpr *minmaxexpr = (MinMaxExpr *) node; -
10508 - -
10509 - switch (minmaxexpr->op) -
10510 - { -
10511 - case IS_GREATEST: -
10512 - appendStringInfoString(buf, "GREATEST("); -
10513 - break; -
10514 - case IS_LEAST: -
10515 - appendStringInfoString(buf, "LEAST("); -
10516 - break; -
10517 - } -
10518 - get_rule_expr((Node *) minmaxexpr->args, context, true); -
10519 - appendStringInfoChar(buf, ')'); -
10520 - } -
10521 - break; -
10522 - -
10523 - case T_SQLValueFunction: -
10524 - { -
10525 - SQLValueFunction *svf = (SQLValueFunction *) node; -
10526 - -
10527 - /* -
10528 - * Note: this code knows that typmod for time, timestamp, and -
10529 - * timestamptz just prints as integer. -
10530 - */ -
10531 - switch (svf->op) -
10532 - { -
10533 - case SVFOP_CURRENT_DATE: -
10534 - appendStringInfoString(buf, "CURRENT_DATE"); -
10535 - break; -
10536 - case SVFOP_CURRENT_TIME: -
10537 - appendStringInfoString(buf, "CURRENT_TIME"); -
10538 - break; -
10539 - case SVFOP_CURRENT_TIME_N: -
10540 - appendStringInfo(buf, "CURRENT_TIME(%d)", svf->typmod); -
10541 - break; -
10542 - case SVFOP_CURRENT_TIMESTAMP: -
10543 - appendStringInfoString(buf, "CURRENT_TIMESTAMP"); -
10544 - break; -
10545 - case SVFOP_CURRENT_TIMESTAMP_N: -
10546 - appendStringInfo(buf, "CURRENT_TIMESTAMP(%d)", -
10547 - svf->typmod); -
10548 - break; -
10549 - case SVFOP_LOCALTIME: -
10550 - appendStringInfoString(buf, "LOCALTIME"); -
10551 - break; -
10552 - case SVFOP_LOCALTIME_N: -
10553 - appendStringInfo(buf, "LOCALTIME(%d)", svf->typmod); -
10554 - break; -
10555 - case SVFOP_LOCALTIMESTAMP: -
10556 - appendStringInfoString(buf, "LOCALTIMESTAMP"); -
10557 - break; -
10558 - case SVFOP_LOCALTIMESTAMP_N: -
10559 - appendStringInfo(buf, "LOCALTIMESTAMP(%d)", -
10560 - svf->typmod); -
10561 - break; -
10562 - case SVFOP_CURRENT_ROLE: -
10563 - appendStringInfoString(buf, "CURRENT_ROLE"); -
10564 - break; -
10565 - case SVFOP_CURRENT_USER: -
10566 - appendStringInfoString(buf, "CURRENT_USER"); -
10567 - break; -
10568 - case SVFOP_USER: -
10569 - appendStringInfoString(buf, "USER"); -
10570 - break; -
10571 - case SVFOP_SESSION_USER: -
10572 - appendStringInfoString(buf, "SESSION_USER"); -
10573 - break; -
10574 - case SVFOP_CURRENT_CATALOG: -
10575 - appendStringInfoString(buf, "CURRENT_CATALOG"); -
10576 - break; -
10577 - case SVFOP_CURRENT_SCHEMA: -
10578 - appendStringInfoString(buf, "CURRENT_SCHEMA"); -
10579 - break; -
10580 - } -
10581 - } -
10582 - break; -
10583 - -
10584 - case T_XmlExpr: -
10585 - { -
10586 - XmlExpr *xexpr = (XmlExpr *) node; -
10587 - bool needcomma = false; -
10588 - ListCell *arg; -
10589 - ListCell *narg; -
10590 - Const *con; -
10591 - -
10592 - switch (xexpr->op) -
10593 - { -
10594 - case IS_XMLCONCAT: -
10595 - appendStringInfoString(buf, "XMLCONCAT("); -
10596 - break; -
10597 - case IS_XMLELEMENT: -
10598 - appendStringInfoString(buf, "XMLELEMENT("); -
10599 - break; -
10600 - case IS_XMLFOREST: -
10601 - appendStringInfoString(buf, "XMLFOREST("); -
10602 - break; -
10603 - case IS_XMLPARSE: -
10604 - appendStringInfoString(buf, "XMLPARSE("); -
10605 - break; -
10606 - case IS_XMLPI: -
10607 - appendStringInfoString(buf, "XMLPI("); -
10608 - break; -
10609 - case IS_XMLROOT: -
10610 - appendStringInfoString(buf, "XMLROOT("); -
10611 - break; -
10612 - case IS_XMLSERIALIZE: -
10613 - appendStringInfoString(buf, "XMLSERIALIZE("); -
10614 - break; -
10615 - case IS_DOCUMENT: -
10616 - break; -
10617 - } -
10618 - if (xexpr->op == IS_XMLPARSE || xexpr->op == IS_XMLSERIALIZE) -
10619 - { -
10620 - if (xexpr->xmloption == XMLOPTION_DOCUMENT) -
10621 - appendStringInfoString(buf, "DOCUMENT "); -
10622 - else -
10623 - appendStringInfoString(buf, "CONTENT "); -
10624 - } -
10625 - if (xexpr->name) -
10626 - { -
10627 - appendStringInfo(buf, "NAME %s", -
10628 - quote_identifier(map_xml_name_to_sql_identifier(xexpr->name))); -
10629 - needcomma = true; -
10630 - } -
10631 - if (xexpr->named_args) -
10632 - { -
10633 - if (xexpr->op != IS_XMLFOREST) -
10634 - { -
10635 - if (needcomma) -
10636 - appendStringInfoString(buf, ", "); -
10637 - appendStringInfoString(buf, "XMLATTRIBUTES("); -
10638 - needcomma = false; -
10639 - } -
10640 - forboth(arg, xexpr->named_args, narg, xexpr->arg_names) -
10641 - { -
10642 - Node *e = (Node *) lfirst(arg); -
10643 - char *argname = strVal(lfirst(narg)); -
10644 - -
10645 - if (needcomma) -
10646 - appendStringInfoString(buf, ", "); -
10647 - get_rule_expr(e, context, true); -
10648 - appendStringInfo(buf, " AS %s", -
10649 - quote_identifier(map_xml_name_to_sql_identifier(argname))); -
10650 - needcomma = true; -
10651 - } -
10652 - if (xexpr->op != IS_XMLFOREST) -
10653 - appendStringInfoChar(buf, ')'); -
10654 - } -
10655 - if (xexpr->args) -
10656 - { -
10657 - if (needcomma) -
10658 - appendStringInfoString(buf, ", "); -
10659 - switch (xexpr->op) -
10660 - { -
10661 - case IS_XMLCONCAT: -
10662 - case IS_XMLELEMENT: -
10663 - case IS_XMLFOREST: -
10664 - case IS_XMLPI: -
10665 - case IS_XMLSERIALIZE: -
10666 - /* no extra decoration needed */ -
10667 - get_rule_expr((Node *) xexpr->args, context, true); -
10668 - break; -
10669 - case IS_XMLPARSE: -
10670 - Assert(list_length(xexpr->args) == 2); -
10671 - -
10672 - get_rule_expr((Node *) linitial(xexpr->args), -
10673 - context, true); -
10674 - -
10675 - con = lsecond_node(Const, xexpr->args); -
10676 - Assert(!con->constisnull); -
10677 - if (DatumGetBool(con->constvalue)) -
10678 - appendStringInfoString(buf, -
10679 - " PRESERVE WHITESPACE"); -
10680 - else -
10681 - appendStringInfoString(buf, -
10682 - " STRIP WHITESPACE"); -
10683 - break; -
10684 - case IS_XMLROOT: -
10685 - Assert(list_length(xexpr->args) == 3); -
10686 - -
10687 - get_rule_expr((Node *) linitial(xexpr->args), -
10688 - context, true); -
10689 - -
10690 - appendStringInfoString(buf, ", VERSION "); -
10691 - con = (Const *) lsecond(xexpr->args); -
10692 - if (IsA(con, Const) && -
10693 - con->constisnull) -
10694 - appendStringInfoString(buf, "NO VALUE"); -
10695 - else -
10696 - get_rule_expr((Node *) con, context, false); -
10697 - -
10698 - con = lthird_node(Const, xexpr->args); -
10699 - if (con->constisnull) -
10700 - /* suppress STANDALONE NO VALUE */ ; -
10701 - else -
10702 - { -
10703 - switch (DatumGetInt32(con->constvalue)) -
10704 - { -
10705 - case XML_STANDALONE_YES: -
10706 - appendStringInfoString(buf, -
10707 - ", STANDALONE YES"); -
10708 - break; -
10709 - case XML_STANDALONE_NO: -
10710 - appendStringInfoString(buf, -
10711 - ", STANDALONE NO"); -
10712 - break; -
10713 - case XML_STANDALONE_NO_VALUE: -
10714 - appendStringInfoString(buf, -
10715 - ", STANDALONE NO VALUE"); -
10716 - break; -
10717 - default: -
10718 - break; -
10719 - } -
10720 - } -
10721 - break; -
10722 - case IS_DOCUMENT: -
10723 - get_rule_expr_paren((Node *) xexpr->args, context, false, node); -
10724 - break; -
10725 - } -
10726 - } -
10727 - if (xexpr->op == IS_XMLSERIALIZE) -
10728 - { -
10729 - appendStringInfo(buf, " AS %s", -
10730 - format_type_with_typemod(xexpr->type, -
10731 - xexpr->typmod)); -
10732 - if (xexpr->indent) -
10733 - appendStringInfoString(buf, " INDENT"); -
10734 - else -
10735 - appendStringInfoString(buf, " NO INDENT"); -
10736 - } -
10737 - -
10738 - if (xexpr->op == IS_DOCUMENT) -
10739 - appendStringInfoString(buf, " IS DOCUMENT"); -
10740 - else -
10741 - appendStringInfoChar(buf, ')'); -
10742 - } -
10743 - break; -
10744 - -
10745 - case T_NullTest: -
10746 - { -
10747 - NullTest *ntest = (NullTest *) node; -
10748 - -
10749 - if (!PRETTY_PAREN(context)) -
10750 - appendStringInfoChar(buf, '('); -
10751 - get_rule_expr_paren((Node *) ntest->arg, context, true, node); -
10752 - -
10753 - /* -
10754 - * For scalar inputs, we prefer to print as IS [NOT] NULL, -
10755 - * which is shorter and traditional. If it's a rowtype input -
10756 - * but we're applying a scalar test, must print IS [NOT] -
10757 - * DISTINCT FROM NULL to be semantically correct. -
10758 - */ -
10759 - if (ntest->argisrow || -
10760 - !type_is_rowtype(exprType((Node *) ntest->arg))) -
10761 - { -
10762 - switch (ntest->nulltesttype) -
10763 - { -
10764 - case IS_NULL: -
10765 - appendStringInfoString(buf, " IS NULL"); -
10766 - break; -
10767 - case IS_NOT_NULL: -
10768 - appendStringInfoString(buf, " IS NOT NULL"); -
10769 - break; -
10770 - default: -
10771 - elog(ERROR, "unrecognized nulltesttype: %d", -
10772 - (int) ntest->nulltesttype); -
10773 - } -
10774 - } -
10775 - else -
10776 - { -
10777 - switch (ntest->nulltesttype) -
10778 - { -
10779 - case IS_NULL: -
10780 - appendStringInfoString(buf, " IS NOT DISTINCT FROM NULL"); -
10781 - break; -
10782 - case IS_NOT_NULL: -
10783 - appendStringInfoString(buf, " IS DISTINCT FROM NULL"); -
10784 - break; -
10785 - default: -
10786 - elog(ERROR, "unrecognized nulltesttype: %d", -
10787 - (int) ntest->nulltesttype); -
10788 - } -
10789 - } -
10790 - if (!PRETTY_PAREN(context)) -
10791 - appendStringInfoChar(buf, ')'); -
10792 - } -
10793 - break; -
10794 - -
10795 - case T_BooleanTest: -
10796 - { -
10797 - BooleanTest *btest = (BooleanTest *) node; -
10798 - -
10799 - if (!PRETTY_PAREN(context)) -
10800 - appendStringInfoChar(buf, '('); -
10801 - get_rule_expr_paren((Node *) btest->arg, context, false, node); -
10802 - switch (btest->booltesttype) -
10803 - { -
10804 - case IS_TRUE: -
10805 - appendStringInfoString(buf, " IS TRUE"); -
10806 - break; -
10807 - case IS_NOT_TRUE: -
10808 - appendStringInfoString(buf, " IS NOT TRUE"); -
10809 - break; -
10810 - case IS_FALSE: -
10811 - appendStringInfoString(buf, " IS FALSE"); -
10812 - break; -
10813 - case IS_NOT_FALSE: -
10814 - appendStringInfoString(buf, " IS NOT FALSE"); -
10815 - break; -
10816 - case IS_UNKNOWN: -
10817 - appendStringInfoString(buf, " IS UNKNOWN"); -
10818 - break; -
10819 - case IS_NOT_UNKNOWN: -
10820 - appendStringInfoString(buf, " IS NOT UNKNOWN"); -
10821 - break; -
10822 - default: -
10823 - elog(ERROR, "unrecognized booltesttype: %d", -
10824 - (int) btest->booltesttype); -
10825 - } -
10826 - if (!PRETTY_PAREN(context)) -
10827 - appendStringInfoChar(buf, ')'); -
10828 - } -
10829 - break; -
10830 - -
10831 - case T_CoerceToDomain: -
10832 - { -
10833 - CoerceToDomain *ctest = (CoerceToDomain *) node; -
10834 - Node *arg = (Node *) ctest->arg; -
10835 - -
10836 - if (ctest->coercionformat == COERCE_IMPLICIT_CAST && -
10837 - !showimplicit) -
10838 - { -
10839 - /* don't show the implicit cast */ -
10840 - get_rule_expr(arg, context, false); -
10841 - } -
10842 - else -
10843 - { -
10844 - get_coercion_expr(arg, context, -
10845 - ctest->resulttype, -
10846 - ctest->resulttypmod, -
10847 - node); -
10848 - } -
10849 - } -
10850 - break; -
10851 - -
10852 - case T_CoerceToDomainValue: -
10853 - appendStringInfoString(buf, "VALUE"); -
10854 - break; -
10855 - -
10856 - case T_SetToDefault: -
10857 - appendStringInfoString(buf, "DEFAULT"); -
10858 - break; -
10859 - -
10860 - case T_CurrentOfExpr: -
10861 - { -
10862 - CurrentOfExpr *cexpr = (CurrentOfExpr *) node; -
10863 - -
10864 - if (cexpr->cursor_name) -
10865 - appendStringInfo(buf, "CURRENT OF %s", -
10866 - quote_identifier(cexpr->cursor_name)); -
10867 - else -
10868 - appendStringInfo(buf, "CURRENT OF $%d", -
10869 - cexpr->cursor_param); -
10870 - } -
10871 - break; -
10872 - -
10873 - case T_NextValueExpr: -
10874 - { -
10875 - NextValueExpr *nvexpr = (NextValueExpr *) node; -
10876 - -
10877 - /* -
10878 - * This isn't exactly nextval(), but that seems close enough -
10879 - * for EXPLAIN's purposes. -
10880 - */ -
10881 - appendStringInfoString(buf, "nextval("); -
10882 - simple_quote_literal(buf, -
10883 - generate_relation_name(nvexpr->seqid, -
10884 - NIL)); -
10885 - appendStringInfoChar(buf, ')'); -
10886 - } -
10887 - break; -
10888 - -
10889 - case T_InferenceElem: -
10890 - { -
10891 - InferenceElem *iexpr = (InferenceElem *) node; -
10892 - bool save_varprefix; -
10893 - bool need_parens; -
10894 - -
10895 - /* -
10896 - * InferenceElem can only refer to target relation, so a -
10897 - * prefix is not useful, and indeed would cause parse errors. -
10898 - */ -
10899 - save_varprefix = context->varprefix; -
10900 - context->varprefix = false; -
10901 - -
10902 - /* -
10903 - * Parenthesize the element unless it's a simple Var or a bare -
10904 - * function call. Follows pg_get_indexdef_worker(). -
10905 - */ -
10906 - need_parens = !IsA(iexpr->expr, Var); -
10907 - if (IsA(iexpr->expr, FuncExpr) && -
10908 - ((FuncExpr *) iexpr->expr)->funcformat == -
10909 - COERCE_EXPLICIT_CALL) -
10910 - need_parens = false; -
10911 - -
10912 - if (need_parens) -
10913 - appendStringInfoChar(buf, '('); -
10914 - get_rule_expr((Node *) iexpr->expr, -
10915 - context, false); -
10916 - if (need_parens) -
10917 - appendStringInfoChar(buf, ')'); -
10918 - -
10919 - context->varprefix = save_varprefix; -
10920 - -
10921 - if (iexpr->infercollid) -
10922 - appendStringInfo(buf, " COLLATE %s", -
10923 - generate_collation_name(iexpr->infercollid)); -
10924 - -
10925 - /* Add the operator class name, if not default */ -
10926 - if (iexpr->inferopclass) -
10927 - { -
10928 - Oid inferopclass = iexpr->inferopclass; -
10929 - Oid inferopcinputtype = get_opclass_input_type(iexpr->inferopclass); -
10930 - -
10931 - get_opclass_name(inferopclass, inferopcinputtype, buf); -
10932 - } -
10933 - } -
10934 - break; -
10935 - -
10936 - case T_ReturningExpr: -
10937 - { -
10938 - ReturningExpr *retExpr = (ReturningExpr *) node; -
10939 - -
10940 - /* -
10941 - * We cannot see a ReturningExpr in rule deparsing, only while -
10942 - * EXPLAINing a query plan (ReturningExpr nodes are only ever -
10943 - * adding during query rewriting). Just display the expression -
10944 - * returned (an expanded view column). -
10945 - */ -
10946 - get_rule_expr((Node *) retExpr->retexpr, context, showimplicit); -
10947 - } -
10948 - break; -
10949 - -
10950 - case T_PartitionBoundSpec: -
10951 - { -
10952 - PartitionBoundSpec *spec = (PartitionBoundSpec *) node; -
10953 - ListCell *cell; -
10954 - char *sep; -
10955 - -
10956 - if (spec->is_default) -
10957 - { -
10958 - appendStringInfoString(buf, "DEFAULT"); -
10959 - break; -
10960 - } -
10961 - -
10962 - switch (spec->strategy) -
10963 - { -
10964 - case PARTITION_STRATEGY_HASH: -
10965 - Assert(spec->modulus > 0 && spec->remainder >= 0); -
10966 - Assert(spec->modulus > spec->remainder); -
10967 - -
10968 - appendStringInfoString(buf, "FOR VALUES"); -
10969 - appendStringInfo(buf, " WITH (modulus %d, remainder %d)", -
10970 - spec->modulus, spec->remainder); -
10971 - break; -
10972 - -
10973 - case PARTITION_STRATEGY_LIST: -
10974 - Assert(spec->listdatums != NIL); -
10975 - -
10976 - appendStringInfoString(buf, "FOR VALUES IN ("); -
10977 - sep = ""; -
10978 - foreach(cell, spec->listdatums) -
10979 - { -
10980 - Const *val = lfirst_node(Const, cell); -
10981 - -
10982 - appendStringInfoString(buf, sep); -
10983 - get_const_expr(val, context, -1); -
10984 - sep = ", "; -
10985 - } -
10986 - -
10987 - appendStringInfoChar(buf, ')'); -
10988 - break; -
10989 - -
10990 - case PARTITION_STRATEGY_RANGE: -
10991 - Assert(spec->lowerdatums != NIL && -
10992 - spec->upperdatums != NIL && -
10993 - list_length(spec->lowerdatums) == -
10994 - list_length(spec->upperdatums)); -
10995 - -
10996 - appendStringInfo(buf, "FOR VALUES FROM %s TO %s", -
10997 - get_range_partbound_string(spec->lowerdatums), -
10998 - get_range_partbound_string(spec->upperdatums)); -
10999 - break; -
11000 - -
11001 - default: -
11002 - elog(ERROR, "unrecognized partition strategy: %d", -
11003 - (int) spec->strategy); -
11004 - break; -
11005 - } -
11006 - } -
11007 - break; -
11008 - -
11009 - case T_JsonValueExpr: -
11010 - { -
11011 - JsonValueExpr *jve = (JsonValueExpr *) node; -
11012 - -
11013 - get_rule_expr((Node *) jve->raw_expr, context, false); -
11014 - get_json_format(jve->format, context->buf); -
11015 - } -
11016 - break; -
11017 - -
11018 - case T_JsonConstructorExpr: -
11019 - get_json_constructor((JsonConstructorExpr *) node, context, false); -
11020 - break; -
11021 - -
11022 - case T_JsonIsPredicate: -
11023 - { -
11024 - JsonIsPredicate *pred = (JsonIsPredicate *) node; -
11025 - -
11026 - if (!PRETTY_PAREN(context)) -
11027 - appendStringInfoChar(context->buf, '('); -
11028 - -
11029 - get_rule_expr_paren(pred->expr, context, true, node); -
11030 - -
11031 - appendStringInfoString(context->buf, " IS JSON"); -
11032 - -
11033 - /* TODO: handle FORMAT clause */ -
11034 - -
11035 - switch (pred->item_type) -
11036 - { -
11037 - case JS_TYPE_SCALAR: -
11038 - appendStringInfoString(context->buf, " SCALAR"); -
11039 - break; -
11040 - case JS_TYPE_ARRAY: -
11041 - appendStringInfoString(context->buf, " ARRAY"); -
11042 - break; -
11043 - case JS_TYPE_OBJECT: -
11044 - appendStringInfoString(context->buf, " OBJECT"); -
11045 - break; -
11046 - default: -
11047 - break; -
11048 - } -
11049 - -
11050 - if (pred->unique_keys) -
11051 - appendStringInfoString(context->buf, " WITH UNIQUE KEYS"); -
11052 - -
11053 - if (!PRETTY_PAREN(context)) -
11054 - appendStringInfoChar(context->buf, ')'); -
11055 - } -
11056 - break; -
11057 - -
11058 - case T_JsonExpr: -
11059 - { -
11060 - JsonExpr *jexpr = (JsonExpr *) node; -
11061 - -
11062 - switch (jexpr->op) -
11063 - { -
11064 - case JSON_EXISTS_OP: -
11065 - appendStringInfoString(buf, "JSON_EXISTS("); -
11066 - break; -
11067 - case JSON_QUERY_OP: -
11068 - appendStringInfoString(buf, "JSON_QUERY("); -
11069 - break; -
11070 - case JSON_VALUE_OP: -
11071 - appendStringInfoString(buf, "JSON_VALUE("); -
11072 - break; -
11073 - default: -
11074 - elog(ERROR, "unrecognized JsonExpr op: %d", -
11075 - (int) jexpr->op); -
11076 - } -
11077 - -
11078 - get_rule_expr(jexpr->formatted_expr, context, showimplicit); -
11079 - -
11080 - appendStringInfoString(buf, ", "); -
11081 - -
11082 - get_json_path_spec(jexpr->path_spec, context, showimplicit); -
11083 - -
11084 - if (jexpr->passing_values) -
11085 - { -
11086 - ListCell *lc1, -
11087 - *lc2; -
11088 - bool needcomma = false; -
11089 - -
11090 - appendStringInfoString(buf, " PASSING "); -
11091 - -
11092 - forboth(lc1, jexpr->passing_names, -
11093 - lc2, jexpr->passing_values) -
11094 - { -
11095 - if (needcomma) -
11096 - appendStringInfoString(buf, ", "); -
11097 - needcomma = true; -
11098 - -
11099 - get_rule_expr((Node *) lfirst(lc2), context, showimplicit); -
11100 - appendStringInfo(buf, " AS %s", -
11101 - quote_identifier(lfirst_node(String, lc1)->sval)); -
11102 - } -
11103 - } -
11104 - -
11105 - if (jexpr->op != JSON_EXISTS_OP || -
11106 - jexpr->returning->typid != BOOLOID) -
11107 - get_json_returning(jexpr->returning, context->buf, -
11108 - jexpr->op == JSON_QUERY_OP); -
11109 - -
11110 - get_json_expr_options(jexpr, context, -
11111 - jexpr->op != JSON_EXISTS_OP ? -
11112 - JSON_BEHAVIOR_NULL : -
11113 - JSON_BEHAVIOR_FALSE); -
11114 - -
11115 - appendStringInfoChar(buf, ')'); -
11116 - } -
11117 - break; -
11118 - -
11119 - case T_List: -
11120 - { -
11121 - char *sep; -
11122 - ListCell *l; -
11123 - -
11124 - sep = ""; -
11125 - foreach(l, (List *) node) -
11126 - { -
11127 - appendStringInfoString(buf, sep); -
11128 - get_rule_expr((Node *) lfirst(l), context, showimplicit); -
11129 - sep = ", "; -
11130 - } -
11131 - } -
11132 - break; -
11133 - -
11134 - case T_TableFunc: -
11135 - get_tablefunc((TableFunc *) node, context, showimplicit); -
11136 - break; -
11137 - -
11138 26 case T_GraphPropertyRef: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11139 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11140 26 GraphPropertyRef *gpr = (GraphPropertyRef *) node; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11141 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11142 26 appendStringInfo(buf, "%s.%s", quote_identifier(gpr->elvarname), quote_identifier(get_propgraph_property_name(gpr->propid))); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11143 26 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11144 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11145 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
11146 - default: -
11147 - elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); -
11148 - break; -
11149 - } -
11150 - } -
get_from_clause_item() lines 12898-13211
Modified Lines Coverage: 19/20 lines (95.0%)
LineHitsSourceCommit
12898 - get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) -
12899 - { -
12900 - StringInfo buf = context->buf; -
12901 - deparse_namespace *dpns = (deparse_namespace *) linitial(context->namespaces); -
12902 - -
12903 - if (IsA(jtnode, RangeTblRef)) -
12904 - { -
12905 - int varno = ((RangeTblRef *) jtnode)->rtindex; -
12906 - RangeTblEntry *rte = rt_fetch(varno, query->rtable); -
12907 - deparse_columns *colinfo = deparse_columns_fetch(varno, dpns); -
12908 - RangeTblFunction *rtfunc1 = NULL; -
12909 - -
12910 - if (rte->lateral) -
12911 - appendStringInfoString(buf, "LATERAL "); -
12912 - -
12913 - /* Print the FROM item proper */ -
12914 - switch (rte->rtekind) -
12915 - { -
12916 - case RTE_RELATION: -
12917 - /* Normal relation RTE */ -
12918 - appendStringInfo(buf, "%s%s", -
12919 - only_marker(rte), -
12920 - generate_relation_name(rte->relid, -
12921 - context->namespaces)); -
12922 - break; -
12923 - case RTE_SUBQUERY: -
12924 - /* Subquery RTE */ -
12925 - appendStringInfoChar(buf, '('); -
12926 - get_query_def(rte->subquery, buf, context->namespaces, NULL, -
12927 - true, -
12928 - context->prettyFlags, context->wrapColumn, -
12929 - context->indentLevel); -
12930 - appendStringInfoChar(buf, ')'); -
12931 - break; -
12932 - case RTE_FUNCTION: -
12933 - /* Function RTE */ -
12934 - rtfunc1 = (RangeTblFunction *) linitial(rte->functions); -
12935 - -
12936 - /* -
12937 - * Omit ROWS FROM() syntax for just one function, unless it -
12938 - * has both a coldeflist and WITH ORDINALITY. If it has both, -
12939 - * we must use ROWS FROM() syntax to avoid ambiguity about -
12940 - * whether the coldeflist includes the ordinality column. -
12941 - */ -
12942 - if (list_length(rte->functions) == 1 && -
12943 - (rtfunc1->funccolnames == NIL || !rte->funcordinality)) -
12944 - { -
12945 - get_rule_expr_funccall(rtfunc1->funcexpr, context, true); -
12946 - /* we'll print the coldeflist below, if it has one */ -
12947 - } -
12948 - else -
12949 - { -
12950 - bool all_unnest; -
12951 - ListCell *lc; -
12952 - -
12953 - /* -
12954 - * If all the function calls in the list are to unnest, -
12955 - * and none need a coldeflist, then collapse the list back -
12956 - * down to UNNEST(args). (If we had more than one -
12957 - * built-in unnest function, this would get more -
12958 - * difficult.) -
12959 - * -
12960 - * XXX This is pretty ugly, since it makes not-terribly- -
12961 - * future-proof assumptions about what the parser would do -
12962 - * with the output; but the alternative is to emit our -
12963 - * nonstandard ROWS FROM() notation for what might have -
12964 - * been a perfectly spec-compliant multi-argument -
12965 - * UNNEST(). -
12966 - */ -
12967 - all_unnest = true; -
12968 - foreach(lc, rte->functions) -
12969 - { -
12970 - RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); -
12971 - -
12972 - if (!IsA(rtfunc->funcexpr, FuncExpr) || -
12973 - ((FuncExpr *) rtfunc->funcexpr)->funcid != F_UNNEST_ANYARRAY || -
12974 - rtfunc->funccolnames != NIL) -
12975 - { -
12976 - all_unnest = false; -
12977 - break; -
12978 - } -
12979 - } -
12980 - -
12981 - if (all_unnest) -
12982 - { -
12983 - List *allargs = NIL; -
12984 - -
12985 - foreach(lc, rte->functions) -
12986 - { -
12987 - RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); -
12988 - List *args = ((FuncExpr *) rtfunc->funcexpr)->args; -
12989 - -
12990 - allargs = list_concat(allargs, args); -
12991 - } -
12992 - -
12993 - appendStringInfoString(buf, "UNNEST("); -
12994 - get_rule_expr((Node *) allargs, context, true); -
12995 - appendStringInfoChar(buf, ')'); -
12996 - } -
12997 - else -
12998 - { -
12999 - int funcno = 0; -
13000 - -
13001 - appendStringInfoString(buf, "ROWS FROM("); -
13002 - foreach(lc, rte->functions) -
13003 - { -
13004 - RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); -
13005 - -
13006 - if (funcno > 0) -
13007 - appendStringInfoString(buf, ", "); -
13008 - get_rule_expr_funccall(rtfunc->funcexpr, context, true); -
13009 - if (rtfunc->funccolnames != NIL) -
13010 - { -
13011 - /* Reconstruct the column definition list */ -
13012 - appendStringInfoString(buf, " AS "); -
13013 - get_from_clause_coldeflist(rtfunc, -
13014 - NULL, -
13015 - context); -
13016 - } -
13017 - funcno++; -
13018 - } -
13019 - appendStringInfoChar(buf, ')'); -
13020 - } -
13021 - /* prevent printing duplicate coldeflist below */ -
13022 - rtfunc1 = NULL; -
13023 - } -
13024 - if (rte->funcordinality) -
13025 - appendStringInfoString(buf, " WITH ORDINALITY"); -
13026 - break; -
13027 - case RTE_TABLEFUNC: -
13028 - get_tablefunc(rte->tablefunc, context, true); -
13029 - break; -
13030 13 case RTE_GRAPH_TABLE: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13031 13 appendStringInfoString(buf, "GRAPH_TABLE ("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13032 13 appendStringInfoString(buf, generate_relation_name(rte->relid, context->namespaces)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13033 13 appendStringInfoString(buf, " MATCH "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13034 13 get_graph_pattern_def(rte->graph_pattern, context); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13035 13 appendStringInfoString(buf, " COLUMNS ("); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13036 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13037 13 ListCell *lc; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13038 13 bool first = true; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13039 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13040 26 foreach(lc, rte->graph_table_columns) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13041 - { 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13042 13 TargetEntry *te = lfirst_node(TargetEntry, lc); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13043 13 deparse_context context = {0}; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13044 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13045 13 if (!first) 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13046 0 appendStringInfoString(buf, ", "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13047 - else 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13048 - first = false; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13049 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13050 13 context.buf = buf; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13051 - 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13052 13 get_rule_expr((Node *) te->expr, &context, false); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13053 13 appendStringInfoString(buf, " AS "); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13054 13 appendStringInfoString(buf, quote_identifier(te->resname)); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13055 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13056 - } 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13057 13 appendStringInfoString(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13058 13 appendStringInfoString(buf, ")"); 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13059 13 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
13060 - case RTE_VALUES: -
13061 - /* Values list RTE */ -
13062 - appendStringInfoChar(buf, '('); -
13063 - get_values_def(rte->values_lists, context); -
13064 - appendStringInfoChar(buf, ')'); -
13065 - break; -
13066 - case RTE_CTE: -
13067 - appendStringInfoString(buf, quote_identifier(rte->ctename)); -
13068 - break; -
13069 - default: -
13070 - elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); -
13071 - break; -
13072 - } -
13073 - -
13074 - /* Print the relation alias, if needed */ -
13075 - get_rte_alias(rte, varno, false, context); -
13076 - -
13077 - /* Print the column definitions or aliases, if needed */ -
13078 - if (rtfunc1 && rtfunc1->funccolnames != NIL) -
13079 - { -
13080 - /* Reconstruct the columndef list, which is also the aliases */ -
13081 - get_from_clause_coldeflist(rtfunc1, colinfo, context); -
13082 - } -
13083 - else -
13084 - { -
13085 - /* Else print column aliases as needed */ -
13086 - get_column_alias_list(colinfo, context); -
13087 - } -
13088 - -
13089 - /* Tablesample clause must go after any alias */ -
13090 - if (rte->rtekind == RTE_RELATION && rte->tablesample) -
13091 - get_tablesample_def(rte->tablesample, context); -
13092 - } -
13093 - else if (IsA(jtnode, JoinExpr)) -
13094 - { -
13095 - JoinExpr *j = (JoinExpr *) jtnode; -
13096 - deparse_columns *colinfo = deparse_columns_fetch(j->rtindex, dpns); -
13097 - bool need_paren_on_right; -
13098 - -
13099 - need_paren_on_right = PRETTY_PAREN(context) && -
13100 - !IsA(j->rarg, RangeTblRef) && -
13101 - !(IsA(j->rarg, JoinExpr) && ((JoinExpr *) j->rarg)->alias != NULL); -
13102 - -
13103 - if (!PRETTY_PAREN(context) || j->alias != NULL) -
13104 - appendStringInfoChar(buf, '('); -
13105 - -
13106 - get_from_clause_item(j->larg, query, context); -
13107 - -
13108 - switch (j->jointype) -
13109 - { -
13110 - case JOIN_INNER: -
13111 - if (j->quals) -
13112 - appendContextKeyword(context, " JOIN ", -
13113 - -PRETTYINDENT_STD, -
13114 - PRETTYINDENT_STD, -
13115 - PRETTYINDENT_JOIN); -
13116 - else -
13117 - appendContextKeyword(context, " CROSS JOIN ", -
13118 - -PRETTYINDENT_STD, -
13119 - PRETTYINDENT_STD, -
13120 - PRETTYINDENT_JOIN); -
13121 - break; -
13122 - case JOIN_LEFT: -
13123 - appendContextKeyword(context, " LEFT JOIN ", -
13124 - -PRETTYINDENT_STD, -
13125 - PRETTYINDENT_STD, -
13126 - PRETTYINDENT_JOIN); -
13127 - break; -
13128 - case JOIN_FULL: -
13129 - appendContextKeyword(context, " FULL JOIN ", -
13130 - -PRETTYINDENT_STD, -
13131 - PRETTYINDENT_STD, -
13132 - PRETTYINDENT_JOIN); -
13133 - break; -
13134 - case JOIN_RIGHT: -
13135 - appendContextKeyword(context, " RIGHT JOIN ", -
13136 - -PRETTYINDENT_STD, -
13137 - PRETTYINDENT_STD, -
13138 - PRETTYINDENT_JOIN); -
13139 - break; -
13140 - default: -
13141 - elog(ERROR, "unrecognized join type: %d", -
13142 - (int) j->jointype); -
13143 - } -
13144 - -
13145 - if (need_paren_on_right) -
13146 - appendStringInfoChar(buf, '('); -
13147 - get_from_clause_item(j->rarg, query, context); -
13148 - if (need_paren_on_right) -
13149 - appendStringInfoChar(buf, ')'); -
13150 - -
13151 - if (j->usingClause) -
13152 - { -
13153 - ListCell *lc; -
13154 - bool first = true; -
13155 - -
13156 - appendStringInfoString(buf, " USING ("); -
13157 - /* Use the assigned names, not what's in usingClause */ -
13158 - foreach(lc, colinfo->usingNames) -
13159 - { -
13160 - char *colname = (char *) lfirst(lc); -
13161 - -
13162 - if (first) -
13163 - first = false; -
13164 - else -
13165 - appendStringInfoString(buf, ", "); -
13166 - appendStringInfoString(buf, quote_identifier(colname)); -
13167 - } -
13168 - appendStringInfoChar(buf, ')'); -
13169 - -
13170 - if (j->join_using_alias) -
13171 - appendStringInfo(buf, " AS %s", -
13172 - quote_identifier(j->join_using_alias->aliasname)); -
13173 - } -
13174 - else if (j->quals) -
13175 - { -
13176 - appendStringInfoString(buf, " ON "); -
13177 - if (!PRETTY_PAREN(context)) -
13178 - appendStringInfoChar(buf, '('); -
13179 - get_rule_expr(j->quals, context, false); -
13180 - if (!PRETTY_PAREN(context)) -
13181 - appendStringInfoChar(buf, ')'); -
13182 - } -
13183 - else if (j->jointype != JOIN_INNER) -
13184 - { -
13185 - /* If we didn't say CROSS JOIN above, we must provide an ON */ -
13186 - appendStringInfoString(buf, " ON TRUE"); -
13187 - } -
13188 - -
13189 - if (!PRETTY_PAREN(context) || j->alias != NULL) -
13190 - appendStringInfoChar(buf, ')'); -
13191 - -
13192 - /* Yes, it's correct to put alias after the right paren ... */ -
13193 - if (j->alias != NULL) -
13194 - { -
13195 - /* -
13196 - * Note that it's correct to emit an alias clause if and only if -
13197 - * there was one originally. Otherwise we'd be converting a named -
13198 - * join to unnamed or vice versa, which creates semantic -
13199 - * subtleties we don't want. However, we might print a different -
13200 - * alias name than was there originally. -
13201 - */ -
13202 - appendStringInfo(buf, " %s", -
13203 - quote_identifier(get_rtable_name(j->rtindex, -
13204 - context))); -
13205 - get_column_alias_list(colinfo, context); -
13206 - } -
13207 - } -
13208 - else -
13209 - elog(ERROR, "unrecognized node type: %d", -
13210 - (int) nodeTag(jtnode)); -
13211 - } -