Skip to content

Commit 269c5a8

Browse files
authored
Adjust fetch size. Purge exp.* rows. (#7155)
1 parent 67c1d43 commit 269c5a8

File tree

17 files changed

+184
-46
lines changed

17 files changed

+184
-46
lines changed

api/src/org/labkey/api/data/AggregateColumnInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public StringExpression getURL(ColumnInfo parent)
108108
}
109109

110110
@Override
111-
public NamedObjectList getSelectList(RenderContext ctx)
111+
public @NotNull NamedObjectList getSelectList(RenderContext ctx)
112112
{
113113
return fk.getSelectList(ctx);
114114
}

api/src/org/labkey/api/data/ForeignKey.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@
3232

3333
/**
3434
* Interface describing a ColumnInfo's foreign key relationship, which might be a "real" FK in the underlying
35-
* database of a "soft" FK, making it a lookup to the foreign key's target.
35+
* database or a "soft" FK, making it a lookup to the foreign key's target.
3636
*/
3737
public interface ForeignKey
3838
{
3939
/**
40-
* Return a new lookup column with the specified displayField. If displayField is null, then this method
40+
* Return a new lookup column with the specified displayField. If displayField is null, then this method
4141
* should return the title column (default display field) of the foreign table.
4242
* It should return null if there is no default display field.
4343
* The ColumnInfo parent is a column which has the value of the foreign key.
@@ -47,8 +47,8 @@ public interface ForeignKey
4747
ColumnInfo createLookupColumn(ColumnInfo parent, String displayField);
4848

4949
/**
50-
* Return the TableInfo for the foreign table. This TableInfo can be used to discover the names of available
51-
* columns in a UI. The returned TableInfo will not necessarily be one that can be used for querying (e.g. passing
50+
* Return the TableInfo for the foreign table. This TableInfo can be used to discover the names of available
51+
* columns in a UI. The returned TableInfo will not necessarily be one that can be used for querying (e.g. passing
5252
* to Table.select...
5353
*/
5454
@Nullable
@@ -61,7 +61,7 @@ default TableDescription getLookupTableDescription()
6161
}
6262

6363
/**
64-
* Return an URL expression for what the hyperlink for this column should be. The hyperlink must be able to be
64+
* Return a URL expression for what the hyperlink for this column should be. The hyperlink must be able to be
6565
* constructed knowing only the foreign key value, as other columns may not be available in the ResultSet.
6666
*/
6767
@Nullable StringExpression getURL(ColumnInfo parent);
@@ -72,7 +72,7 @@ default TableDescription getLookupTableDescription()
7272
@NotNull NamedObjectList getSelectList(RenderContext ctx);
7373

7474
/**
75-
* @return The container id of the foreign user schema table. Null means current container.
75+
* @return The container id of the foreign user schema table. Null means current container.
7676
*/
7777
Container getLookupContainer();
7878

@@ -111,7 +111,7 @@ default String getLookupSchemaName()
111111

