rawsql-ts 0.24.4 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/esm/index.d.ts +6 -0
  2. package/dist/esm/index.js +6 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/index.min.js +5 -5
  5. package/dist/esm/index.min.js.map +4 -4
  6. package/dist/esm/parsers/FunctionExpressionParser.d.ts +3 -0
  7. package/dist/esm/parsers/FunctionExpressionParser.js +50 -2
  8. package/dist/esm/parsers/FunctionExpressionParser.js.map +1 -1
  9. package/dist/esm/parsers/SqlPrintTokenParser.d.ts +1 -0
  10. package/dist/esm/parsers/SqlPrintTokenParser.js +11 -1
  11. package/dist/esm/parsers/SqlPrintTokenParser.js.map +1 -1
  12. package/dist/esm/transformers/AstCommentAttachmentExtractor.d.ts +61 -0
  13. package/dist/esm/transformers/AstCommentAttachmentExtractor.js +221 -0
  14. package/dist/esm/transformers/AstCommentAttachmentExtractor.js.map +1 -0
  15. package/dist/esm/transformers/ClauseScopedColumnReferenceCollector.d.ts +47 -0
  16. package/dist/esm/transformers/ClauseScopedColumnReferenceCollector.js +235 -0
  17. package/dist/esm/transformers/ClauseScopedColumnReferenceCollector.js.map +1 -0
  18. package/dist/esm/transformers/NamedQueryDefinitionExtractor.d.ts +53 -0
  19. package/dist/esm/transformers/NamedQueryDefinitionExtractor.js +370 -0
  20. package/dist/esm/transformers/NamedQueryDefinitionExtractor.js.map +1 -0
  21. package/dist/esm/transformers/SelectBodyExtractor.d.ts +21 -0
  22. package/dist/esm/transformers/SelectBodyExtractor.js +137 -0
  23. package/dist/esm/transformers/SelectBodyExtractor.js.map +1 -0
  24. package/dist/esm/transformers/SelectOutputCollector.d.ts +47 -0
  25. package/dist/esm/transformers/SelectOutputCollector.js +281 -0
  26. package/dist/esm/transformers/SelectOutputCollector.js.map +1 -0
  27. package/dist/esm/transformers/SelectValueCollector.d.ts +9 -1
  28. package/dist/esm/transformers/SelectValueCollector.js +83 -58
  29. package/dist/esm/transformers/SelectValueCollector.js.map +1 -1
  30. package/dist/esm/transformers/WildcardColumnInferenceCollector.d.ts +129 -0
  31. package/dist/esm/transformers/WildcardColumnInferenceCollector.js +373 -0
  32. package/dist/esm/transformers/WildcardColumnInferenceCollector.js.map +1 -0
  33. package/dist/index.js +6 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/index.min.js +5 -5
  36. package/dist/index.min.js.map +4 -4
  37. package/dist/parsers/FunctionExpressionParser.js +49 -1
  38. package/dist/parsers/FunctionExpressionParser.js.map +1 -1
  39. package/dist/parsers/SqlPrintTokenParser.js +11 -1
  40. package/dist/parsers/SqlPrintTokenParser.js.map +1 -1
  41. package/dist/src/index.d.ts +6 -0
  42. package/dist/src/parsers/FunctionExpressionParser.d.ts +3 -0
  43. package/dist/src/parsers/SqlPrintTokenParser.d.ts +1 -0
  44. package/dist/src/transformers/AstCommentAttachmentExtractor.d.ts +61 -0
  45. package/dist/src/transformers/ClauseScopedColumnReferenceCollector.d.ts +47 -0
  46. package/dist/src/transformers/NamedQueryDefinitionExtractor.d.ts +53 -0
  47. package/dist/src/transformers/SelectBodyExtractor.d.ts +21 -0
  48. package/dist/src/transformers/SelectOutputCollector.d.ts +47 -0
  49. package/dist/src/transformers/SelectValueCollector.d.ts +9 -1
  50. package/dist/src/transformers/WildcardColumnInferenceCollector.d.ts +129 -0
  51. package/dist/transformers/AstCommentAttachmentExtractor.js +231 -0
  52. package/dist/transformers/AstCommentAttachmentExtractor.js.map +1 -0
  53. package/dist/transformers/ClauseScopedColumnReferenceCollector.js +239 -0
  54. package/dist/transformers/ClauseScopedColumnReferenceCollector.js.map +1 -0
  55. package/dist/transformers/NamedQueryDefinitionExtractor.js +374 -0
  56. package/dist/transformers/NamedQueryDefinitionExtractor.js.map +1 -0
  57. package/dist/transformers/SelectBodyExtractor.js +141 -0
  58. package/dist/transformers/SelectBodyExtractor.js.map +1 -0
  59. package/dist/transformers/SelectOutputCollector.js +291 -0
  60. package/dist/transformers/SelectOutputCollector.js.map +1 -0
  61. package/dist/transformers/SelectValueCollector.js +83 -58
  62. package/dist/transformers/SelectValueCollector.js.map +1 -1
  63. package/dist/transformers/WildcardColumnInferenceCollector.js +377 -0
  64. package/dist/transformers/WildcardColumnInferenceCollector.js.map +1 -0
  65. package/dist/tsconfig.browser.tsbuildinfo +1 -1
  66. package/package.json +1 -1
