CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/database/postgres/schema/indexes.ts
Views: 687
1
import getLogger from "@cocalc/backend/logger";
2
import type { Client } from "@cocalc/database/pool";
3
import type { TableSchema } from "./types";
4
import { make_valid_name } from "@cocalc/util/misc";
5
6
const log = getLogger("db:schema:indexes");
7
8
function possiblyAddParens(query: string): string {
9
if (query[0] == "(") {
10
return query;
11
}
12
if (query.toLowerCase().startsWith("using")) {
13
// do not add for using queries, since that violates PostgreSQL syntax
14
return query;
15
}
16
return `(${query})`;
17
}
18
19
export function createIndexesQueries(
20
schema: TableSchema
21
): { name: string; query: string; unique: boolean }[] {
22
const v = schema.pg_indexes ?? [];
23
if (schema.fields.expire != null && !v.includes("expire")) {
24
v.push("expire");
25
}
26
const queries: { name: string; query: string; unique: boolean }[] = [];
27
for (let query of v) {
28
query = query.trim();
29
const name = `${schema.name}_${make_valid_name(query)}_idx`; // this first, then...
30
query = possiblyAddParens(query);
31
queries.push({ name, query, unique: false });
32
}
33
const w = schema.pg_unique_indexes ?? [];
34
for (let query of w) {
35
query = query.trim();
36
const name = `${schema.name}_${make_valid_name(query)}_unique_idx`;
37
query = possiblyAddParens(query);
38
queries.push({ name, query, unique: true });
39
}
40
return queries;
41
}
42
43
// IMPORTANT: There is also code in database/postgres/schema/sync.ts that creates indexes.
44
export async function createIndexes(
45
db: Client,
46
schema: TableSchema
47
): Promise<void> {
48
log.debug("createIndexes", schema.name, " creating SQL query");
49
for (const { name, query, unique } of createIndexesQueries(schema)) {
50
// Shorthand index is just the part in parens.
51
// 2020-10-12: it makes total sense to add CONCURRENTLY to this index command to avoid locking up the table,
52
// but the first time we tried this in production (postgres 10), it just made "invalid" indices.
53
// the problem might be that several create index commands were issued rapidly, which threw this off
54
// So, for now, it's probably best to either create them manually first (concurrently) or be
55
// aware that this does lock up briefly.
56
const fullQuery = `CREATE ${unique ? "UNIQUE" : ""} INDEX ${name} ON ${
57
schema.name
58
} ${query}`;
59
log.debug("createIndexes -- creating ", name, " using ", fullQuery);
60
await db.query(fullQuery);
61
}
62
}
63
64