112112
/**
113113
* Fixup any references fo FieldKeys that may have been reparented or renamed by Query and
114-
* generate a new ForeignKey. If fixup is not needed, return null.
114+
* generate a new ForeignKey. If fixup is not needed, return null.
115115
*
116116
* @param parent A new parent FieldKey to inject, e.g. "title" becomes "parent/title".
117117
* @param mapping Rename FieldKeys, e.g. "foo" becomes "bar".

api/src/org/labkey/api/data/SqlExecutingSelector.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.labkey.api.data;
1818

19-
import org.apache.logging.log4j.LogManager;
2019
import org.apache.logging.log4j.Logger;
2120
import org.jetbrains.annotations.NotNull;
2221
import org.jetbrains.annotations.Nullable;
@@ -25,6 +24,7 @@
2524
import org.labkey.api.data.dialect.StatementWrapper;
2625
import org.labkey.api.util.ExceptionUtil;
2726
import org.labkey.api.util.MemTracker;
27+
import org.labkey.api.util.logging.LogHelper;
2828
import org.springframework.dao.ConcurrencyFailureException;
2929
import org.springframework.jdbc.BadSqlGrammarException;
3030

@@ -40,19 +40,21 @@
4040
import static org.labkey.api.util.ExceptionUtil.CALCULATED_COLUMN_SQL_TAG;
4141

4242
/**
43-
* Selector that is driven by SQL, which subclasses can control how it's interpreted (LabKey SQL, raw DB SQL, etc)
43+
* Selector that is driven by SQL, which subclasses can control how it's interpreted (LabKey SQL, raw DB SQL, etc.)
4444
*/
4545
public abstract class SqlExecutingSelector<FACTORY extends SqlFactory, SELECTOR extends SqlExecutingSelector<FACTORY, SELECTOR>> extends BaseSelector<SELECTOR>
4646
{
47+
private static final Logger LOGGER = LogHelper.getLogger(SqlExecutingSelector.class, "Log warnings about SQL exceptions");
48+
4749
int _maxRows = Table.ALL_ROWS;
4850
protected long _offset = Table.NO_OFFSET;
4951
@Nullable Map<String, Object> _namedParameters = null;
5052
private ConnectionFactory _connectionFactory = super::getConnection;
53+
private Integer _fetchSize = null; // By default, use the standard fetch size
5154

52-
private @Nullable AsyncQueryRequest _asyncRequest = null;
55+
private @Nullable AsyncQueryRequest<?> _asyncRequest = null;
5356
private @Nullable StackTraceElement[] _loggingStacktrace = null;
5457
private final QueryLogging _queryLogging;
55-
private static final Logger LOGGER = LogManager.getLogger(SqlExecutingSelector.class);
5658

5759
// SQL factory used for the duration of a single query execution. This allows reuse of instances, since query-specific
5860
// optimizations won't mutate the ExecutingSelector's externally set state.
@@ -111,6 +113,16 @@ public SELECTOR setJdbcCaching(boolean cache)
111113
return getThis();
112114
}
113115

116+
/**
117+
* Set a ResultSet fetch size that differs from the default value (1,000 rows on PostgreSQL). This is normally a
118+
* fine fetch size, but not when dealing with rows containing large TEXT or BYTEA columns.
119+
*/
120+
public SELECTOR setFetchSize(int fetchSize)
121+
{
122+
_fetchSize = fetchSize;
123+
return getThis();
124+
}
125+
114126
@Override
115127
protected ResultSetFactory getStandardResultSetFactory()
116128
{
@@ -282,7 +294,7 @@ protected boolean exists(FACTORY factory)
282294
}
283295

284296

285-
void setAsyncRequest(@Nullable AsyncQueryRequest asyncRequest)
297+
void setAsyncRequest(@Nullable AsyncQueryRequest<?> asyncRequest)
286298
{
287299
_asyncRequest = asyncRequest;
288300

@@ -291,7 +303,7 @@ void setAsyncRequest(@Nullable AsyncQueryRequest asyncRequest)
291303
}
292304

293305
@Nullable
294-
private AsyncQueryRequest getAsyncRequest()
306+
private AsyncQueryRequest<?> getAsyncRequest()
295307
{
296308
return _asyncRequest;
297309
}
@@ -466,7 +478,7 @@ public <T> T handleResultSet(ResultSetHandler<T> handler)
466478
}
467479
}
468480

