|
13 | 13 |
|
14 | 14 | import java.io.*; |
15 | 15 | import java.util.*; |
| 16 | +import java.util.logging.Level; |
| 17 | +import java.util.logging.Logger; |
16 | 18 |
|
17 | 19 | import static net.sf.jsqlparser.test.TestUtils.*; |
18 | 20 |
|
@@ -879,7 +881,7 @@ public void testTime() throws JSQLParserException { |
879 | 881 | (((TimeValue) ((GreaterThan) plainSelect.getWhere()).getRightExpression()).getValue()).toString()); |
880 | 882 | assertStatementCanBeDeparsedAs(select, statement); |
881 | 883 | } |
882 | | - |
| 884 | + |
883 | 885 | public void testBetweenDate() throws JSQLParserException { |
884 | 886 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE col BETWEEN {d '2015-09-19'} AND {d '2015-09-24'}"); |
885 | 887 | } |
@@ -1604,17 +1606,17 @@ public void testInterval3() throws JSQLParserException { |
1604 | 1606 | String stmt = "SELECT 5 + INTERVAL '3' day"; |
1605 | 1607 | assertSqlCanBeParsedAndDeparsed(stmt); |
1606 | 1608 | } |
1607 | | - |
| 1609 | + |
1608 | 1610 | public void testInterval4() throws JSQLParserException { |
1609 | 1611 | String stmt = "SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND"; |
1610 | 1612 | assertSqlCanBeParsedAndDeparsed(stmt); |
1611 | 1613 | } |
1612 | | - |
| 1614 | + |
1613 | 1615 | public void testInterval5_Issue228() throws JSQLParserException { |
1614 | 1616 | assertSqlCanBeParsedAndDeparsed("SELECT ADDDATE(timeColumn1, INTERVAL 420 MINUTES) AS timeColumn1 FROM tbl"); |
1615 | 1617 | assertSqlCanBeParsedAndDeparsed("SELECT ADDDATE(timeColumn1, INTERVAL -420 MINUTES) AS timeColumn1 FROM tbl"); |
1616 | 1618 | } |
1617 | | - |
| 1619 | + |
1618 | 1620 | public void testMultiValueIn() throws JSQLParserException { |
1619 | 1621 | String stmt = "SELECT * FROM mytable WHERE (a, b, c) IN (SELECT a, b, c FROM mytable2)"; |
1620 | 1622 | assertSqlCanBeParsedAndDeparsed(stmt); |
@@ -1766,7 +1768,7 @@ public void testOracleHierarchicalQuery4() throws JSQLParserException { |
1766 | 1768 | String stmt = "SELECT last_name, employee_id, manager_id, LEVEL FROM employees CONNECT BY PRIOR employee_id = manager_id START WITH employee_id = 100 ORDER SIBLINGS BY last_name"; |
1767 | 1769 | assertSqlCanBeParsedAndDeparsed(stmt); |
1768 | 1770 | } |
1769 | | - |
| 1771 | + |
1770 | 1772 | public void testOracleHierarchicalQueryIssue196() throws JSQLParserException { |
1771 | 1773 | String stmt = "SELECT num1, num2, level FROM carol_tmp START WITH num2 = 1008 CONNECT BY num2 = PRIOR num1 ORDER BY level DESC"; |
1772 | 1774 | assertSqlCanBeParsedAndDeparsed(stmt); |
@@ -1802,7 +1804,7 @@ public void testReservedKeyword2() throws JSQLParserException { |
1802 | 1804 | final String stmt = "SELECT open FROM tableName"; |
1803 | 1805 | assertSqlCanBeParsedAndDeparsed(stmt); |
1804 | 1806 | } |
1805 | | - |
| 1807 | + |
1806 | 1808 | public void testReservedKeyword3() throws JSQLParserException { |
1807 | 1809 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable1 t JOIN mytable2 AS prior ON t.id = prior.id"); |
1808 | 1810 | } |
@@ -1856,7 +1858,7 @@ public void testSelectOracleColl() throws JSQLParserException { |
1856 | 1858 | public void testSelectInnerWith() throws JSQLParserException { |
1857 | 1859 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM (WITH actor AS (SELECT 'a' aid FROM DUAL) SELECT aid FROM actor)"); |
1858 | 1860 | } |
1859 | | - |
| 1861 | + |
1860 | 1862 | public void testSelectWithinGroup() throws JSQLParserException { |
1861 | 1863 | assertSqlCanBeParsedAndDeparsed("SELECT LISTAGG(col1, '##') WITHIN GROUP (ORDER BY col1) FROM table1"); |
1862 | 1864 | } |
@@ -1944,68 +1946,68 @@ public void testIssue160_signedParameter() throws JSQLParserException { |
1944 | 1946 | public void testIssue160_signedParameter2() throws JSQLParserException { |
1945 | 1947 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE -? = 5"); |
1946 | 1948 | } |
1947 | | - |
| 1949 | + |
1948 | 1950 | public void testIssue162_doubleUserVar() throws JSQLParserException { |
1949 | 1951 | assertSqlCanBeParsedAndDeparsed("SELECT @@SPID AS ID, SYSTEM_USER AS \"Login Name\", USER AS \"User Name\""); |
1950 | 1952 | } |
1951 | | - |
1952 | | - public void testIssue167_singleQuoteEscape() throws JSQLParserException { |
| 1953 | + |
| 1954 | + public void testIssue167_singleQuoteEscape() throws JSQLParserException { |
1953 | 1955 | assertSqlCanBeParsedAndDeparsed("SELECT 'a'"); |
1954 | | - assertSqlCanBeParsedAndDeparsed("SELECT ''''"); |
1955 | | - assertSqlCanBeParsedAndDeparsed("SELECT '\\''"); |
1956 | | - assertSqlCanBeParsedAndDeparsed("SELECT 'ab''ab'"); |
1957 | | - assertSqlCanBeParsedAndDeparsed("SELECT 'ab\\'ab'"); |
1958 | | - } |
1959 | | - |
1960 | | - /** |
1961 | | - * These are accepted due to reading one backslash and a double quote. |
1962 | | - */ |
1963 | | - public void testIssue167_singleQuoteEscape2() throws JSQLParserException { |
1964 | | - assertSqlCanBeParsedAndDeparsed("SELECT '\\'''"); |
1965 | | - assertSqlCanBeParsedAndDeparsed("SELECT '\\\\''"); |
1966 | | - } |
1967 | | - |
1968 | | - public void testIssue77_singleQuoteEscape2() throws JSQLParserException { |
1969 | | - assertSqlCanBeParsedAndDeparsed("SELECT 'test\\'' FROM dual"); |
1970 | | - } |
1971 | | - |
| 1956 | + assertSqlCanBeParsedAndDeparsed("SELECT ''''"); |
| 1957 | + assertSqlCanBeParsedAndDeparsed("SELECT '\\''"); |
| 1958 | + assertSqlCanBeParsedAndDeparsed("SELECT 'ab''ab'"); |
| 1959 | + assertSqlCanBeParsedAndDeparsed("SELECT 'ab\\'ab'"); |
| 1960 | + } |
| 1961 | + |
| 1962 | + /** |
| 1963 | + * These are accepted due to reading one backslash and a double quote. |
| 1964 | + */ |
| 1965 | + public void testIssue167_singleQuoteEscape2() throws JSQLParserException { |
| 1966 | + assertSqlCanBeParsedAndDeparsed("SELECT '\\'''"); |
| 1967 | + assertSqlCanBeParsedAndDeparsed("SELECT '\\\\''"); |
| 1968 | + } |
| 1969 | + |
| 1970 | + public void testIssue77_singleQuoteEscape2() throws JSQLParserException { |
| 1971 | + assertSqlCanBeParsedAndDeparsed("SELECT 'test\\'' FROM dual"); |
| 1972 | + } |
| 1973 | + |
1972 | 1974 | public void testIssue223_singleQuoteEscape() throws JSQLParserException { |
1973 | | - assertSqlCanBeParsedAndDeparsed("SELECT '\\'test\\''"); |
1974 | | - } |
1975 | | - |
| 1975 | + assertSqlCanBeParsedAndDeparsed("SELECT '\\'test\\''"); |
| 1976 | + } |
| 1977 | + |
1976 | 1978 | public void testOracleHint() throws JSQLParserException { |
1977 | 1979 | assertOracleHintExists("SELECT /*+ SOMEHINT */ * FROM mytable", true, "SOMEHINT"); |
1978 | 1980 | assertOracleHintExists("SELECT /*+ MORE HINTS POSSIBLE */ * FROM mytable", true, "MORE HINTS POSSIBLE"); |
1979 | 1981 | assertOracleHintExists("SELECT /*+ MORE\nHINTS\t\nPOSSIBLE */ * FROM mytable", true, "MORE\nHINTS\t\nPOSSIBLE"); |
1980 | 1982 | assertOracleHintExists("SELECT /*+ leading(sn di md sh ot) cardinality(ot 1000) */ c, b FROM mytable", true, "leading(sn di md sh ot) cardinality(ot 1000)"); |
1981 | | - assertOracleHintExists("SELECT /*+ ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b) \n" + |
1982 | | - " USE_NL (glcc glf) USE_MERGE (gp gsb) */\n" + |
1983 | | - " b.application_id\n" + |
1984 | | - "FROM jl_br_journals j,\n" + |
1985 | | - " po_vendors p", true, "ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b) \n" + |
1986 | | - " USE_NL (glcc glf) USE_MERGE (gp gsb)"); |
1987 | | - assertOracleHintExists("SELECT /*+ROWID(emp)*/ /*+ THIS IS NOT HINT! ***/ * \n" + |
1988 | | - "FROM emp \n" + |
1989 | | - "WHERE rowid > 'AAAAtkAABAAAFNTAAA' AND empno = 155", false, "ROWID(emp)"); |
1990 | | - assertOracleHintExists("SELECT /*+ INDEX(patients sex_index) use sex_index because there are few\n" + |
1991 | | - " male patients */ name, height, weight\n" + |
1992 | | - "FROM patients\n" + |
1993 | | - "WHERE sex = 'm'", true, "INDEX(patients sex_index) use sex_index because there are few\n male patients"); |
1994 | | - assertOracleHintExists("SELECT /*+INDEX_COMBINE(emp sal_bmi hiredate_bmi)*/ * \n" + |
1995 | | - "FROM emp \n" + |
1996 | | - "WHERE sal < 50000 AND hiredate < '01-JAN-1990'", true, "INDEX_COMBINE(emp sal_bmi hiredate_bmi)"); |
1997 | | - assertOracleHintExists("SELECT --+ CLUSTER \n" + |
1998 | | - "emp.ename, deptno\n" + |
1999 | | - "FROM emp, dept\n" + |
2000 | | - "WHERE deptno = 10 \n" + |
2001 | | - "AND emp.deptno = dept.deptno", true, "CLUSTER"); |
| 1983 | + assertOracleHintExists("SELECT /*+ ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b) \n" |
| 1984 | + + " USE_NL (glcc glf) USE_MERGE (gp gsb) */\n" |
| 1985 | + + " b.application_id\n" |
| 1986 | + + "FROM jl_br_journals j,\n" |
| 1987 | + + " po_vendors p", true, "ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b) \n" |
| 1988 | + + " USE_NL (glcc glf) USE_MERGE (gp gsb)"); |
| 1989 | + assertOracleHintExists("SELECT /*+ROWID(emp)*/ /*+ THIS IS NOT HINT! ***/ * \n" |
| 1990 | + + "FROM emp \n" |
| 1991 | + + "WHERE rowid > 'AAAAtkAABAAAFNTAAA' AND empno = 155", false, "ROWID(emp)"); |
| 1992 | + assertOracleHintExists("SELECT /*+ INDEX(patients sex_index) use sex_index because there are few\n" |
| 1993 | + + " male patients */ name, height, weight\n" |
| 1994 | + + "FROM patients\n" |
| 1995 | + + "WHERE sex = 'm'", true, "INDEX(patients sex_index) use sex_index because there are few\n male patients"); |
| 1996 | + assertOracleHintExists("SELECT /*+INDEX_COMBINE(emp sal_bmi hiredate_bmi)*/ * \n" |
| 1997 | + + "FROM emp \n" |
| 1998 | + + "WHERE sal < 50000 AND hiredate < '01-JAN-1990'", true, "INDEX_COMBINE(emp sal_bmi hiredate_bmi)"); |
| 1999 | + assertOracleHintExists("SELECT --+ CLUSTER \n" |
| 2000 | + + "emp.ename, deptno\n" |
| 2001 | + + "FROM emp, dept\n" |
| 2002 | + + "WHERE deptno = 10 \n" |
| 2003 | + + "AND emp.deptno = dept.deptno", true, "CLUSTER"); |
2002 | 2004 | assertOracleHintExists("SELECT --+ CLUSTER \n --+ some other comment, not hint\n /* even more comments */ * from dual", false, "CLUSTER"); |
2003 | 2005 | assertOracleHintExists("(SELECT * from t1) UNION (select /*+ CLUSTER */ * from dual)", true, null, "CLUSTER"); |
2004 | 2006 | assertOracleHintExists("(SELECT * from t1) UNION (select /*+ CLUSTER */ * from dual) UNION (select * from dual)", true, null, "CLUSTER", null); |
2005 | 2007 | assertOracleHintExists("(SELECT --+ HINT1 HINT2 HINT3\n * from t1) UNION (select /*+ HINT4 HINT5 */ * from dual)", true, "HINT1 HINT2 HINT3", "HINT4 HINT5"); |
2006 | 2008 |
|
2007 | 2009 | } |
2008 | | - |
| 2010 | + |
2009 | 2011 | public void testOracleHintExpression() throws JSQLParserException { |
2010 | 2012 | String statement = "SELECT --+ HINT\n * FROM tab1"; |
2011 | 2013 | Statement parsed = parserManager.parse(new StringReader(statement)); |
@@ -2076,56 +2078,85 @@ public void testTableFunctionWithAlias() throws Exception { |
2076 | 2078 | assertEquals("z", fromItem.getAlias().getName()); |
2077 | 2079 | assertStatementCanBeDeparsedAs(select, statement); |
2078 | 2080 | } |
2079 | | - |
| 2081 | + |
2080 | 2082 | public void testIssue151_tableFunction() throws JSQLParserException { |
2081 | | - assertSqlCanBeParsedAndDeparsed("SELECT * FROM tables a LEFT JOIN getdata() b ON a.id = b.id"); |
2082 | | - } |
2083 | | - |
| 2083 | + assertSqlCanBeParsedAndDeparsed("SELECT * FROM tables a LEFT JOIN getdata() b ON a.id = b.id"); |
| 2084 | + } |
| 2085 | + |
2084 | 2086 | public void testIssue217_keywordSeparator() throws JSQLParserException { |
2085 | 2087 | assertSqlCanBeParsedAndDeparsed("SELECT Separator"); |
2086 | 2088 | } |
2087 | | - |
| 2089 | + |
2088 | 2090 | public void testIssue215_possibleEndlessParsing() throws JSQLParserException { |
2089 | 2091 | assertSqlCanBeParsedAndDeparsed("SELECT (CASE WHEN ((value LIKE '%t1%') OR (value LIKE '%t2%')) THEN 't1s' WHEN ((((((((((((((((((((((((((((value LIKE '%t3%') OR (value LIKE '%t3%')) OR (value LIKE '%t3%')) OR (value LIKE '%t4%')) OR (value LIKE '%t4%')) OR (value LIKE '%t5%')) OR (value LIKE '%t6%')) OR (value LIKE '%t6%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t8%')) OR (value LIKE '%t8%')) OR (value LIKE '%CTO%')) OR (value LIKE '%cto%')) OR (value LIKE '%Cto%')) OR (value LIKE '%t9%')) OR (value LIKE '%t9%')) OR (value LIKE '%COO%')) OR (value LIKE '%coo%')) OR (value LIKE '%Coo%')) OR (value LIKE '%t10%')) OR (value LIKE '%t10%')) OR (value LIKE '%CIO%')) OR (value LIKE '%cio%')) OR (value LIKE '%Cio%')) OR (value LIKE '%t11%')) OR (value LIKE '%t11%')) THEN 't' WHEN ((((value LIKE '%t12%') OR (value LIKE '%t12%')) OR (value LIKE '%VP%')) OR (value LIKE '%vp%')) THEN 'Vice t12s' WHEN ((((((value LIKE '% IT %') OR (value LIKE '%t13%')) OR (value LIKE '%t13%')) OR (value LIKE '% it %')) OR (value LIKE '%tech%')) OR (value LIKE '%Tech%')) THEN 'IT' WHEN ((((value LIKE '%Analyst%') OR (value LIKE '%t14%')) OR (value LIKE '%Analytic%')) OR (value LIKE '%analytic%')) THEN 'Analysts' WHEN ((value LIKE '%Manager%') OR (value LIKE '%manager%')) THEN 't15' ELSE 'Other' END) FROM tab1"); |
2090 | 2092 | } |
2091 | | - |
| 2093 | + |
2092 | 2094 | public void testIssue215_possibleEndlessParsing2() throws JSQLParserException { |
2093 | 2095 | assertSqlCanBeParsedAndDeparsed("SELECT (CASE WHEN ((value LIKE '%t1%') OR (value LIKE '%t2%')) THEN 't1s' ELSE 'Other' END) FROM tab1"); |
2094 | 2096 | } |
2095 | | - |
| 2097 | + |
2096 | 2098 | public void testIssue215_possibleEndlessParsing3() throws JSQLParserException { |
2097 | 2099 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE ((((((((((((((((((((((((((((value LIKE '%t3%') OR (value LIKE '%t3%')) OR (value LIKE '%t3%')) OR (value LIKE '%t4%')) OR (value LIKE '%t4%')) OR (value LIKE '%t5%')) OR (value LIKE '%t6%')) OR (value LIKE '%t6%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t8%')) OR (value LIKE '%t8%')) OR (value LIKE '%CTO%')) OR (value LIKE '%cto%')) OR (value LIKE '%Cto%')) OR (value LIKE '%t9%')) OR (value LIKE '%t9%')) OR (value LIKE '%COO%')) OR (value LIKE '%coo%')) OR (value LIKE '%Coo%')) OR (value LIKE '%t10%')) OR (value LIKE '%t10%')) OR (value LIKE '%CIO%')) OR (value LIKE '%cio%')) OR (value LIKE '%Cio%')) OR (value LIKE '%t11%')) OR (value LIKE '%t11%'))"); |
2098 | 2100 | } |
2099 | | - |
| 2101 | + |
2100 | 2102 | public void testIssue215_possibleEndlessParsing4() throws JSQLParserException { |
2101 | 2103 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE ((value LIKE '%t3%') OR (value LIKE '%t3%'))"); |
2102 | | - } |
2103 | | - |
| 2104 | + } |
| 2105 | + |
2104 | 2106 | public void testIssue215_possibleEndlessParsing5() throws JSQLParserException { |
2105 | 2107 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE ((((((value LIKE '%t3%') OR (value LIKE '%t3%')) OR (value LIKE '%t3%')) OR (value LIKE '%t4%')) OR (value LIKE '%t4%')) OR (value LIKE '%t5%'))"); |
2106 | 2108 | } |
2107 | | - |
| 2109 | + |
2108 | 2110 | public void testIssue215_possibleEndlessParsing6() throws JSQLParserException { |
2109 | 2111 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE (((((((((((((value LIKE '%t3%') OR (value LIKE '%t3%')) OR (value LIKE '%t3%')) OR (value LIKE '%t4%')) OR (value LIKE '%t4%')) OR (value LIKE '%t5%')) OR (value LIKE '%t6%')) OR (value LIKE '%t6%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t8%')) OR (value LIKE '%t8%'))"); |
2110 | 2112 | } |
2111 | | - |
| 2113 | + |
2112 | 2114 | public void testIssue215_possibleEndlessParsing7() throws JSQLParserException { |
2113 | 2115 | assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE (((((((((((((((((((((value LIKE '%t3%') OR (value LIKE '%t3%')) OR (value LIKE '%t3%')) OR (value LIKE '%t4%')) OR (value LIKE '%t4%')) OR (value LIKE '%t5%')) OR (value LIKE '%t6%')) OR (value LIKE '%t6%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t7%')) OR (value LIKE '%t8%')) OR (value LIKE '%t8%')) OR (value LIKE '%CTO%')) OR (value LIKE '%cto%')) OR (value LIKE '%Cto%')) OR (value LIKE '%t9%')) OR (value LIKE '%t9%')) OR (value LIKE '%COO%')) OR (value LIKE '%coo%')) OR (value LIKE '%Coo%'))"); |
2114 | 2116 | } |
2115 | | - |
| 2117 | + |
2116 | 2118 | public void testIssue230_cascadeKeyword() throws JSQLParserException { |
2117 | 2119 | assertSqlCanBeParsedAndDeparsed("SELECT t.cascade AS cas FROM t"); |
2118 | 2120 | } |
2119 | | - |
| 2121 | + |
2120 | 2122 | public void testBooleanValue() throws JSQLParserException { |
2121 | 2123 | assertSqlCanBeParsedAndDeparsed("SELECT col FROM t WHERE a"); |
2122 | 2124 | } |
2123 | | - |
| 2125 | + |
2124 | 2126 | public void testBooleanValue2() throws JSQLParserException { |
2125 | 2127 | assertSqlCanBeParsedAndDeparsed("SELECT col FROM t WHERE 3 < 5 AND a"); |
2126 | 2128 | } |
2127 | | - |
| 2129 | + |
2128 | 2130 | public void testNotWithoutParenthesisIssue234() throws JSQLParserException { |
2129 | 2131 | assertSqlCanBeParsedAndDeparsed("SELECT count(*) FROM \"Persons\" WHERE NOT \"F_NAME\" = 'John'"); |
2130 | 2132 | } |
| 2133 | + |
| 2134 | + public void testWhereIssue240_1() throws JSQLParserException { |
| 2135 | + assertSqlCanBeParsedAndDeparsed("SELECT count(*) FROM mytable WHERE 1"); |
| 2136 | + } |
| 2137 | + |
| 2138 | + public void testWhereIssue240_0() throws JSQLParserException { |
| 2139 | + assertSqlCanBeParsedAndDeparsed("SELECT count(*) FROM mytable WHERE 0"); |
| 2140 | + } |
| 2141 | + |
| 2142 | + public void testWhereIssue240_notBoolean() { |
| 2143 | + try { |
| 2144 | + CCJSqlParserUtil.parse("SELECT count(*) FROM mytable WHERE 5"); |
| 2145 | + fail("should not be parsed"); |
| 2146 | + } catch (JSQLParserException ex) { |
| 2147 | + |
| 2148 | + } |
| 2149 | + } |
| 2150 | + |
| 2151 | + public void testWhereIssue240_true() throws JSQLParserException { |
| 2152 | + assertSqlCanBeParsedAndDeparsed("SELECT count(*) FROM mytable WHERE true"); |
| 2153 | + } |
| 2154 | + |
| 2155 | + public void testWhereIssue240_false() throws JSQLParserException { |
| 2156 | + assertSqlCanBeParsedAndDeparsed("SELECT count(*) FROM mytable WHERE false"); |
| 2157 | + } |
| 2158 | + |
| 2159 | + public void testWhereIssue241KeywordEnd() throws JSQLParserException { |
| 2160 | + assertSqlCanBeParsedAndDeparsed("SELECT l.end FROM lessons l"); |
| 2161 | + } |
2131 | 2162 | } |
0 commit comments