@@ -42,6 +42,8 @@ export * from './transformers/CTEDependencyAnalyzer';
42
42
  export * from './transformers/CTETableReferenceCollector';
43
43
  export * from './transformers/CTEQueryDecomposer';
44
44
  export type { CTERestorationResult } from './transformers/CTEQueryDecomposer';
45
+ export * from './transformers/NamedQueryDefinitionExtractor';
46
+ export * from './transformers/AstCommentAttachmentExtractor';
45
47
  export * from './transformers/CTEComposer';
46
48
  export * from './transformers/CTERenamer';
47
49
  export * from './transformers/AliasRenamer';
@@ -50,6 +52,7 @@ export * from './formatters/OriginalFormatRestorer';
50
52
  export * from './transformers/SqlIdentifierRenamer';
51
53
  export type { ScopeRange } from './transformers/SqlIdentifierRenamer';
52
54
  export * from './transformers/ColumnReferenceCollector';
55
+ export * from './transformers/ClauseScopedColumnReferenceCollector';
53
56
  export * from './transformers/Formatter';
54
57
  export * from './transformers/SqlFormatter';
55
58
  export * from './transformers/QueryBuilder';
@@ -64,6 +67,9 @@ export * from './transformers/SimulatedSelectConverter';
64
67
  export * from './transformers/DDLToFixtureConverter';
65
68
  export * from './transformers/DDLGeneralizer';
66
69
  export * from './transformers/DDLDiffGenerator';
70
+ export * from './transformers/SelectBodyExtractor';
71
+ export * from './transformers/SelectOutputCollector';
72
+ export * from './transformers/WildcardColumnInferenceCollector';
67
73
  export * from './transformers/SelectValueCollector';
68
74
  export * from './transformers/SelectableColumnCollector';
69
75
  export { DuplicateDetectionMode } from './transformers/SelectableColumnCollector';