469-
private ResultSet executeQuery(Connection conn, SQLFragment sqlFragment, boolean scrollable, @Nullable AsyncQueryRequest asyncRequest, @Nullable Integer statementMaxRows) throws SQLException
481+
private ResultSet executeQuery(Connection conn, SQLFragment sqlFragment, boolean scrollable, @Nullable AsyncQueryRequest<?> asyncRequest, @Nullable Integer statementMaxRows) throws SQLException
470482
{
471483
List<Object> parameters = sqlFragment.getParams();
472484
String sql = sqlFragment.getSQL();
@@ -475,13 +487,13 @@ private ResultSet executeQuery(Connection conn, SQLFragment sqlFragment, boolean
475487
if (null == parameters || parameters.isEmpty())
476488
{
477489
Statement stmt = conn.createStatement(scrollable ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
478-
initializeStatement(conn, stmt, asyncRequest, statementMaxRows);
490+
initializeStatement(stmt, asyncRequest, statementMaxRows);
479491
rs = stmt.executeQuery(sql);
480492
}
481493
else
482494
{
483495
PreparedStatement stmt = conn.prepareStatement(sql, scrollable ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
484-
initializeStatement(conn, stmt, asyncRequest, statementMaxRows);
496+
initializeStatement(stmt, asyncRequest, statementMaxRows);
485497

486498
try (Parameter.ParameterList jdbcParameters = new Parameter.ParameterList())
487499
{
@@ -499,14 +511,19 @@ private ResultSet executeQuery(Connection conn, SQLFragment sqlFragment, boolean
499511
return rs;
500512
}
501513

502-
private void initializeStatement(Connection conn, Statement stmt, @Nullable AsyncQueryRequest asyncRequest, @Nullable Integer statementMaxRows) throws SQLException
514+
private void initializeStatement(Statement stmt, @Nullable AsyncQueryRequest<?> asyncRequest, @Nullable Integer statementMaxRows) throws SQLException
503515
{
504516
// Don't set max rows if null or special ALL_ROWS value (we're assuming statement.getMaxRows() defaults to 0, though this isn't actually documented...)
505517
if (null != statementMaxRows && Table.ALL_ROWS != statementMaxRows)
506518
{
507519
stmt.setMaxRows(statementMaxRows == Table.NO_ROWS ? 1 : statementMaxRows);
508520
}
509521

522+
if (null != _fetchSize)
523+
{
524+
stmt.setFetchSize(_fetchSize);
525+
}
526+
510527
if (asyncRequest != null)
511528
{
512529
asyncRequest.setStatement(stmt);

api/src/org/labkey/api/data/SqlFactory.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
import java.sql.ResultSet;
2121
import java.sql.SQLException;
2222

23-
/**
24-
* User: adam
25-
* Date: 1/22/12
26-
* Time: 2:33 PM
27-
*/
2823
public interface SqlFactory
2924
{
3025
/** Returns the SQL to execute. If null, execution is skipped and handler is called with null parameters, allowing

api/src/org/labkey/api/data/dialect/BasePostgreSqlDialect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1810,7 +1810,7 @@ public ConnectionFactory getConnectionFactory(boolean useJdbcCaching, DbScope sc
18101810

18111811
private Closer configureToDisableJdbcCaching(ConnectionWrapper connection, DbScope scope) throws SQLException
18121812
{
1813-
assert connection.getAutoCommit(); // We just got a new connection... it better be set to auto commit
1813+
assert connection.getAutoCommit(); // We just got a new connection... it better be set to auto commit
18141814

18151815
try
18161816
{

api/src/org/labkey/api/util/StringUtilsLabKey.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.junit.Test;
2727
import org.labkey.api.data.Container;
2828
import org.labkey.api.exp.Identifiable;
29-
import org.labkey.api.security.Encryption;
3029
import org.labkey.api.view.ViewServlet;
3130

3231
import java.nio.charset.Charset;

api/src/org/labkey/api/view/FolderManagement.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public enum TYPE
4747
FolderManagement
4848
{
4949
@Override
50-
void addNavTrail(BaseViewAction action, NavTree root, Container c, User user)
50+
void addNavTrail(BaseViewAction<?> action, NavTree root, Container c, User user)
5151
{
5252
// In the root, view is rendered as a standalone page (no tab strip). Create an appropriate nav trail.
5353
if (c.isRoot())
@@ -76,7 +76,7 @@ boolean shouldRenderTabStrip(Container container)
7676
ProjectSettings // Used for project settings
7777
{
7878
@Override
79-
void addNavTrail(BaseViewAction action, NavTree root, Container c, User user)
79+
void addNavTrail(BaseViewAction<?> action, NavTree root, Container c, User user)
8080
{
8181
action.setHelpTopic("customizeLook");
8282
root.addChild("Project Settings");
@@ -91,7 +91,7 @@ boolean shouldRenderTabStrip(Container container)
9191
LookAndFeelSettings // Used for the admin console actions -- allows for troubleshooter permissions
9292
{
9393
@Override
94-
void addNavTrail(BaseViewAction action, NavTree root, Container c, User user)
94+
void addNavTrail(BaseViewAction<?> action, NavTree root, Container c, User user)
9595
{
9696
action.setHelpTopic("customizeLook");
9797
PageFlowUtil.urlProvider(AdminUrls.class).addAdminNavTrail(root, "Look and Feel Settings", action.getClass(), c);
@@ -104,7 +104,7 @@ boolean shouldRenderTabStrip(Container container)
104104
}
105105
};
106106

107-
abstract void addNavTrail(BaseViewAction action, NavTree root, Container c, User user);
107+
abstract void addNavTrail(BaseViewAction<?> action, NavTree root, Container c, User user);
108108

109109
abstract boolean shouldRenderTabStrip(Container container);
110110
}
@@ -170,14 +170,14 @@ public List<NavTree> getTabList()
170170
protected abstract List<TabProvider> getTabProviders();
171171

172172
@Override
173-
public abstract HttpView getTabView(String tabId) throws Exception;
173+
public abstract HttpView<?> getTabView(String tabId) throws Exception;
174174
}
175175

176176

177177
/**
178178
* Marker interface for actions that register themselves with a management page
179179
*/
180-
interface ManagementAction extends Controller
180+
public interface ManagementAction extends Controller
181181
{
182182
}
183183

@@ -208,7 +208,7 @@ public final ModelAndView getView(Object form, BindException errors) throws Exce
208208
}
209209

210210
protected abstract TYPE getType();
211-
protected abstract HttpView getTabView() throws Exception;
211+
protected abstract HttpView<?> getTabView() throws Exception;
212212

213213
@Override
214214
public void addNavTrail(NavTree root)
@@ -244,7 +244,7 @@ public URLHelper getSuccessURL(FORM form)
244244

245245
protected abstract TYPE getType();
246246

247-
protected abstract HttpView getTabView(FORM form, boolean reshow, BindException errors) throws Exception;
247+
protected abstract HttpView<?> getTabView(FORM form, boolean reshow, BindException errors) throws Exception;
248248

249249
@Override
250250
public void addNavTrail(NavTree root)
@@ -255,7 +255,7 @@ public void addNavTrail(NavTree root)
255255

256256

257257
/** Wrap the provided view in a tab strip, if that's what the type desires **/
258-
private static HttpView wrapViewInTabStrip(BaseViewAction action, TYPE type, HttpView view, BindException errors)
258+
private static HttpView<?> wrapViewInTabStrip(BaseViewAction<?> action, TYPE type, HttpView<?> view, BindException errors)
259259
{
260260
ViewContext ctx = action.getViewContext();
261261
Container c = ctx.getContainer();
@@ -268,7 +268,7 @@ private static HttpView wrapViewInTabStrip(BaseViewAction action, TYPE type, Htt
268268
return new ManagementTabStrip(c, tabId, errors)
269269
{
270270
@Override
271-
public HttpView getTabView(String tabId)
271+
public HttpView<?> getTabView(String tabId)
272272
{
273273
return view;
274274
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- These tables have FKs to exp.Data without corresponding indices. Add indices to speed up exp.Data delete.
2+
CREATE INDEX IX_DataInput_DataId ON exp.DataInput (DataId);
3+
CREATE INDEX IX_DataAncestors_RowId ON exp.DataAncestors (RowId);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Not needed since it's redundant with exp.DataInput's PK
2+
DROP INDEX exp.IX_DataInput_DataId;
3+
4+
CREATE INDEX IX_MaterialAncestors_RowId ON exp.MaterialAncestors (RowId);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- These tables have FKs to exp.Data without corresponding indices. Add indices to speed up exp.Data delete.
2+
CREATE INDEX IX_DataInput_DataId ON exp.DataInput (DataId);
3+
CREATE INDEX IX_DataAncestors_RowId ON exp.DataAncestors (RowId);

0 commit comments

Comments
 (0)