@@ -150,11 +150,25 @@ public class PostgresCatalog {
150150 * that backtracks, sub-selects correlated deep enough to multiply. The client is told so, with PostgreSQL's
151151 * {@code program_limit_exceeded}, rather than handed an empty answer that would look like an empty catalog.
152152 */
153- public static final class WorkLimitExceeded extends RuntimeException {
153+ public static final class WorkLimitExceeded extends Refusal {
154154 public static final String SQLSTATE = "54000" ;
155155
156156 WorkLimitExceeded () {
157- super ("The catalog query needs more work than one statement may spend: simplify it" );
157+ super ("The catalog query needs more work than one statement may spend: simplify it" , SQLSTATE );
158+ }
159+ }
160+
161+ /**
162+ * A catalog query this server refuses, with the SQLSTATE the client acts on. The text is written by this class and holds no
163+ * stored value (at most the name of a relation the client typed), and the cause is the client's query, never a fault of the
164+ * server: so production mode keeps the message, as it does for a refused SET, and logs no SEVERE stack trace for it.
165+ */
166+ public abstract static class Refusal extends RuntimeException {
167+ public final String sqlState ;
168+
169+ Refusal (final String message , final String sqlState ) {
170+ super (message );
171+ this .sqlState = sqlState ;
158172 }
159173 }
160174
@@ -171,11 +185,11 @@ public static final class WorkLimitExceeded extends RuntimeException {
171185 * with {@link WorkLimitExceeded} does not depend on why the statement was refused. PostgreSQL's own {@code undefined_table}
172186 * would claim the relation does not exist, which a real PostgreSQL has.
173187 */
174- public static final class UnsupportedCatalogQuery extends RuntimeException {
188+ public static final class UnsupportedCatalogQuery extends Refusal {
175189 public static final String SQLSTATE = "0A000" ;
176190
177191 UnsupportedCatalogQuery (final String message ) {
178- super (message );
192+ super (message , SQLSTATE );
179193 }
180194 }
181195
@@ -1222,6 +1236,7 @@ private static Row tableRow(final Context context, final DocumentType type) {
12221236 // relhasindex and hasindexes are FALSE because pg_index is not modelled (issue #10371): every query that would enumerate a
12231237 // table's indexes names it and is refused, so a catalog that said "this relation has indexes" would send psql's \d, which
12241238 // reads the flag first, straight into that refusal. The flag follows what this catalog can show, not what the type has.
1239+ // TODO #10473: model pg_index, then answer !type.getAllIndexes(false).isEmpty() again (here and in pg_tables.hasindexes)
12251240 return singletonRow (context )//
12261241 .with ("pg_class" , "oid" , oid , "relname" , type .getName (), "relnamespace" , SCHEMA_OID , "relowner" , OWNER_OID ,//
12271242 "relkind" , "r" , "relpersistence" , "p" , "relnatts" , type .getPropertyNames ().size (),//
0 commit comments