@query-doctor/core 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1926,120 +1926,120 @@ var Statistics = class Statistics {
1926
1926
  const processedTables = /* @__PURE__ */ new Set();
1927
1927
  let columnStatsUpdatePromise;
1928
1928
  const columnStatsValues = [];
1929
- if (this.exportedMetadata) {
1930
- for (const table of this.ownMetadata) {
1931
- if (!table.columns) continue;
1932
- for (const column of table.columns) {
1933
- const { stats } = column;
1934
- if (!stats) {
1935
- columnStatsValues.push({
1936
- schema_name: table.schemaName,
1937
- table_name: table.tableName,
1938
- column_name: column.columnName,
1939
- stainherit: false,
1940
- stanullfrac: .1,
1941
- stawidth: 20,
1942
- stadistinct: .1,
1943
- stakind1: 0,
1944
- stakind2: 0,
1945
- stakind3: 0,
1946
- stakind4: 0,
1947
- stakind5: 0,
1948
- stacoll1: "",
1949
- stacoll2: "",
1950
- stacoll3: "",
1951
- stacoll4: "",
1952
- stacoll5: "",
1953
- staop1: "",
1954
- staop2: "",
1955
- staop3: "",
1956
- staop4: "",
1957
- staop5: "",
1958
- stanumbers1: null,
1959
- stanumbers2: null,
1960
- stanumbers3: null,
1961
- stanumbers4: null,
1962
- stanumbers5: null,
1963
- stavalues1: null,
1964
- stavalues2: null,
1965
- stavalues3: null,
1966
- stavalues4: null,
1967
- stavalues5: null,
1968
- _value_type1: "real",
1969
- _value_type2: "real",
1970
- _value_type3: "real",
1971
- _value_type4: "real",
1972
- _value_type5: "real"
1973
- });
1974
- continue;
1975
- }
1929
+ for (const table of this.ownMetadata) {
1930
+ const target = (this.exportedMetadata?.find((m) => m.tableName === table.tableName && m.schemaName === table.schemaName))?.columns ?? table.columns;
1931
+ if (!target) continue;
1932
+ for (const column of target) {
1933
+ const { stats } = column;
1934
+ if (!stats || this.mode.kind === "fromAssumption") {
1976
1935
  columnStatsValues.push({
1977
1936
  schema_name: table.schemaName,
1978
1937
  table_name: table.tableName,
1979
1938
  column_name: column.columnName,
1980
- stainherit: stats.stainherit ?? false,
1981
- stanullfrac: stats.stanullfrac,
1982
- stawidth: stats.stawidth,
1983
- stadistinct: stats.stadistinct,
1984
- stakind1: stats.stakind1,
1985
- stakind2: stats.stakind2,
1986
- stakind3: stats.stakind3,
1987
- stakind4: stats.stakind4,
1988
- stakind5: stats.stakind5,
1989
- staop1: stats.staop1,
1990
- staop2: stats.staop2,
1991
- staop3: stats.staop3,
1992
- staop4: stats.staop4,
1993
- staop5: stats.staop5,
1994
- stacoll1: stats.stacoll1,
1995
- stacoll2: stats.stacoll2,
1996
- stacoll3: stats.stacoll3,
1997
- stacoll4: stats.stacoll4,
1998
- stacoll5: stats.stacoll5,
1999
- stanumbers1: stats.stanumbers1,
2000
- stanumbers2: stats.stanumbers2,
2001
- stanumbers3: stats.stanumbers3,
2002
- stanumbers4: stats.stanumbers4,
2003
- stanumbers5: stats.stanumbers5,
2004
- stavalues1: Statistics.safeStavalues(stats.stavalues1),
2005
- stavalues2: Statistics.safeStavalues(stats.stavalues2),
2006
- stavalues3: Statistics.safeStavalues(stats.stavalues3),
2007
- stavalues4: Statistics.safeStavalues(stats.stavalues4),
2008
- stavalues5: Statistics.safeStavalues(stats.stavalues5),
2009
- _value_type1: this.stavalueKind(Statistics.safeStavalues(stats.stavalues1)),
2010
- _value_type2: this.stavalueKind(Statistics.safeStavalues(stats.stavalues2)),
2011
- _value_type3: this.stavalueKind(Statistics.safeStavalues(stats.stavalues3)),
2012
- _value_type4: this.stavalueKind(Statistics.safeStavalues(stats.stavalues4)),
2013
- _value_type5: this.stavalueKind(Statistics.safeStavalues(stats.stavalues5))
1939
+ stainherit: false,
1940
+ stanullfrac: .04,
1941
+ stawidth: stats?.stawidth ?? 32,
1942
+ stadistinct: -.9,
1943
+ stakind1: 0,
1944
+ stakind2: 0,
1945
+ stakind3: 3,
1946
+ stakind4: 0,
1947
+ stakind5: 0,
1948
+ stacoll1: "0",
1949
+ stacoll2: "0",
1950
+ stacoll3: "0",
1951
+ stacoll4: "0",
1952
+ stacoll5: "0",
1953
+ staop1: "0",
1954
+ staop2: "0",
1955
+ staop3: "0",
1956
+ staop4: "0",
1957
+ staop5: "0",
1958
+ stanumbers1: null,
1959
+ stanumbers2: null,
1960
+ stanumbers3: [.9],
1961
+ stanumbers4: null,
1962
+ stanumbers5: null,
1963
+ stavalues1: null,
1964
+ stavalues2: null,
1965
+ stavalues3: null,
1966
+ stavalues4: null,
1967
+ stavalues5: null,
1968
+ _value_type1: "real",
1969
+ _value_type2: "real",
1970
+ _value_type3: "real",
1971
+ _value_type4: "real",
1972
+ _value_type5: "real"
2014
1973
  });
1974
+ continue;
2015
1975
  }
1976
+ columnStatsValues.push({
1977
+ schema_name: table.schemaName,
1978
+ table_name: table.tableName,
1979
+ column_name: column.columnName,
1980
+ stainherit: stats.stainherit ?? false,
1981
+ stanullfrac: stats.stanullfrac,
1982
+ stawidth: stats.stawidth,
1983
+ stadistinct: stats.stadistinct,
1984
+ stakind1: stats.stakind1,
1985
+ stakind2: stats.stakind2,
1986
+ stakind3: stats.stakind3,
1987
+ stakind4: stats.stakind4,
1988
+ stakind5: stats.stakind5,
1989
+ staop1: stats.staop1,
1990
+ staop2: stats.staop2,
1991
+ staop3: stats.staop3,
1992
+ staop4: stats.staop4,
1993
+ staop5: stats.staop5,
1994
+ stacoll1: stats.stacoll1,
1995
+ stacoll2: stats.stacoll2,
1996
+ stacoll3: stats.stacoll3,
1997
+ stacoll4: stats.stacoll4,
1998
+ stacoll5: stats.stacoll5,
1999
+ stanumbers1: stats.stanumbers1,
2000
+ stanumbers2: stats.stanumbers2,
2001
+ stanumbers3: stats.stanumbers3,
2002
+ stanumbers4: stats.stanumbers4,
2003
+ stanumbers5: stats.stanumbers5,
2004
+ stavalues1: Statistics.safeStavalues(stats.stavalues1),
2005
+ stavalues2: Statistics.safeStavalues(stats.stavalues2),
2006
+ stavalues3: Statistics.safeStavalues(stats.stavalues3),
2007
+ stavalues4: Statistics.safeStavalues(stats.stavalues4),
2008
+ stavalues5: Statistics.safeStavalues(stats.stavalues5),
2009
+ _value_type1: this.stavalueKind(Statistics.safeStavalues(stats.stavalues1)),
2010
+ _value_type2: this.stavalueKind(Statistics.safeStavalues(stats.stavalues2)),
2011
+ _value_type3: this.stavalueKind(Statistics.safeStavalues(stats.stavalues3)),
2012
+ _value_type4: this.stavalueKind(Statistics.safeStavalues(stats.stavalues4)),
2013
+ _value_type5: this.stavalueKind(Statistics.safeStavalues(stats.stavalues5))
2014
+ });
2016
2015
  }
2017
- /**
2018
- * Postgres has 5 different slots for storing statistics per column and a potentially unlimited
2019
- * number of statistic types to choose from. Each code in `stakindN` can mean different things.
2020
- * Some statistics are just numerical values such as `n_distinct` and `correlation`, meaning
2021
- * they're only derived from `stanumbersN` and the value of `stanumbersN` is never read.
2022
- * Others take advantage of the `stavaluesN` columns which use `anyarray` type to store
2023
- * concrete values internally for things like histogram bounds.
2024
- * Unfortunately we cannot change anyarrays without a C extension.
2025
- *
2026
- * (1) = most common values
2027
- * (2) = scalar histogram
2028
- * (3) = correlation <- can change
2029
- * (4) = most common elements
2030
- * (5) = distinct elem count histogram <- can change
2031
- * (6) = length histogram (?) These don't appear in pg_stats
2032
- * (7) = bounds histogram (?) These don't appear in pg_stats
2033
- * (N) = potentially many more kinds of statistics. But postgres <=18 only uses these 7.
2034
- *
2035
- * What we're doing here is setting ANY statistic we cannot directly control
2036
- * (anything that relies on stavaluesN) to 0 to make sure the planner isn't influenced by what
2037
- * what the db collected from the test data.
2038
- * Because we do our tests with `generic_plan` it seems it's already unlikely that the planner will be
2039
- * using things like common values or histogram bounds to make the planning decisions we care about.
2040
- * This is a just in case.
2041
- */
2042
- const sql = dedent.default`
2016
+ }
2017
+ /**
2018
+ * Postgres has 5 different slots for storing statistics per column and a potentially unlimited
2019
+ * number of statistic types to choose from. Each code in `stakindN` can mean different things.
2020
+ * Some statistics are just numerical values such as `n_distinct` and `correlation`, meaning
2021
+ * they're only derived from `stanumbersN` and the value of `stanumbersN` is never read.
2022
+ * Others take advantage of the `stavaluesN` columns which use `anyarray` type to store
2023
+ * concrete values internally for things like histogram bounds.
2024
+ * Unfortunately we cannot change anyarrays without a C extension.
2025
+ *
2026
+ * (1) = most common values
2027
+ * (2) = scalar histogram
2028
+ * (3) = correlation <- can change
2029
+ * (4) = most common elements
2030
+ * (5) = distinct elem count histogram <- can change
2031
+ * (6) = length histogram (?) These don't appear in pg_stats
2032
+ * (7) = bounds histogram (?) These don't appear in pg_stats
2033
+ * (N) = potentially many more kinds of statistics. But postgres <=18 only uses these 7.
2034
+ *
2035
+ * What we're doing here is setting ANY statistic we cannot directly control
2036
+ * (anything that relies on stavaluesN) to 0 to make sure the planner isn't influenced by what
2037
+ * what the db collected from the test data.
2038
+ * Because we do our tests with `generic_plan` it seems it's already unlikely that the planner will be
2039
+ * using things like common values or histogram bounds to make the planning decisions we care about.
2040
+ * This is a just in case.
2041
+ */
2042
+ const sql = dedent.default`
2043
2043
  WITH input AS (
2044
2044
  SELECT
2045
2045
  c.oid AS starelid,
@@ -2222,30 +2222,29 @@ var Statistics = class Statistics {
2222
2222
  returning starelid, staattnum, stainherit, stakind1, stakind2, stakind3, stakind4, stakind5
2223
2223
  )
2224
2224
  select * from updated union all (select * from inserted); -- @qd_introspection`;
2225
- columnStatsUpdatePromise = tx.exec(sql, [columnStatsValues]).catch((err) => {
2226
- console.error("Something wrong wrong updating column stats");
2227
- console.error(err);
2228
- throw err;
2229
- });
2230
- }
2225
+ columnStatsUpdatePromise = tx.exec(sql, [columnStatsValues]).catch((err) => {
2226
+ console.error("Something wrong wrong updating column stats");
2227
+ console.error(err);
2228
+ throw err;
2229
+ });
2231
2230
  const reltuplesValues = [];
2232
2231
  for (const table of this.ownMetadata) {
2233
- if (!table.columns) continue;
2234
2232
  processedTables.add(`${table.schemaName}.${table.tableName}`);
2235
2233
  let targetTable;
2236
2234
  if (this.exportedMetadata) targetTable = this.exportedMetadata.find((m) => m.tableName === table.tableName && m.schemaName === table.schemaName);
2235
+ else targetTable = table;
2237
2236
  let reltuples;
2238
2237
  let relpages;
2239
2238
  let relallvisible = 0;
2240
2239
  let relallfrozen;
2241
- if (targetTable) {
2240
+ if (this.mode.kind === "fromAssumption") {
2241
+ reltuples = this.mode.reltuples;
2242
+ relpages = this.mode.relpages;
2243
+ } else if (targetTable) {
2242
2244
  reltuples = targetTable.reltuples;
2243
2245
  relpages = targetTable.relpages;
2244
2246
  relallvisible = targetTable.relallvisible;
2245
2247
  relallfrozen = targetTable.relallfrozen;
2246
- } else if (this.mode.kind === "fromAssumption") {
2247
- reltuples = this.mode.reltuples;
2248
- relpages = this.mode.relpages;
2249
2248
  } else {
2250
2249
  warnings.tablesNotInExports.push(`${table.schemaName}.${table.tableName}`);
2251
2250
  reltuples = DEFAULT_RELTUPLES;
@@ -2259,7 +2258,15 @@ var Statistics = class Statistics {
2259
2258
  relallfrozen,
2260
2259
  relallvisible
2261
2260
  });
2262
- if (targetTable && targetTable.indexes) for (const index of targetTable.indexes) reltuplesValues.push({
2261
+ if (this.mode.kind === "fromAssumption") for (const index of table.indexes) reltuplesValues.push({
2262
+ relname: index.indexName,
2263
+ schema_name: table.schemaName,
2264
+ reltuples: this.mode.reltuples,
2265
+ relpages: Math.ceil(this.mode.relpages * .2),
2266
+ relallfrozen: 0,
2267
+ relallvisible: this.mode.relpages
2268
+ });
2269
+ if (targetTable) for (const index of targetTable.indexes) reltuplesValues.push({
2263
2270
  relname: index.indexName,
2264
2271
  schema_name: targetTable.schemaName,
2265
2272
  reltuples: index.reltuples,