sql-typechecker 0.0.16 → 0.0.19

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/out/cli.js CHANGED
@@ -4110,7 +4110,7 @@ var require_lodash = __commonJS((exports2, module2) => {
4110
4110
  function isNull(value2) {
4111
4111
  return value2 === null;
4112
4112
  }
4113
- function isNil(value2) {
4113
+ function isNil2(value2) {
4114
4114
  return value2 == null;
4115
4115
  }
4116
4116
  function isNumber(value2) {
@@ -5174,7 +5174,7 @@ var require_lodash = __commonJS((exports2, module2) => {
5174
5174
  lodash.isMatchWith = isMatchWith;
5175
5175
  lodash.isNaN = isNaN2;
5176
5176
  lodash.isNative = isNative;
5177
- lodash.isNil = isNil;
5177
+ lodash.isNil = isNil2;
5178
5178
  lodash.isNull = isNull;
5179
5179
  lodash.isNumber = isNumber;
5180
5180
  lodash.isObject = isObject;
@@ -226429,8 +226429,8 @@ ${fromBody}`;
226429
226429
  jsxMode = true;
226430
226430
  forceNoIndent = true;
226431
226431
  const wrap = (doc2) => [ifBreak("("), indent([softline, doc2]), softline, ifBreak(")")];
226432
- const isNil = (node2) => node2.type === "NullLiteral" || node2.type === "Literal" && node2.value === null || node2.type === "Identifier" && node2.name === "undefined";
226433
- parts.push(" ? ", isNil(consequentNode) ? print(consequentNodePropertyName) : wrap(print(consequentNodePropertyName)), " : ", alternateNode.type === node.type || isNil(alternateNode) ? print(alternateNodePropertyName) : wrap(print(alternateNodePropertyName)));
226432
+ const isNil2 = (node2) => node2.type === "NullLiteral" || node2.type === "Literal" && node2.value === null || node2.type === "Identifier" && node2.name === "undefined";
226433
+ parts.push(" ? ", isNil2(consequentNode) ? print(consequentNodePropertyName) : wrap(print(consequentNodePropertyName)), " : ", alternateNode.type === node.type || isNil2(alternateNode) ? print(alternateNodePropertyName) : wrap(print(alternateNodePropertyName)));
226434
226434
  } else {
226435
226435
  const part = [line, "? ", consequentNode.type === node.type ? ifBreak("", "(") : "", align(2, print(consequentNodePropertyName)), consequentNode.type === node.type ? ifBreak("", ")") : "", line, ": ", alternateNode.type === node.type ? print(alternateNodePropertyName) : align(2, print(alternateNodePropertyName))];
226436
226436
  parts.push(parent.type !== node.type || parent[alternateNodePropertyName] === node || isParentTest ? part : options.useTabs ? dedent(indent(part)) : align(Math.max(0, options.tabWidth - 2), part));
@@ -235895,13 +235895,14 @@ ${text}`;
235895
235895
 
235896
235896
  // src/cli.ts
235897
235897
  var fs = __toModule(require("fs/promises"));
235898
- var import_lodash = __toModule(require_lodash());
235898
+ var import_lodash2 = __toModule(require_lodash());
235899
235899
  var path = __toModule(require("path"));
235900
235900
  var import_pgsql_ast_parser2 = __toModule(require_lib());
235901
235901
  var prettier = __toModule(require_prettier());
235902
235902
 
235903
235903
  // src/typecheck.ts
235904
235904
  var import_assert = __toModule(require("assert"));
235905
+ var import_lodash = __toModule(require_lodash());
235905
235906
  var import_pgsql_ast_parser = __toModule(require_lib());
235906
235907
 
235907
235908
  // src/normalize.ts
@@ -241688,6 +241689,10 @@ var BuiltinTypes = {
241688
241689
  Jsonb: {
241689
241690
  kind: "scalar",
241690
241691
  name: {name: "jsonb"}
241692
+ },
241693
+ Null: {
241694
+ kind: "scalar",
241695
+ name: {name: "null"}
241691
241696
  }
241692
241697
  };
241693
241698
  var allNumericBuiltinTypes = [
@@ -241907,15 +241912,30 @@ function unifyCallGeneral(call, argTypes, expectedArgs, returnT) {
241907
241912
  return returnT;
241908
241913
  }
241909
241914
  function castScalars(e, source, target, type) {
241915
+ const matchingCast = findMatchingCast([source.name], source, target, type);
241916
+ if (matchingCast === null) {
241917
+ throw new TypeMismatch(e, {expected: target, actual: source});
241918
+ }
241919
+ }
241920
+ function findMatchingCast(visited, from, to, type) {
241910
241921
  const casts = builtincasts;
241911
- if (eqQNames(source.name, target.name)) {
241912
- return;
241922
+ if (eqQNames(from.name, to.name)) {
241923
+ return {source: from, target: to, type: "implicit"};
241913
241924
  } else {
241914
- const matchingCast = casts.find((c) => eqQNames(c.source.name, source.name) && eqQNames(c.target.name, target.name) && (c.type === type || c.type === "implicit" && type === "assignment" || c.type === "implicit" && type === "explicit"));
241915
- if (matchingCast) {
241916
- return;
241925
+ const halfMatching = casts.filter((c) => eqQNames(c.source.name, from.name) && (c.type === type || c.type === "implicit" && type === "assignment" || c.type === "implicit" && type === "explicit") && !visited.some((v) => eqQNames(v, c.target.name)));
241926
+ const matchingCast = halfMatching.find((c) => eqQNames(c.target.name, to.name));
241927
+ if (!import_lodash.isNil(matchingCast)) {
241928
+ return matchingCast;
241929
+ } else if (type === "explicit") {
241930
+ for (let halfM of halfMatching) {
241931
+ const found = findMatchingCast(visited.concat(from.name), halfM.target, to, type);
241932
+ if (!import_lodash.isNil(found)) {
241933
+ return found;
241934
+ }
241935
+ }
241936
+ return null;
241917
241937
  } else {
241918
- throw new TypeMismatch(e, {expected: target, actual: source});
241938
+ return null;
241919
241939
  }
241920
241940
  }
241921
241941
  }
@@ -242029,8 +242049,12 @@ function elabSelect(g, c, s) {
242029
242049
  kind: "record",
242030
242050
  fields: fr.type.fields.map((fi) => {
242031
242051
  const foundNullabilityInference = inferredNullability.find((inf) => eqQNames(inf.fromName, fr.name) && inf.fieldName === fi.name?.name);
242032
- const t = foundNullabilityInference ? foundNullabilityInference.isNull === true ? nullify(fi.type) : unnullify(fi.type) : fi.type;
242033
- return {name: fi.name, type: t};
242052
+ if (foundNullabilityInference && isNullable(fi.type)) {
242053
+ const t = foundNullabilityInference.isNull === true ? BuiltinTypes.Null : unnullify(fi.type);
242054
+ return {name: fi.name, type: t};
242055
+ } else {
242056
+ return fi;
242057
+ }
242034
242058
  })
242035
242059
  }
242036
242060
  }))
@@ -242043,13 +242067,12 @@ function elabSelect(g, c, s) {
242043
242067
  const names = [];
242044
242068
  const fields = (s.columns || []).flatMap((c2) => {
242045
242069
  const n = c2.alias ? c2.alias : deriveNameFromExpr(c2.expr);
242046
- if (n === null) {
242047
- throw new UnableToDeriveFieldName(c2.expr);
242048
- }
242049
- if (names.includes(n.name)) {
242050
- throw new DuplicateFieldNames(c2.expr, n.name);
242070
+ if (!import_lodash.isNil(n)) {
242071
+ if (names.includes(n.name)) {
242072
+ throw new DuplicateFieldNames(c2.expr, n.name);
242073
+ }
242074
+ names.push(n.name);
242051
242075
  }
242052
- names.push(n.name);
242053
242076
  const t = elabExpr(g, newC, c2.expr);
242054
242077
  if (t.kind === "record") {
242055
242078
  if (t.fields.length === 0) {
@@ -242468,12 +242491,15 @@ var ColumnsMismatch = class extends ErrorWithLocation {
242468
242491
  };
242469
242492
  var KindMismatch = class extends ErrorWithLocation {
242470
242493
  constructor(e, type, errormsg) {
242471
- super(e._location, `KindMismatch: ${e}: ${type}: ${errormsg}}`);
242472
- }
242473
- };
242474
- var UnableToDeriveFieldName = class extends ErrorWithLocation {
242475
- constructor(e) {
242476
- super(e._location, `Unable to derive field name for expression ${e}, please provide an alias with <expr> AS <name>`);
242494
+ super(e._location, `
242495
+ KindMismatch:
242496
+ ${import_pgsql_ast_parser.toSql.expr(e)}
242497
+
242498
+ ${errormsg}}
242499
+
242500
+ Type:
242501
+ ${JSON.stringify(type)}
242502
+ `);
242477
242503
  }
242478
242504
  };
242479
242505
  var DuplicateFieldNames = class extends ErrorWithLocation {
@@ -242510,6 +242536,22 @@ ${JSON.stringify(ts.actual)}}
242510
242536
  this.mess = mess;
242511
242537
  }
242512
242538
  };
242539
+ var CannotCast = class extends ErrorWithLocation {
242540
+ constructor(e, ts) {
242541
+ super(e._location, `
242542
+ Cannot cast:
242543
+ ${JSON.stringify(ts.from)}
242544
+
242545
+ to
242546
+ ${JSON.stringify(ts.to)}}
242547
+
242548
+ in expr:
242549
+ ${import_pgsql_ast_parser.toSql.expr(e)}
242550
+ `);
242551
+ this.from = ts.from;
242552
+ this.to = ts.to;
242553
+ }
242554
+ };
242513
242555
  var warnings = [];
242514
242556
  function registerWarning(e, message) {
242515
242557
  warnings.push([e, message]);
@@ -242811,6 +242853,12 @@ function elabCall(g, c, e) {
242811
242853
  throw new InvalidArguments(e, e.function, argTypes);
242812
242854
  }
242813
242855
  }
242856
+ if (eqQNames(e.function, {name: "nextval"})) {
242857
+ return unifyCallGeneral(e, argTypes, [BuiltinTypes.Text], BuiltinTypes.Bigint);
242858
+ }
242859
+ if (eqQNames(e.function, {name: "now"})) {
242860
+ return unifyCallGeneral(e, argTypes, [], BuiltinTypes.Timestamp);
242861
+ }
242814
242862
  if (eqQNames(e.function, {name: "any"}) || eqQNames(e.function, {name: "some"}) || eqQNames(e.function, {name: "all"})) {
242815
242863
  if (e.args.length !== 1) {
242816
242864
  throw new InvalidArguments(e, e.function, argTypes);
@@ -242860,7 +242908,6 @@ function elabCall(g, c, e) {
242860
242908
  return unifyCallGeneral(e, argTypes, [BuiltinTypes.AnyScalar], BuiltinTypes.Boolean);
242861
242909
  }
242862
242910
  if (eqQNames(e.function, {name: "coalesce"}) || eqQNames(e.function, {name: "nullif"})) {
242863
- debugger;
242864
242911
  if (e.args.length === 0) {
242865
242912
  throw new InvalidArguments(e, e.function, []);
242866
242913
  }
@@ -243048,7 +243095,11 @@ function elabExpr(g, c, e) {
243048
243095
  } else if (e.type === "cast") {
243049
243096
  const operandT = elabExpr(g, c, e.operand);
243050
243097
  const toT = mkType(e.to, []);
243051
- cast(e, operandT, nullify(toT), "explicit");
243098
+ try {
243099
+ cast(e, operandT, toT, "explicit");
243100
+ } catch (err) {
243101
+ throw new CannotCast(e, {from: operandT, to: toT});
243102
+ }
243052
243103
  if (isNullable(operandT)) {
243053
243104
  return toT;
243054
243105
  } else {
@@ -243273,7 +243324,7 @@ function functionToTypescript(f) {
243273
243324
  return "";
243274
243325
  }
243275
243326
  }
243276
- const asExpression = f.returns.kind === "record" ? ` AS ${f.name.name}(${f.returns.fields.map((f2) => (f2.name?.name || "") + " " + showTypeDroppingNullable(f2.type)).join(", ")})` : "";
243327
+ const asExpression = f.returns.kind === "record" ? ` AS ${f.name.name}(${f.returns.fields.map((f2, i) => (f2.name?.name || "field" + i) + " " + showTypeDroppingNullable(f2.type)).join(", ")})` : "";
243277
243328
  const recreatedSqlFunctionStatement = `
243278
243329
  CREATE FUNCTION ${f.name.name}(${argsForCreateFunction}) RETURNS ${f.multipleRows ? "SETOF " : ""}${f.returns.kind === "record" ? "RECORD" : f.returns.kind === "void" ? "void" : showTypeDroppingNullable(f.returns)} AS
243279
243330
  $$${f.code}$$ LANGUAGE ${f.language};
@@ -243477,14 +243528,13 @@ async function go() {
243477
243528
  await fs.appendFile(functionsOutFile, writing, "utf-8");
243478
243529
  } catch (err) {
243479
243530
  if (err instanceof ErrorWithLocation && err.l !== void 0) {
243480
- debugger;
243481
243531
  const found = findCode(st.code || "", err.l);
243482
243532
  if (found) {
243483
243533
  console.error("");
243484
- console.error(`Found error at line ${found.lineNumber}`);
243534
+ console.error(`Typechecking error`);
243485
243535
  console.error("");
243486
243536
  console.error(found.line);
243487
- console.error(import_lodash.repeat(" ", found.range[0]) + import_lodash.repeat("^", found.range[1] - found.range[0]));
243537
+ console.error(import_lodash2.repeat(" ", found.range[0]) + import_lodash2.repeat("^", found.range[1] - found.range[0]));
243488
243538
  }
243489
243539
  }
243490
243540
  console.error(err instanceof Error ? err.message : JSON.stringify(err));
@@ -243507,7 +243557,7 @@ function findCode(s, l) {
243507
243557
  lineNumber,
243508
243558
  range: [
243509
243559
  l.start - counted,
243510
- import_lodash.min([lineLength, l.end - counted]) || lineLength
243560
+ import_lodash2.min([lineLength, l.end - counted]) || lineLength
243511
243561
  ]
243512
243562
  };
243513
243563
  }