Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/src/org/labkey/api/data/DataColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ protected ColumnInfo getDisplayField(@NotNull ColumnInfo col, boolean withLookup
return null==display ? col : display;
}

@Override
public void setWithLookup(boolean withLookup)
{
_displayColumn = withLookup ? getDisplayField(_boundColumn, true) : _boundColumn;
}

@Override
public String toString()
{
Expand Down
5 changes: 5 additions & 0 deletions api/src/org/labkey/api/data/DisplayColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,11 @@ public void setRequiresHtmlFiltering(boolean requiresHtmlFiltering)
_requiresHtmlFiltering = requiresHtmlFiltering;
}

public void setWithLookup(boolean withLookup)
{
// subclasses override as needed
}

public void setLinkTarget(String linkTarget)
{
_linkTarget = linkTarget;
Expand Down
10 changes: 10 additions & 0 deletions api/src/org/labkey/api/util/PageFlowUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2676,6 +2676,16 @@ private static boolean shouldEscapeForExport(@NotNull String value)
return StringUtils.containsAny(value,",\"");
}

/// Generate one row of tab-delimited output using RFC 4180 quoting rules.
/// Fields containing tabs, newlines, or double quotes are enclosed in double quotes,
/// with embedded double quotes escaped by doubling.
public static String joinValuesWithTabs4180(@NotNull List<String> values)
{
return values.stream()
.map(value -> null == value ? "" : StringUtils.containsAny(value, "\t\n\r\"") ? "\"" + Strings.CS.replace(value, "\"", "\"\"") + "\"" : value)
.collect(Collectors.joining("\t"));
}


/**
* Issue 52925: App export to csv/tsv ignores filter with column containing double quote
Expand Down
3 changes: 2 additions & 1 deletion query/src/org/labkey/query/QueryModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ public Set<String> getSchemaNames()
RolapReader.RolapTest.class,
RolapTestCase.class,
SelectRowsStreamHack.TestCase.class,
ServerManager.TestCase.class
ServerManager.TestCase.class,
SqlController.TestCase.class
);
}

Expand Down
16 changes: 15 additions & 1 deletion query/src/org/labkey/query/controllers/LabKeySql.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,18 @@ When writing LabKey SQL queries that work with JSON columns:
3. **Use `jsonb_extract_path_text()` for nested field access** — this is often the clearest way to extract a deeply nested text value: `jsonb_extract_path_text(col, 'level1', 'level2', 'field')`.
4. **Use `jsonb_build_object()` to construct JSON** — for building JSON from column values: `jsonb_build_object('id', rowid, 'name', label)`.
5. **Check database type first** — these functions only work on PostgreSQL. If the target server may use MS SQL Server, do not use them.
6. **The `validateSQL` MCP tool can verify syntax** — use it to check JSON function calls before the user saves a query.
6. **The `validateSQL` MCP tool can verify syntax** — use it to check JSON function calls before the user saves a query.

-----

### **Fetching Live Data for LLM Inspection**

The `sql-execute.view` endpoint is for **the LLM to inspect live data while generating code** — do not emit it in generated Python, R, or other scripts (use the `labkey` client API there instead). Always include `LIMIT` to avoid fetching excess rows.
Unlike the LabKey client APIs (`selectRows`, `executeSql`), this endpoint does not automatically resolve lookups to display values — it returns exactly what the SQL selects. Use LabKey SQL's dot-notation to traverse lookups explicitly when you need a human-readable value. For example, `SELECT CreatedBy FROM lists.MyList` returns a raw integer user ID; `SELECT CreatedBy.DisplayName FROM lists.MyList` returns the display name.

```bash
curl -H "Authorization: Bearer <APIKEY>" \
"https://<server>/<containerPath>/sql-execute.view?schemaName=<schema>&sql=SELECT+...+LIMIT+20&format=tsv"
```

The response is RFC 4180 TSV: a header row of column names followed by one data row per result. Values are rendered via `DisplayColumn.getTsvFormattedValue()` — dates as ISO-8601, multi-value columns correctly serialized.
Loading