├── src
├── lang
│ ├── type
│ │ ├── index.js
│ │ └── DataType.js
│ ├── registry.js
│ ├── expr
│ │ ├── ref
│ │ │ ├── abstracts
│ │ │ │ ├── ErrorRefUnknown.js
│ │ │ │ ├── ErrorRefAmbiguous.js
│ │ │ │ ├── ErrorFKInvalid.js
│ │ │ │ ├── AbstractMagicRef.js
│ │ │ │ └── AbstractClassicRef.js
│ │ │ ├── TableRef2.js
│ │ │ ├── WindowRef.js
│ │ │ ├── LQDeepDeepRef2.js
│ │ │ ├── TableRef0.js
│ │ │ ├── ColumnRef0.js
│ │ │ ├── LQBackRefAbstraction.js
│ │ │ ├── LQBackRefEndpoint.js
│ │ │ ├── LQDeepRef2.js
│ │ │ ├── Identifier.js
│ │ │ ├── index.js
│ │ │ ├── LQBackBackRef.js
│ │ │ └── LQDeepDeepRef1.js
│ │ ├── case
│ │ │ ├── index.js
│ │ │ ├── CaseBranch.js
│ │ │ └── CaseExpr.js
│ │ ├── var
│ │ │ ├── index.js
│ │ │ ├── BindVar.js
│ │ │ ├── UserVar.js
│ │ │ └── SystemVar.js
│ │ ├── call
│ │ │ ├── constructs
│ │ │ │ ├── index.js
│ │ │ │ ├── PGFilterClause.js
│ │ │ │ └── PGWithinGroupClause.js
│ │ │ └── index.js
│ │ ├── AbstractClassicExpr.js
│ │ ├── etc
│ │ │ ├── index.js
│ │ │ ├── PredicateExpr.js
│ │ │ ├── QuantitativeExpr.js
│ │ │ ├── ExtractExpr.js
│ │ │ └── CastExpr.js
│ │ ├── abstraction
│ │ │ ├── index.js
│ │ │ ├── TypedRowConstructor.js
│ │ │ ├── ParenExpr.js
│ │ │ └── ScalarSubquery.js
│ │ ├── literals
│ │ │ ├── NullLiteral.js
│ │ │ ├── UnknownLiteral.js
│ │ │ ├── DefaultLiteral.js
│ │ │ ├── AbstractLiteral.js
│ │ │ ├── TypedDateLiteral.js
│ │ │ ├── BitLiteral.js
│ │ │ ├── BoolLiteral.js
│ │ │ ├── HexLiteral.js
│ │ │ ├── TypedTimeZoneLiteral.js
│ │ │ ├── NumberLiteral.js
│ │ │ ├── AbstractLQJsonLiteral.js
│ │ │ ├── StringLiteral.js
│ │ │ ├── TypedLiteral.js
│ │ │ ├── TypedTimeLiteral.js
│ │ │ ├── TypedTimestampLiteral.js
│ │ │ ├── index.js
│ │ │ ├── PGTypedArrayLiteral.js
│ │ │ └── LQArrayLiteral.js
│ │ ├── op
│ │ │ ├── index.js
│ │ │ ├── InExpr.js
│ │ │ ├── DistinctFromExpr.js
│ │ │ ├── BetweenExpr.js
│ │ │ ├── PGCastExpr2.js
│ │ │ ├── UnaryExpr.js
│ │ │ ├── AtTimeZoneExpr.js
│ │ │ └── BinaryExpr.js
│ │ ├── index.js
│ │ └── Expr.js
│ ├── ddl
│ │ ├── index
│ │ │ ├── index.js
│ │ │ ├── IndexDiff.js
│ │ │ └── IndexSchema.js
│ │ ├── table
│ │ │ ├── index.js
│ │ │ └── TableDiff.js
│ │ ├── column
│ │ │ ├── index.js
│ │ │ └── ColumnDiff.js
│ │ ├── namespace
│ │ │ ├── index.js
│ │ │ ├── SchemaDiff.js
│ │ │ └── NamespaceSchema.js
│ │ ├── ident
│ │ │ ├── NamespaceIdent.js
│ │ │ ├── index.js
│ │ │ ├── ColumnIdent.js
│ │ │ └── TableIdent.js
│ │ ├── constraint
│ │ │ ├── constructs
│ │ │ │ ├── PGIndexParameters.js
│ │ │ │ ├── PGIndexParamUsing.js
│ │ │ │ ├── FKMatchRule.js
│ │ │ │ ├── FKDeleteRule.js
│ │ │ │ ├── FKUpdateRule.js
│ │ │ │ ├── index.js
│ │ │ │ ├── PGIndexParamInclude.js
│ │ │ │ ├── PGIndexParamWith.js
│ │ │ │ ├── ReferentialAction.js
│ │ │ │ └── PGTableEXConstraintItem.js
│ │ │ ├── MYColumnCommentModifier.js
│ │ │ ├── MYColumnVisibilityModifier.js
│ │ │ ├── MYColumnOnUpdateModifier.js
│ │ │ ├── ColumnDefaultConstraint.js
│ │ │ ├── ColumnNullConstraint.js
│ │ │ ├── MYColumnAutoIncrementModifier.js
│ │ │ ├── ColumnPKConstraint.js
│ │ │ ├── TablePKConstraint.js
│ │ │ ├── CheckConstraint.js
│ │ │ ├── index.js
│ │ │ ├── ColumnExpressionConstraint.js
│ │ │ ├── ColumnIdentityConstraint.js
│ │ │ ├── ColumnFKConstraint.js
│ │ │ ├── TableFKConstraint.js
│ │ │ ├── TableUKConstraint.js
│ │ │ ├── ColumnUKConstraint.js
│ │ │ └── PGTableEXConstraint.js
│ │ ├── index.js
│ │ ├── DDLStmt.js
│ │ ├── DropTableStmt.js
│ │ ├── DropSchemaStmt.js
│ │ └── CreateTableStmt.js
│ ├── abstracts
│ │ ├── SugarMixin.js
│ │ ├── AbstractDiff.js
│ │ ├── TypeSysMixin.js
│ │ ├── JSONSchema.js
│ │ ├── AbstractNodeList.js
│ │ ├── AbstractStmt.js
│ │ ├── ResultSchemaMixin.js
│ │ ├── AbstractNonDDLStmt.js
│ │ ├── OriginSchemasMixin.js
│ │ ├── AbstractSchema.js
│ │ └── util.js
│ ├── qualif
│ │ ├── index.js
│ │ ├── LQVersionSpec.js
│ │ └── AggrNotation.js
│ ├── cte
│ │ ├── constructs
│ │ │ ├── index.js
│ │ │ ├── PGSearchClause.js
│ │ │ └── PGCycleClause.js
│ │ ├── index.js
│ │ ├── CTEItemAlias.js
│ │ └── CTE.js
│ ├── dml
│ │ ├── TA
│ │ │ └── index.js
│ │ ├── constructors
│ │ │ ├── index.js
│ │ │ ├── ColumnsConstructor.js
│ │ │ └── ValuesConstructor.js
│ │ ├── expr
│ │ │ ├── KW.js
│ │ │ ├── index.js
│ │ │ ├── MYVarAssignmentExpr.js
│ │ │ ├── AssignmentExpr.js
│ │ │ ├── ConfigAssignmentExpr.js
│ │ │ ├── ConfigAssignmentExprAlt1.js
│ │ │ └── ConfigAssignmentExprAlt2.js
│ │ ├── clauses
│ │ │ ├── ReturningClause.js
│ │ │ ├── PGDefaultValuesClause.js
│ │ │ ├── UsingFromClause.js
│ │ │ ├── SetClause.js
│ │ │ ├── ColumnsSpec.js
│ │ │ ├── ValuesClause.js
│ │ │ ├── MYPartitionClause.js
│ │ │ ├── PGWhereCurrentClause.js
│ │ │ ├── index.js
│ │ │ ├── MYOnDuplicateKeyUpdateClause.js
│ │ │ ├── PGConflictTargetIndexSpec.js
│ │ │ ├── PGConflictTarget.js
│ │ │ └── PGOnConflictClause.js
│ │ ├── index.js
│ │ ├── MYSetStmt.js
│ │ ├── PGSetStmt.js
│ │ └── DMLStmt.js
│ ├── dql
│ │ ├── clauses
│ │ │ ├── FieldsSpec.js
│ │ │ ├── Field.js
│ │ │ ├── OnClause.js
│ │ │ ├── WhereClause.js
│ │ │ ├── FromClause.js
│ │ │ ├── HavingClause.js
│ │ │ ├── WindowClause.js
│ │ │ ├── PGOrderOperator.js
│ │ │ ├── WindowDeclaration.js
│ │ │ ├── PartitionByClause.js
│ │ │ ├── OffsetClause.js
│ │ │ ├── UsingClause.js
│ │ │ ├── OrderByClause.js
│ │ │ ├── OrderElement.js
│ │ │ ├── WindowSpec.js
│ │ │ ├── WindowFrameBound.js
│ │ │ ├── GroupByClause.js
│ │ │ ├── DistinctClause.js
│ │ │ ├── index.js
│ │ │ ├── PGFetchClause.js
│ │ │ ├── LimitClause.js
│ │ │ ├── GroupingElement.js
│ │ │ └── WindowFrameSpec.js
│ │ ├── TA
│ │ │ ├── ValuesTableLiteral.js
│ │ │ ├── index.js
│ │ │ ├── SRFExprDDL1.js
│ │ │ ├── SRFExprDDL2.js
│ │ │ ├── SelectItemAlias.js
│ │ │ ├── FromItemAlias.js
│ │ │ └── SRFExpr1.js
│ │ ├── index.js
│ │ ├── CompleteSelectStmt.js
│ │ └── TableStmt.js
│ ├── index.js
│ └── Script.js
├── index.js
├── flashql
│ ├── fetch
│ │ ├── FlashRequest.js
│ │ └── AbstractFetchClient.js
│ └── ConflictError.js
└── entry
│ ├── Result.js
│ └── abstracts
│ ├── Spawnable.js
│ └── SimpleEmitter.js
├── site
├── .vitepress
│ ├── cache
│ │ └── deps
│ │ │ ├── package.json
│ │ │ ├── vue.js.map
│ │ │ ├── vitepress___@vueuse_core.js.map
│ │ │ └── _metadata.json
│ ├── dist
│ │ ├── img
│ │ │ └── brand
│ │ │ │ ├── linked-ql-logo.png
│ │ │ │ ├── linked-ql-main.png
│ │ │ │ ├── linked-ql-min.png
│ │ │ │ ├── linked-ql-min2.png
│ │ │ │ └── linked-ql-main2.png
│ │ ├── assets
│ │ │ ├── inter-italic-greek.DJ8dCoTZ.woff2
│ │ │ ├── inter-italic-latin.C2AdPX0b.woff2
│ │ │ ├── inter-roman-greek.BBVDIX6e.woff2
│ │ │ ├── inter-roman-latin.Di8DUHzh.woff2
│ │ │ ├── inter-italic-cyrillic.By2_1cv3.woff2
│ │ │ ├── inter-roman-cyrillic.C5lxZ8CY.woff2
│ │ │ ├── inter-roman-greek-ext.CqjqNYQ-.woff2
│ │ │ ├── inter-roman-latin-ext.4ZJIpNVo.woff2
│ │ │ ├── inter-italic-greek-ext.1u6EdAuj.woff2
│ │ │ ├── inter-italic-latin-ext.CN1xVJS-.woff2
│ │ │ ├── inter-italic-vietnamese.BSbpV94h.woff2
│ │ │ ├── inter-roman-vietnamese.BjW4sHH5.woff2
│ │ │ ├── inter-italic-cyrillic-ext.r48I6akx.woff2
│ │ │ ├── inter-roman-cyrillic-ext.BBPuwvHQ.woff2
│ │ │ ├── flashql.md.dxGRqIGO.lean.js
│ │ │ ├── docs.md.CwIgAZwB.lean.js
│ │ │ ├── docs_setup.md.xW8pIM-m.lean.js
│ │ │ ├── capabilities.md.BztTe5GT.lean.js
│ │ │ ├── flashql_lang.md.-dKEfD4V.lean.js
│ │ │ ├── docs_query-api.md.Bm8hN7oZ.lean.js
│ │ │ ├── capabilities_upsert.md.hDNJkkyH.lean.js
│ │ │ ├── overview.md.CIcdfHfj.lean.js
│ │ │ ├── capabilities_deeprefs.md.CYOx2SXL.lean.js
│ │ │ ├── flashql_foreign-io.md.B-X4SFru.lean.js
│ │ │ ├── capabilities_live-queries.md.CHhoCYV3.lean.js
│ │ │ ├── capabilities_json-literals.md.rGE9X-tr.lean.js
│ │ │ ├── app.Ds4M_nwI.js
│ │ │ ├── index.md.BsUu5Xl8.js
│ │ │ └── index.md.BsUu5Xl8.lean.js
│ │ ├── hashmap.json
│ │ └── vp-icons.css
│ └── theme
│ │ ├── index.ts
│ │ └── custom.css
├── public
│ └── img
│ │ └── brand
│ │ ├── linked-ql-min.png
│ │ ├── linked-ql-logo.png
│ │ ├── linked-ql-main.png
│ │ ├── linked-ql-main2.png
│ │ └── linked-ql-min2.png
└── index.md
├── resources
├── linked-ql-logo-2.af
├── linked-ql-logo.af
├── linked-ql-logo.png
├── linked-ql-main.png
├── linked-ql-main2.png
├── linked-ql-min.png
├── linked-ql-min2.png
├── linked-ql-main-a.png
├── linked-ql-main-b.png
├── linked-ql-main-c.png
├── linked-ql-mobile.png
├── linked-ql-mobile2.png
├── linked-ql-logo.afdesign
├── linked-ql-main.afdesign
├── linked-ql-main2.afdesign
├── linked-ql-min.afdesign
├── linked-ql-min2.afdesign
├── linked-ql-mobile-a.png
├── linked-ql-mobile.afdesign
└── linked-ql-mobile2.afdesign
├── .gitignore
├── .eslintrc.yml
├── test
├── 00.live 2.js
└── 00.live.js
├── .github
├── FUNDING.yml
└── workflows
│ └── publish.yml
└── LICENSE
/src/lang/type/index.js:
--------------------------------------------------------------------------------
1 | export { DataType } from './DataType.js';
2 |
--------------------------------------------------------------------------------
/src/lang/registry.js:
--------------------------------------------------------------------------------
1 | export const registry = Object.create(null);
2 |
--------------------------------------------------------------------------------
/site/.vitepress/cache/deps/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module"
3 | }
4 |
--------------------------------------------------------------------------------
/src/lang/expr/ref/abstracts/ErrorRefUnknown.js:
--------------------------------------------------------------------------------
1 | export class ErrorRefUnknown extends Error {}
--------------------------------------------------------------------------------
/src/lang/expr/ref/abstracts/ErrorRefAmbiguous.js:
--------------------------------------------------------------------------------
1 | export class ErrorRefAmbiguous extends Error {}
--------------------------------------------------------------------------------
/resources/linked-ql-logo-2.af:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-logo-2.af
--------------------------------------------------------------------------------
/resources/linked-ql-logo.af:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-logo.af
--------------------------------------------------------------------------------
/resources/linked-ql-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-logo.png
--------------------------------------------------------------------------------
/resources/linked-ql-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-main.png
--------------------------------------------------------------------------------
/resources/linked-ql-main2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-main2.png
--------------------------------------------------------------------------------
/resources/linked-ql-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-min.png
--------------------------------------------------------------------------------
/resources/linked-ql-min2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-min2.png
--------------------------------------------------------------------------------
/resources/linked-ql-main-a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-main-a.png
--------------------------------------------------------------------------------
/resources/linked-ql-main-b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-main-b.png
--------------------------------------------------------------------------------
/resources/linked-ql-main-c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-main-c.png
--------------------------------------------------------------------------------
/resources/linked-ql-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-mobile.png
--------------------------------------------------------------------------------
/resources/linked-ql-mobile2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-mobile2.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .*
2 | !/.github
3 | !.vitepress
4 | !/.gitignore
5 | !.eslintrc.yml
6 | coverage
7 | demo
8 | node_modules
9 |
--------------------------------------------------------------------------------
/resources/linked-ql-logo.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-logo.afdesign
--------------------------------------------------------------------------------
/resources/linked-ql-main.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-main.afdesign
--------------------------------------------------------------------------------
/resources/linked-ql-main2.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-main2.afdesign
--------------------------------------------------------------------------------
/resources/linked-ql-min.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-min.afdesign
--------------------------------------------------------------------------------
/resources/linked-ql-min2.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-min2.afdesign
--------------------------------------------------------------------------------
/resources/linked-ql-mobile-a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-mobile-a.png
--------------------------------------------------------------------------------
/src/lang/expr/case/index.js:
--------------------------------------------------------------------------------
1 | export { CaseExpr } from './CaseExpr.js';
2 | export { CaseBranch } from './CaseBranch.js';
3 |
--------------------------------------------------------------------------------
/resources/linked-ql-mobile.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-mobile.afdesign
--------------------------------------------------------------------------------
/resources/linked-ql-mobile2.afdesign:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/resources/linked-ql-mobile2.afdesign
--------------------------------------------------------------------------------
/src/lang/ddl/index/index.js:
--------------------------------------------------------------------------------
1 | export { IndexDiff } from './IndexDiff.js';
2 | export { IndexSchema } from './IndexSchema.js';
3 |
--------------------------------------------------------------------------------
/src/lang/ddl/table/index.js:
--------------------------------------------------------------------------------
1 | export { TableDiff } from './TableDiff.js';
2 | export { TableSchema } from './TableSchema.js';
3 |
--------------------------------------------------------------------------------
/site/public/img/brand/linked-ql-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/public/img/brand/linked-ql-min.png
--------------------------------------------------------------------------------
/src/lang/abstracts/SugarMixin.js:
--------------------------------------------------------------------------------
1 | export const SugarMixin = Class => class extends Class {
2 | get isSugar() { return true; }
3 | }
--------------------------------------------------------------------------------
/src/lang/ddl/column/index.js:
--------------------------------------------------------------------------------
1 | export { ColumnDiff } from './ColumnDiff.js';
2 | export { ColumnSchema } from './ColumnSchema.js';
3 |
--------------------------------------------------------------------------------
/site/public/img/brand/linked-ql-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/public/img/brand/linked-ql-logo.png
--------------------------------------------------------------------------------
/site/public/img/brand/linked-ql-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/public/img/brand/linked-ql-main.png
--------------------------------------------------------------------------------
/site/public/img/brand/linked-ql-main2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/public/img/brand/linked-ql-main2.png
--------------------------------------------------------------------------------
/site/public/img/brand/linked-ql-min2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/public/img/brand/linked-ql-min2.png
--------------------------------------------------------------------------------
/src/lang/qualif/index.js:
--------------------------------------------------------------------------------
1 | export { AggrNotation } from './AggrNotation.js';
2 | export { LQVersionSpec } from './LQVersionSpec.js';
3 |
--------------------------------------------------------------------------------
/src/lang/ddl/namespace/index.js:
--------------------------------------------------------------------------------
1 | export { SchemaDiff } from './SchemaDiff.js';
2 | export { NamespaceSchema } from './NamespaceSchema.js';
3 |
--------------------------------------------------------------------------------
/src/lang/cte/constructs/index.js:
--------------------------------------------------------------------------------
1 | export { PGCycleClause } from './PGCycleClause.js';
2 | export { PGSearchClause } from './PGSearchClause.js';
3 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/img/brand/linked-ql-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/img/brand/linked-ql-logo.png
--------------------------------------------------------------------------------
/site/.vitepress/dist/img/brand/linked-ql-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/img/brand/linked-ql-main.png
--------------------------------------------------------------------------------
/site/.vitepress/dist/img/brand/linked-ql-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/img/brand/linked-ql-min.png
--------------------------------------------------------------------------------
/site/.vitepress/dist/img/brand/linked-ql-min2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/img/brand/linked-ql-min2.png
--------------------------------------------------------------------------------
/src/lang/ddl/column/ColumnDiff.js:
--------------------------------------------------------------------------------
1 | import { AbstractDiff } from '../../abstracts/AbstractDiff.js';
2 |
3 | export class ColumnDiff extends AbstractDiff {}
--------------------------------------------------------------------------------
/src/lang/ddl/index/IndexDiff.js:
--------------------------------------------------------------------------------
1 | import { AbstractDiff } from '../../abstracts/AbstractDiff.js';
2 |
3 | export class IndexDiff extends AbstractDiff {}
--------------------------------------------------------------------------------
/src/lang/ddl/table/TableDiff.js:
--------------------------------------------------------------------------------
1 | import { AbstractDiff } from '../../abstracts/AbstractDiff.js';
2 |
3 | export class TableDiff extends AbstractDiff {}
--------------------------------------------------------------------------------
/src/lang/dml/TA/index.js:
--------------------------------------------------------------------------------
1 | export { TableAbstraction2 } from './TableAbstraction2.js';
2 | export { TableAbstraction1 } from './TableAbstraction1.js';
3 |
--------------------------------------------------------------------------------
/site/.vitepress/cache/deps/vue.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "sources": [],
4 | "sourcesContent": [],
5 | "mappings": "",
6 | "names": []
7 | }
8 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/img/brand/linked-ql-main2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/img/brand/linked-ql-main2.png
--------------------------------------------------------------------------------
/src/lang/ddl/ident/NamespaceIdent.js:
--------------------------------------------------------------------------------
1 | import { Identifier } from '../../expr/ref/Identifier.js';
2 |
3 | export class NamespaceIdent extends Identifier {}
4 |
--------------------------------------------------------------------------------
/src/lang/ddl/namespace/SchemaDiff.js:
--------------------------------------------------------------------------------
1 | import { AbstractDiff } from '../../abstracts/AbstractDiff.js';
2 |
3 | export class SchemaDiff extends AbstractDiff {}
--------------------------------------------------------------------------------
/site/.vitepress/theme/index.ts:
--------------------------------------------------------------------------------
1 | import DefaultTheme from 'vitepress/theme'
2 | import './custom.css'
3 |
4 | export default {
5 | extends: DefaultTheme
6 | }
7 |
--------------------------------------------------------------------------------
/src/lang/expr/var/index.js:
--------------------------------------------------------------------------------
1 | export { BindVar } from './BindVar.js';
2 | export { SystemVar } from './SystemVar.js';
3 | export { UserVar } from './UserVar.js';
4 |
--------------------------------------------------------------------------------
/src/lang/dml/constructors/index.js:
--------------------------------------------------------------------------------
1 | export { ColumnsConstructor } from './ColumnsConstructor.js';
2 | export { ValuesConstructor } from './ValuesConstructor.js';
3 |
--------------------------------------------------------------------------------
/src/lang/expr/call/constructs/index.js:
--------------------------------------------------------------------------------
1 | export { PGFilterClause } from './PGFilterClause.js';
2 | export { PGWithinGroupClause } from './PGWithinGroupClause.js';
3 |
--------------------------------------------------------------------------------
/src/lang/expr/call/index.js:
--------------------------------------------------------------------------------
1 | export * from './constructs/index.js';
2 | export { AggrCallExpr } from './AggrCallExpr.js';
3 | export { CallExpr } from './CallExpr.js';
4 |
--------------------------------------------------------------------------------
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | env:
2 | browser: true
3 | es2021: true
4 | extends: 'eslint:recommended'
5 | parserOptions:
6 | ecmaVersion: 12
7 | sourceType: module
8 | rules: {}
9 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2
--------------------------------------------------------------------------------
/site/.vitepress/cache/deps/vitepress___@vueuse_core.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "sources": [],
4 | "sourcesContent": [],
5 | "mappings": "",
6 | "names": []
7 | }
8 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2
--------------------------------------------------------------------------------
/src/lang/abstracts/AbstractDiff.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from './AbstractNodeList.js';
2 |
3 | export class AbstractDiff extends AbstractNodeList {
4 |
5 | /* AST API */
6 | }
--------------------------------------------------------------------------------
/src/lang/ddl/ident/index.js:
--------------------------------------------------------------------------------
1 | export { ColumnIdent } from './ColumnIdent.js';
2 | export { NamespaceIdent } from './NamespaceIdent.js';
3 | export { TableIdent } from './TableIdent.js';
4 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linked-db/linked-ql/HEAD/site/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import './lang/index.js';
2 | import { FlashQL } from './flashql/FlashQL.js';
3 | import { Script } from './lang/Script.js';
4 |
5 | export { FlashQL }
6 | export { Script };
7 |
--------------------------------------------------------------------------------
/src/lang/expr/ref/TableRef2.js:
--------------------------------------------------------------------------------
1 | import { TableRef1 } from './TableRef1.js';
2 |
3 | export class TableRef2 extends TableRef1 {
4 |
5 | canReferenceInlineTables() { return false; }
6 | }
--------------------------------------------------------------------------------
/src/lang/cte/index.js:
--------------------------------------------------------------------------------
1 | export * from './constructs/index.js';
2 | export { CTE } from './CTE.js';
3 | export { CTEItem } from './CTEItem.js';
4 | export { CTEItemAlias } from './CTEItemAlias.js';
5 |
--------------------------------------------------------------------------------
/src/lang/expr/ref/abstracts/ErrorFKInvalid.js:
--------------------------------------------------------------------------------
1 | export class ErrorFKInvalid extends Error {
2 |
3 | constructor(message) {
4 | super(message);
5 | this.name = 'ErrorFKInvalid';
6 | }
7 |
8 | }
--------------------------------------------------------------------------------
/src/flashql/fetch/FlashRequest.js:
--------------------------------------------------------------------------------
1 | import { JSONSchema } from '../../lang/abstracts/JSONSchema.js';
2 |
3 | export class FlashRequest extends Request {
4 | resultSchema() {
5 | return new JSONSchema
6 | }
7 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/WindowRef.js:
--------------------------------------------------------------------------------
1 | import { Identifier } from './Identifier.js';
2 |
3 | export class WindowRef extends Identifier {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxPriority() { return -1; }
8 | }
--------------------------------------------------------------------------------
/src/lang/abstracts/TypeSysMixin.js:
--------------------------------------------------------------------------------
1 | import { registry } from '../registry.js';
2 |
3 | export const TypeSysMixin = (Class) => class extends Class {
4 |
5 | dataType() { return registry.DataType.fromJSON({ value: 'TEXT' }); };
6 | }
--------------------------------------------------------------------------------
/src/lang/expr/AbstractClassicExpr.js:
--------------------------------------------------------------------------------
1 | import { TypeSysMixin } from '../abstracts/TypeSysMixin.js';
2 | import { AbstractNode } from '../abstracts/AbstractNode.js';
3 |
4 | export class AbstractClassicExpr extends TypeSysMixin(AbstractNode) {}
--------------------------------------------------------------------------------
/src/lang/expr/etc/index.js:
--------------------------------------------------------------------------------
1 | export { CastExpr } from './CastExpr.js';
2 | export { ExtractExpr } from './ExtractExpr.js';
3 | export { PredicateExpr } from './PredicateExpr.js';
4 | export { QuantitativeExpr } from './QuantitativeExpr.js';
5 |
--------------------------------------------------------------------------------
/src/lang/expr/abstraction/index.js:
--------------------------------------------------------------------------------
1 | export { ParenExpr } from './ParenExpr.js';
2 | export { RowConstructor } from './RowConstructor.js';
3 | export { ScalarSubquery } from './ScalarSubquery.js';
4 | export { TypedRowConstructor } from './TypedRowConstructor.js';
5 |
--------------------------------------------------------------------------------
/src/lang/dql/clauses/FieldsSpec.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../expr/abstracts/AbstractNodeList.js';
2 | import { Field } from './Field.js';
3 |
4 | export class FieldsSpec extends AbstractNodeList {
5 | static get EXPECTED_TYPES() { return [Field]; }
6 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/NullLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 |
3 | export class NullLiteral extends AbstractLiteral {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'null_literal', as: '.' }; }
8 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/Field.js:
--------------------------------------------------------------------------------
1 | import { AbstractAliasableExpr } from '../../expr/abstracts/AbstractAliasableExpr.js';
2 | import { Exprs } from '../../expr/grammar.js';
3 |
4 | export class Field extends AbstractAliasableExpr {
5 | static get EXPECTED_TYPES() { return Exprs; }
6 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/UnknownLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 |
3 | export class UnknownLiteral extends AbstractLiteral {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'unknown_literal', as: '.' }; }
8 | }
--------------------------------------------------------------------------------
/src/flashql/ConflictError.js:
--------------------------------------------------------------------------------
1 | export class ConflictError extends Error {
2 |
3 | #existing;
4 | get existing() { return this.#existing; }
5 |
6 | constructor(message, existing) {
7 | super(message);
8 | this.#existing = existing;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/lang/expr/literals/DefaultLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 |
3 | export class DefaultLiteral extends AbstractLiteral {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'keyword', as: '.', value: 'DEFAULT' }; }
8 | }
--------------------------------------------------------------------------------
/src/lang/ddl/ident/ColumnIdent.js:
--------------------------------------------------------------------------------
1 | import { PathMixin } from '../../abstracts/PathMixin.js';
2 | import { Identifier } from '../../expr/index.js';
3 |
4 | export class ColumnIdent extends PathMixin(Identifier) {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _qualifierType() { return 'TableRef2'; }
9 | }
--------------------------------------------------------------------------------
/src/lang/ddl/ident/TableIdent.js:
--------------------------------------------------------------------------------
1 | import { PathMixin } from '../../abstracts/PathMixin.js';
2 | import { Identifier } from '../../expr/index.js';
3 |
4 | export class TableIdent extends PathMixin(Identifier) {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _qualifierType() { return 'NamespaceRef'; }
9 | }
--------------------------------------------------------------------------------
/src/lang/dml/expr/KW.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class KW extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'keyword', as: '.' }; }
8 |
9 | /* AST API */
10 |
11 | value() { return this._get('value'); }
12 | }
--------------------------------------------------------------------------------
/src/lang/expr/var/BindVar.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 |
3 | export class BindVar extends AbstractClassicExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'bind_var', as: '.' }; }
8 |
9 | /* AST API */
10 |
11 | value() { return this._get('value'); }
12 | }
--------------------------------------------------------------------------------
/src/lang/ddl/index/IndexSchema.js:
--------------------------------------------------------------------------------
1 | import { AbstractSchema } from '../../abstracts/AbstractSchema.js';
2 |
3 | export class IndexSchema extends AbstractSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'Identifier', as: 'name', assert: true },
10 | ];
11 | }
12 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/AbstractLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 |
3 | export class AbstractLiteral extends AbstractClassicExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxPriority() { return 49; }
8 |
9 | /* AST API */
10 |
11 | value() { return this._get('value'); }
12 | }
--------------------------------------------------------------------------------
/src/lang/expr/var/UserVar.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 |
3 | export class UserVar extends AbstractClassicExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'user_var', as: '.' }; }
8 |
9 | /* AST API */
10 |
11 | value() { return this._get('value'); }
12 | }
--------------------------------------------------------------------------------
/src/lang/expr/var/SystemVar.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 |
3 | export class SystemVar extends AbstractClassicExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'system_var', as: '.' }; }
8 |
9 | /* AST API */
10 |
11 | value() { return this._get('value'); }
12 | }
--------------------------------------------------------------------------------
/src/lang/dql/TA/ValuesTableLiteral.js:
--------------------------------------------------------------------------------
1 | import { ValuesConstructor } from '../../dml/constructors/ValuesConstructor.js';
2 |
3 | export class ValuesTableLiteral extends ValuesConstructor {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return { type: 'paren_block', syntax: super.syntaxRules, autoIndent: true };
9 | }
10 | }
--------------------------------------------------------------------------------
/src/lang/dql/index.js:
--------------------------------------------------------------------------------
1 | export * from './clauses/index.js';
2 | export * from './TA/index.js';
3 | export { CompleteSelectStmt } from './CompleteSelectStmt.js';
4 | export { BasicSelectStmt } from './BasicSelectStmt.js';
5 | export { CompositeSelectStmt } from './CompositeSelectStmt.js';
6 | export { SelectStmt } from './SelectStmt.js';
7 | export { TableStmt } from './TableStmt.js';
8 |
--------------------------------------------------------------------------------
/src/entry/Result.js:
--------------------------------------------------------------------------------
1 | export class Result {
2 |
3 | #rows
4 | #rowCount
5 |
6 | get rows() { return this.#rows; }
7 | get rowCount() { return this.#rowCount; }
8 | get affectedRows() { return this.#rowCount; }
9 |
10 | constructor({ rows = [], rowCount = 0 } = {}) {
11 | this.#rows = rows;
12 | this.#rowCount = rowCount;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/lang/expr/op/index.js:
--------------------------------------------------------------------------------
1 | export { AtTimeZoneExpr } from './AtTimeZoneExpr.js';
2 | export { BetweenExpr } from './BetweenExpr.js';
3 | export { BinaryExpr } from './BinaryExpr.js';
4 | export { DistinctFromExpr } from './DistinctFromExpr.js';
5 | export { InExpr } from './InExpr.js';
6 | export { PGCastExpr2 } from './PGCastExpr2.js';
7 | export { UnaryExpr } from './UnaryExpr.js';
8 |
--------------------------------------------------------------------------------
/src/lang/dml/clauses/ReturningClause.js:
--------------------------------------------------------------------------------
1 | import { SelectList } from '../../dql/clauses/SelectList.js';
2 |
3 | export class ReturningClause extends SelectList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'RETURNING' },
10 | ...[].concat(super.syntaxRules),
11 | ];
12 | }
13 | }
--------------------------------------------------------------------------------
/src/lang/abstracts/JSONSchema.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from './AbstractNodeList.js';
2 |
3 | export class JSONSchema extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return { type: ['JSONSchema', 'TableSchema', 'ColumnSchema', 'ColumnRef1'/* result of resolving ColumnRef0 */], as: 'entries', arity: Infinity };
9 | }
10 | }
--------------------------------------------------------------------------------
/src/lang/dml/expr/index.js:
--------------------------------------------------------------------------------
1 | export { AssignmentExpr } from './AssignmentExpr.js';
2 | export { ConfigAssignmentExpr } from './ConfigAssignmentExpr.js';
3 | export { ConfigAssignmentExprAlt1 } from './ConfigAssignmentExprAlt1.js';
4 | export { ConfigAssignmentExprAlt2 } from './ConfigAssignmentExprAlt2.js';
5 | export { MYVarAssignmentExpr } from './MYVarAssignmentExpr.js';
6 | export { KW } from './KW.js';
7 |
--------------------------------------------------------------------------------
/src/lang/expr/literals/TypedDateLiteral.js:
--------------------------------------------------------------------------------
1 | import { TypedLiteral } from './TypedLiteral.js';
2 |
3 | export class TypedDateLiteral extends TypedLiteral {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'data_type', as: 'data_type', value: 'DATE' },
10 | { type: 'string_literal', as: 'value' },
11 | ];
12 | }
13 | }
--------------------------------------------------------------------------------
/src/lang/qualif/LQVersionSpec.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../abstracts/AbstractNode.js';
2 |
3 | export class LQVersionSpec extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return { type: 'version_spec', as: '.' }; }
8 |
9 | static get syntaxPriority() { return -1; }
10 |
11 | /* AST API */
12 |
13 | value() { return this._get('value'); }
14 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/flashql.md.dxGRqIGO.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as n,o as l,ag as e}from"./chunks/framework.B-XtCDNB.js";const d=JSON.parse('{"title":"FlashQL","description":"","frontmatter":{},"headers":[],"relativePath":"flashql.md","filePath":"flashql.md"}'),p={name:"flashql.md"};function o(t,s,r,c,i,y){return l(),n("div",null,[...s[0]||(s[0]=[e("",46)])])}const F=a(p,[["render",o]]);export{d as __pageData,F as default};
2 |
--------------------------------------------------------------------------------
/src/lang/qualif/AggrNotation.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../abstracts/AbstractNode.js';
2 |
3 | export class AggrNotation extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | type: 'bracket_block', syntax: { type: 'Expr', as: '_', arity: 0, assert: true }
10 | };
11 | }
12 |
13 | static get syntaxPriority() { return -1; }
14 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/docs.md.CwIgAZwB.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as n,o as e,ag as l}from"./chunks/framework.B-XtCDNB.js";const D=JSON.parse('{"title":"Getting Started with LinkedQL","description":"","frontmatter":{},"headers":[],"relativePath":"docs.md","filePath":"docs.md"}'),t={name:"docs.md"};function o(p,s,r,i,c,d){return e(),n("div",null,[...s[0]||(s[0]=[l("",28)])])}const F=a(t,[["render",o]]);export{D as __pageData,F as default};
2 |
--------------------------------------------------------------------------------
/src/lang/expr/literals/BitLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class BitLiteral extends AbstractLiteral {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: 'bit_literal', as: '.' }; }
9 |
10 | /* TYPESYS API */
11 |
12 | dataType() { return registry.DataType.fromJSON({ value: 'BINARY' }); }
13 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/BoolLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class BoolLiteral extends AbstractLiteral {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: 'bool_literal', as: '.' }; }
9 |
10 | /* TYPESYS API */
11 |
12 | dataType() { return registry.DataType.fromJSON({ value: 'BOOLEAN' }); }
13 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/HexLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class HexLiteral extends AbstractLiteral {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: 'hex_literal', as: '.' }; }
9 |
10 | /* TYPESYS API */
11 |
12 | dataType() { return registry.DataType.fromJSON({ value: 'BINARY' }); }
13 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/TypedTimeZoneLiteral.js:
--------------------------------------------------------------------------------
1 | import { TypedLiteral } from './TypedLiteral.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class TypedTimeZoneLiteral extends TypedLiteral {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return [
10 | { type: 'keyword', value: 'TIME ZONE' },
11 | { type: 'Expr', as: 'value' },
12 | ];
13 | }
14 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/NumberLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class NumberLiteral extends AbstractLiteral {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: 'number_literal', as: '.' }; }
9 |
10 | /* TYPESYS API */
11 |
12 | dataType() { return registry.DataType.fromJSON({ value: 'INT' }); }
13 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/docs_setup.md.xW8pIM-m.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as l,o as n,ag as t}from"./chunks/framework.B-XtCDNB.js";const F=JSON.parse('{"title":"Dialects & Clients","description":"","frontmatter":{},"headers":[],"relativePath":"docs/setup.md","filePath":"docs/setup.md"}'),e={name:"docs/setup.md"};function o(p,s,c,r,i,y){return n(),l("div",null,[...s[0]||(s[0]=[t("",38)])])}const d=a(e,[["render",o]]);export{F as __pageData,d as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/capabilities.md.BztTe5GT.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as n,o as l,ag as e}from"./chunks/framework.B-XtCDNB.js";const F=JSON.parse('{"title":"Capabilities Overview","description":"","frontmatter":{},"headers":[],"relativePath":"capabilities.md","filePath":"capabilities.md"}'),t={name:"capabilities.md"};function o(p,s,r,c,i,y){return l(),n("div",null,[...s[0]||(s[0]=[e("",32)])])}const d=a(t,[["render",o]]);export{F as __pageData,d as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/flashql_lang.md.-dKEfD4V.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as e,c as d,o as l,ag as n}from"./chunks/framework.B-XtCDNB.js";const x=JSON.parse('{"title":"Language Reference","description":"","frontmatter":{},"headers":[],"relativePath":"flashql/lang.md","filePath":"flashql/lang.md"}'),a={name:"flashql/lang.md"};function c(i,t,s,r,o,g){return l(),d("div",null,[...t[0]||(t[0]=[n("",17)])])}const f=e(a,[["render",c]]);export{x as __pageData,f as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/docs_query-api.md.Bm8hN7oZ.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as e,o as n,ag as t}from"./chunks/framework.B-XtCDNB.js";const D=JSON.parse('{"title":"Query Interface","description":"","frontmatter":{},"headers":[],"relativePath":"docs/query-api.md","filePath":"docs/query-api.md"}'),l={name:"docs/query-api.md"};function o(p,s,r,c,i,y){return n(),e("div",null,[...s[0]||(s[0]=[t("",46)])])}const F=a(l,[["render",o]]);export{D as __pageData,F as default};
2 |
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/PGIndexParameters.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../../abstracts/AbstractNodeList.js';
2 |
3 | export class PGIndexParameters extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: ['PGIndexParamInclude', 'PGIndexParamUsing', 'PGIndexParamWith'], as: 'entries', arity: Infinity, singletons: true },
10 | ];
11 | }
12 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/OnClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class OnClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'ON' },
10 | { type: 'Expr', as: 'expr', assert: true }
11 | ];
12 | }
13 |
14 | /* AST API */
15 |
16 | expr() { return this._get('expr'); }
17 | }
--------------------------------------------------------------------------------
/src/lang/dml/expr/MYVarAssignmentExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from '../../expr/op/BinaryExpr.js';
2 |
3 | export class MYVarAssignmentExpr extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: ['UserVar', 'SystemVar'], as: 'left' },
10 | { type: 'operator', as: 'operator', value: ['=', ':='] },
11 | { type: 'Expr', as: 'right' },
12 | ];
13 | }
14 | }
--------------------------------------------------------------------------------
/src/lang/expr/abstraction/TypedRowConstructor.js:
--------------------------------------------------------------------------------
1 | import { RowConstructor } from './RowConstructor.js';
2 |
3 | export class TypedRowConstructor extends RowConstructor {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'ROW' },
10 | ...[].concat(super.syntaxRules)
11 | ];
12 | }
13 |
14 | static get syntaxPriority() { return 52; } // Above CallExpr
15 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/capabilities_upsert.md.hDNJkkyH.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as e,o as n,ag as l}from"./chunks/framework.B-XtCDNB.js";const D=JSON.parse('{"title":"UPSERT","description":"","frontmatter":{},"headers":[],"relativePath":"capabilities/upsert.md","filePath":"capabilities/upsert.md"}'),o={name:"capabilities/upsert.md"};function p(t,s,c,r,i,y){return n(),e("div",null,[...s[0]||(s[0]=[l("",32)])])}const u=a(o,[["render",p]]);export{D as __pageData,u as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/overview.md.CIcdfHfj.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as e,c as a,o as i,ag as n}from"./chunks/framework.B-XtCDNB.js";const p=JSON.parse('{"title":"LinkedQL — A Modern Take on SQL and SQL Databases","description":"","frontmatter":{},"headers":[],"relativePath":"overview.md","filePath":"overview.md"}'),r={name:"overview.md"};function s(l,t,o,d,h,g){return i(),a("div",null,[...t[0]||(t[0]=[n("",19)])])}const f=e(r,[["render",s]]);export{p as __pageData,f as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/hashmap.json:
--------------------------------------------------------------------------------
1 | {"capabilities.md":"BztTe5GT","capabilities_deeprefs.md":"CYOx2SXL","capabilities_json-literals.md":"rGE9X-tr","capabilities_live-queries.md":"CHhoCYV3","capabilities_upsert.md":"hDNJkkyH","docs.md":"CwIgAZwB","docs_query-api.md":"Bm8hN7oZ","docs_setup.md":"xW8pIM-m","engineering_realtime-engine.md":"DjOtRGtl","flashql.md":"dxGRqIGO","flashql_foreign-io.md":"B-X4SFru","flashql_lang.md":"-dKEfD4V","index.md":"BsUu5Xl8","overview.md":"CIcdfHfj"}
2 |
--------------------------------------------------------------------------------
/src/lang/dml/index.js:
--------------------------------------------------------------------------------
1 | export * from './clauses/index.js';
2 | export * from './constructors/index.js';
3 | export * from './expr/index.js';
4 | export * from './TA/index.js';
5 | export { DeleteStmt } from './DeleteStmt.js';
6 | export { InsertStmt } from './InsertStmt.js';
7 | export { MYSetStmt } from './MYSetStmt.js';
8 | export { PGSetStmt } from './PGSetStmt.js';
9 | export { UpdateStmt } from './UpdateStmt.js';
10 | export { UpsertStmt } from './UpsertStmt.js';
11 |
--------------------------------------------------------------------------------
/src/lang/dql/clauses/WhereClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class WhereClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'WHERE' },
10 | { type: 'Expr', as: 'expr', assert: true }
11 | ];
12 | }
13 |
14 | /* AST API */
15 |
16 | expr() { return this._get('expr'); }
17 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/AbstractLQJsonLiteral.js:
--------------------------------------------------------------------------------
1 | import { SugarMixin } from '../../abstracts/SugarMixin.js';
2 | import { TypeSysMixin } from '../../abstracts/TypeSysMixin.js';
3 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
4 | import { registry } from '../../registry.js';
5 |
6 | export class AbstractLQJsonLiteral extends SugarMixin(TypeSysMixin(AbstractNodeList)) {
7 |
8 | dataType() { return registry.DataType.fromJSON({ value: 'JSON' }); }
9 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/capabilities_deeprefs.md.CYOx2SXL.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as n,o as e,ag as l}from"./chunks/framework.B-XtCDNB.js";const B=JSON.parse('{"title":"DeepRefs","description":"","frontmatter":{},"headers":[],"relativePath":"capabilities/deeprefs.md","filePath":"capabilities/deeprefs.md"}'),o={name:"capabilities/deeprefs.md"};function p(t,s,c,r,i,y){return e(),n("div",null,[...s[0]||(s[0]=[l("",196)])])}const C=a(o,[["render",p]]);export{B as __pageData,C as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/flashql_foreign-io.md.B-X4SFru.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as n,o as l,ag as p}from"./chunks/framework.B-XtCDNB.js";const y=JSON.parse('{"title":"Federation & Sync (Alpha)","description":"","frontmatter":{},"headers":[],"relativePath":"flashql/foreign-io.md","filePath":"flashql/foreign-io.md"}'),o={name:"flashql/foreign-io.md"};function e(t,s,c,r,i,D){return l(),n("div",null,[...s[0]||(s[0]=[p("",39)])])}const d=a(o,[["render",e]]);export{y as __pageData,d as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/capabilities_live-queries.md.CHhoCYV3.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as n,o as e,ag as l}from"./chunks/framework.B-XtCDNB.js";const F=JSON.parse('{"title":"Live Queries","description":"","frontmatter":{},"headers":[],"relativePath":"capabilities/live-queries.md","filePath":"capabilities/live-queries.md"}'),o={name:"capabilities/live-queries.md"};function p(t,s,c,r,i,y){return e(),n("div",null,[...s[0]||(s[0]=[l("",166)])])}const d=a(o,[["render",p]]);export{F as __pageData,d as default};
2 |
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/MYColumnCommentModifier.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class MYColumnCommentModifier extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'mysql',
10 | syntax: [
11 | { type: 'keyword', value: 'COMMENT' },
12 | { type: 'string_literal', as: '.' },
13 | ],
14 | };
15 | }
16 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/capabilities_json-literals.md.rGE9X-tr.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as a,c as e,o as n,ag as t}from"./chunks/framework.B-XtCDNB.js";const h=JSON.parse('{"title":"JSON Literals","description":"","frontmatter":{},"headers":[],"relativePath":"capabilities/json-literals.md","filePath":"capabilities/json-literals.md"}'),l={name:"capabilities/json-literals.md"};function o(p,s,r,c,i,d){return n(),e("div",null,[...s[0]||(s[0]=[t("",53)])])}const u=a(l,[["render",o]]);export{h as __pageData,u as default};
2 |
--------------------------------------------------------------------------------
/src/lang/dml/clauses/PGDefaultValuesClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGDefaultValuesClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'postgres',
10 | syntax: [
11 | { type: 'keyword', as: '.', value: 'DEFAULT' },
12 | { type: 'keyword', value: 'VALUES' },
13 | ]
14 | };
15 | }
16 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/FromClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class FromClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'FROM' },
11 | { type: 'FromItem', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true }
12 | ];
13 | }
14 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/PGIndexParamUsing.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
2 |
3 | export class PGIndexParamUsing extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'USING' },
10 | { type: 'keyword', value: 'INDEX' },
11 | { type: 'keyword', value: 'TABLESPACE' },
12 | { type: 'identifier', as: '.' },
13 | ];
14 | }
15 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/UsingFromClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class UsingFromClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'USING' },
11 | { type: 'FromItem', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true }
12 | ];
13 | }
14 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/MYColumnVisibilityModifier.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class MYColumnVisibilityModifier extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'mysql',
10 | syntaxes: [
11 | { type: 'keyword', as: '.', value: 'VISIBLE' },
12 | { type: 'keyword', as: '.', value: 'INVISIBLE' },
13 | ],
14 | };
15 | }
16 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/FKMatchRule.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
2 |
3 | export class FKMatchRule extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'MATCH' },
10 | { type: 'keyword', as: 'value', value: ['FULL', 'PARTIAL', 'SIMPLE'], assert: true },
11 | ];
12 | }
13 |
14 | /*. AST API */
15 |
16 | value() { return this._get('value'); }
17 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/SetClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class SetClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'SET' },
11 | { type: 'AssignmentExpr', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
12 | ];
13 | }
14 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/HavingClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class HavingClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'HAVING' },
10 | { type: 'Expr', as: 'expr', assert: true }
11 | ];
12 | }
13 |
14 | static get syntaxPriority() { return -1; }
15 |
16 | /* AST API */
17 |
18 | expr() { return this._get('expr'); }
19 | }
--------------------------------------------------------------------------------
/src/lang/ddl/index.js:
--------------------------------------------------------------------------------
1 | export * from './column/index.js';
2 | export * from './constraint/index.js';
3 | export * from './ident/index.js';
4 | export * from './index/index.js';
5 | export * from './namespace/index.js';
6 | export * from './table/index.js';
7 | export { CreateSchemaStmt } from './CreateSchemaStmt.js';
8 | export { DropSchemaStmt } from './DropSchemaStmt.js';
9 | export { CreateTableStmt } from './CreateTableStmt.js';
10 | export { DropTableStmt } from './DropTableStmt.js';
11 | export { DDLStmt } from './DDLStmt.js'
12 |
--------------------------------------------------------------------------------
/src/lang/expr/literals/StringLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLiteral } from './AbstractLiteral.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class StringLiteral extends AbstractLiteral {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: 'string_literal', as: '.' }; }
9 |
10 | /* AST API */
11 |
12 | qualifier() { return this._get('qualifier'); }
13 |
14 | /* TYPESYS API */
15 |
16 | dataType() { return registry.DataType.fromJSON({ value: 'TEXT' }); }
17 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/WindowClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class WindowClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'WINDOW' },
11 | { type: 'WindowDeclaration', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
12 | ];
13 | }
14 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/MYColumnOnUpdateModifier.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class MYColumnOnUpdateModifier extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'mysql',
10 | syntax: [
11 | { type: 'keyword', value: 'ON' },
12 | { type: 'keyword', value: 'UPDATE' },
13 | { type: 'keyword', as: '.' },
14 | ],
15 | };
16 | }
17 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/FKDeleteRule.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
2 |
3 | export class FKDeleteRule extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'ON' },
10 | { type: 'keyword', value: 'DELETE' },
11 | { type: 'ReferentialAction', as: 'action', assert: true },
12 | ];
13 | }
14 |
15 | /*. AST API */
16 |
17 | action() { return this._get('action'); }
18 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/FKUpdateRule.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
2 |
3 | export class FKUpdateRule extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'ON' },
10 | { type: 'keyword', value: 'UPDATE' },
11 | { type: 'ReferentialAction', as: 'action', assert: true },
12 | ];
13 | }
14 |
15 | /*. AST API */
16 |
17 | action() { return this._get('action'); }
18 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/ColumnsSpec.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../expr/abstracts/AbstractNodeList.js';
2 | import { ColumnRef } from '../../expr/refs/ColumnRef.js';
3 | import { PathRight } from '../../expr/path/PathRight.js';
4 |
5 | export class ColumnsSpec extends AbstractNodeList {
6 | static get EXPECTED_TYPES() { return [PathRight, ColumnRef]; }
7 | static get TAGS() { return ['(', ')']; }
8 |
9 | static get expose() {
10 | return {
11 | columns: (context, ...entries) => this.fromJSON(context, { entries }),
12 | };
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/PGOrderOperator.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGOrderOperator extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'postgres',
10 | syntax: [
11 | { type: 'keyword', value: 'USING' },
12 | { type: 'operator', as: '.', assert: true },
13 | ],
14 | };
15 | }
16 |
17 | /* AST API */
18 |
19 | value() { return this._get('value'); }
20 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/ValuesClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../expr/abstracts/AbstractNodeList.js';
2 | import { Parens } from '../../expr/Parens.js';
3 | import { RowSpec } from './RowSpec.js';
4 |
5 | export class ValuesClause extends AbstractNodeList {
6 | static get EXPECTED_TYPES() { return [RowSpec, Parens]; }
7 | static get ARGS_DELEGATION() { return 'add'; }
8 | static get CLAUSE() { return 'VALUES'; }
9 |
10 | static get expose() {
11 | return {
12 | values: (context, ...entries) => this.fromJSON(context, { entries }),
13 | };
14 | }
15 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/WindowDeclaration.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class WindowDeclaration extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'Identifier', as: 'name' },
10 | { type: 'keyword', value: 'AS' },
11 | { type: 'WindowSpec', as: 'spec', assert: true }
12 | ];
13 | }
14 |
15 | /* AST API */
16 |
17 | name() { return this._get('name'); }
18 |
19 | spec() { return this._get('spec'); }
20 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/index.js:
--------------------------------------------------------------------------------
1 | export { FKMatchRule } from './FKMatchRule.js';
2 | export { FKDeleteRule } from './FKDeleteRule.js';
3 | export { FKUpdateRule } from './FKUpdateRule.js';
4 | export { PGIndexParameters } from './PGIndexParameters.js';
5 | export { PGIndexParamInclude } from './PGIndexParamInclude.js';
6 | export { PGIndexParamUsing } from './PGIndexParamUsing.js';
7 | export { PGIndexParamWith } from './PGIndexParamWith.js';
8 | export { PGTableEXConstraintItem } from './PGTableEXConstraintItem.js';
9 | export { ReferentialAction } from './ReferentialAction.js';
10 |
--------------------------------------------------------------------------------
/src/lang/expr/ref/LQDeepDeepRef2.js:
--------------------------------------------------------------------------------
1 | import { LQDeepDeepRef1 } from './LQDeepDeepRef1.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class LQDeepDeepRef2 extends LQDeepDeepRef1 {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _rightType() { return ['LQDeepDeepRef2', 'ColumnRef2', 'ColumnsConstructor']; } // for inheritance
9 |
10 | /* JSON API */
11 |
12 | jsonfy({ toDeepRef = false, toKind = 2, ...options } = {}, transformer = null, schemaInference = null) {
13 | return super.jsonfy({ toDeepRef, toKind, ...options }, transformer = null, schemaInference);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/TableRef0.js:
--------------------------------------------------------------------------------
1 | import { TableRef1 } from './TableRef1.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class TableRef0 extends TableRef1 {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _qualifierType() { return ['NamespaceRef']; }
9 |
10 | static get syntaxRules() {
11 | return this.buildSyntaxRules({ type: 'operator', as: '.', value: '*', autoSpacing: false });
12 | }
13 |
14 | static get syntaxPriority() { return -1; }
15 |
16 | /* API */
17 |
18 | dataType() { return registry.DataType.fromJSON({ value: 'SET' }); }
19 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/PartitionByClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class PartitionByClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'PARTITION' },
11 | { type: 'keyword', value: 'BY', assert: true },
12 | { type: 'Expr', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 }
13 | ];
14 | }
15 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/ColumnRef0.js:
--------------------------------------------------------------------------------
1 | import { ColumnRef1 } from './ColumnRef1.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class ColumnRef0 extends ColumnRef1 {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _qualifierType() { return ['TableRef1']; }
9 |
10 | static get syntaxRules() {
11 | return this.buildSyntaxRules({ type: 'operator', as: '.', value: '*', autoSpacing: false });
12 | }
13 |
14 | static get syntaxPriority() { return -1; }
15 |
16 | /* API */
17 |
18 | dataType() { return registry.DataType.fromJSON({ value: 'SET' }); }
19 | }
--------------------------------------------------------------------------------
/src/lang/expr/op/InExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from './BinaryExpr.js';
2 |
3 | export class InExpr extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'Expr', as: 'left', peek: [1, 'operator', ['NOT', 'IN']] },
10 | { type: 'operator', as: 'negation', value: 'NOT', booleanfy: true, optional: true },
11 | { type: 'operator', as: 'operator', value: 'IN' },
12 | { type: ['DerivedQuery', 'RowConstructor', 'TypedRowConstructor'], as: 'right', assert: true },
13 | ];
14 | }
15 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/MYPartitionClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class MYPartitionClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'mysql',
11 | syntax: [
12 | { type: 'keyword', value: 'PARTITION' },
13 | { type: 'Identifier', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true }
14 | ],
15 | };
16 | }
17 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/PGIndexParamInclude.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../../abstracts/AbstractNodeList.js';
2 |
3 | export class PGIndexParamInclude extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'INCLUDE' },
11 | {
12 | type: 'paren_block',
13 | syntax: { type: 'ColumnRef2', as: 'entries', arity: { min: 1 }, itemSeparator },
14 | }
15 | ];
16 | }
17 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/PGIndexParamWith.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../../abstracts/AbstractNodeList.js';
2 |
3 | export class PGIndexParamWith extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'WITH' },
11 | {
12 | type: 'paren_block',
13 | syntax: { type: 'ConfigAssignmentExprAlt2', as: 'entries', arity: { min: 1 }, itemSeparator },
14 | }
15 | ];
16 | }
17 | }
--------------------------------------------------------------------------------
/src/lang/dql/TA/index.js:
--------------------------------------------------------------------------------
1 | export { DerivedQuery } from './DerivedQuery.js';
2 | export { FromItem } from './FromItem.js';
3 | export { FromItemAlias } from './FromItemAlias.js';
4 | export { SelectItem } from './SelectItem.js';
5 | export { SelectItemAlias } from './SelectItemAlias.js';
6 | export { SRFExpr1 } from './SRFExpr1.js';
7 | export { SRFExpr2 } from './SRFExpr2.js';
8 | export { SRFExpr3 } from './SRFExpr3.js';
9 | export { SRFExpr4 } from './SRFExpr4.js';
10 | export { SRFExprDDL1 } from './SRFExprDDL1.js';
11 | export { SRFExprDDL2 } from './SRFExprDDL2.js';
12 | export { ValuesTableLiteral } from './ValuesTableLiteral.js';
13 |
--------------------------------------------------------------------------------
/src/lang/index.js:
--------------------------------------------------------------------------------
1 | import * as cte from './cte/index.js';
2 | import * as ddl from './ddl/index.js';
3 | import * as dml from './dml/index.js';
4 | import * as dql from './dql/index.js';
5 | import * as expr from './expr/index.js';
6 | import * as qualif from './qualif/index.js';
7 | import * as type from './type/index.js';
8 | import { JSONSchema } from './abstracts/JSONSchema.js';
9 | import { StdStmt } from './StdStmt.js';
10 | import { Script } from './Script.js';
11 | import { registry } from './registry.js';
12 |
13 | Object.assign(registry, { ...cte, ...ddl, ...dml, ...dql, ...expr, ...qualif, ...type, StdStmt, Script, JSONSchema });
14 |
--------------------------------------------------------------------------------
/src/lang/expr/op/DistinctFromExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from './BinaryExpr.js';
2 |
3 | export class DistinctFromExpr extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'Expr', as: 'left', peek: [1, 'operator', ['IS', 'IS NOT']] },
10 | { type: 'operator', as: 'logic', value: ['IS', 'IS NOT'] },
11 | { type: 'operator', as: 'operator', value: 'DISTINCT FROM' },
12 | { type: 'Expr', as: 'right', assert: true },
13 | ];
14 | }
15 |
16 | /* AST API */
17 |
18 | logic() { return this._get('logic'); }
19 | }
--------------------------------------------------------------------------------
/src/lang/dml/expr/AssignmentExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from '../../expr/op/BinaryExpr.js';
2 |
3 | export class AssignmentExpr extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: ['LQDeepRef2', 'ColumnsConstructor', 'ColumnRef2'], as: 'left', dialect: 'postgres' },
10 | { type: ['LQDeepRef2', 'ColumnRef1'], as: 'left', dialect: 'mysql' },
11 | { type: 'operator', as: 'operator', value: '=' },
12 | { type: ['ValuesTableLiteral'/* For deep dimensional inserts */, 'DerivedQuery', 'Expr'], as: 'right' },
13 | ];
14 | }
15 | }
--------------------------------------------------------------------------------
/src/lang/ddl/DDLStmt.js:
--------------------------------------------------------------------------------
1 | import { AbstractStmt } from '../abstracts/AbstractStmt.js';
2 |
3 | export class DDLStmt extends AbstractStmt {
4 |
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: ['CreateSchemaStmt', 'DropSchemaStmt', 'CreateTableStmt', 'DropTableStmt'] }; }
9 |
10 | /** API */
11 |
12 | jsonfy({ deSugar, ...options } = {}, transformer = null, schemaInference = null) {
13 | if (this.returningClause?.()) {
14 | options = { deSugar, ...options };
15 | }
16 | return super.jsonfy(options, transformer, schemaInference);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/lang/expr/ref/LQBackRefAbstraction.js:
--------------------------------------------------------------------------------
1 | import { ParenExpr } from '../abstraction/ParenExpr.js';
2 |
3 | export class LQBackRefAbstraction extends ParenExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | type: 'paren_block',
10 | syntaxes: [
11 | { type: 'Expr', as: 'expr', peek: [1, 'operator', '<~'] }, // (fk <~ fk2 <~ tbl)
12 | { type: 'Expr', as: 'expr', peek: [2, 'operator', '<~'] }, // ((alias) fk <~ fk2 <~ tbl)
13 | ],
14 | };
15 | }
16 |
17 | static get syntaxPriority() { return 51; } // Above RowConstructor
18 |
19 | /* AST API */
20 |
21 | expr() { return this._get('expr'); }
22 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/PGWhereCurrentClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGWhereCurrentClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'postgres',
10 | syntax: [
11 | { type: 'keyword', value: 'WHERE' },
12 | { type: 'keyword', value: 'CURRENT OF' },
13 | { type: 'identifier', as: 'cursor_name', assert: true }
14 | ]
15 | };
16 | }
17 |
18 | /* AST API */
19 |
20 | cursorName() { return this._get('cursor_name'); }
21 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/OffsetClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class OffsetClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'OFFSET' },
10 | { type: 'Expr', as: 'expr', assert: true, },
11 | { type: 'keyword', as: 'pg_row_kw', value: ['ROW', 'ROWS'], optional: true, dialect: 'postgres' },
12 | ];
13 | }
14 |
15 | /* AST API */
16 |
17 | expr() { return this._get('expr'); }
18 |
19 | // -- Postgres
20 |
21 | pgRowKW() { return this._get('pg_row_kw'); }
22 | }
--------------------------------------------------------------------------------
/src/lang/expr/case/CaseBranch.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class CaseBranch extends AbstractNode {
4 |
5 | /* DEFS */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'WHEN' },
10 | { type: 'Expr', as: 'condition' },
11 | { type: 'keyword', value: 'THEN' },
12 | { type: 'Expr', as: 'consequent' }
13 | ];
14 | }
15 |
16 | static get syntaxPriority() { return -1; }
17 |
18 | /* AST API */
19 |
20 | condition() { return this._get('condition'); }
21 |
22 | consequent() { return this._get('consequent'); }
23 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/index.js:
--------------------------------------------------------------------------------
1 | export { MYOnDuplicateKeyUpdateClause } from './MYOnDuplicateKeyUpdateClause.js';
2 | export { MYPartitionClause } from './MYPartitionClause.js';
3 | export { PGConflictTarget } from './PGConflictTarget.js';
4 | export { PGConflictTargetIndexSpec } from './PGConflictTargetIndexSpec.js';
5 | export { PGDefaultValuesClause } from './PGDefaultValuesClause.js';
6 | export { PGOnConflictClause } from './PGOnConflictClause.js';
7 | export { ReturningClause } from './ReturningClause.js';
8 | export { PGWhereCurrentClause } from './PGWhereCurrentClause.js';
9 | export { SetClause } from './SetClause.js';
10 | export { UsingFromClause } from './UsingFromClause.js';
11 |
--------------------------------------------------------------------------------
/src/lang/expr/literals/TypedLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class TypedLiteral extends AbstractClassicExpr {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return [
10 | { type: 'data_type', as: 'data_type' },
11 | { type: 'string_literal', as: 'value' },
12 | ];
13 | }
14 |
15 | static get syntaxPriority() { return 50; }
16 |
17 | /* AST API */
18 |
19 | dataType() { return registry.DataType.fromJSON({ value: this._get('data_type') }); }
20 |
21 | value() { return this._get('value'); }
22 | }
--------------------------------------------------------------------------------
/src/lang/expr/op/BetweenExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from './BinaryExpr.js';
2 |
3 | export class BetweenExpr extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'operator', value: 'AND' };
9 | return [
10 | { type: 'Expr', as: 'left', peek: [1, 'operator', ['NOT', 'BETWEEN']] },
11 | { type: 'operator', as: 'negation', value: 'NOT', booleanfy: true, optional: true },
12 | { type: 'operator', as: 'operator', value: 'BETWEEN' },
13 | { type: 'Expr', as: 'right', arity: { min: 2, max: 2, eager: false }, itemSeparator, assert: true },
14 | ];
15 | }
16 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/LQBackRefEndpoint.js:
--------------------------------------------------------------------------------
1 | import { ColumnRef2 } from './ColumnRef2.js';
2 |
3 | export class LQBackRefEndpoint extends ColumnRef2 {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | {
10 | optional: true,
11 | type: 'paren_block',
12 | syntax: { type: 'Identifier', as: 'qualifier' },
13 | },
14 | { ...[].concat(super.syntaxRules)[0], peek: [1, 'operator', '<~'] },
15 | ];
16 | }
17 |
18 | static get syntaxPriority() { return 52; } // Above ColumnRef1
19 |
20 | static morphsTo() { return ColumnRef2; }
21 |
22 | /* API */
23 |
24 | qualifier() { return this._get('qualifier'); }
25 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/ColumnDefaultConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 |
3 | export class ColumnDefaultConstraint extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return this.buildSyntaxRules([
9 | { type: 'keyword', value: 'DEFAULT' },
10 | { type: 'Expr', as: 'expr', assert: true, dialect: 'postgres' },
11 | { type: ['NumberLiteral', 'StringLiteral', 'NullLiteral', 'BoolLiteral', 'CallExpr', 'RowConstructor'], as: 'expr', assert: true, dialect: 'mysql' },
12 | ]);
13 | }
14 |
15 | /* AST API */
16 |
17 | expr() { return this._get('expr'); }
18 | }
--------------------------------------------------------------------------------
/src/lang/dml/constructors/ColumnsConstructor.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class ColumnsConstructor extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | syntax: [
11 | {
12 | type: 'paren_block',
13 | syntax: { type: ['LQDeepRef2', 'ColumnRef2'], as: 'entries', arity: Infinity, itemSeparator, autoIndent: 10 },
14 | },
15 | ],
16 | };
17 | }
18 |
19 | static get syntaxPriority() { return -1; }
20 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/LQDeepRef2.js:
--------------------------------------------------------------------------------
1 | import { LQDeepRef1 } from './LQDeepRef1.js';
2 |
3 | export class LQDeepRef2 extends LQDeepRef1 {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get _rightType() { return ['LQDeepDeepRef2', 'ColumnRef2', 'ColumnsConstructor']; } // for inheritance
8 |
9 | static get syntaxPriority() { return -1; }
10 |
11 | /* JSON API */
12 |
13 | resolve(transformer, schemaInference, toKind = 2) {
14 | return super.resolve(transformer, schemaInference, toKind);
15 | }
16 |
17 | jsonfy({ toDeepRef = false, toKind = 2, ...options } = {}, transformer = null, schemaInference = null) {
18 | return super.jsonfy({ toDeepRef, toKind, ...options }, transformer, schemaInference);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/lang/dql/CompleteSelectStmt.js:
--------------------------------------------------------------------------------
1 | import { BasicSelectStmt } from './BasicSelectStmt.js';
2 |
3 | export class CompleteSelectStmt extends BasicSelectStmt {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return this.buildSyntaxRules(); }
8 |
9 | static get syntaxPriority() { return 99; }
10 |
11 | /* AST API */
12 |
13 | orderByClause() { return this._get('order_by_clause'); }
14 |
15 | offsetClause() { return this._get('offset_clause'); }
16 |
17 | limitClause() { return this._get('limit_clause'); }
18 |
19 | forClause() { return this._get('for_clause'); }
20 |
21 | // -- Postgres
22 |
23 | pgFetchClause() { return this._get('pg_fetch_clause'); }
24 | }
--------------------------------------------------------------------------------
/src/lang/expr/etc/PredicateExpr.js:
--------------------------------------------------------------------------------
1 | import { registry } from '../../registry.js';
2 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
3 |
4 | export class PredicateExpr extends AbstractClassicExpr {
5 |
6 | /* DEFS */
7 |
8 | static get syntaxRules() {
9 | return [
10 | { type: 'keyword', as: 'predicate', value: ['EXISTS'] },
11 | { type: 'ScalarSubquery', as: 'expr' },
12 | ];
13 | }
14 |
15 | /* AST API */
16 |
17 | predicate() { return this._get('predicate'); }
18 |
19 | expr() { return this._get('expr'); }
20 |
21 | /* TYPESYS API */
22 |
23 | dataType() { return registry.DataType.fromJSON({ value: 'BOOLEAN' }); }
24 | }
25 |
--------------------------------------------------------------------------------
/src/lang/expr/op/PGCastExpr2.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from './BinaryExpr.js';
2 |
3 | export class PGCastExpr2 extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'postgres',
10 | syntax: [
11 | { type: 'Expr', as: 'left', peek: [1, 'operator', '::'] },
12 | { type: 'operator', as: 'operator', value: '::', autoSpacing: false },
13 | { type: 'DataType', as: 'right', assert: true, autoSpacing: false },
14 | ]
15 | };
16 | }
17 |
18 | /* TYPESYS API */
19 |
20 | expr() { return this.left(); }
21 |
22 | dataType() { return this.right(); }
23 | }
--------------------------------------------------------------------------------
/src/lang/dql/TA/SRFExprDDL1.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class SRFExprDDL1 extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', as: 'as_kw', value: 'AS' },
11 | {
12 | type: 'paren_block',
13 | syntax: { type: 'ColumnSchema', as: 'column_defs', arity: { min: 1 }, itemSeparator },
14 | }
15 | ];
16 | }
17 |
18 | /* AST API */
19 |
20 | asKW() { return this._get('as_kw'); }
21 |
22 | columnDefs() { return this._get('column_defs'); }
23 | }
--------------------------------------------------------------------------------
/src/lang/expr/etc/QuantitativeExpr.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class QuantitativeExpr extends AbstractNode {
4 |
5 | /* DEFS */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', as: 'quantifier', value: ['ALL', 'ANY', 'SOME'] },
10 | {
11 | syntaxes: [
12 | { type: 'DerivedQuery', as: 'expr' },
13 | { type: 'paren_block', syntax: { type: 'Expr', as: 'expr' } }
14 | ],
15 | }
16 | ];
17 | }
18 |
19 | /* AST API */
20 |
21 | quantifier() { return this._get('quantifier'); }
22 |
23 | expr() { return this._get('expr'); }
24 | }
25 |
--------------------------------------------------------------------------------
/src/lang/expr/index.js:
--------------------------------------------------------------------------------
1 | export * from './abstraction/index.js';
2 | export * from './call/index.js';
3 | export * from './case/index.js';
4 | export * from './etc/index.js';
5 | export * from './literals/index.js';
6 | export * from './op/index.js';
7 | export * from './ref/index.js';
8 | export * from './abstraction/index.js';
9 | export * from './var/index.js';
10 | export { LQBackRefAbstraction } from './ref/LQBackRefAbstraction.js';
11 | export { RowConstructor } from './abstraction/RowConstructor.js';
12 | export { ScalarSubquery } from './abstraction/ScalarSubquery.js';
13 | export { TypedRowConstructor } from './abstraction/TypedRowConstructor.js';
14 | export { Expr } from './Expr.js';
15 |
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/ColumnNullConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 |
3 | export class ColumnNullConstraint extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return this.buildSyntaxRules([
9 | {
10 | syntaxes: [
11 | [
12 | { type: 'operator', as: '.', value: 'NOT' },
13 | { type: 'null_literal', value: 'NULL' },
14 | ],
15 | { type: 'null_literal', as: '.', value: 'NULL' },
16 | ]
17 | }
18 | ]);
19 | }
20 |
21 | /* AST API */
22 |
23 | value() { return this._get('value'); }
24 | }
--------------------------------------------------------------------------------
/src/entry/abstracts/Spawnable.js:
--------------------------------------------------------------------------------
1 | import { fork } from 'node:child_process';
2 | import { fileURLToPath } from 'node:url';
3 | import { ProxyDriver } from './driver/ProxyDriver.js';
4 |
5 | export const Spawnable = (Base) => class extends Base {
6 | static spawn(params) {
7 | const __file__ = fileURLToPath(import.meta.url);
8 | const worker = fork(__file__, ['--linked-ql-client-autorun'], params);
9 | return worker;
10 | }
11 | }
12 |
13 | if (process.send && process.argv.includes('--linked-ql-client-autorun')) {
14 | const DB_PARAMS = process.env.DB_PARAMS;
15 |
16 | const driver = new ProxyDriver(DB_PARAMS);
17 | const instance = new Client(driver);
18 |
19 | process.on('message', () => {
20 |
21 | });
22 | }
--------------------------------------------------------------------------------
/src/lang/cte/CTEItemAlias.js:
--------------------------------------------------------------------------------
1 | import { Identifier } from '../expr/ref/Identifier.js';
2 |
3 | export class CTEItemAlias extends Identifier {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { ...[].concat(super.syntaxRules)[0] },
11 | {
12 | type: 'paren_block',
13 | syntax: { type: 'Identifier', as: 'columns', arity: { min: 1 }, itemSeparator, assert: true },
14 | if: 'value',
15 | optional: true,
16 | optionalParens: true,
17 | }
18 | ];
19 | }
20 |
21 | /* AST API */
22 |
23 | columns() { return this._get('columns'); }
24 | }
--------------------------------------------------------------------------------
/src/lang/expr/etc/ExtractExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from '../op/BinaryExpr.js';
2 |
3 | export class ExtractExpr extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'EXTRACT' },
10 | {
11 | type: 'paren_block',
12 | syntax: [
13 | { type: 'Expr', as: 'left' },
14 | { type: 'keyword', value: 'FROM' },
15 | { type: 'Expr', as: 'right', assert: true },
16 | ],
17 | autoSpacing: false
18 | }
19 | ];
20 | }
21 |
22 | /* AST API */
23 |
24 | left() { return this._get('left'); }
25 |
26 | right() { return this._get('right'); }
27 | }
--------------------------------------------------------------------------------
/src/lang/dml/MYSetStmt.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../abstracts/AbstractNodeList.js';
2 |
3 | export class MYSetStmt extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'mysql',
11 | syntax: [
12 | { type: 'keyword', value: 'SET' },
13 | { type: 'MYVarAssignmentExpr', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
14 | ]
15 | };
16 | }
17 |
18 | /** API */
19 |
20 | jsonfy({ deSugar, ...options } = {}, transformer = null, schemaInference = null) {
21 | return super.jsonfy(options, transformer, schemaInference);
22 | }
23 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/MYOnDuplicateKeyUpdateClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class MYOnDuplicateKeyUpdateClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'mysql',
11 | syntax: [
12 | { type: 'keyword', value: 'ON' },
13 | { type: 'keyword', value: 'DUPLICATE' },
14 | { type: 'keyword', value: 'KEY' },
15 | { type: 'keyword', value: 'UPDATE' },
16 | { type: 'AssignmentExpr', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: true },
17 | ]
18 | };
19 | }
20 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/TypedTimeLiteral.js:
--------------------------------------------------------------------------------
1 | import { TypedLiteral } from './TypedLiteral.js';
2 |
3 | export class TypedTimeLiteral extends TypedLiteral {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'data_type', as: 'data_type', value: 'TIME' },
10 | { type: 'string_literal', as: 'value' },
11 | {
12 | optional: true,
13 | dialect: 'postgres',
14 | syntax: [
15 | { type: 'keyword', as: 'pg_with_tz', value: ['WITH', 'WITHOUT'] },
16 | { type: 'keyword', value: 'TIME ZONE', assert: true },
17 | ]
18 | },
19 | ];
20 | }
21 |
22 | /* AST API */
23 |
24 | pgWithTZ() { return this._get('pg_with_tz'); }
25 | }
--------------------------------------------------------------------------------
/src/lang/dml/expr/ConfigAssignmentExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from '../../expr/op/BinaryExpr.js';
2 |
3 | export class ConfigAssignmentExpr extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', as: 'my_default_kw', value: 'DEFAULT', booleanfy: true, dialect: 'mysql', optional: true },
10 | {
11 | syntaxes: [
12 | { type: 'keyword', as: 'left' },
13 | { type: 'identifier', as: 'left' },
14 | ],
15 | },
16 | { type: 'operator', as: 'operator', value: '=' },
17 | { type: ['Expr', 'KW'], as: 'right' },
18 | ];
19 | }
20 |
21 | /* API */
22 |
23 | myDefaultKW() { return this._get('my_default_kw'); }
24 | }
--------------------------------------------------------------------------------
/src/lang/expr/call/constructs/PGFilterClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
2 |
3 | export class PGFilterClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'postgres',
10 | syntax: [
11 | { type: 'keyword', value: 'FILTER' },
12 | {
13 | type: 'paren_block',
14 | syntax: { type: 'WhereClause', as: 'where_clause' },
15 | assert: true,
16 | autoIndent: true
17 | }
18 | ]
19 | };
20 | }
21 |
22 | static get syntaxPriority() { return -1; }
23 |
24 | /* AST API */
25 |
26 | whereClause() { return this._get('where_clause'); }
27 | }
--------------------------------------------------------------------------------
/test/00.live 2.js:
--------------------------------------------------------------------------------
1 | import { PGClient } from '../src/entry/postgres/PGClient.js';
2 |
3 | const client1 = new PGClient;
4 | await client1.connect();
5 |
6 |
7 | const sql = `
8 | SELECT table_name
9 | FROM information_schema.tables
10 | WHERE table_schema = 'public'
11 | `;
12 |
13 | const result = await client1.query(sql);
14 | console.log(result.rows);
15 |
16 | //await client1.query(`SELECT pg_drop_replication_slot('linkedql_default_slot')`);
17 | //console.log((await client1.query(`SELECT * FROM pg_replication_slots`)).rows);
18 |
19 | //const result2 = await client1.query(`UPDATE rrr SET fname = 'John Doe 22' WHERE id = 3`);
20 | //const result2 = await client1.query(`DELETE FROM rrr WHERE id = 1`);
21 | const result3 = await client1.query(`INSERT INTO rrr (fname) VALUES ('John Doe 222---222')`);
22 | await client1.disconnect();
--------------------------------------------------------------------------------
/src/lang/abstracts/AbstractNodeList.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from './AbstractNode.js';
2 |
3 | export class AbstractNodeList extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() { return []; }
8 |
9 | // API
10 |
11 | get length() { return (this._get('entries') || []).length; }
12 |
13 | [Symbol.iterator]() { return (this._get('entries') || [])[Symbol.iterator](); }
14 |
15 | ['entries']() { return (this._get('entries') || []).slice(0); }
16 |
17 | delete(index) { return this._delete('entries', index); }
18 |
19 | get(index) { return this._get('entries', index); }
20 |
21 | set(index, value) { return this._set('entries', index, value); }
22 |
23 | has(index) { return this._has('entries', index); }
24 |
25 | add(...args) { return this._add('entries', ...args); }
26 | }
--------------------------------------------------------------------------------
/src/lang/dml/expr/ConfigAssignmentExprAlt1.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from '../../expr/op/BinaryExpr.js';
2 |
3 | export class ConfigAssignmentExprAlt1 extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', as: 'my_default_kw', value: 'DEFAULT', booleanfy: true, dialect: 'mysql', optional: true },
10 | {
11 | syntaxes: [
12 | { type: 'keyword', as: 'left' },
13 | { type: 'identifier', as: 'left' },
14 | ],
15 | },
16 | { type: 'operator', as: 'operator', value: '=', optional: true },
17 | { type: ['Expr', 'KW'], as: 'right' },
18 | ];
19 | }
20 |
21 | /* API */
22 |
23 | myDefaultKW() { return this._get('my_default_kw'); }
24 | }
--------------------------------------------------------------------------------
/src/lang/expr/abstraction/ParenExpr.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 |
3 | export class ParenExpr extends AbstractClassicExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | type: 'paren_block',
10 | syntax: { type: 'Expr', as: 'expr' },
11 | autoIndent: true,
12 | };
13 | }
14 |
15 | static get syntaxPriority() { return -1; }
16 |
17 | /* AST API */
18 |
19 | expr() { return this._get('expr'); }
20 |
21 | exprUnwrapped() {
22 | const expr = this._get('expr');
23 | if (expr instanceof ParenExpr) {
24 | return expr.exprUnwrapped();
25 | }
26 | return expr;
27 | }
28 |
29 | /* TYPESYS */
30 |
31 | dataType() { return this.expr()?.dataType(); }
32 | }
--------------------------------------------------------------------------------
/src/lang/expr/etc/CastExpr.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 |
3 | export class CastExpr extends AbstractClassicExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'CAST' },
10 | {
11 | type: 'paren_block',
12 | syntax: [
13 | { type: 'Expr', as: 'expr' },
14 | { type: 'keyword', value: 'AS' },
15 | { type: 'DataType', as: 'data_type', assert: true },
16 | ],
17 | assert: true,
18 | autoSpacing: false,
19 | }
20 | ];
21 | }
22 |
23 | /* AST API */
24 |
25 | expr() { return this._get('expr'); }
26 |
27 | dataType() { return this._get('data_type'); }
28 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/MYColumnAutoIncrementModifier.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 | import { ColumnIdentityConstraint } from './ColumnIdentityConstraint.js';
3 |
4 | export class MYColumnAutoIncrementModifier extends AbstractNode {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return {
10 | dialect: 'mysql',
11 | syntax: { type: 'keyword', as: '.', value: 'AUTO_INCREMENT' },
12 | };
13 | }
14 |
15 | /* JSON RULES */
16 |
17 | jsonfy(options = {}, transformer = null, schemaInference = null) {
18 | return (options.toDialect || this.options.dialect) === 'postgres'
19 | ? (new ColumnIdentityConstraint).jsonfy(options, transformer, schemaInference)
20 | : super.jsonfy(options, transformer, schemaInference);
21 | }
22 | }
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: ox-harris # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: webqit # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/vp-icons.css:
--------------------------------------------------------------------------------
1 | .vpi-social-github{--icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}
--------------------------------------------------------------------------------
/src/lang/expr/ref/abstracts/AbstractMagicRef.js:
--------------------------------------------------------------------------------
1 | import { ErrorFKInvalid } from './ErrorFKInvalid.js';
2 | import { SugarMixin } from '../../../abstracts/SugarMixin.js';
3 | import { BinaryExpr } from '../../op/BinaryExpr.js';
4 |
5 | export class AbstractMagicRef extends SugarMixin(BinaryExpr) {
6 |
7 | rhsTable(transformer, schemaInference) {
8 | const resolveOperand = this.operand()?.resolve(transformer, schemaInference);
9 | const fk = resolveOperand.resultSchema()/* ColumnSchema */?.fkConstraint(true);
10 | if (!fk) {
11 | throw new ErrorFKInvalid(`[${this.parentNode || this}] Column ${this.operand()} is not a foreign key.`);
12 | }
13 | return fk.targetTable()?.resolve(null/*transformer*/, schemaInference);
14 | }
15 |
16 | rhsSchema(transformer, schemaInference) { return this.rhsTable(transformer, schemaInference)?.resultSchema(); }
17 | }
--------------------------------------------------------------------------------
/src/lang/expr/call/constructs/PGWithinGroupClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
2 |
3 | export class PGWithinGroupClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'postgres',
10 | syntax: [
11 | { type: 'keyword', value: 'WITHIN' },
12 | { type: 'keyword', value: 'GROUP' },
13 | {
14 | type: 'paren_block',
15 | syntax: { type: 'OrderByClause', as: 'order_by_clause' },
16 | assert: true,
17 | autoIndent: true,
18 | },
19 | ]
20 | };
21 | }
22 |
23 | static get syntaxPriority() { return -1; }
24 |
25 | /* AST API */
26 |
27 | orderByClause() { return this._get('order_by_clause'); }
28 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/Identifier.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 | import { _eq } from '../../abstracts/util.js';
3 |
4 | export class Identifier extends AbstractNode {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: 'identifier', as: '.' }; }
9 |
10 | static get syntaxPriority() { return -1; }
11 |
12 | /* AST API */
13 |
14 | value() { return this._get('value'); }
15 |
16 | /* API */
17 |
18 | identifiesAs(ident, cs = undefined) {
19 | if (ident instanceof Identifier) {
20 | return _eq(this.value(), ident.value(), cs === undefined ? (this._has('delim') || ident._has('delim')) : cs);
21 | }
22 | if (typeof ident === 'string') {
23 | return _eq(this._get('value'), ident, cs === undefined ? this._has('delim') : cs);
24 | }
25 | return super.identifiesAs(ident, cs);
26 | }
27 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/index.js:
--------------------------------------------------------------------------------
1 | export { ColumnRef0 } from './ColumnRef0.js';
2 | export { ColumnRef1 } from './ColumnRef1.js';
3 | export { ColumnRef2 } from './ColumnRef2.js';
4 | export { Identifier } from './Identifier.js';
5 | export { LQBackBackRef } from './LQBackBackRef.js';
6 | export { LQBackRef } from './LQBackRef.js';
7 | export { LQBackRefAbstraction } from './LQBackRefAbstraction.js';
8 | export { LQBackRefEndpoint } from './LQBackRefEndpoint.js';
9 | export { LQDeepDeepRef1 } from './LQDeepDeepRef1.js';
10 | export { LQDeepDeepRef2 } from './LQDeepDeepRef2.js';
11 | export { LQDeepRef1 } from './LQDeepRef1.js';
12 | export { LQDeepRef2 } from './LQDeepRef2.js';
13 | export { NamespaceRef } from './NamespaceRef.js';
14 | export { TableRef0 } from './TableRef0.js';
15 | export { TableRef1 } from './TableRef1.js';
16 | export { TableRef2 } from './TableRef2.js';
17 | export { WindowRef } from './WindowRef.js';
18 |
--------------------------------------------------------------------------------
/src/lang/dql/clauses/UsingClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class UsingClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'USING' },
11 | {
12 | syntaxes: [
13 | { type: 'Identifier', as: 'column' },
14 | {
15 | type: 'paren_block',
16 | syntax: { type: 'Identifier', as: 'columns', arity: { min: 1 }, itemSeparator, assert: true }
17 | }
18 | ], assert: true
19 | },
20 | ];
21 | }
22 |
23 | /* AST API */
24 |
25 | column() { return this._get('column'); }
26 |
27 | columns() { return this._get('columns'); }
28 | }
--------------------------------------------------------------------------------
/src/lang/expr/Expr.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from './AbstractClassicExpr.js';
2 | import * as exprs from './index.js';
3 |
4 | export class Expr extends AbstractClassicExpr {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return { type: ExprNamesInOrder, expression: 1 };
10 | }
11 |
12 | /* API */
13 |
14 | static [Symbol.hasInstance](instance) {
15 | return instance instanceof AbstractClassicExpr || instance.constructor.name in exprs;
16 | }
17 | }
18 |
19 | const ExprNames = Object.keys(exprs);
20 | const ExprNamesInOrder = ExprNames.filter((k) => {
21 | return exprs[k] !== Expr && exprs[k].syntaxPriority !== -1;
22 | }).sort((a, b) => {
23 | const comp = (exprs[b].syntaxPriority ?? 100) - (exprs[a].syntaxPriority ?? 100);
24 | if (comp === 0) return exprs[b].prototype.isPrototypeOf(exprs[a].prototype) ? -1 : 1;
25 | return comp;
26 | });
27 |
--------------------------------------------------------------------------------
/src/lang/dml/expr/ConfigAssignmentExprAlt2.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from '../../expr/op/BinaryExpr.js';
2 |
3 | export class ConfigAssignmentExprAlt2 extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', as: 'default_kw', value: 'DEFAULT', booleanfy: true, optional: true },
10 | {
11 | syntaxes: [
12 | { type: 'keyword', as: 'left' },
13 | { type: 'identifier', as: 'left' },
14 | ],
15 | },
16 | {
17 | optional: true,
18 | syntax: [
19 | { type: 'operator', as: 'operator', value: '=' },
20 | { type: ['Expr', 'KW'], as: 'right' },
21 | ],
22 | }
23 | ];
24 | }
25 |
26 | /* API */
27 |
28 | myDefaultKW() { return this._get('my_default_kw'); }
29 | }
--------------------------------------------------------------------------------
/src/lang/expr/op/UnaryExpr.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class UnaryExpr extends AbstractClassicExpr {
5 |
6 | /* DEFS */
7 |
8 | static get syntaxRules() {
9 | return [
10 | { type: 'operator', as: 'operator', value: ['-', '+', 'NOT'] },
11 | { type: 'Expr', as: 'operand', autoSpacing: ['NOT'] },
12 | ];
13 | }
14 |
15 | static get syntaxPriority() { return 1;/* higher than BinaryExpr */ }
16 |
17 | /* AST API */
18 |
19 | operator() { return this._get('operator'); }
20 |
21 | operand() { return this._get('operand'); }
22 |
23 | /* TYPESYS API */
24 |
25 | dataType() {
26 | const operator = this.operator();
27 | if (!operator) return super.dataType();
28 | return registry.DataType.fromJSON({ value: operator === 'NOT' ? 'BOOLEAN' : 'NUMBER' });
29 | }
30 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/TypedTimestampLiteral.js:
--------------------------------------------------------------------------------
1 | import { TypedLiteral } from './TypedLiteral.js';
2 |
3 | export class TypedTimestampLiteral extends TypedLiteral {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'data_type', as: 'data_type', value: 'TIMESTAMP', dialect: 'postgres' },
10 | { type: 'data_type', as: 'data_type', value: ['TIMESTAMP', 'DATETIME'], dialect: 'mysql' },
11 | { type: 'string_literal', as: 'value' },
12 | {
13 | optional: true,
14 | dialect: 'postgres',
15 | syntax: [
16 | { type: 'keyword', as: 'pg_with_tz', value: ['WITH', 'WITHOUT'] },
17 | { type: 'keyword', value: 'TIME ZONE', assert: true },
18 | ]
19 | }
20 | ];
21 | }
22 |
23 | /* AST API */
24 |
25 | pgWithTZ() { return this._get('pg_with_tz'); }
26 | }
--------------------------------------------------------------------------------
/src/lang/ddl/namespace/NamespaceSchema.js:
--------------------------------------------------------------------------------
1 | import { AbstractSchema } from '../../abstracts/AbstractSchema.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class NamespaceSchema extends AbstractSchema {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | const itemSeparator = { type: 'punctuation', value: ',' };
10 | return [
11 | { type: 'NamespaceIdent', as: 'name', assert: true },
12 | {
13 | type: 'paren_block',
14 | syntax: { type: 'TableSchema', as: 'entries', arity: Infinity, itemSeparator, singletons: 'BY_KEY', autoIndent: true },
15 | },
16 | ];
17 | }
18 |
19 | /* API */
20 |
21 | tables() {
22 | const result = [];
23 | for (const entry of this) {
24 | if (!(entry instanceof registry.TableSchema)) continue;
25 | result.push(entry);
26 | }
27 | return result;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/lang/expr/op/AtTimeZoneExpr.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from './BinaryExpr.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class AtTimeZoneExpr extends BinaryExpr {
5 |
6 | /* DEFS */
7 |
8 | static get syntaxRules() {
9 | return [
10 | { type: 'Expr', as: 'left', peek: [1, 'operator', 'AT'] },
11 | { type: 'operator', as: 'operator', value: 'AT' },
12 | {
13 | syntaxes: [
14 | { type: 'TypedTimeZoneLiteral', as: 'right' },
15 | { type: 'keyword', as: 'right', value: 'LOCAL' }
16 | ]
17 | }
18 | ];
19 | }
20 |
21 | static get syntaxPriority() { return 0; }
22 |
23 | /* AST API */
24 |
25 | left() { return this._get('left'); }
26 |
27 | right() { return this._get('right'); }
28 |
29 | /* TYPESYS API */
30 |
31 | dataType() { return registry.DataType.fromJSON({ value: 'TIME ZONE' }); }
32 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/ColumnPKConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class ColumnPKConstraint extends ConstraintSchema {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return this.buildSyntaxRules([
10 | { type: 'keyword', value: 'PRIMARY' },
11 | { type: 'keyword', as: '.', value: 'KEY', assert: true },
12 | { type: 'PGIndexParameters', as: 'pg_index_parameters', optional: true, dialect: 'postgres' },
13 | ]);
14 | }
15 |
16 | /* AST API */
17 |
18 | primaryKW() { return this._get('primary_kw'); }
19 |
20 | pgIndexParameters() { return this._get('pg_index_parameters'); }
21 |
22 | /* API */
23 |
24 | columns() {
25 | return this.parentNode instanceof registry.ColumnSchema
26 | ? [registry.ColumnRef2.fromJSON({ value: this.parentNode.name().value() })]
27 | : [];
28 | }
29 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/OrderByClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class OrderByClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'ORDER' },
11 | { type: 'keyword', value: 'BY', assert: true },
12 | { type: 'OrderElement', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
13 | {
14 | optional: true,
15 | autoIndent: true,
16 | syntax: [
17 | { type: 'keyword', as: 'with_rollup', value: 'WITH', booleanfy: true },
18 | { type: 'keyword', value: 'ROLLUP', assert: true },
19 | ]
20 | },
21 | ];
22 | }
23 |
24 | /* AST API */
25 |
26 | withRollup() { return this._get('with_rollup'); }
27 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/TablePKConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 |
3 | export class TablePKConstraint extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return this.buildSyntaxRules([
10 | { type: 'keyword', value: 'PRIMARY' },
11 | { type: 'keyword', as: '.', value: 'KEY', assert: true },
12 | {
13 | type: 'paren_block',
14 | syntax: { type: 'ColumnRef2', as: 'columns', arity: { min: 1 }, itemSeparator, singletons: 'BY_KEY', assert: true },
15 | assert: true,
16 | },
17 | { type: 'PGIndexParameters', as: 'pg_index_parameters', optional: true, dialect: 'postgres' },
18 | ]);
19 | }
20 |
21 | /* AST API */
22 |
23 | columns() { return this._get('columns'); }
24 |
25 | pgIndexParameters() { return this._get('pg_index_parameters'); }
26 | }
--------------------------------------------------------------------------------
/src/flashql/fetch/AbstractFetchClient.js:
--------------------------------------------------------------------------------
1 | import { normalizeQueryArgs } from '../../entry/abstracts/util.js';
2 | import { AbstractClient } from '../../entry/abstracts/AbstractClient.js';
3 |
4 | export class AbstractFetchClient extends AbstractClient {
5 |
6 | async parse(requestSpec, { alias = null, dynamicWhereMode = false, ...options } = {}) {
7 | }
8 |
9 | async resolve(request, options = {}) {
10 | }
11 |
12 | async request(...args) {
13 | const [_request, options] = normalizeQueryArgs(...args);
14 | const request = await this.parse(_request, options);
15 | return await this._request(request, options);
16 | }
17 |
18 | async stream(...args) {
19 | const [_request, options] = normalizeQueryArgs(...args);
20 | const request = await this.parse(_request, options);
21 | return await this._stream(request, options);
22 | }
23 |
24 | async showCreate(selector, structured = false) {
25 | return await this._showCreate(selector, structured);
26 | }
27 | }
--------------------------------------------------------------------------------
/site/.vitepress/theme/custom.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /* Logo */
3 | --vp-nav-logo-height: 40px;
4 |
5 | /* Dark background for code blocks */
6 | --vp-code-block-bg: #212327;
7 |
8 | --vp-button-brand-text: black;
9 | --vp-button-brand-hover-text: black;
10 | --vp-button-brand-active-text: black;
11 |
12 | --vp-c-brand-1: #e9c80d;
13 | --vp-c-brand-2: gold;
14 | --vp-c-brand-3: #ffbf00;
15 | }
16 |
17 | .nowrap {
18 | white-space: nowrap;
19 | }
20 |
21 | h1 { counter-reset: h2_c; }
22 |
23 | h2 {
24 | counter-increment: h2_c;
25 | counter-reset: h3_c;
26 | }
27 | h2:not(.title, .text, :has(em)):before { content: counter(h2_c) ". "; }
28 |
29 | h3 {
30 | counter-increment: h3_c;
31 | counter-reset: h4_c;
32 | }
33 | h3:not(.text):before { content: counter(h2_c) "." counter(h3_c) ". "; }
34 |
35 | h4 {
36 | counter-increment: h4_c;
37 | }
38 | h4:not(.text):before { content: counter(h2_c) "." counter(h3_c) "." counter(h4_c) ". "; }
39 |
40 | :is(h2, h3, h4)::before {
41 | font-family: "Roboto Mono", monospace;
42 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/OrderElement.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class OrderElement extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'Expr', as: 'expr' },
10 | {
11 | optional: true,
12 | syntaxes: [
13 | { type: 'keyword', value: ['ASC', 'DESC'], as: 'dir' },
14 | { type: 'PGOrderOperator', as: 'dir' },
15 | ]
16 | },
17 | {
18 | optional: true,
19 | syntax: [
20 | { type: 'keyword', value: 'NULLS' },
21 | { type: 'keyword', as: 'nulls_spec', value: ['FIRST', 'LAST'], assert: true },
22 | ]
23 | },
24 | ];
25 | }
26 |
27 | /* AST API */
28 |
29 | expr() { return this._get('expr'); }
30 |
31 | dir() { return this._get('dir'); }
32 |
33 | nullsSpec() { return this._get('nulls_spec'); }
34 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/index.js:
--------------------------------------------------------------------------------
1 | export { BitLiteral } from './BitLiteral.js';
2 | export { BoolLiteral } from './BoolLiteral.js';
3 | export { DefaultLiteral } from './DefaultLiteral.js';
4 | export { HexLiteral } from './HexLiteral.js';
5 | export { NullLiteral } from './NullLiteral.js';
6 | export { NumberLiteral } from './NumberLiteral.js';
7 | export { StringLiteral } from './StringLiteral.js';
8 | export { TypedDateLiteral } from './TypedDateLiteral.js';
9 | export { TypedIntervalLiteral } from './TypedIntervalLiteral.js';
10 | export { TypedLiteral } from './TypedLiteral.js';
11 | export { TypedTimeLiteral } from './TypedTimeLiteral.js';
12 | export { TypedTimestampLiteral } from './TypedTimestampLiteral.js';
13 | export { TypedTimeZoneLiteral } from './TypedTimeZoneLiteral.js';
14 | export { UnknownLiteral } from './UnknownLiteral.js';
15 | export { LQArrayLiteral } from './LQArrayLiteral.js';
16 | export { LQObjectLiteral } from './LQObjectLiteral.js';
17 | export { LQObjectProperty } from './LQObjectProperty.js';
18 | export { PGTypedArrayLiteral } from './PGTypedArrayLiteral.js';
19 |
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/ReferentialAction.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
2 |
3 | export class ReferentialAction extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | syntaxes: [
11 | { type: 'keyword', as: 'value', value: ['NO ACTION', 'RESTRICT', 'CASCADE'] },
12 | [
13 | { type: 'keyword', as: 'value', value: ['SET NULL', 'SET DEFAULT'] },
14 | {
15 | optional: true,
16 | dialect: 'postgres',
17 | type: 'paren_block',
18 | syntax: { type: 'Identifier', as: 'columns', arity: { min: 1 }, itemSeparator },
19 | }
20 | ],
21 | ],
22 | };
23 | }
24 |
25 | /*. AST API */
26 |
27 | value() { return this._get('value'); }
28 |
29 | columns() { return this._get('columns'); }
30 | }
--------------------------------------------------------------------------------
/test/00.live.js:
--------------------------------------------------------------------------------
1 | import { PGClient } from '../src/entry/postgres/PGClient.js';
2 | import { Script } from '../src/lang/Script.js';
3 |
4 | //const r = await Script.parse(`SELECdT INTO`);
5 | //console.log(r.entries()[0], r+'', r.jsonfy());
6 | //process.exit();
7 |
8 | const client1 = new PGClient;
9 | await client1.connect();
10 |
11 |
12 | const sql = `
13 | SELECT table_name
14 | FROM information_schema.tables
15 | WHERE table_schema = 'public'
16 | `;
17 |
18 | const result = await client1.query(sql);
19 | console.log(result.rows);
20 |
21 | //await client1.query(`ALTER TABLE rrr RENAME COLUMN full_name TO fname`);
22 |
23 | //await client1.query(`SELECT pg_drop_replication_slot('linkedql_default_slot')`);
24 | //console.log((await client1.query(`SELECT * FROM pg_replication_slots`)).rows);
25 |
26 | //const result2 = await client1.query(`UPDATE rrr SET fname = 'John Doe 22' WHERE id = 3`);
27 | //const result2 = await client1.query(`DELETE FROM rrr WHERE id = 1`);
28 | const result3 = await client1.query(`INSERT INTO rrr (fname) VALUES ('John Doe 222---222')`);
29 | await client1.disconnect();
--------------------------------------------------------------------------------
/src/lang/dql/clauses/WindowSpec.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class WindowSpec extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | type: 'paren_block',
10 | syntax: [
11 | { type: 'WindowRef', as: 'super_window', optional: true },
12 | { type: 'PartitionByClause', as: 'partition_by_clause', optional: true, autoIndent: true },
13 | { type: 'OrderByClause', as: 'order_by_clause', optional: true, autoIndent: true },
14 | { type: 'WindowFrameSpec', as: 'frame_spec', optional: true, autoIndent: true },
15 | ],
16 | autoIndent: true,
17 | autoIndentAdjust: -1
18 | };
19 | }
20 |
21 | /* AST API */
22 |
23 | superWindow() { return this._get('super_window'); }
24 |
25 | partitionByClause() { return this._get('partition_by_clause'); }
26 |
27 | orderByClause() { return this._get('order_by_clause'); }
28 |
29 | frameSpec() { return this._get('frame_spec'); }
30 | }
--------------------------------------------------------------------------------
/src/lang/abstracts/AbstractStmt.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from './AbstractNode.js';
2 |
3 | export class AbstractStmt extends AbstractNode {
4 |
5 | get statementNode() { return this; }
6 |
7 | /* JSON API */
8 |
9 | #uuid;
10 |
11 | get uuid() {
12 | if (!this.#uuid) {
13 | this.#uuid = `$query${(0 | Math.random() * 9e6).toString(36)}`;
14 | }
15 | return this.#uuid;
16 | }
17 |
18 | static fromJSON(inputJson, options = {}, callback = null) {
19 | if (inputJson instanceof AbstractNode) {
20 | return super.fromJSON(inputJson, options, callback);
21 | }
22 | const { uuid, ...restJson } = inputJson;
23 | const instance = super.fromJSON(restJson, options, callback);
24 | if (instance) {
25 | instance.#uuid = uuid;
26 | }
27 | return instance;
28 | }
29 |
30 | jsonfy(options = {}, transformer = null, schemaInference = null) {
31 | let resultJson = super.jsonfy(options, transformer, schemaInference);
32 | if (this.#uuid) {
33 | resultJson = {
34 | uuid: this.#uuid,
35 | ...resultJson,
36 | };
37 | }
38 | return resultJson;
39 | }
40 | }
--------------------------------------------------------------------------------
/src/lang/dql/TA/SRFExprDDL2.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class SRFExprDDL2 extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | {
11 | syntaxes: [
12 | { type: 'Identifier', as: 'alias', peek: [1, 'paren_block'] },
13 | [
14 | { type: 'keyword', as: 'as_kw', value: 'AS', peek: [2, 'paren_block'] },
15 | { type: 'Identifier', as: 'alias', assert: true }
16 | ]
17 | ]
18 | },
19 | {
20 | type: 'paren_block',
21 | syntax: { type: 'ColumnSchema', as: 'column_defs', arity: { min: 1 }, itemSeparator },
22 | }
23 | ];
24 | }
25 |
26 | /* AST API */
27 |
28 | asKW() { return this._get('as_kw'); }
29 |
30 | alias() { return this._get('alias'); }
31 |
32 | columnDefs() { return this._get('column_defs'); }
33 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Linked DB
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/lang/expr/case/CaseExpr.js:
--------------------------------------------------------------------------------
1 | import { TypeSysMixin } from '../../abstracts/TypeSysMixin.js';
2 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
3 |
4 | export class CaseExpr extends TypeSysMixin(AbstractNodeList) {
5 |
6 | /* DEFS */
7 |
8 | static get syntaxRules() {
9 | return [
10 | { type: 'keyword', value: 'CASE' },
11 | { type: 'Expr', as: 'subject', optional: true },
12 | { type: 'CaseBranch', as: 'entries', arity: { min: 1 }, assert: true, autoIndent: 2 },
13 | {
14 | optional: true,
15 | syntax: [
16 | { type: 'keyword', value: 'ELSE' },
17 | { type: 'Expr', as: 'alternate', autoIndent: true },
18 | ],
19 | autoSpacing: '\n',
20 | },
21 | { type: 'keyword', value: 'END', autoSpacing: '\n' },
22 | ];
23 | }
24 |
25 | /* AST API */
26 |
27 | subject() { return this._get('subject'); }
28 |
29 | branches() { return this.entries(); }
30 |
31 | alternate() { return this._get('alternate'); }
32 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/WindowFrameBound.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class WindowFrameBound extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | syntaxes: [
10 | { type: 'keyword', as: 'specifier', value: 'CURRENT ROW' },
11 | [
12 | { type: 'keyword', as: 'specifier', value: 'UNBOUNDED' },
13 | { type: 'keyword', as: 'dir', value: ['PRECEDING', 'FOLLOWING'] },
14 | ],
15 | [
16 | { type: 'number_literal', as: 'specifier' },
17 | { type: 'keyword', as: 'dir', value: ['PRECEDING', 'FOLLOWING'] },
18 | ],
19 | [
20 | { type: 'Expr'/* Ideally, Temporal types */, as: 'specifier' },
21 | { type: 'keyword', as: 'dir', value: ['PRECEDING', 'FOLLOWING'] },
22 | ],
23 | ]
24 | };
25 | }
26 |
27 | /* AST API */
28 |
29 | specifier() { return this._get('specifier'); }
30 |
31 | dir() { return this._get('dir'); }
32 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/CheckConstraint.js:
--------------------------------------------------------------------------------
1 | import { registry } from '../../registry.js';
2 | import { ConstraintSchema } from './ConstraintSchema.js';
3 |
4 | export class CheckConstraint extends ConstraintSchema {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return this.buildSyntaxRules([
10 | { type: 'keyword', value: 'CHECK' },
11 | {
12 | type: 'paren_block',
13 | syntax: { type: 'Expr', as: 'expr', assert: true },
14 | assert: true,
15 | },
16 | { type: 'keyword', as: 'no_inherit_kw', value: 'NO INHERIT', optional: true }
17 | ]);
18 | }
19 |
20 | /* AST API */
21 |
22 | expr() { return this._get('expr'); }
23 |
24 | noInheritKW() { return this._get('no_inherit_kw'); }
25 |
26 | /* API */
27 |
28 | columns() {
29 | const columns = [];
30 | this.expr()?.walkTree((node) => {
31 | if (node instanceof registry.ColumnRef1) {
32 | columns.push(registry.ColumnRef2.fromJSON({ value: node.value() }))
33 | } else return node;
34 | });
35 | return columns;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/GroupByClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class GroupByClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'GROUP' },
11 | { type: 'keyword', value: 'BY', assert: true },
12 | { type: 'keyword', as: 'all_or_distinct', value: ['ALL', 'DISTINCT'], optional: true },
13 | { type: 'GroupingElement', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
14 | {
15 | optional: true,
16 | autoIndent: true,
17 | syntax: [
18 | { type: 'keyword', as: 'with_rollup', value: 'WITH', booleanfy: true },
19 | { type: 'keyword', value: 'ROLLUP', assert: true },
20 | ]
21 | },
22 | ];
23 | }
24 |
25 | /* AST API */
26 |
27 | allOrDistinct() { return this._get('all_or_distinct'); }
28 |
29 | withRollup() { return this._get('with_rollup'); }
30 | }
--------------------------------------------------------------------------------
/src/lang/abstracts/ResultSchemaMixin.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from './AbstractNode.js';
2 |
3 | export const ResultSchemaMixin = (Class) => class extends Class {
4 |
5 | #result_schema;
6 |
7 | resultSchema() { return this.#result_schema; }
8 |
9 | static fromJSON(inputJson, options = {}, callback = null) {
10 | if (!inputJson || inputJson instanceof AbstractNode) {
11 | return super.fromJSON(inputJson, options, callback);
12 | }
13 | const { result_schema, ...restJson } = inputJson;
14 | const instance = super.fromJSON(restJson, options, callback);
15 | if (instance && result_schema) {
16 | if (!(result_schema instanceof AbstractNode)) {
17 | throw new Error(`Invalid Schema object passed at inputJson.result_schema`);
18 | }
19 | instance.#result_schema = result_schema;
20 | }
21 | return instance;
22 | }
23 |
24 | jsonfy(options = {}, transformer = null, schemaInference = null) {
25 | let resultJson = super.jsonfy(options, transformer, schemaInference);
26 | if (this.#result_schema && options.resultSchemas !== false) {
27 | resultJson = {
28 | ...resultJson,
29 | result_schema: this.#result_schema,
30 | };
31 | }
32 | return resultJson;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/entry/abstracts/SimpleEmitter.js:
--------------------------------------------------------------------------------
1 | export class SimpleEmitter {
2 |
3 | #listeners = new Map;
4 | #closeCallbacks = new Set;
5 |
6 | on(event, fn) {
7 | if (!this.#listeners.has(event)) {
8 | this.#listeners.set(event, new Set);
9 | }
10 | this.#listeners.get(event).add(fn);
11 | return () => {
12 | this.#listeners.get(event).delete(fn);
13 | if (!this.#listeners.get(event).size) {
14 | this.#listeners.delete(event);
15 | if (!this.#listeners.size) {
16 | for (const fn of this.#closeCallbacks) fn();
17 | this.#closeCallbacks.clear();
18 | }
19 | }
20 | };
21 | }
22 |
23 | onClose(fn) { this.#closeCallbacks.add(fn); }
24 |
25 | emit(event, payload) {
26 | const s = this.#listeners.get(event);
27 | if (!s) return;
28 | for (const fn of s) {
29 | fn(payload);
30 | try {
31 | } catch (err) {
32 | // eslint-disable-next-line no-console
33 | console.error('emitter handler error', err);
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/lang/dql/clauses/DistinctClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class DistinctClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | syntaxes: [
11 | {
12 | dialect: 'postgres',
13 | syntax: [
14 | { type: 'keyword', value: 'DISTINCT' },
15 | { type: 'keyword', value: 'ON' },
16 | {
17 | type: 'paren_block',
18 | syntax: { type: 'Expr', as: 'pg_distinct_on_list', arity: { min: 1 }, itemSeparator, assert: true }
19 | },
20 | ],
21 | },
22 | { type: 'keyword', as: 'all_or_distinct', value: ['ALL', 'DISTINCT'] },
23 | ]
24 | };
25 | }
26 |
27 | /* AST API */
28 |
29 | allOrDistinct() { return this._get('all_or_distinct'); }
30 |
31 | // -- Postgres
32 |
33 | pgDistinctOnList() { return this._get('pg_distinct_on_list'); }
34 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/index.js:
--------------------------------------------------------------------------------
1 | export * from './constructs/index.js';
2 | export { CheckConstraint } from './CheckConstraint.js';
3 | export { ColumnDefaultConstraint } from './ColumnDefaultConstraint.js';
4 | export { ColumnExpressionConstraint } from './ColumnExpressionConstraint.js';
5 | export { ColumnFKConstraint } from './ColumnFKConstraint.js';
6 | export { ColumnIdentityConstraint } from './ColumnIdentityConstraint.js';
7 | export { ColumnNullConstraint } from './ColumnNullConstraint.js';
8 | export { ColumnPKConstraint } from './ColumnPKConstraint.js';
9 | export { ColumnUKConstraint } from './ColumnUKConstraint.js';
10 | export { ConstraintSchema } from './ConstraintSchema.js';
11 | export { MYColumnAutoIncrementModifier } from './MYColumnAutoIncrementModifier.js';
12 | export { MYColumnCommentModifier } from './MYColumnCommentModifier.js';
13 | export { MYColumnOnUpdateModifier } from './MYColumnOnUpdateModifier.js';
14 | export { MYColumnVisibilityModifier } from './MYColumnVisibilityModifier.js';
15 | export { PGTableEXConstraint } from './PGTableEXConstraint.js';
16 | export { TableFKConstraint } from './TableFKConstraint.js';
17 | export { TablePKConstraint } from './TablePKConstraint.js';
18 | export { TableUKConstraint } from './TableUKConstraint.js';
19 |
--------------------------------------------------------------------------------
/src/lang/dml/clauses/PGConflictTargetIndexSpec.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGConflictTargetIndexSpec extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | {
10 | syntaxes: [
11 | { type: 'ColumnRef2', as: 'column_name' },
12 | { type: 'paren_block', syntax: { type: 'Expr', as: 'expr', assert: true }, autoIndent: true },
13 | { type: 'CallExpr', as: 'expr' }, // Must come after the parens option
14 | ],
15 | },
16 | {
17 | optional: true,
18 | syntax: [
19 | { type: 'operator', value: 'COLLATE' },
20 | { type: 'string_literal', as: 'collation', assert: true },
21 | ],
22 | },
23 | { type: 'Identifier', as: 'opclass', optional: true },
24 | ];
25 | }
26 |
27 | /* AST API */
28 |
29 | columnName() { return this._get('column_name'); }
30 |
31 | expr() { return this._get('expr'); }
32 |
33 | collation() { return this._get('collation'); }
34 |
35 | opclass() { return this._get('opclass'); }
36 | }
--------------------------------------------------------------------------------
/src/lang/dql/TA/SelectItemAlias.js:
--------------------------------------------------------------------------------
1 | import { Identifier } from '../../expr/ref/Identifier.js';
2 |
3 | export class SelectItemAlias extends Identifier {
4 | static get syntaxRules() {
5 | return [
6 | {
7 | syntaxes: [
8 | { ...[].concat(super.syntaxRules)[0] },
9 | [
10 | { type: 'keyword', as: 'as_kw', value: 'AS', booleanfy: true },
11 | { ...[].concat(super.syntaxRules)[0], assert: true },
12 | ]
13 | ]
14 | },
15 | { type: 'AggrNotation', as: 'is_aggr', autoSpacing: false, optional: true },
16 | ];
17 | }
18 |
19 | /* AST API */
20 |
21 | asKW() { return this._get('as_kw'); }
22 |
23 | isAggr() { return this._get('is_aggr'); }
24 |
25 | // --------------
26 |
27 | jsonfy(options = {}, transformer = null, schemaInference = null) {
28 | let resultJson = super.jsonfy(options, transformer, schemaInference);
29 | if ((options.deSugar === true || options.deSugar?.normalizeCasing) && !resultJson.delim) {
30 | resultJson = { ...resultJson, value: resultJson.value.toLowerCase(), };
31 | }
32 | return resultJson;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/index.js:
--------------------------------------------------------------------------------
1 | export { DistinctClause } from './DistinctClause.js';
2 | export { ForClause } from './ForClause.js';
3 | export { FromClause } from './FromClause.js';
4 | export { GroupByClause } from './GroupByClause.js';
5 | export { GroupingElement } from './GroupingElement.js';
6 | export { HavingClause } from './HavingClause.js';
7 | export { JoinClause } from './JoinClause.js';
8 | export { LimitClause } from './LimitClause.js';
9 | export { OffsetClause } from './OffsetClause.js';
10 | export { OnClause } from './OnClause.js';
11 | export { OrderByClause } from './OrderByClause.js';
12 | export { OrderElement } from './OrderElement.js';
13 | export { PartitionByClause } from './PartitionByClause.js';
14 | export { PGFetchClause } from './PGFetchClause.js';
15 | export { PGOrderOperator } from './PGOrderOperator.js';
16 | export { SelectList } from './SelectList.js';
17 | export { UsingClause } from './UsingClause.js';
18 | export { WhereClause } from './WhereClause.js';
19 | export { WindowClause } from './WindowClause.js';
20 | export { WindowDeclaration } from './WindowDeclaration.js';
21 | export { WindowFrameSpec } from './WindowFrameSpec.js';
22 | export { WindowFrameBound } from './WindowFrameBound.js';
23 | export { WindowSpec } from './WindowSpec.js';
24 |
--------------------------------------------------------------------------------
/src/lang/dql/clauses/PGFetchClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGFetchClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return {
9 | dialect: 'postgres',
10 | syntax: [
11 | { type: 'keyword', value: 'FETCH' },
12 | { type: 'keyword', as: 'rel_kw', value: ['FIRST', 'NEXT'] },
13 | { type: 'Expr', as: 'expr', optional: true },
14 | { type: 'keyword', as: 'row_kw', value: ['ROW', 'ROWS'], assert: true },
15 | {
16 | syntaxes: [
17 | { type: 'keyword', value: 'ONLY' },
18 | [
19 | { type: 'keyword', as: 'with_ties', value: 'WITH' },
20 | { type: 'keyword', value: 'TIES', assert: true },
21 | ]
22 | ]
23 | }
24 | ]
25 | };
26 | }
27 |
28 | /* AST API */
29 |
30 | relKW() { return this._get('rel_kw'); }
31 |
32 | expr() { return this._get('expr'); }
33 |
34 | rowKW() { return this._get('row_kw'); }
35 |
36 | withTies() { return this._get('with_ties'); }
37 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/PGConflictTarget.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGConflictTarget extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | syntaxes: [
11 | [
12 | { type: 'keyword', value: 'ON' },
13 | { type: 'keyword', value: 'CONSTRAINT' },
14 | { type: 'Identifier', as: 'constraint_name', assert: true }
15 | ],
16 | [
17 | {
18 | type: 'paren_block',
19 | syntax: { type: 'PGConflictTargetIndexSpec', as: 'index_list', arity: { min: 1 }, itemSeparator, assert: true },
20 | autoIndent: true,
21 | },
22 | { type: 'WhereClause', as: 'where_clause', optional: true, autoIndent: true },
23 | ],
24 | ],
25 | };
26 | }
27 |
28 | /* AST API */
29 |
30 | constraintName() { return this._get('constraint_name'); }
31 |
32 | indexList() { return this._get('index_list'); }
33 |
34 | whereClause() { return this._get('where_clause'); }
35 | }
--------------------------------------------------------------------------------
/src/lang/ddl/DropTableStmt.js:
--------------------------------------------------------------------------------
1 | import { DDLStmt } from './DDLStmt.js';
2 |
3 | export class DropTableStmt extends DDLStmt {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'DROP' },
11 | { type: 'keyword', as: 'my_temporary_kw', value: 'TEMPORARY', booleanfy: true, optional: true, dialect: 'mysql' },
12 | { type: 'keyword', value: 'TABLE' },
13 | {
14 | optional: true,
15 | syntax: [
16 | { type: 'keyword', as: 'if_exists', value: 'IF', booleanfy: true },
17 | { type: 'keyword', value: 'EXISTS' },
18 | ]
19 | },
20 | { type: ['TableIdent', 'Identifier'/* to support mock names */], as: 'names', arity: { min: 1 }, itemSeparator },
21 | { type: 'keyword', as: 'cascade_rule', value: ['CASCADE', 'RESTRICT'], optional: true },
22 | ];
23 | }
24 |
25 | /* AST API */
26 |
27 | myTemporaryKW() { return this._get('my_temporary_kw'); }
28 |
29 | ifExists() { return this._get('if_exists'); }
30 |
31 | names() { return this._get('names'); }
32 |
33 | cascadeRule() { return this._get('cascade_rule'); }
34 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/app.Ds4M_nwI.js:
--------------------------------------------------------------------------------
1 | import{R as p}from"./chunks/theme.CAZbyQ2r.js";import{R as s,a2 as i,a3 as u,a4 as c,a5 as l,a6 as f,a7 as d,a8 as m,a9 as h,aa as g,ab as A,d as v,u as R,v as w,s as y,ac as C,ad as P,ae as b,af as E}from"./chunks/framework.B-XtCDNB.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),S=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),P(),b(),n.setup&&n.setup(),()=>E(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(S)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};
2 |
--------------------------------------------------------------------------------
/src/lang/dql/clauses/LimitClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class LimitClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'LIMIT' },
10 | {
11 | dialect: 'mysql',
12 | syntax: [
13 | {
14 | optional: true,
15 | syntax: [
16 | { type: 'Expr', as: 'my_offset' },
17 | { type: 'punctuation', value: ',', autoSpacing: false },
18 | ]
19 | },
20 | { type: 'Expr', as: 'expr', assert: true, },
21 | ]
22 | },
23 | {
24 | dialect: 'postgres',
25 | syntaxes: [
26 | { type: 'keyword', as: 'pg_all_kw', value: 'ALL' },
27 | { type: 'Expr', as: 'expr', assert: true },
28 | ],
29 | },
30 | ];
31 | }
32 |
33 | /* AST API */
34 |
35 | expr() { return this._get('expr'); }
36 |
37 | // -- Postgres
38 |
39 | pgAllKW() { return this._get('pg_all_kw'); }
40 |
41 | // -- MySQL
42 |
43 | myOffset() { return this._get('my_offset'); }
44 | }
--------------------------------------------------------------------------------
/src/lang/cte/constructs/PGSearchClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGSearchClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'postgres',
11 | syntax: [
12 | { type: 'keyword', value: 'SEARCH' },
13 | {
14 | assert: true,
15 | syntax: [
16 | { type: 'keyword', as: 'breadth_or_depth_first', value: ['BREADTH', 'DEPTH'] },
17 | { type: 'keyword', value: 'FIRST' },
18 | { type: 'keyword', value: 'BY' },
19 | { type: 'ColumnRef1', as: 'column_names', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
20 | { type: 'keyword', value: 'SET' },
21 | { type: 'ColumnRef1', as: 'seq_col_name' },
22 | ]
23 | }
24 | ]
25 | };
26 | }
27 |
28 | /* AST API */
29 |
30 | breadthOrDepthFirst() { return this._get('breadth_or_depth_first'); }
31 |
32 | columnNames() { return this._get('column_names'); }
33 |
34 | seqColName() { return this._get('seq_col_name'); }
35 | }
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish to npm
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | jobs:
9 | publish:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout repository
14 | uses: actions/checkout@v4
15 |
16 | - name: Setup Node.js
17 | uses: actions/setup-node@v4
18 | with:
19 | node-version: 20
20 | registry-url: 'https://registry.npmjs.org/'
21 |
22 | - name: Install dependencies
23 | run: npm ci
24 |
25 | - name: Build
26 | run: npm run build
27 |
28 | - name: Determine npm tag
29 | id: tag
30 | run: |
31 | # Extract tag name without "refs/tags/"
32 | TAG_REF=${GITHUB_REF#refs/tags/}
33 | echo "Detected Git tag: $TAG_REF"
34 |
35 | # Determine npm tag
36 | if [[ "$TAG_REF" == *-* ]]; then
37 | # prerelease (contains a hyphen)
38 | NPM_TAG=$(echo "$TAG_REF" | sed -E 's/^v[0-9]+\.[0-9]+\.[0-9]+-([a-zA-Z0-9]+).*/\1/')
39 | else
40 | NPM_TAG="latest"
41 | fi
42 | echo "npm publish will use tag: $NPM_TAG"
43 | echo "tag=$NPM_TAG" >> $GITHUB_OUTPUT
44 |
45 | - name: Publish to npm
46 | env:
47 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
48 | run: npm publish --tag ${{ steps.tag.outputs.tag }}
49 |
--------------------------------------------------------------------------------
/src/lang/abstracts/AbstractNonDDLStmt.js:
--------------------------------------------------------------------------------
1 | import { ResultSchemaMixin } from './ResultSchemaMixin.js';
2 | import { OriginSchemasMixin } from '../abstracts/OriginSchemasMixin.js';
3 | import { AbstractStmt } from './AbstractStmt.js';
4 |
5 | export class AbstractNonDDLStmt extends ResultSchemaMixin(OriginSchemasMixin(AbstractStmt)) {
6 |
7 | renderBindings(values) {
8 | if (!Array.isArray(values)) throw new Error(`Values must be an array`);
9 | const queryBindings = [...this.queryBindings()];
10 | for (let i = 0; i < values.length; i++) {
11 | const bindings = queryBindings.filter(b => b.offset() === i+1);
12 | if (!bindings.length) throw new Error(`No bindings exists at offset #${i}`);
13 | bindings.forEach(b => b.value(values[i]));
14 | }
15 | }
16 |
17 | normalizeBindings(dedupe = false) {
18 | const queryBindings = [...this.queryBindings()];
19 | if (!dedupe) {
20 | queryBindings.forEach((b, i) => b.offset(i+1));
21 | return queryBindings;
22 | }
23 | let redundants = new Map, $offset = 1;
24 | for (const b of queryBindings) {
25 | if (b.offset() === 0 || !redundants.has(b.offset())) {
26 | const newOffset = $offset++;
27 | redundants.set(b.offset(), newOffset);
28 | b.offset(newOffset);
29 | } else b.offset(redundants.get(b.offset())).withDetail('redundant', true);
30 | }
31 | return queryBindings.filter(b => !b.getDetail('redundant'));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/ColumnExpressionConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 |
3 | export class ColumnExpressionConstraint extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return this.buildSyntaxRules([
9 | {
10 | dialect: 'postgres',
11 | syntax: [
12 | { type: 'keyword', value: 'GENERATED' },
13 | { type: 'keyword', value: 'ALWAYS' },
14 | { type: 'keyword', value: 'AS' },
15 | {
16 | type: 'paren_block',
17 | syntax: { type: 'Expr', as: 'expr', assert: true },
18 | },
19 | { type: 'keyword', as: 'stored', value: 'STORED', assert: true },
20 | ],
21 | },
22 | {
23 | dialect: 'mysql',
24 | syntax: [
25 | {
26 | optional: true,
27 | syntax: [
28 | { type: 'keyword', as: 'my_generated_kw', value: 'GENERATED', booleanfy: true },
29 | { type: 'keyword', value: 'ALWAYS' },
30 | ],
31 | },
32 | { type: 'keyword', value: 'AS' },
33 | {
34 | type: 'paren_block',
35 | syntax: { type: 'Expr', as: 'expr', assert: true },
36 | },
37 | { type: 'keyword', as: 'stored', value: ['STORED', 'VIRTUAL'], optional: true },
38 | ],
39 | },
40 | ]);
41 | }
42 |
43 | /* AST API */
44 |
45 | myGeneratedKW() { return this._get('my_generated_kw'); }
46 |
47 | expr() { return this._get('expr'); }
48 |
49 | stored() { return this._get('stored'); }
50 | }
--------------------------------------------------------------------------------
/src/lang/ddl/DropSchemaStmt.js:
--------------------------------------------------------------------------------
1 | import { DDLStmt } from './DDLStmt.js';
2 |
3 | export class DropSchemaStmt extends DDLStmt {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | { type: 'keyword', value: 'DROP' },
11 | { type: 'keyword', value: 'SCHEMA', dialect: 'postgres' },
12 | { type: 'keyword', value: ['SCHEMA', 'DATABASE'], dialect: 'mysql' },
13 | {
14 | optional: true,
15 | syntax: [
16 | { type: 'keyword', as: 'if_exists', value: 'IF', booleanfy: true },
17 | { type: 'keyword', value: 'EXISTS' },
18 | ]
19 | },
20 | { type: ['NamespaceIdent', 'Identifier'/* to support mock names */], as: 'pg_names', arity: { min: 1 }, itemSeparator, dialect: 'postgres' },
21 | { type: ['NamespaceIdent', 'Identifier'/* to support mock names */], as: 'my_name', dialect: 'mysql' },
22 | { type: 'keyword', as: 'pg_cascade_rule', value: ['CASCADE', 'RESTRICT'], optional: true, dialect: 'postgres' },
23 | ];
24 | }
25 |
26 | /* AST API */
27 |
28 | ifExists() { return this._get('if_exists'); }
29 |
30 | pgNames() { return this._get('pg_names'); }
31 |
32 | myName() { return this._get('my_name'); }
33 |
34 | pgCascadeRule() { return this._get('pg_cascade_rule'); }
35 | }
--------------------------------------------------------------------------------
/src/lang/expr/abstraction/ScalarSubquery.js:
--------------------------------------------------------------------------------
1 | import { DerivedQuery } from '../../dql/TA/DerivedQuery.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class ScalarSubquery extends DerivedQuery {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return {
10 | type: 'paren_block',
11 | syntax: { type: ['SelectStmt', 'CTE'], as: 'expr' },
12 | autoIndent: true,
13 | };
14 | }
15 |
16 | static get syntaxPriority() { return 48; } // Below RowConstructor
17 |
18 | /* TYPESYS API */
19 |
20 | dataType() {
21 | if (this.resultSchema()) {
22 | return this.resultSchema().dataType();
23 | }
24 | return registry.DataType.fromJSON({ value: 'TEXT' });
25 | }
26 |
27 | /* JSON API */
28 |
29 | jsonfy(options = {}, transformer = null, schemaInference = null) {
30 | let resultJson = super.jsonfy(options, transformer, schemaInference);
31 | if (options.deSugar) {
32 | let resultSchema = resultJson.expr?.result_schema;
33 | if (resultSchema?.length !== 1) {
34 | throw new Error(`Scalar subqueries must return a scalar value.`);
35 | }
36 | resultSchema = resultSchema.entries()[0];
37 | resultJson = {
38 | ...resultJson,
39 | result_schema: resultSchema,
40 | };
41 | }
42 | return resultJson;
43 | }
44 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/GroupingElement.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class GroupingElement extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | syntaxes: [
11 | [
12 | { type: 'keyword', value: 'GROUPING SETS' },
13 | {
14 | type: 'paren_block', syntax:
15 | { type: 'GroupingElement', as: 'grouping_sets', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
16 | autoIndent: true
17 | }
18 | ],
19 | [
20 | { type: 'keyword', value: 'ROLLUP' },
21 | { type: 'RowConstructor', as: 'rollup_set', assert: true },
22 | ],
23 | [
24 | { type: 'keyword', value: 'CUBE' },
25 | { type: 'RowConstructor', as: 'cube_set', assert: true },
26 | ],
27 | { type: 'Expr', as: 'expr' },
28 | ]
29 | };
30 | }
31 |
32 | /* AST API */
33 |
34 | groupingSets() { return this._get('grouping_sets'); }
35 |
36 | rollupSet() { return this._get('rollup_set'); }
37 |
38 | cubeSet() { return this._get('cube_set'); }
39 |
40 | expr() { return this._get('expr'); }
41 | }
--------------------------------------------------------------------------------
/src/lang/dml/PGSetStmt.js:
--------------------------------------------------------------------------------
1 | import { BinaryExpr } from '../expr/op/BinaryExpr.js';
2 |
3 | export class PGSetStmt extends BinaryExpr {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'postgres',
11 | syntax: [
12 | { type: 'keyword', value: 'SET' },
13 | { type: 'identifier', as: 'scope_kw', value: ['LOCAL', 'SESSION'], optional: true },
14 | {
15 | syntaxes: [
16 | { type: 'keyword', as: 'left' },
17 | { type: 'identifier', as: 'left' },
18 | ],
19 | },
20 | {
21 | optional: true,
22 | syntaxes: [
23 | { type: 'operator', as: 'operator', value: '=' },
24 | { type: 'keyword', as: 'operator', value: 'TO' }
25 | ],
26 | },
27 | { type: ['Expr', 'KW'], as: 'right', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
28 | ]
29 | };
30 | }
31 |
32 | /* API */
33 |
34 | scopeKW() { return this._get('scope_kw'); }
35 |
36 | /** API */
37 |
38 | jsonfy({ deSugar, ...options } = {}, transformer = null, schemaInference = null) {
39 | return super.jsonfy(options, transformer, schemaInference);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/lang/expr/literals/PGTypedArrayLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class PGTypedArrayLiteral extends AbstractNodeList {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | const itemSeparator = { type: 'punctuation', value: ',' };
10 | return {
11 | dialect: 'postgres',
12 | syntax: [
13 | { type: 'keyword', value: 'ARRAY' },
14 | {
15 | type: 'bracket_block',
16 | syntax: { type: 'Expr', as: 'entries', arity: Infinity, itemSeparator, autoIndent: 2 },
17 | autoSpacing: false,
18 | },
19 | ],
20 | };
21 | }
22 |
23 | static morphsTo() { return registry.CallExpr; }
24 |
25 | /* TYPESYS API */
26 |
27 | dataType() { return registry.DataType.fromJSON({ value: 'JSON' }); }
28 |
29 | /* JSON API */
30 |
31 | jsonfy(options = {}, transformer = null, schemaInference = null) {
32 | let resultJson = super.jsonfy(options, transformer, schemaInference);
33 | if ((options.toDialect || this.options.dialect) === 'mysql') {
34 | resultJson = {
35 | nodeName: registry.CallExpr.NODE_NAME,
36 | name: 'JSON_ARRAY',
37 | arguments: resultJson.entries,
38 | };
39 | }
40 | return resultJson;
41 | }
42 | }
--------------------------------------------------------------------------------
/src/lang/dql/clauses/WindowFrameSpec.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class WindowFrameSpec extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'operator', value: 'AND' };
9 | return [
10 | { type: 'keyword', as: 'specifier', value: ['ROWS', 'RANGE', 'GROUPS'] },
11 | {
12 | syntaxes: [
13 | [
14 | { type: 'operator', as: 'with_between_clause', value: 'BETWEEN', booleanfy: true },
15 | { type: 'WindowFrameBound', as: 'bounds', arity: 2, itemSeparator, assert: true },
16 | ],
17 | { type: 'WindowFrameBound', as: 'bounds', arity: 1, itemSeparator, assert: true },
18 |
19 | ]
20 | },
21 | {
22 | optional: true,
23 | syntax: [
24 | { type: 'keyword', value: 'EXCLUDE' },
25 | { type: 'keyword', as: 'exclusion', value: ['CURRENT ROW', 'GROUP', 'TIES', 'NO OTHERS'], assert: true },
26 | ]
27 | },
28 | ];
29 | }
30 |
31 | /* AST API */
32 |
33 | specifier() { return this._get('specifier'); }
34 |
35 | withBetweenClause() { return this._get('with_between_clause'); }
36 |
37 | bounds() { return this._get('bounds'); }
38 |
39 | exclusion() { return this._get('exclusion'); }
40 | }
--------------------------------------------------------------------------------
/src/lang/dml/DMLStmt.js:
--------------------------------------------------------------------------------
1 | import { AbstractNonDDLStmt } from '../abstracts/AbstractNonDDLStmt.js';
2 | import { registry } from '../registry.js';
3 |
4 | export class DMLStmt extends AbstractNonDDLStmt {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() { return { type: ['InsertStmt', 'UpsertStmt', 'UpdateStmt', 'DeleteStmt'] }; }
9 |
10 | finalizeOutputJSON(resultJson, transformer, schemaInference, options) {
11 |
12 | if (resultJson.returning_clause) {
13 | // 1. Re-resolve output list for cases of just-added deep refs in returning_clause
14 | // wherein schemas wouldn't have been resolvable at the time
15 | // 2. Finalize output list for the last time, honouring given deSugaring level with regards to star selects "*"
16 | // and ofcos finalize output schemas
17 | const returningClauseJson = this.returningClause().finalizeJSON(resultJson.returning_clause, transformer, schemaInference, options);
18 | // Apply now
19 | resultJson = {
20 | ...resultJson,
21 | returning_clause: returningClauseJson,
22 | result_schema: returningClauseJson.result_schema,
23 | };
24 | } else {
25 | resultJson = {
26 | ...resultJson,
27 | result_schema: registry.JSONSchema.fromJSON({ entries: [] }, this.options),
28 | };
29 | }
30 |
31 | return resultJson;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/lang/ddl/CreateTableStmt.js:
--------------------------------------------------------------------------------
1 | import { DDLStmt } from './DDLStmt.js';
2 |
3 | export class CreateTableStmt extends DDLStmt {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | return [
9 | { type: 'keyword', value: 'CREATE' },
10 | {
11 | optional: true,
12 | syntaxes: [
13 | { type: 'keyword', as: 'temporary_kw', value: 'TEMPORARY', booleanfy: true },
14 | { type: 'keyword', as: 'temporary_kw', value: 'TEMP', booleanfy: true, dialect: 'postgres' },
15 | ],
16 | },
17 | { type: 'keyword', value: 'TABLE' },
18 | {
19 | optional: true,
20 | syntax: [
21 | { type: 'keyword', as: 'if_not_exists', value: 'IF', booleanfy: true },
22 | { type: 'operator', value: 'NOT' },
23 | { type: 'keyword', value: 'EXISTS' },
24 | ],
25 | },
26 | { type: 'TableSchema', as: 'argument' },
27 | { type: ['ConfigAssignmentExprAlt1', 'ConfigAssignmentExprAlt2'], as: 'my_create_options', arity: Infinity, dialect: 'mysql' }
28 | ];
29 | }
30 |
31 | /* AST API */
32 |
33 | temporaryKW() { return this._get('temporary_kw'); }
34 |
35 | ifNotExists() { return this._get('if_not_exists'); }
36 |
37 | argument() { return this._get('argument'); }
38 |
39 | myCreateOptions() { return this._get('my_create_options'); }
40 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/ColumnIdentityConstraint.js:
--------------------------------------------------------------------------------
1 | import { MYColumnAutoIncrementModifier } from './MYColumnAutoIncrementModifier.js';
2 | import { ConstraintSchema } from './ConstraintSchema.js';
3 |
4 | export class ColumnIdentityConstraint extends ConstraintSchema {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return this.buildSyntaxRules([
10 | { type: 'keyword', value: 'GENERATED' },
11 | {
12 | syntaxes: [
13 | { type: 'keyword', as: 'always_kw', value: 'ALWAYS', booleanfy: true },
14 | {
15 | syntax: [
16 | { type: 'keyword', as: 'by_default_kw', value: 'BY', booleanfy: true },
17 | { type: 'keyword', value: 'DEFAULT', assert: true },
18 | ],
19 | },
20 | ],
21 | },
22 | {
23 | optional: true,
24 | syntax: [
25 | { type: 'keyword', as: 'as_identity_kw', value: 'AS', booleanfy: true },
26 | { type: 'keyword', value: 'IDENTITY', assert: true },
27 | ]
28 | }
29 | ]);
30 | }
31 |
32 | /* AST API */
33 |
34 | alwaysKW() { return this._get('always_kw'); }
35 |
36 | byDefaultKW() { return this._get('by_default_kw'); }
37 |
38 | asIdentityKW() { return this._get('as_identity_kw'); }
39 |
40 | /* JSON API */
41 |
42 | jsonfy(options = {}, transformer = null, schemaInference = null) {
43 | return (options.toDialect || this.options.dialect) === 'mysql'
44 | ? (new MYColumnAutoIncrementModifier).jsonfy(options, transformer, schemaInference)
45 | : super.jsonfy(options, transformer, schemaInference);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/lang/dql/TableStmt.js:
--------------------------------------------------------------------------------
1 | import { AbstractNonDDLStmt } from '../abstracts/AbstractNonDDLStmt.js';
2 | import { registry } from '../registry.js';
3 |
4 | export class TableStmt extends AbstractNonDDLStmt {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return [
10 | { type: 'keyword', value: 'TABLE' },
11 | { type: 'keyword', as: 'pg_only_kw', value: 'ONLY', optional: true, dialect: 'postgres' },
12 | { type: 'TableRef2', as: 'table_ref', assert: true },
13 | { type: 'operator', as: 'pg_star_ref', value: '*', booleanfy: true, optional: true, dialect: 'postgres' },
14 | ];
15 | }
16 |
17 | /* AST API */
18 |
19 | tableRef() { return this._get('table_ref'); }
20 |
21 | // -- Postgres
22 |
23 | pgOnlyKW() { return this._get('pg_only_kw'); }
24 |
25 | pgStarRef() { return this._get('pg_star_ref'); }
26 |
27 | /* JSON API */
28 |
29 | jsonfy(options = {}, transformer = null, schemaInference = null) {
30 | let resultJson = super.jsonfy({ ...options, forceDeSugar: options.deSugar }, transformer, schemaInference);
31 | if (options.deSugar) {
32 | const tableSchema = resultJson.table_ref.result_schema;
33 | resultJson = {
34 | ...resultJson,
35 | result_schema: registry.JSONSchema.fromJSON({ entries: tableSchema.jsonfy().entries }),
36 | origin_schemas: [tableSchema], // or this.getOriginSchemas(transformer)
37 | };
38 | }
39 | return resultJson;
40 | }
41 | }
--------------------------------------------------------------------------------
/src/lang/dql/TA/FromItemAlias.js:
--------------------------------------------------------------------------------
1 | import { Identifier } from '../../expr/ref/Identifier.js';
2 |
3 | export class FromItemAlias extends Identifier {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | {
11 | syntaxes: [
12 | { ...[].concat(super.syntaxRules)[0] },
13 | [
14 | { type: 'keyword', as: 'as_kw', value: 'AS', booleanfy: true },
15 | { ...[].concat(super.syntaxRules)[0], assert: true },
16 | ]
17 | ]
18 | },
19 | {
20 | type: 'paren_block',
21 | syntax: { type: 'Identifier', as: 'columns', arity: { min: 1 }, itemSeparator, assert: true },
22 | if: 'value',
23 | optional: true,
24 | optionalParens: true,
25 | }
26 | ];
27 | }
28 |
29 | /* AST API */
30 |
31 | asKW() { return this._get('as_kw'); }
32 |
33 | columns() { return this._get('columns'); }
34 |
35 | // --------------
36 |
37 | jsonfy(options = {}, transformer = null, schemaInference = null) {
38 | let resultJson = super.jsonfy(options, transformer, schemaInference);
39 | if ((options.deSugar === true || options.deSugar?.normalizeCasing) && !resultJson.delim) {
40 | resultJson = { ...resultJson, value: resultJson.value.toLowerCase() };
41 | }
42 | return resultJson;
43 | }
44 | }
--------------------------------------------------------------------------------
/src/lang/expr/op/BinaryExpr.js:
--------------------------------------------------------------------------------
1 | import { AbstractClassicExpr } from '../AbstractClassicExpr.js';
2 | import { operators } from '../../toktypes.js';
3 | import { registry } from '../../registry.js';
4 |
5 | export class BinaryExpr extends AbstractClassicExpr {
6 |
7 | /* DEFS */
8 |
9 | static get syntaxRules() {
10 | return [
11 | { type: 'Expr', as: 'left', peek: [1, 'operator', ['NOT', undefined/* IMPORTANT */]] },
12 | { type: 'operator', as: 'negation', value: 'NOT', booleanfy: true, optional: true },
13 | { type: 'operator', as: 'operator' },
14 | { type: 'Expr', as: 'right' },
15 | ];
16 | }
17 |
18 | static get syntaxPriority() { return 0; }
19 |
20 | /* AST API */
21 |
22 | left() { return this._get('left'); }
23 |
24 | negation() { return this._get('negation'); }
25 |
26 | operator() { return this._get('operator'); }
27 |
28 | right() { return this._get('right'); }
29 |
30 | /* TYPESYS API */
31 |
32 | dataType() {
33 | const operator = this.operator();
34 | if (!operator) return this.left()?.dataType();
35 |
36 | const toDialect = this.options.dialect;
37 | const operatorMap = new Map(operators.common.concat(operators[toDialect]));
38 | const resultType = operatorMap.get(operator)?.resultType;
39 | if (!resultType) return;
40 |
41 | if (resultType === ':right') {
42 | return this.right()?.dataType();
43 | }
44 | if (resultType === ':left') {
45 | return this.left()?.dataType();
46 | }
47 | return registry.DataType.fromJSON({ value: resultType.toUpperCase() });
48 | }
49 | }
--------------------------------------------------------------------------------
/src/lang/dql/TA/SRFExpr1.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 | import { ResultSchemaMixin } from '../../abstracts/ResultSchemaMixin.js';
3 | import { registry } from '../../registry.js';
4 |
5 | export class SRFExpr1 extends ResultSchemaMixin(AbstractNode) {
6 |
7 | /* SYNTAX RULES */
8 |
9 | static get syntaxRules() {
10 | return [
11 | { type: 'CallExpr', as: 'call_expr' },
12 | { type: ['SRFExprDDL1', 'SRFExprDDL2'], as: 'qualif' },
13 | ];
14 | }
15 |
16 | /* AST API */
17 |
18 | callExpr() { return this._get('call_expr'); }
19 |
20 | qualif() { return this._get('qualif'); }
21 |
22 | /* JSON API */
23 |
24 | jsonfy(options = {}, transformer = null, schemaInference = null) {
25 | let resultJson = super.jsonfy(options, transformer, schemaInference);
26 | if (options.deSugar) {
27 |
28 | const columnDefsJson = resultJson.qualif?.column_defs || [];
29 | const resultSchema = resultJson.qualif?.alias
30 | // a. Compose from "column_defs" with explicit table alias
31 | ? registry.TableSchema.fromJSON({
32 | name: resultJson.qualif.alias,
33 | entries: columnDefsJson,
34 | })
35 | // b. Compose from "column_defs" without explicit table alias
36 | : registry.JSONSchema.fromJSON({
37 | entries: columnDefsJson,
38 | });
39 |
40 | resultJson = {
41 | ...resultJson,
42 | result_schema: resultSchema
43 | };
44 | }
45 |
46 | return resultJson;
47 | }
48 | }
--------------------------------------------------------------------------------
/src/lang/dml/constructors/ValuesConstructor.js:
--------------------------------------------------------------------------------
1 | import { ResultSchemaMixin } from '../../abstracts/ResultSchemaMixin.js';
2 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
3 |
4 | export class ValuesConstructor extends ResultSchemaMixin(AbstractNodeList) {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | const itemSeparator = { type: 'punctuation', value: ',' };
10 | return {
11 | syntaxes: [
12 | [
13 | { type: 'keyword', value: 'VALUES' },
14 | { type: ['TypedRowConstructor', 'RowConstructor'], as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 }
15 | ],
16 | {
17 | dialect: 'mysql',
18 | syntax: [
19 | { type: 'keyword', value: ['VALUES', 'VALUE'] },
20 | { type: ['TypedRowConstructor', 'RowConstructor'], as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 }
21 | ]
22 | },
23 | ],
24 | };
25 | }
26 |
27 | static get syntaxPriority() { return -1; }
28 |
29 | /* JSON API */
30 |
31 | jsonfy(options = {}, transformer = null, schemaInference = null) {
32 | let resultJson = super.jsonfy({ ...options, forceDeSugar: options.deSugar }, transformer, schemaInference);
33 | if (options.deSugar) {
34 | const row1_resultSchema = resultJson.entries?.[0]?.result_schema;
35 | resultJson = {
36 | ...resultJson,
37 | result_schema: row1_resultSchema?.clone()
38 | };
39 | }
40 | return resultJson;
41 | }
42 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/ColumnFKConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 | import { registry } from '../../registry.js';
3 |
4 | const {
5 | ColumnSchema,
6 | ColumnRef2,
7 | } = registry;
8 |
9 | export class ColumnFKConstraint extends ConstraintSchema {
10 |
11 | /* SYNTAX RULES */
12 |
13 | static get syntaxRules() {
14 | const itemSeparator = { type: 'punctuation', value: ',' };
15 | return this.buildSyntaxRules([
16 | { type: 'keyword', value: 'REFERENCES' },
17 | { type: 'TableRef2', as: 'target_table', assert: true },
18 | {
19 | dialect: 'postgres',
20 | optional: true,
21 | type: 'paren_block',
22 | syntax: { type: 'Identifier', as: 'target_columns', arity: 1, itemSeparator, singletons: 'BY_KEY', assert: true },
23 | },
24 | {
25 | dialect: 'mysql',
26 | type: 'paren_block',
27 | syntax: { type: 'Identifier', as: 'target_columns', arity: 1, itemSeparator, singletons: 'BY_KEY', assert: true },
28 | },
29 | { type: ['FKMatchRule', 'FKDeleteRule', 'FKUpdateRule'], as: 'referential_rules', arity: Infinity, singletons: true },
30 |
31 | ]);
32 | }
33 |
34 | /* AST API */
35 |
36 | targetTable() { return this._get('target_table'); }
37 |
38 | targetColumns() { return this._get('target_columns'); }
39 |
40 | referentialRules() { return this._get('referential_rules'); }
41 |
42 | /* API */
43 |
44 | columns() {
45 | return this.parentNode instanceof ColumnSchema
46 | ? [ColumnRef2.fromJSON({ value: this.parentNode.name().value() })]
47 | : [];
48 | }
49 | }
--------------------------------------------------------------------------------
/src/lang/abstracts/OriginSchemasMixin.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from './AbstractNode.js';
2 | import { registry } from '../registry.js';
3 |
4 | export const OriginSchemasMixin = (Class) => class extends Class {
5 |
6 | #origin_schemas;
7 |
8 | originSchemas() { return this.#origin_schemas; }
9 |
10 | static fromJSON(inputJson, options = {}, callback = null) {
11 | if (!inputJson || inputJson instanceof AbstractNode) {
12 | return super.fromJSON(inputJson, options, callback);
13 | }
14 | const { origin_schemas, ...restJson } = inputJson;
15 | const instance = super.fromJSON(restJson, options, callback);
16 | if (instance && origin_schemas) {
17 | if (!Array.isArray(origin_schemas)) {
18 | throw new Error(`Invalid list passed at inputJson.origin_schemas`);
19 | }
20 | instance.#origin_schemas = origin_schemas;
21 | }
22 | return instance;
23 | }
24 |
25 | jsonfy(options = {}, transformer = null, schemaInference = null) {
26 | let resultJson = super.jsonfy(options, transformer, schemaInference);
27 | if (this.#origin_schemas && options.originSchemas !== false) {
28 | resultJson = {
29 | ...resultJson,
30 | origin_schemas: this.#origin_schemas,
31 | };
32 | }
33 | return resultJson;
34 | }
35 |
36 | getOriginSchemas(transformer) {
37 | const originSchemas = [];
38 | let foundJSONSchema = false;
39 | for (const { resultSchema } of transformer.statementContext.artifacts.get('tableSchemas')) {
40 | if (resultSchema instanceof registry.JSONSchema) {
41 | if (foundJSONSchema) {
42 | // Not expect; not valid SQL; but however
43 | throw new Error(`Multiple anonymous origin schemas detected`);
44 | }
45 | foundJSONSchema = true;
46 | }
47 | originSchemas.push(resultSchema);
48 | }
49 | return originSchemas;
50 | }
51 | }
--------------------------------------------------------------------------------
/src/lang/dml/clauses/PGOnConflictClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from '../../abstracts/AbstractNodeList.js';
2 |
3 | export class PGOnConflictClause extends AbstractNodeList {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'postgres',
11 | syntax: [
12 | { type: 'keyword', value: 'ON' },
13 | { type: 'keyword', value: 'CONFLICT' },
14 | {
15 | syntaxes: [
16 | [
17 | { type: 'PGConflictTarget', as: 'conflict_target', optional: true },
18 | { type: 'keyword', as: 'do_nothing_kw', value: 'DO', booleanfy: true },
19 | { type: 'keyword', value: 'NOTHING' },
20 | ],
21 | [
22 | { type: 'PGConflictTarget', as: 'conflict_target' },
23 | { type: 'keyword', value: 'DO' },
24 | { type: 'keyword', value: 'UPDATE' },
25 | { type: 'keyword', value: 'SET' },
26 | { type: 'AssignmentExpr', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: true },
27 | { type: 'WhereClause', as: 'where_clause', optional: true, autoIndent: true },
28 | ],
29 | ],
30 | }
31 | ],
32 | };
33 | }
34 |
35 | /* AST API */
36 |
37 | conflictTarget() { return this._get('conflict_target'); }
38 |
39 | doNothingKW() { return this._get('do_nothing_kw'); }
40 |
41 | whereClause() { return this._get('where_clause'); }
42 | }
--------------------------------------------------------------------------------
/site/.vitepress/cache/deps/_metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "hash": "d133ad6b",
3 | "configHash": "60d1ba4e",
4 | "lockfileHash": "f450393d",
5 | "browserHash": "37503542",
6 | "optimized": {
7 | "vue": {
8 | "src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
9 | "file": "vue.js",
10 | "fileHash": "1f9f2d58",
11 | "needsInterop": false
12 | },
13 | "vitepress > @vue/devtools-api": {
14 | "src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
15 | "file": "vitepress___@vue_devtools-api.js",
16 | "fileHash": "6ea27cdd",
17 | "needsInterop": false
18 | },
19 | "vitepress > @vueuse/core": {
20 | "src": "../../../../node_modules/@vueuse/core/index.mjs",
21 | "file": "vitepress___@vueuse_core.js",
22 | "fileHash": "8ed43ceb",
23 | "needsInterop": false
24 | },
25 | "vitepress > @vueuse/integrations/useFocusTrap": {
26 | "src": "../../../../node_modules/@vueuse/integrations/useFocusTrap.mjs",
27 | "file": "vitepress___@vueuse_integrations_useFocusTrap.js",
28 | "fileHash": "a735dd0e",
29 | "needsInterop": false
30 | },
31 | "vitepress > mark.js/src/vanilla.js": {
32 | "src": "../../../../node_modules/mark.js/src/vanilla.js",
33 | "file": "vitepress___mark__js_src_vanilla__js.js",
34 | "fileHash": "05c2f6c3",
35 | "needsInterop": false
36 | },
37 | "vitepress > minisearch": {
38 | "src": "../../../../node_modules/minisearch/dist/es/index.js",
39 | "file": "vitepress___minisearch.js",
40 | "fileHash": "84e1bfaa",
41 | "needsInterop": false
42 | }
43 | },
44 | "chunks": {
45 | "chunk-Q2AYPHVK": {
46 | "file": "chunk-Q2AYPHVK.js"
47 | },
48 | "chunk-QAXAIFA7": {
49 | "file": "chunk-QAXAIFA7.js"
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/TableFKConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 |
3 | export class TableFKConstraint extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return this.buildSyntaxRules([
10 | { type: 'keyword', value: 'FOREIGN' },
11 | { type: 'keyword', value: 'KEY', assert: true },
12 | {
13 | type: 'paren_block',
14 | syntax: { type: 'ColumnRef2', as: 'columns', arity: { min: 1 }, itemSeparator, assert: true, singletons: 'BY_KEY' },
15 | },
16 | { type: 'keyword', value: 'REFERENCES' },
17 | { type: 'TableRef2', as: 'target_table', assert: true },
18 | {
19 | dialect: 'postgres',
20 | optional: true,
21 | type: 'paren_block',
22 | syntax: { type: 'Identifier', as: 'target_columns', arity: { min: 1 }, itemSeparator, singletons: 'BY_KEY', assert: true },
23 | },
24 | {
25 | dialect: 'mysql',
26 | type: 'paren_block',
27 | syntax: { type: 'Identifier', as: 'target_columns', arity: { min: 1 }, itemSeparator, singletons: 'BY_KEY', assert: true },
28 | },
29 | { type: ['FKMatchRule', 'FKDeleteRule', 'FKUpdateRule'], as: 'referential_rules', arity: Infinity, assert: true, singletons: true },
30 | ]);
31 | }
32 |
33 | /* AST API */
34 |
35 | columns() { return this._get('columns'); }
36 |
37 | targetTable() { return this._get('target_table'); }
38 |
39 | targetColumns() { return this._get('target_columns'); }
40 |
41 | referentialRules() { return this._get('referential_rules'); }
42 | }
43 |
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/TableUKConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 |
3 | export class TableUKConstraint extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return this.buildSyntaxRules([
10 | { type: 'keyword', value: 'UNIQUE' },
11 | { type: 'keyword', as: 'my_key_kw', value: ['KEY', 'INDEX'], optional: true, dialect: 'mysql' },
12 | {
13 | optional: true,
14 | dialect: 'postgres',
15 | syntaxes: [
16 | [
17 | { type: 'keyword', value: 'NULLS' },
18 | { type: 'operator', as: 'pg_nulls_distinct', value: 'NOT' },
19 | { type: 'keyword', value: 'DISTINCT', assert: true },
20 | ],
21 | [
22 | { type: 'keyword', value: 'NULLS' },
23 | { type: 'keyword', as: 'pg_nulls_distinct', value: 'DISTINCT', assert: true },
24 | ],
25 | ]
26 | },
27 | {
28 | type: 'paren_block',
29 | syntax: { type: 'ColumnRef2', as: 'columns', arity: { min: 1 }, itemSeparator, singletons: 'BY_KEY', assert: true },
30 | assert: true,
31 | },
32 | { type: 'PGIndexParameters', as: 'pg_index_parameters', optional: true, dialect: 'postgres' }
33 | ]);
34 | }
35 |
36 | /* AST API */
37 |
38 | myKeyKW() { return this._get('my_key_kw'); }
39 |
40 | pgNullsDistinct() { return this._get('pg_nulls_distinct'); }
41 |
42 | columns() { return this._get('columns'); }
43 |
44 | pgIndexParameters() { return this._get('pg_index_parameters'); }
45 | }
--------------------------------------------------------------------------------
/src/lang/abstracts/AbstractSchema.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from './AbstractNodeList.js';
2 | import { AbstractNode } from './AbstractNode.js';
3 | import { registry } from '../registry.js';
4 |
5 | export class AbstractSchema extends AbstractNodeList {
6 |
7 | /* AST API */
8 |
9 | name() { return this._get('name'); }
10 |
11 | /* API */
12 |
13 | identifiesAs(value, ...args) {
14 | return this.name()?.identifiesAs(
15 | value instanceof AbstractSchema ? value.name() : value,
16 | ...args
17 | );
18 | }
19 |
20 | /* JSON API */
21 |
22 | static fromJSON(inputJson, options = {}, callback = null) {
23 | if (inputJson instanceof AbstractNode) {
24 | return super.fromJSON(inputJson, options, callback);
25 | }
26 | const { ddl_name, ...restJson } = inputJson;
27 | const node = super.fromJSON(restJson, options, callback);
28 | if (ddl_name && node) {
29 | const iddlNameIdent = [registry.NamespaceIdent, registry.TableIdent, registry.ColumnIdent].reduce((prev, Class) => prev || Class.fromJSON(ddl_name), null);
30 | node._set('ddl_name', iddlNameIdent);
31 | }
32 | return node;
33 | }
34 |
35 | jsonfy({ renameTo, ...options } = {}, transformer = null, schemaInference = null) {
36 | let resultJson = super.jsonfy(options, transformer, schemaInference);
37 | if (renameTo) {
38 | if (renameTo instanceof AbstractNode) {
39 | throw new Error(`options.renameTo must be a JSON value.`);
40 | }
41 | if (resultJson.name?.value && !resultJson.ddl_name) {
42 | resultJson = { ...resultJson, ddl_name: resultJson.name };
43 | }
44 | return { ...resultJson, name: renameTo };
45 | }
46 | return resultJson;
47 | }
48 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/ColumnUKConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class ColumnUKConstraint extends ConstraintSchema {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | return this.buildSyntaxRules([
10 | { type: 'keyword', value: 'UNIQUE' },
11 | { type: 'keyword', as: 'my_key_kw', value: ['KEY', 'INDEX'], optional: true, dialect: 'mysql' },
12 | {
13 | optional: true,
14 | dialect: 'postgres',
15 | syntaxes: [
16 | [
17 | { type: 'keyword', value: 'NULLS' },
18 | { type: 'operator', as: 'pg_nulls_distinct', value: 'NOT' },
19 | { type: 'keyword', value: 'DISTINCT', assert: true },
20 | ],
21 | [
22 | { type: 'keyword', value: 'NULLS' },
23 | { type: 'keyword', as: 'pg_nulls_distinct', value: 'DISTINCT', assert: true },
24 | ],
25 | ]
26 | },
27 | { type: 'PGIndexParameters', as: 'pg_index_parameters', optional: true, dialect: 'postgres' }
28 | ]);
29 | }
30 |
31 | /* AST API */
32 |
33 | myKeyKW() { return this._get('my_key_kw'); }
34 |
35 | pgNullsDistinct() { return this._get('pg_nulls_distinct'); }
36 |
37 | pgIndexParameters() { return this._get('pg_index_parameters'); }
38 |
39 | /* API */
40 |
41 | columns() {
42 | const {
43 | ColumnSchema,
44 | ColumnRef2,
45 | } = registry;
46 | return this.parentNode instanceof ColumnSchema
47 | ? [ColumnRef2.fromJSON({ value: this.parentNode.name().value() })]
48 | : [];
49 | }
50 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/LQBackBackRef.js:
--------------------------------------------------------------------------------
1 | import { AbstractMagicRef } from './abstracts/AbstractMagicRef.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class LQBackBackRef extends AbstractMagicRef {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _leftType() {
9 | return [
10 | 'LQBackRefEndpoint'/* must come first to prevent left-recursion */,
11 | 'LQBackBackRef'
12 | ];
13 | } // for inheritance
14 |
15 | static get syntaxRules() {
16 | return [
17 | { type: this._leftType, as: 'left', peek: [1, 'operator', '<~'] },
18 | { type: 'operator', value: '<~' },
19 | { type: 'ColumnRef2', as: 'right', peek: [1, 'operator', '<~'] },
20 | ];
21 | }
22 |
23 | static get syntaxPriority() { return 1; }
24 |
25 | static morphsTo() { return [registry.LQDeepRef1, registry.LQDeepRef2, registry.LQDeepDeepRef1, registry.LQDeepDeepRef2]; }
26 |
27 | /* API */
28 |
29 | operand() { return this.right(); }
30 |
31 | endpoint() { return this.left() instanceof LQBackBackRef ? this.left().endpoint() : this.left(); }
32 |
33 | /* JSON API */
34 |
35 | jsonfy({ reverseRef = false, toKind = 1, ...options } = {}, transformer = null, schemaInference = null) {
36 | if (reverseRef) {
37 | return {
38 | nodeName: toKind === 2
39 | ? (reverseRef === Infinity ? registry.LQDeepDeepRef2.NODE_NAME : registry.LQDeepRef2.NODE_NAME)
40 | : (reverseRef === Infinity ? registry.LQDeepDeepRef1.NODE_NAME : registry.LQDeepRef1.NODE_NAME),
41 | left: this.right().jsonfy({ toKind: reverseRef !== Infinity ? 1 : 2, ...options }),
42 | right: this.left() instanceof registry.LQBackRefEndpoint
43 | ? { nodeName: registry.ColumnRef2.NODE_NAME, value: this.left().value(), delim: this.left()._get('delim') }
44 | : this.left().jsonfy({ reverseRef: Infinity, toKind, ...options }),
45 | };
46 | }
47 | return super.jsonfy(options, transformer, schemaInference);
48 | }
49 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/PGTableEXConstraint.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from './ConstraintSchema.js';
2 |
3 | export class PGTableEXConstraint extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'postgres',
11 | syntax: this.buildSyntaxRules([
12 | { type: 'keyword', value: 'EXCLUDE' },
13 | {
14 | optional: true,
15 | syntax: [
16 | { type: 'keyword', value: 'USING' },
17 | { type: 'keyword', as: 'index_method', assert: true },
18 | ],
19 | },
20 | {
21 | type: 'paren_block',
22 | syntax: { type: 'PGTableEXConstraintItem', as: 'entries', arity: { min: 1 }, itemSeparator, assert: true },
23 | assert: true,
24 | },
25 | { type: 'PGIndexParameters', as: 'pg_index_parameters', optional: true },
26 | {
27 | optional: true,
28 | syntax: [
29 | { type: 'keyword', value: 'WHERE' },
30 | {
31 | type: 'paren_block',
32 | syntax: { type: 'Expr', as: 'where_predicate', assert: true },
33 | assert: true,
34 | }
35 | ],
36 | }
37 | ])
38 | };
39 | }
40 |
41 | /* AST API */
42 |
43 | indexMethod() { return this._get('index_method'); }
44 |
45 | entries() { return this._get('entries'); }
46 |
47 | pgIndexParameters() { return this._get('pg_index_parameters'); }
48 |
49 | wherePredicate() { return this._get('where_predicate'); }
50 | }
--------------------------------------------------------------------------------
/src/lang/cte/constructs/PGCycleClause.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../../abstracts/AbstractNode.js';
2 |
3 | export class PGCycleClause extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return {
10 | dialect: 'postgres',
11 | syntax: [
12 | { type: 'keyword', value: 'CYCLE' },
13 | {
14 | assert: true,
15 | syntax: [
16 | { type: 'ColumnRef1', as: 'column_names', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
17 | { type: 'keyword', value: 'SET' },
18 | { type: 'ColumnRef1', as: 'mark_col_name' },
19 | {
20 | optional: true,
21 | syntax: [
22 | { type: 'keyword', value: 'TO' },
23 | { type: 'Expr', as: 'mark_value' },
24 | { type: 'keyword', value: 'DEFAULT' },
25 | { type: 'Expr', as: 'mark_default' },
26 | ]
27 | },
28 | { type: 'keyword', value: 'USING' },
29 | { type: 'ColumnRef1', as: 'path_col_name' },
30 | ]
31 | },
32 | ]
33 | };
34 | }
35 |
36 | /* AST API */
37 |
38 | breadthOrDepthFirst() { return this._get('breadth_or_depth_first'); }
39 |
40 | columnNames() { return this._get('column_names'); }
41 |
42 | markColName() { return this._get('mark_col_name'); }
43 |
44 | markValue() { return this._get('mark_value'); }
45 |
46 | markDefault() { return this._get('mark_default'); }
47 |
48 | pathColName() { return this._get('path_col_name'); }
49 | }
--------------------------------------------------------------------------------
/src/lang/type/DataType.js:
--------------------------------------------------------------------------------
1 | import { AbstractNode } from '../abstracts/AbstractNode.js';
2 |
3 | export class DataType extends AbstractNode {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | {
11 | syntaxes: [
12 | [
13 | { type: 'data_type', as: '.', value: ['TIME', 'TIMESTAMP'], dialect: 'postgres' },
14 | { type: 'data_type', as: '.', value: ['TIME', 'TIMESTAMP', 'DATETIME'], dialect: 'mysql' },
15 | {
16 | optional: true,
17 | dialect: 'postgres',
18 | syntax: [
19 | { type: 'keyword', as: 'pg_with_tz', value: ['WITH', 'WITHOUT'] },
20 | { type: 'keyword', value: 'TIME ZONE', assert: true },
21 | ]
22 | }
23 | ],
24 | { type: 'data_type', as: '.' },
25 | { type: 'keyword', as: '.', value: ['SET'] },
26 | ]
27 | },
28 | {
29 | type: 'paren_block',
30 | syntax: { type: 'Expr', as: 'specificity', arity: Infinity, itemSeparator, assert: true },
31 | optional: true,
32 | optionalParens: true,
33 | autoSpacing: false
34 | },
35 | { type: 'AggrNotation', as: 'pg_is_aggr', autoSpacing: false, optional: true, dialect: 'postgres' },
36 | ];
37 | }
38 |
39 | /* AST API */
40 |
41 | value() { return this._get('value'); }
42 |
43 | specificity() { return this._get('specificity'); }
44 |
45 | // -- Postgres
46 |
47 | pgIsAggr() { return this._get('pg_is_aggr'); }
48 |
49 | pgWithTZ() { return this._get('pg_with_tz'); }
50 | }
--------------------------------------------------------------------------------
/site/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | title: LinkedQL
4 | hero:
5 | name: LinkedQL
6 | text: A modern take on SQL and SQL databases.
7 | tagline: >
8 | Reactivity, Relationships, JSON, Schemas, Embedding, Federation & Sync, and More → SOLVED.
9 | actions:
10 | - theme: brand
11 | text: Get Started
12 | link: /docs/
13 | - theme: alt
14 | text: Star on GitHub
15 | link: https://github.com/linked-db/linked-ql
16 | features:
17 | - title: Relationships Solved
18 | details: Traverse relationships directly in your queries — without writing a JOIN. Meet DeepRefs, the syntax shorthand that lets you follow relationships using simple arrow notation — SELECT a ~> b
19 | - title: JSON Solved
20 | details: Bring JSON-like clearity to your queries. LinkedQL's first-class support for JSON notation saves you the wrangling with SQL's low-level JSON functions — SELECT { a, b }
21 | - title: Schemas Solved
22 | details: Take a break from manual schema ops. LinkedQL operates with full context of your schema and automates the world for you. With Automatic Schema Inference, everything just works — without you
23 | - title: Reactivity Solved
24 | details: Turn on reactivity over arbitrary SQL with { live∶ true }. You get back a live view of your query. Live Queries in LinkedQL works directly on your database without a middleware or GraphQL servers.
25 | - title: Versioning Solved
26 | details: Get automatic database versioning as you iterate and evolve your schemas. LinkedQL makes that a reality right on your database. And that means, no more manual migration practices.
27 | - title: Embedding, Federation & Sync Solved
28 | details: Run SQL anywhere — even offline. Meet FlashQL, the in-memory engine that brings full LinkedQL semantics to the client and edge. And it comes as one query space over your entire data universe.
29 | ---
30 |
--------------------------------------------------------------------------------
/src/lang/expr/ref/LQDeepDeepRef1.js:
--------------------------------------------------------------------------------
1 | import { AbstractMagicRef } from './abstracts/AbstractMagicRef.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class LQDeepDeepRef1 extends AbstractMagicRef {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _rightType() { return ['LQDeepDeepRef1', 'LQObjectLiteral', 'LQArrayLiteral', 'RowConstructor', 'ColumnRef2']; } // for inheritance
9 |
10 | static get syntaxRules() {
11 | return [
12 | { type: ['ColumnRef2', 'LQBackRefAbstraction'], as: 'left', peek: [1, 'operator', '~>'] },
13 | { type: 'operator', value: '~>' },
14 | { type: this._rightType, as: 'right' },
15 | ];
16 | }
17 |
18 | static get syntaxPriority() { return -1; }
19 |
20 | static morphsTo() { return [registry.LQDeepRef1, registry.LQDeepRef2, registry.LQDeepDeepRef1, registry.LQDeepDeepRef2]; }
21 |
22 | /* API */
23 |
24 | operand() { return this.left(); }
25 |
26 | endpoint() { return this.right() instanceof LQDeepDeepRef1 ? this.right().endpoint() : this.right(); }
27 |
28 | /* JSON API */
29 |
30 | jsonfy({ toDeepRef = false, toKind = 1, ...options } = {}, transformer = null, schemaInference = null) {
31 | if (toDeepRef || toKind === 1 || toKind === 2) {
32 | const altsMap = [
33 | registry.LQDeepRef1.NODE_NAME, registry.LQDeepRef2.NODE_NAME,
34 | registry.LQDeepDeepRef1.NODE_NAME, registry.LQDeepDeepRef2.NODE_NAME
35 | ];
36 |
37 | let currentIndex = altsMap.indexOf(this.NODE_NAME);
38 | if (toDeepRef && currentIndex > 1) {
39 | currentIndex -= 2;
40 | }
41 |
42 | const NODE_NAME = altsMap[(currentIndex + 1) % 2 === toKind % 2
43 | ? currentIndex
44 | : (toKind % 2 // its 1 or 3
45 | ? currentIndex - 1
46 | : currentIndex + 1)];
47 |
48 | return {
49 | nodeName: NODE_NAME,
50 | left: this.left().jsonfy({ toKind: currentIndex > 1 ? 2 : 1 }), // Left is always ColumnRef1 for DeepRef, but ColumnRef2 for DeepDeepRef
51 | right: this.right().jsonfy({ toKind: this.right() instanceof LQDeepDeepRef1 ? toKind : undefined }),
52 | };
53 | }
54 |
55 | return super.jsonfy(options, transformer, schemaInference);
56 | }
57 | }
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/index.md.BsUu5Xl8.js:
--------------------------------------------------------------------------------
1 | import{_ as e,c as t,o as a}from"./chunks/framework.B-XtCDNB.js";const h=JSON.parse(`{"title":"LinkedQL","description":"","frontmatter":{"layout":"home","title":"LinkedQL","hero":{"name":"LinkedQL","text":"A modern take on SQL and SQL databases.","tagline":"Relationships, JSON, Schema, Reactivity, Versioning, Offline → SOLVED.\\n","actions":[{"theme":"brand","text":"Get Started","link":"/docs/"},{"theme":"alt","text":"Star on GitHub","link":"https://github.com/linked-db/linked-ql"}]},"features":[{"title":"Relationships Solved","details":"Traverse relationships directly in your queries — without writing a JOIN. Meet DeepRefs, the syntax shorthand that lets you follow relationships using simple arrow notation — SELECT a ~> b"},{"title":"JSON Solved","details":"Bring JSON-like clearity to your queries. LinkedQL's first-class support for JSON notation saves you the wrangling with SQL's low-level JSON functions — SELECT { a, b }"},{"title":"Schema Solved","details":"Take a break from manual schema ops. LinkedQL operates with full context of your schema and automates the world for you. With Automatic Schema Inference, everything just works — without you"},{"title":"Reactivity Solved","details":"Turn on reactivity over arbitrary SQL with { live∶ true }. You get back a live view of your query. Live Queries in LinkedQL works directly on your database without a middleware or GraphQL servers."},{"title":"Versioning Solved","details":"Get automatic database versioning as you iterate and evolve your schemas. LinkedQL makes that a reality right on your database. And that means, no more manual migration practices."},{"title":"Offline Solved","details":"Run SQL anywhere — even offline. Meet FlashQL, the in-memory engine that brings full LinkedQL semantics to the client and edge. And it comes as one query space over your entire data universe."}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}`),i={name:"index.md"};function n(o,s,r,l,d,c){return a(),t("div")}const m=e(i,[["render",n]]);export{h as __pageData,m as default};
2 |
--------------------------------------------------------------------------------
/site/.vitepress/dist/assets/index.md.BsUu5Xl8.lean.js:
--------------------------------------------------------------------------------
1 | import{_ as e,c as t,o as a}from"./chunks/framework.B-XtCDNB.js";const h=JSON.parse(`{"title":"LinkedQL","description":"","frontmatter":{"layout":"home","title":"LinkedQL","hero":{"name":"LinkedQL","text":"A modern take on SQL and SQL databases.","tagline":"Relationships, JSON, Schema, Reactivity, Versioning, Offline → SOLVED.\\n","actions":[{"theme":"brand","text":"Get Started","link":"/docs/"},{"theme":"alt","text":"Star on GitHub","link":"https://github.com/linked-db/linked-ql"}]},"features":[{"title":"Relationships Solved","details":"Traverse relationships directly in your queries — without writing a JOIN. Meet DeepRefs, the syntax shorthand that lets you follow relationships using simple arrow notation — SELECT a ~> b"},{"title":"JSON Solved","details":"Bring JSON-like clearity to your queries. LinkedQL's first-class support for JSON notation saves you the wrangling with SQL's low-level JSON functions — SELECT { a, b }"},{"title":"Schema Solved","details":"Take a break from manual schema ops. LinkedQL operates with full context of your schema and automates the world for you. With Automatic Schema Inference, everything just works — without you"},{"title":"Reactivity Solved","details":"Turn on reactivity over arbitrary SQL with { live∶ true }. You get back a live view of your query. Live Queries in LinkedQL works directly on your database without a middleware or GraphQL servers."},{"title":"Versioning Solved","details":"Get automatic database versioning as you iterate and evolve your schemas. LinkedQL makes that a reality right on your database. And that means, no more manual migration practices."},{"title":"Offline Solved","details":"Run SQL anywhere — even offline. Meet FlashQL, the in-memory engine that brings full LinkedQL semantics to the client and edge. And it comes as one query space over your entire data universe."}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}`),i={name:"index.md"};function n(o,s,r,l,d,c){return a(),t("div")}const m=e(i,[["render",n]]);export{h as __pageData,m as default};
2 |
--------------------------------------------------------------------------------
/src/lang/expr/literals/LQArrayLiteral.js:
--------------------------------------------------------------------------------
1 | import { AbstractLQJsonLiteral } from './AbstractLQJsonLiteral.js';
2 | import { registry } from '../../registry.js';
3 |
4 | export class LQArrayLiteral extends AbstractLQJsonLiteral {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get syntaxRules() {
9 | const itemSeparator = { type: 'punctuation', value: ',' };
10 | return {
11 | syntax: [
12 | {
13 | type: 'bracket_block',
14 | syntax: { type: 'Expr', as: 'entries', arity: Infinity, itemSeparator, autoIndent: 2 },
15 | },
16 | ],
17 | };
18 | }
19 |
20 | static morphsTo() { return registry.CallExpr; }
21 |
22 | /* JSON API */
23 |
24 | jsonfy(options = {}, transformer = null, schemaInference = null) {
25 | let resultJson = super.jsonfy(options, transformer, schemaInference);
26 | if (options.deSugar) {
27 | const resultSchemas = [];
28 |
29 | resultJson = {
30 | nodeName: registry.CallExpr.NODE_NAME,
31 | name: (options.toDialect || this.options.dialect) === 'mysql' ? 'JSON_ARRAY' : 'JSON_BUILD_ARRAY',
32 | arguments: resultJson.entries.map((e, i) => {
33 |
34 | let resultSchema = e.result_schema;
35 | const namespaceIdent = { value: i, nodeName: registry.Identifier.NODE_NAME };
36 |
37 | if (resultSchema instanceof registry.ColumnSchema) {
38 | resultSchema = resultSchema.clone({ renameTo: namespaceIdent });
39 | } else {
40 | resultSchema = registry.ColumnSchema.fromJSON({
41 | name: namespaceIdent,
42 | data_type: this.entries()[i].dataType().jsonfy(),
43 | });
44 | }
45 | resultSchemas.push(resultSchema);
46 |
47 | return e;
48 | }),
49 | result_schema: registry.JSONSchema.fromJSON({ entries: resultSchemas }, { assert: true })
50 | };
51 | }
52 |
53 | return resultJson;
54 | }
55 | }
--------------------------------------------------------------------------------
/src/lang/Script.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeList } from './abstracts/AbstractNodeList.js';
2 | import { StdStmt } from './StdStmt.js';
3 |
4 | export class Script extends AbstractNodeList {
5 |
6 | /* SYNTAX RULES */
7 |
8 | static get _contentTypes() {
9 | return [
10 | 'SelectStmt',
11 | 'TableStmt',
12 | 'InsertStmt',
13 | 'UpsertStmt',
14 | 'UpdateStmt',
15 | 'DeleteStmt',
16 | 'MYSetStmt',
17 | 'PGSetStmt',
18 | 'CTE',
19 | 'CreateSchemaStmt',
20 | 'DropSchemaStmt',
21 | 'CreateTableStmt',
22 | 'DropTableStmt',
23 | 'StdStmt',
24 | ];
25 | }
26 |
27 | static get syntaxRules() {
28 | const itemSeparator = { type: 'punctuation', value: ';' };
29 | return { type: this._contentTypes, as: 'entries', arity: Infinity, itemSeparator, autoSpacing: '\n' };
30 | }
31 |
32 | /* API */
33 |
34 | static async parse(input, options = {}) {
35 | const tokenStream = await this.toStream(input, options);
36 | const result = await super.parse(tokenStream, options);
37 | if (!tokenStream.done && tokenStream.current()) {
38 | const current = tokenStream.current();
39 | const message = `[${this.NODE_NAME}] Unexpected ${current.type} token:${typeof current.value === 'string' ? ` "${current.value}"` : ''} at `;
40 | throw new SyntaxError(message);
41 | }
42 | return result;
43 | }
44 |
45 | static async _parseFromRules(tokenStream, syntaxRules, { left, minPrecedence, trail, ...options }, resultAST = {}) {
46 | let rulesArray;
47 | if (!options.supportStdStmt && (rulesArray = [].concat(syntaxRules)).length === 1 && Array.isArray(rulesArray[0].type) && rulesArray[0].type.includes('StdStmt')) {
48 | syntaxRules = { ...rulesArray[0], type: rulesArray[0].type.filter((r) => r !== 'StdStmt') };
49 | }
50 | return super._parseFromRules(tokenStream, syntaxRules, { left, minPrecedence, trail, ...options }, resultAST);
51 | }
52 |
53 | stringify(options = {}) { return `${super.stringify(options)};`; }
54 | }
--------------------------------------------------------------------------------
/src/lang/abstracts/util.js:
--------------------------------------------------------------------------------
1 | import { _isObject } from '@webqit/util/js/index.js';
2 |
3 | export function _eq(a, b, cs = false, ignoreList = null) {
4 | if (Array.isArray(a) && Array.isArray(b)) {
5 | return a.length === b.length && (b = b.slice(0).sort())
6 | && a.slice(0).sort().every((x, i) => _eq(x, b[i], cs, ignoreList));
7 | }
8 | if (typeof a?.jsonfy === 'function') a = a.jsonfy();
9 | if (typeof b?.jsonfy === 'function') b = b.jsonfy();
10 | if (_isObject(a) && _isObject(b)) {
11 | const temp = {
12 | indexs_a: Object.keys(a),
13 | indexs_b: Object.keys(b),
14 | };
15 | if (ignoreList?.length) {
16 | const $ignoreList = [].concat(ignoreList);
17 | temp.indexs_a = temp.indexs_a.filter((k) => !$ignoreList.includes(k));
18 | temp.indexs_b = temp.indexs_b.filter((k) => !$ignoreList.includes(k));
19 | }
20 | return temp.indexs_a.length === temp.indexs_b.length
21 | && temp.indexs_a.reduce((prev, k) => prev && _eq(a[k], b[k], cs, ignoreList), true);
22 | }
23 | if (typeof a === 'string' && typeof b === 'string' && cs === false) {
24 | return a.toLowerCase() === b.toLowerCase();
25 | }
26 | return a === b;
27 | }
28 |
29 | export function _toCapsSnake(str) {
30 | // Handle cases like "myVariableName" -> "my_Variable_Name"
31 | // This regex looks for a lowercase letter or digit followed by an uppercase letter.
32 | // It inserts an underscore between them.
33 | let result = str.replace(/([a-z0-9])([A-Z])/g, '$1_$2');
34 |
35 | // Handle cases like "HTMLParser" -> "HTML_Parser" or "APICall" -> "API_Call"
36 | // This regex looks for an uppercase letter followed by another uppercase letter
37 | // which is then followed by a lowercase letter. This targets the transition
38 | // from an acronym to a new word.
39 | // Example: In "HTMLParser", it matches 'L' and then 'P' (uppercase) followed by 'a' (lowercase).
40 | // It inserts an underscore between the first uppercase letter and the second.
41 | result = result.replace(/([A-Z])([A-Z][a-z])/g, '$1_$2');
42 |
43 | // Convert the entire string to uppercase.
44 | return result.toUpperCase();
45 | }
--------------------------------------------------------------------------------
/src/lang/ddl/constraint/constructs/PGTableEXConstraintItem.js:
--------------------------------------------------------------------------------
1 | import { ConstraintSchema } from '../ConstraintSchema.js';
2 |
3 | export class PGTableEXConstraintItem extends ConstraintSchema {
4 |
5 | /* SYNTAX RULES */
6 |
7 | static get syntaxRules() {
8 | const itemSeparator = { type: 'punctuation', value: ',' };
9 | return [
10 | {
11 | syntaxes: [
12 | { type: 'ColumnRef2', as: 'expr' },
13 | { type: 'ParenExpr', as: 'expr' },
14 | ],
15 | },
16 | {
17 | optional: true,
18 | syntax: [
19 | { type: 'operator', value: 'COLLATE' },
20 | { type: 'string_literal', as: 'collation', assert: true },
21 | ],
22 | },
23 | {
24 | optional: true,
25 | syntax: [
26 | { type: 'Identifier', as: 'opclass' },
27 | {
28 | optional: true,
29 | type: 'paren_block',
30 | syntax: { type: 'ConfigAssignmentExpr', as: 'opclass_parameters', arity: { min: 1 }, itemSeparator, assert: true },
31 | },
32 | ],
33 | },
34 | { type: 'keyword', value: ['ASC', 'DESC'], as: 'dir', optional: true },
35 | {
36 | optional: true,
37 | syntax: [
38 | { type: 'keyword', value: 'NULLS' },
39 | { type: 'keyword', as: 'nulls_spec', value: ['FIRST', 'LAST'], assert: true },
40 | ]
41 | },
42 | { type: 'keyword', value: 'WITH' },
43 | { type: 'operator', as: 'operator' },
44 | ];
45 | }
46 |
47 | /* AST API */
48 |
49 | expr() { return this._get('expr'); }
50 |
51 | collation() { return this._get('collation'); }
52 |
53 | opclass() { return this._get('opclass'); }
54 |
55 | opclassParameters() { return this._get('opclass_parameters'); }
56 |
57 | dir() { return this._get('dir'); }
58 |
59 | nullsSpec() { return this._get('nulls_spec'); }
60 |
61 | operator() { return this._get('operator'); }
62 | }
--------------------------------------------------------------------------------
/src/lang/cte/CTE.js:
--------------------------------------------------------------------------------
1 | import { AbstractNonDDLStmt } from '../abstracts/AbstractNonDDLStmt.js';
2 | import { Transformer } from '../Transformer.js';
3 | import { registry } from '../registry.js';
4 |
5 | export class CTE extends AbstractNonDDLStmt {
6 |
7 | /* SYNTAX RULES */
8 |
9 | static get _bodyTypes() {
10 | return [
11 | 'SelectStmt',
12 | 'TableStmt',
13 | 'InsertStmt',
14 | 'UpsertStmt',
15 | 'UpdateStmt',
16 | 'DeleteStmt',
17 | 'ValuesConstructor',
18 | ];
19 | }
20 |
21 | static get syntaxRules() {
22 | const itemSeparator = { type: 'punctuation', value: ',' };
23 | return [
24 | { type: 'keyword', value: 'WITH' },
25 | { type: 'keyword', as: 'recursive', value: 'RECURSIVE', booleanfy: true, optional: true },
26 | { type: 'CTEItem', as: 'declarations', arity: { min: 1 }, itemSeparator, assert: true, autoIndent: 2 },
27 | { type: this._bodyTypes, as: 'body', assert: true, autoSpacing: '\n' },
28 | ];
29 | }
30 |
31 | /* AST API */
32 |
33 | recursive() { return this._get('recursive'); }
34 |
35 | declarations() { return this._get('declarations'); }
36 |
37 | body() { return this._get('body'); }
38 |
39 | /* JSON API */
40 |
41 | jsonfy(options = {}, transformer = null, schemaInference = null) {
42 | if (!options.deSugar) return super.jsonfy(options, transformer, schemaInference);
43 |
44 | let outerResultSchema;
45 |
46 | transformer = new Transformer((node, defaultTransform, keyHint) => {
47 | // Process body nodes
48 | if (keyHint === 'body' && node.parentNode === this) {
49 | const bodyResultJson = defaultTransform();
50 |
51 | outerResultSchema = bodyResultJson.result_schema;
52 |
53 | return bodyResultJson;
54 | }
55 |
56 | return defaultTransform();
57 | }, transformer, this);
58 |
59 | // Run transform
60 | const resultJson = super.jsonfy(options, transformer, schemaInference);
61 | return {
62 | ...resultJson,
63 | result_schema: outerResultSchema,
64 | };
65 | }
66 | }
--------------------------------------------------------------------------------
/src/lang/expr/ref/abstracts/AbstractClassicRef.js:
--------------------------------------------------------------------------------
1 | import { ErrorRefUnknown } from './ErrorRefUnknown.js';
2 | import { ErrorRefAmbiguous } from './ErrorRefAmbiguous.js';
3 | import { AbstractNode } from '../../../abstracts/AbstractNode.js';
4 | import { ResultSchemaMixin } from '../../../abstracts/ResultSchemaMixin.js';
5 | import { TypeSysMixin } from '../../../abstracts/TypeSysMixin.js';
6 | import { Identifier } from '../Identifier.js';
7 |
8 | export class AbstractClassicRef extends ResultSchemaMixin(TypeSysMixin(Identifier)) {
9 |
10 | #resolution;
11 |
12 | resolution() { return this.#resolution; }
13 |
14 | lookup(transformer, schemaInference) { return []; }
15 |
16 | resolve(transformer, schemaInference) {
17 | const resultSet = this.lookup(null, transformer, schemaInference) || [];
18 | const objectType = this.constructor.name.match(/namespace/i) ? 'Namespace' : (this.constructor.name.match(/table/i) ? 'Table' : 'Column');
19 | if (resultSet.length > 1) {
20 | throw new ErrorRefAmbiguous(`[${this.parentNode?.parentNode || this.parentNode || this}] ${objectType} ${this} is ambiguous. (Is it ${resultSet.join(' or ')}?)`);
21 | } else if (!resultSet.length) {
22 | throw new ErrorRefUnknown(`[${this.parentNode?.parentNode || this.parentNode || this}] ${objectType} ${this} does not exist.`);
23 | }
24 | return resultSet[0];
25 | }
26 |
27 | static fromJSON(inputJson, options = {}, callback = null) {
28 | if (!inputJson || inputJson instanceof AbstractNode) {
29 | return super.fromJSON(inputJson, options, callback);
30 | }
31 | const { resolution, ...restJson } = inputJson;
32 | const instance = super.fromJSON(restJson, options, callback);
33 | if (instance && resolution) {
34 | if (typeof resolution !== 'string') {
35 | throw new Error(`Invalid "resolution" hint passed at inputJson.resolution`);
36 | }
37 | instance.#resolution = resolution;
38 | }
39 | return instance;
40 | }
41 |
42 | jsonfy(options = {}, transformer = null, schemaInference = null) {
43 | let resultJson = super.jsonfy(options, transformer, schemaInference);
44 | if (this.#resolution) {
45 | resultJson = {
46 | ...resultJson,
47 | resolution: this.#resolution,
48 | };
49 | }
50 | return resultJson;
51 | }
52 | }
--------------------------------------------------------------------------------