@@ -6,6 +6,7 @@ export declare class FunctionExpressionParser {
6
6
  */
7
7
  private static readonly AGGREGATE_FUNCTIONS_WITH_ORDER_BY;
8
8
  private static readonly SQL_JSON_CONSTRUCTORS;
9
+ private static readonly QUANTIFIED_COMPARISON_FUNCTIONS;
9
10
  /**
10
11
  * Parse ARRAY expressions - handles both ARRAY[...] (literal) and ARRAY(...) (query) syntax
11
12
  * @param lexemes Array of lexemes to parse
@@ -31,6 +32,8 @@ export declare class FunctionExpressionParser {
31
32
  */
32
33
  private static parseBetweenUpperBound;
33
34
  private static parseFunctionCall;
35
+ private static isSubqueryArgumentStart;
36
+ private static parseSubqueryArgumentWithComments;
34
37
  /**
35
38
  * Captures SQL/JSON constructor arguments as RawString while preserving closing
36
39
  * comments via getClosingComments. Empty argument lists still use ValueList.
@@ -211,6 +211,7 @@ export declare class SqlPrintTokenParser implements SqlComponentVisitor<SqlPrint
211
211
  private visitValueList;
212
212
  private visitColumnReference;
213
213
  private visitFunctionCall;
214
+ private isQuantifiedComparisonFunction;
214
215
  private relocateGroupingSetComments;
215
216
  private isGroupingSetsFunction;
216
217
  private extractPositionedComments;
@@ -0,0 +1,61 @@
1
+ import { SqlComponent } from "../models/SqlComponent";
2
+ /**
3
+ * Source span for a comment when parser metadata is available.
4
+ *
5
+ * @remarks The current parser stores comment text on AST nodes but does not
6
+ * retain reliable per-comment source spans, so extractors usually omit this.
7
+ */
8
+ export interface AstCommentSourceRange {
9
+ start: number;
10
+ end: number;
11
+ }
12
+ /**
13
+ * Conservatively describes where an AST comment fact appears relative to syntax.
14
+ */
15
+ export type AstCommentPlacement = "leading" | "trailing" | "inner" | "detached";
16
+ /**
17
+ * Generic comment fact extracted from SQL AST comment metadata.
18
+ *
19
+ * @remarks `targetNode` is optional because SQL comments do not always have a
20
+ * strict syntactic owner. Ambiguous legacy buckets are emitted as detached.
21
+ */
22
+ export interface AstCommentAttachment {
23
+ text: string;
24
+ sourceOrder: number;
25
+ placement: AstCommentPlacement;
26
+ targetNode?: SqlComponent;
27
+ range?: AstCommentSourceRange;
28
+ }
29
+ /**
30
+ * Extracts comment attachment facts already represented in the SQL AST.
31
+ *
32
+ * @remarks This API does not infer product-specific meanings or rewrite
33
+ * comments. It returns a deterministic flat list without mutating the input AST.
34
+ */
35
+ export declare class AstCommentAttachmentExtractor {
36
+ private readonly attachments;
37
+ private readonly visited;
38
+ private readonly suppressedDetachedCommentArrays;
39
+ /**
40
+ * Extract comment attachment facts from a SQL AST component.
41
+ */
42
+ static extract(input: SqlComponent | null | undefined): AstCommentAttachment[];
43
+ private visit;
44
+ private visitSqlComponent;
45
+ private visitFallbackProperties;
46
+ private shouldSkipProperty;
47
+ private emitHeaderComments;
48
+ private emitLegacyComments;
49
+ private emitPositionedComments;
50
+ private emitSelectItemKeywordComments;
51
+ private emitKeywordPositionedComments;
52
+ private emitDetachedComments;
53
+ private emitComments;
54
+ private isSelectQuery;
55
+ private suppressWithClauseTrailingCommentsAlreadyCopiedToQuery;
56
+ private containsCommentSequence;
57
+ }
58
+ /**
59
+ * Extract comment attachment facts from a SQL AST component.
60
+ */
61
+ export declare function extractAstCommentAttachments(input: SqlComponent | null | undefined): AstCommentAttachment[];
@@ -0,0 +1,47 @@
1
+ import { SimpleSelectQuery } from "../models/SimpleSelectQuery";
2
+ import { ColumnReference, ValueComponent } from "../models/ValueComponent";
3
+ export type ClauseScopedColumnReferenceClause = "select" | "where" | "joinOn" | "groupBy" | "having" | "orderBy" | "window" | "limitOffset";
4
+ export interface ClauseScopedColumnReferenceInfo {
5
+ clause: ClauseScopedColumnReferenceClause;
6
+ reference: ColumnReference;
7
+ qualifiedName: string;
8
+ namespaces: string[];
9
+ namespace: string | null;
10
+ column: string;
11
+ expression: ValueComponent;
12
+ }
13
+ export interface ClauseScopedColumnReferences {
14
+ select: ClauseScopedColumnReferenceInfo[];
15
+ where: ClauseScopedColumnReferenceInfo[];
16
+ joinOn: ClauseScopedColumnReferenceInfo[];
17
+ groupBy: ClauseScopedColumnReferenceInfo[];
18
+ having: ClauseScopedColumnReferenceInfo[];
19
+ orderBy: ClauseScopedColumnReferenceInfo[];
20
+ window: ClauseScopedColumnReferenceInfo[];
21
+ limitOffset: ClauseScopedColumnReferenceInfo[];
22
+ }
23
+ /**
24
+ * Collects ColumnReference nodes grouped by the root SimpleSelectQuery clause that owns them.
25
+ *
26
+ * Subquery and CTE bodies are intentionally not traversed because they have their own query-body
27
+ * ownership. Use ColumnReferenceCollector when comprehensive tree traversal is required.
28
+ */
29
+ export declare class ClauseScopedColumnReferenceCollector {
30
+ collect(query: SimpleSelectQuery): ClauseScopedColumnReferences;
31
+ private createEmptyResult;
32
+ private collectFromSelectClause;
33
+ private collectFromJoinClauses;
34
+ private collectFromWhereClause;
35
+ private collectFromGroupByClause;
36
+ private collectFromHavingClause;
37
+ private collectFromOrderByClause;
38
+ private collectFromLimitClause;
39
+ private collectFromOffsetClause;
40
+ private collectFromFetchClause;
41
+ private collectFromWindowsClause;
42
+ private collectFromValueComponent;
43
+ private collectFromFunctionCall;
44
+ private collectFromWindowFrameExpression;
45
+ private createInfo;
46
+ private getNameText;
47
+ }
@@ -0,0 +1,53 @@
1
+ import { CTEQuery } from "../models/Clause";
2
+ import { SqlComponent } from "../models/SqlComponent";
3
+ /**
4
+ * Source span for a named query definition when parser position metadata is available.
5
+ *
6
+ * @remarks The current extractor does not synthesize ranges. `range` and `nameRange`
7
+ * are returned as `null` until AST nodes expose reliable definition spans.
8
+ */
9
+ export interface NamedQueryDefinitionSourceRange {
10
+ start: number;
11
+ end: number;
12
+ }
13
+ /**
14
+ * DTO-style representation of a named query definition from a SQL AST.
15
+ */
16
+ export interface NamedQueryDefinition {
17
+ /** The stable definition name, such as a CTE alias. */
18
+ name: string;
19
+ /** The AST query node that defines the named query. */
20
+ query: CTEQuery;
21
+ /** Whether the definition belongs to a `WITH RECURSIVE` clause, when that context is available. */
22
+ recursive?: boolean;
23
+ /** Full definition source range when available. Currently `null`. */
24
+ range: NamedQueryDefinitionSourceRange | null;
25
+ /** Definition-name source range when available. Currently `null`. */
26
+ nameRange: NamedQueryDefinitionSourceRange | null;
27
+ }
28
+ /**
29
+ * Extracts named query definitions, starting with CTE definitions from `WITH` clauses.
30
+ *
31
+ * @remarks Definitions are emitted in SQL source order. For nested CTEs, the outer
32
+ * CTE definition is emitted when its name is encountered, then definitions inside
33
+ * that CTE body are emitted before later sibling CTE definitions.
34
+ */
35
+ export declare class NamedQueryDefinitionExtractor {
36
+ private readonly definitions;
37
+ private readonly visited;
38
+ /**
39
+ * Extract named query definitions from an AST component.
40
+ */
41
+ static extract(input: SqlComponent | null | undefined): NamedQueryDefinition[];
42
+ private visit;
43
+ private visitSelectQuery;
44
+ private visitSimpleSelectQuery;
45
+ private visitInsertQuery;
46
+ private visitUpdateQuery;
47
+ private visitDeleteQuery;
48
+ private visitMergeQuery;
49
+ private visitWithClause;
50
+ private visitCommonTable;
51
+ private visitKnownSqlComponent;
52
+ private visitKnownValueComponent;
53
+ }
@@ -0,0 +1,21 @@
1
+ import { SelectQuery } from "../models/SelectQuery";
2
+ import { SqlComponent } from "../models/SqlComponent";
3
+ export type SelectBodyWrapperKind = "create-table-as" | "create-view" | "create-materialized-view" | "insert-select";
4
+ export interface SelectBodyExtractionResult {
5
+ supported: boolean;
6
+ kind: SelectBodyWrapperKind | null;
7
+ targetName: string | null;
8
+ selectQuery: SelectQuery | null;
9
+ reason?: string;
10
+ }
11
+ export declare class SelectBodyExtractor {
12
+ static extract(input: string | SqlComponent): SelectBodyExtractionResult;
13
+ private static extractFromSql;
14
+ private static extractFromStatement;
15
+ private static extractCreateViewFromLexemes;
16
+ private static isCreateViewStatement;
17
+ private static consumeBalancedParentheses;
18
+ private static createTableTargetName;
19
+ private static insertTargetName;
20
+ private static unsupported;
21
+ }
@@ -0,0 +1,47 @@
1
+ import { CommonTable } from "../models/Clause";
2
+ import { SqlComponent } from "../models/SqlComponent";
3
+ import { ValueComponent } from "../models/ValueComponent";
4
+ import { TableColumnResolver } from "./TableColumnResolver";
5
+ export interface SelectOutputColumn {
6
+ name: string;
7
+ value: ValueComponent;
8
+ outputIndex: number;
9
+ sourceAlias: string | null;
10
+ sourceName: string | null;
11
+ sourceColumnName: string | null;
12
+ }
13
+ /**
14
+ * Collects SELECT output columns without collapsing duplicate output names.
15
+ *
16
+ * This collector is intended for callers that need stable SELECT-list positions.
17
+ * It keeps output order and assigns outputIndex after supported wildcard expansion.
18
+ */
19
+ export declare class SelectOutputCollector {
20
+ private tableColumnResolver;
21
+ private commonTableCollector;
22
+ private commonTables;
23
+ constructor(tableColumnResolver?: TableColumnResolver | null, initialCommonTables?: CommonTable[] | null);
24
+ collect(arg: SqlComponent): SelectOutputColumn[];
25
+ private collectRaw;
26
+ private collectSimpleSelectQuery;
27
+ private collectSelectItem;
28
+ private expandWildcard;
29
+ private collectFromClause;
30
+ private collectJoinClause;
31
+ private getJoinSourceName;
32
+ private collectSourceExpression;
33
+ private findCommonTable;
34
+ private collectTableSource;
35
+ private collectNestedSelectQuery;
36
+ private collectCteQuery;
37
+ private collectReturningOutputs;
38
+ private extractReturningOutputs;
39
+ private extractSelectItemName;
40
+ private qualifyOutputs;
41
+ private createExplicitOutput;
42
+ private resolveColumnSourceMetadata;
43
+ private getSourceMatchNames;
44
+ private getColumnReferenceSourceAlias;
45
+ private getColumnReferenceSourceName;
46
+ private isSelectQuery;
47
+ }
@@ -16,7 +16,8 @@ export declare class SelectValueCollector implements SqlComponentVisitor<void> {
16
16
  private commonTableCollector;
17
17
  private commonTables;
18
18
  initialCommonTables: CommonTable[] | null;
19
- constructor(tableColumnResolver?: TableColumnResolver | null, initialCommonTables?: CommonTable[] | null);
19
+ private preserveDuplicateSelectItems;
20
+ constructor(tableColumnResolver?: TableColumnResolver | null, initialCommonTables?: CommonTable[] | null, preserveDuplicateSelectItems?: boolean);
20
21
  /**
21
22
  * Get all collected SelectItems as an array of objects with name and value properties
22
23
  * @returns An array of objects with name (string) and value (ValueComponent) properties
@@ -50,11 +51,18 @@ export declare class SelectValueCollector implements SqlComponentVisitor<void> {
50
51
  private processFromClause;
51
52
  private processJoinClause;
52
53
  private processSourceExpression;
54
+ private expandWildcardValue;
55
+ private collectFromClauseValues;
56
+ private collectJoinClauseValues;
57
+ private getJoinSourceName;
58
+ private collectSourceExpressionValues;
53
59
  private visitSelectClause;
54
60
  private processSelectItem;
55
61
  private visitSourceExpression;
56
62
  private visitFromClause;
57
63
  private addSelectValueAsUnique;
64
+ private addSelectValue;
65
+ private addSelectValueFromSelectItem;
58
66
  private collectValuesFromCteQuery;
59
67
  private collectValuesFromReturning;
60
68
  private extractValuesFromReturningClause;
@@ -0,0 +1,129 @@
1
+ import { SelectQuery } from "../models/SelectQuery";
2
+ import { ClauseScopedColumnReferenceClause } from "./ClauseScopedColumnReferenceCollector";
3
+ /** Kind of named query boundary whose wildcard output is being inferred. */
4
+ export type WildcardColumnInferenceTargetKind = "cte" | "derivedTable";
5
+ /** Syntax form of the wildcard SELECT item that may supply required columns. */
6
+ export type WildcardColumnInferenceWildcardKind = "qualified" | "unqualified";
7
+ /** Conservative reason why a downstream requirement could not be assigned to one wildcard supplier. */
8
+ export type WildcardColumnInferenceUnresolvedReason = "duplicateOutputOwnership" | "multipleWildcardSuppliers" | "unqualifiedWildcardMultipleSources" | "noWildcardSupplier" | "unsupportedQueryShape";
9
+ /** Clause-scoped downstream reference that requires an output column from the target. */
10
+ export interface WildcardColumnInferenceRequiredBy {
11
+ /** Clause that owns the downstream reference. */
12
+ clause: ClauseScopedColumnReferenceClause;
13
+ /** SQL text form of the downstream column reference. */
14
+ qualifiedName: string;
15
+ /** Namespace or alias used by the downstream reference, if present. */
16
+ namespace: string | null;
17
+ /** Output column name required by the downstream reference. */
18
+ column: string;
19
+ }
20
+ /** Metadata for a wildcard SELECT item inside the target query. */
21
+ export interface WildcardColumnInferenceWildcard {
22
+ /** Whether the wildcard was written as `*` or as a qualified form such as `a.*`. */
23
+ kind: WildcardColumnInferenceWildcardKind;
24
+ /** SELECT-list position of the wildcard item. */
25
+ outputIndex: number;
26
+ /** Source alias that the wildcard can safely be associated with, when known. */
27
+ sourceAlias: string | null;
28
+ /** Physical source name for the wildcard source, when it is statically visible. */
29
+ sourceName: string | null;
30
+ }
31
+ /** Explicit non-wildcard output preserved alongside inferred wildcard requirements. */
32
+ export interface WildcardColumnInferenceExplicitColumn {
33
+ /** Output name exposed by the explicit SELECT item. */
34
+ outputName: string;
35
+ /** Source alias for a simple qualified column expression, when uniquely known. */
36
+ sourceAlias: string | null;
37
+ /** Physical source name for a simple qualified column expression, when uniquely known. */
38
+ sourceName: string | null;
39
+ /** Source column name for a simple qualified column expression, when uniquely known. */
40
+ sourceColumnName: string | null;
41
+ }
42
+ /** Resolved required column supplied by a single unambiguous wildcard. */
43
+ export interface WildcardColumnInferenceResolvedColumn {
44
+ /** Output column name required from the target. */
45
+ outputName: string;
46
+ /** Source alias selected as the wildcard supplier. */
47
+ sourceAlias: string | null;
48
+ /** Physical source name selected as the wildcard supplier, when known. */
49
+ sourceName: string | null;
50
+ /** Source column name inferred from the downstream output requirement. */
51
+ sourceColumnName: string;
52
+ /** Wildcard SELECT item that supplies this required column. */
53
+ wildcard: WildcardColumnInferenceWildcard;
54
+ /** Distinct downstream clauses that required this column. */
55
+ requiredByClause: ClauseScopedColumnReferenceClause[];
56
+ /** Clause-scoped downstream references that required this column. */
57
+ requiredBy: WildcardColumnInferenceRequiredBy[];
58
+ }
59
+ /** Required output column that could not be assigned to a single wildcard supplier. */
60
+ export interface WildcardColumnInferenceUnresolvedColumn {
61
+ /** Output column name required from the target. */
62
+ outputName: string;
63
+ /** Conservative reason why inference did not choose a supplier. */
64
+ reason: WildcardColumnInferenceUnresolvedReason;
65
+ /** Candidate wildcard suppliers visible for this requirement. */
66
+ candidateWildcards: WildcardColumnInferenceWildcard[];
67
+ /** Distinct downstream clauses that required this column. */
68
+ requiredByClause: ClauseScopedColumnReferenceClause[];
69
+ /** Clause-scoped downstream references that required this column. */
70
+ requiredBy: WildcardColumnInferenceRequiredBy[];
71
+ }
72
+ /** Metadata-only wildcard inference result for one CTE or derived table target. */
73
+ export interface WildcardColumnInferenceResult {
74
+ /** Kind of target whose wildcard output was inspected. */
75
+ targetKind: WildcardColumnInferenceTargetKind;
76
+ /** CTE name for CTE targets, otherwise null. */
77
+ targetName: string | null;
78
+ /** Alias used by the downstream consumer when available. */
79
+ targetAlias: string | null;
80
+ /** Wildcard SELECT items found inside the target query. */
81
+ wildcards: WildcardColumnInferenceWildcard[];
82
+ /** Explicit non-wildcard outputs found inside the target query. */
83
+ explicitColumns: WildcardColumnInferenceExplicitColumn[];
84
+ /** Downstream requirements assigned to exactly one wildcard supplier. */
85
+ requiredColumns: WildcardColumnInferenceResolvedColumn[];
86
+ /** Downstream requirements that were intentionally left unresolved. */
87
+ unresolvedColumns: WildcardColumnInferenceUnresolvedColumn[];
88
+ }
89
+ /**
90
+ * Infers the subset of wildcard columns required by downstream references.
91
+ *
92
+ * This collector only returns metadata. It does not rewrite SQL and does not attempt full
93
+ * table-column discovery. When ownership is ambiguous, the requirement is reported as unresolved.
94
+ */
95
+ export declare class WildcardColumnInferenceCollector {
96
+ private readonly clauseCollector;
97
+ private readonly requirements;
98
+ private readonly visitedQueries;
99
+ private nextObjectId;
100
+ private objectIds;
101
+ /**
102
+ * Collect wildcard column inference metadata for CTEs and derived tables visible in a SELECT query.
103
+ */
104
+ collect(query: SelectQuery): WildcardColumnInferenceResult[];
105
+ private collectFromSelectQuery;
106
+ private collectCteQuery;
107
+ private collectConsumerRequirements;
108
+ private collectConsumerTargets;
109
+ private createCteTarget;
110
+ private createDerivedTableTarget;
111
+ private collectNestedSources;
112
+ private addRequirement;
113
+ private inferTarget;
114
+ private collectTargetOutputMetadata;
115
+ private collectWildcardMetadata;
116
+ private createUnresolved;
117
+ private flattenReferences;
118
+ private createRequiredBy;
119
+ private collectRequiredByClauses;
120
+ private getTargetMatchNames;
121
+ private getUniqueTarget;
122
+ private getUniqueSource;
123
+ private getSourceMatchNames;
124
+ private getSourceName;
125
+ private collectLeadingCommonTables;
126
+ private mergeCommonTables;
127
+ private getObjectId;
128
+ private isSelectQuery;
129
+ }
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AstCommentAttachmentExtractor = void 0;
4
+ exports.extractAstCommentAttachments = extractAstCommentAttachments;
5
+ const SelectQuery_1 = require("../models/SelectQuery");
6
+ const Clause_1 = require("../models/Clause");
7
+ const SqlComponent_1 = require("../models/SqlComponent");
8
+ /**
9
+ * Extracts comment attachment facts already represented in the SQL AST.
10
+ *
11
+ * @remarks This API does not infer product-specific meanings or rewrite
12
+ * comments. It returns a deterministic flat list without mutating the input AST.
13
+ */
14
+ class AstCommentAttachmentExtractor {
15
+ constructor() {
16
+ this.attachments = [];
17
+ this.visited = new Set();
18
+ this.suppressedDetachedCommentArrays = new WeakSet();
19
+ }
20
+ /**
21
+ * Extract comment attachment facts from a SQL AST component.
22
+ */
23
+ static extract(input) {
24
+ if (!input) {
25
+ return [];
26
+ }
27
+ const extractor = new AstCommentAttachmentExtractor();
28
+ extractor.visit(input);
29
+ return extractor.attachments;
30
+ }
31
+ visit(value) {
32
+ if (!value || typeof value !== "object") {
33
+ return;
34
+ }
35
+ if (this.visited.has(value)) {
36
+ return;
37
+ }
38
+ this.visited.add(value);
39
+ if (Array.isArray(value)) {
40
+ for (const item of value) {
41
+ this.visit(item);
42
+ }
43
+ return;
44
+ }
45
+ if (value instanceof SqlComponent_1.SqlComponent) {
46
+ this.visitSqlComponent(value);
47
+ return;
48
+ }
49
+ }
50
+ visitSqlComponent(component) {
51
+ this.emitHeaderComments(component);
52
+ this.emitPositionedComments(component, "before");
53
+ if (!(component instanceof SelectQuery_1.SimpleSelectQuery)) {
54
+ this.emitLegacyComments(component);
55
+ }
56
+ if (component instanceof Clause_1.SelectItem) {
57
+ this.emitPositionedComments(component, "after");
58
+ this.emitSelectItemKeywordComments(component);
59
+ this.visit(component.value);
60
+ this.visit(component.identifier);
61
+ return;
62
+ }
63
+ if (component instanceof Clause_1.CommonTable) {
64
+ this.visit(component.aliasExpression);
65
+ this.visit(component.query);
66
+ this.emitPositionedComments(component, "after");
67
+ return;
68
+ }
69
+ if (component instanceof Clause_1.WithClause) {
70
+ this.visit(component.tables);
71
+ this.emitDetachedComments(component.trailingComments);
72
+ this.emitDetachedComments(component.globalComments);
73
+ this.emitPositionedComments(component, "after");
74
+ return;
75
+ }
76
+ if (component instanceof SelectQuery_1.SimpleSelectQuery) {
77
+ this.suppressWithClauseTrailingCommentsAlreadyCopiedToQuery(component);
78
+ this.visit(component.withClause);
79
+ this.emitLegacyComments(component);
80
+ this.visit(component.selectClause);
81
+ this.visit(component.fromClause);
82
+ this.visit(component.whereClause);
83
+ this.visit(component.groupByClause);
84
+ this.visit(component.havingClause);
85
+ this.visit(component.windowClause);
86
+ this.visit(component.orderByClause);
87
+ this.visit(component.limitClause);
88
+ this.visit(component.offsetClause);
89
+ this.visit(component.fetchClause);
90
+ this.visit(component.forClause);
91
+ this.emitPositionedComments(component, "after");
92
+ return;
93
+ }
94
+ if (component instanceof SelectQuery_1.BinarySelectQuery) {
95
+ this.visit(component.left);
96
+ this.visit(component.right);
97
+ this.emitPositionedComments(component, "after");
98
+ return;
99
+ }
100
+ if (component instanceof SelectQuery_1.ValuesQuery) {
101
+ this.visit(component.withClause);
102
+ this.visit(component.tuples);
103
+ this.emitPositionedComments(component, "after");
104
+ return;
105
+ }
106
+ if (component instanceof Clause_1.SelectClause) {
107
+ this.visit(component.distinct);
108
+ this.visit(component.hints);
109
+ this.visit(component.items);
110
+ this.emitPositionedComments(component, "after");
111
+ return;
112
+ }
113
+ if (component instanceof Clause_1.SourceAliasExpression) {
114
+ this.visit(component.table);
115
+ this.visit(component.columns);
116
+ this.emitPositionedComments(component, "after");
117
+ return;
118
+ }
119
+ this.visitFallbackProperties(component);
120
+ this.emitPositionedComments(component, "after");
121
+ }
122
+ visitFallbackProperties(component) {
123
+ for (const key of Object.keys(component)) {
124
+ if (this.shouldSkipProperty(key)) {
125
+ continue;
126
+ }
127
+ this.visit(component[key]);
128
+ }
129
+ }
130
+ shouldSkipProperty(key) {
131
+ return key === "comments" ||
132
+ key === "positionedComments" ||
133
+ key === "headerComments" ||
134
+ key === "trailingComments" ||
135
+ key === "globalComments" ||
136
+ key === "asKeywordPositionedComments" ||
137
+ key === "asKeywordComments" ||
138
+ key === "aliasPositionedComments" ||
139
+ key === "aliasComments" ||
140
+ key === "cteNameCache";
141
+ }
142
+ emitHeaderComments(component) {
143
+ if (!this.isSelectQuery(component)) {
144
+ return;
145
+ }
146
+ this.emitComments(component.headerComments, "leading", component);
147
+ }
148
+ emitLegacyComments(component) {
149
+ this.emitComments(component.comments, "detached");
150
+ }
151
+ emitPositionedComments(component, position) {
152
+ if (!component.positionedComments) {
153
+ return;
154
+ }
155
+ for (const positionedComment of component.positionedComments) {
156
+ if (positionedComment.position !== position) {
157
+ continue;
158
+ }
159
+ this.emitComments(positionedComment.comments, position === "before" ? "leading" : "trailing", component);
160
+ }
161
+ }
162
+ emitSelectItemKeywordComments(selectItem) {
163
+ const itemWithCommentFields = selectItem;
164
+ this.emitKeywordPositionedComments(itemWithCommentFields.asKeywordPositionedComments, selectItem, "inner");
165
+ this.emitComments(itemWithCommentFields.asKeywordComments, "inner", selectItem);
166
+ this.emitKeywordPositionedComments(itemWithCommentFields.aliasPositionedComments, selectItem);
167
+ this.emitComments(itemWithCommentFields.aliasComments, "trailing", selectItem);
168
+ }
169
+ emitKeywordPositionedComments(positionedComments, targetNode, placementOverride) {
170
+ if (!positionedComments) {
171
+ return;
172
+ }
173
+ for (const positionedComment of positionedComments) {
174
+ const placement = placementOverride !== null && placementOverride !== void 0 ? placementOverride : (positionedComment.position === "before" ? "leading" : "trailing");
175
+ this.emitComments(positionedComment.comments, placement, targetNode);
176
+ }
177
+ }
178
+ emitDetachedComments(comments) {
179
+ if (comments && this.suppressedDetachedCommentArrays.has(comments)) {
180
+ return;
181
+ }
182
+ this.emitComments(comments, "detached");
183
+ }
184
+ emitComments(comments, placement, targetNode) {
185
+ if (!comments) {
186
+ return;
187
+ }
188
+ for (const text of comments) {
189
+ this.attachments.push({
190
+ text,
191
+ sourceOrder: this.attachments.length,
192
+ placement,
193
+ ...(targetNode ? { targetNode } : {})
194
+ });
195
+ }
196
+ }
197
+ isSelectQuery(component) {
198
+ return "__selectQueryType" in component &&
199
+ component.__selectQueryType === "SelectQuery";
200
+ }
201
+ suppressWithClauseTrailingCommentsAlreadyCopiedToQuery(query) {
202
+ var _a;
203
+ const trailingComments = (_a = query.withClause) === null || _a === void 0 ? void 0 : _a.trailingComments;
204
+ if (!trailingComments || !query.comments) {
205
+ return;
206
+ }
207
+ if (this.containsCommentSequence(query.comments, trailingComments)) {
208
+ this.suppressedDetachedCommentArrays.add(trailingComments);
209
+ }
210
+ }
211
+ containsCommentSequence(source, candidate) {
212
+ if (candidate.length === 0) {
213
+ return true;
214
+ }
215
+ for (let start = 0; start <= source.length - candidate.length; start++) {
216
+ const matches = candidate.every((comment, index) => source[start + index] === comment);
217
+ if (matches) {
218
+ return true;
219
+ }
220
+ }
221
+ return false;
222
+ }
223
+ }
224
+ exports.AstCommentAttachmentExtractor = AstCommentAttachmentExtractor;
225
+ /**
226
+ * Extract comment attachment facts from a SQL AST component.
227
+ */
228
+ function extractAstCommentAttachments(input) {
229
+ return AstCommentAttachmentExtractor.extract(input);
230
+ }
231
+ //# sourceMappingURL=AstCommentAttachmentExtractor.js.map