public final class DynamicSqlLineageResolver extends Object
TDynamicSqlStringEvaluator), then for each materialized EXEC site run
ordinary dlineage on the concrete string and tag the resulting edges with
dynamic provenance.
This is purely additive — it constructs fresh, throwaway
DataFlowAnalyzer instances for the materialized strings and never
touches the default analysis path, so default dlineage output is unchanged.
| Modifier and Type | Class and Description |
|---|---|
static class |
DynamicSqlLineageResolver.CallSiteDiscovery
What a call-site discovery found and what it left: the literal binding sets, each with the call it came
from, and a note for every call that names the procedure but was not taken, saying why (Mantis 4962).
|
static class |
DynamicSqlLineageResolver.MaterializedSite
Materialized dynamic-SQL text for one EXEC / sp_executesql site, produced by the
no-bindings default-path evaluation (
materializeSitesWithoutBindings(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.EDbVendor, gudusoft.gsqlparser.dlineage.dynamicsql.DynamicLineageOptions)). |
| Modifier and Type | Method and Description |
|---|---|
static String |
caseCollision(TCustomSqlStatement procAst,
TSQLEnv sqlEnv)
Why the evaluation cannot be trusted with
declared under the catalog's rules names: the
evaluation keys variables without their case, so two names the rules keep apart but that differ only in case
would share a value. |
static List<Map<String,SqlValue>> |
discoverCallSiteBindings(TCustomSqlStatement procAst,
int maxBindingSets)
Discover parameter bindings from literal call sites of
procAst in the same
parsed file: top-level EXEC <proc> 'literal', @p = 'literal', ... statements
whose (unqualified) module name matches the procedure name. |
static DynamicSqlLineageResolver.CallSiteDiscovery |
discoverCallSites(TCustomSqlStatement procAst,
int maxBindingSets)
discoverCallSiteBindings(gudusoft.gsqlparser.TCustomSqlStatement, int) with its account: the same binding sets in the same order, the call each
came from, and the calls in the file that name the procedure but were not bound. |
static DynamicSqlLineageResolver.CallSiteDiscovery |
discoverCallSites(TCustomSqlStatement procAst,
int maxBindingSets,
TSQLEnv sqlEnv,
RoutineCatalog catalog,
DynamicLineageOptions options)
discoverCallSites(TCustomSqlStatement, int) with what a call whose actuals are not literals needs
(Mantis 4962): the catalog (sqlEnv, for a calling procedure's presets), the other units
(catalog, for a calling procedure's own calls there) and the evaluation's options. |
static List<Map<String,SqlValue>> |
discoverCrossFileCallSiteBindings(TCustomSqlStatement procAst,
RoutineCatalog catalog,
int maxBindingSets)
Discover parameter bindings from literal call sites of
procAst located in
OTHER files of the same multi-file analysis (plan Phase 5: cross-file routine
references). |
static DynamicSqlLineageResolver.CallSiteDiscovery |
discoverCrossFileCallSites(TCustomSqlStatement procAst,
RoutineCatalog catalog,
int maxBindingSets)
discoverCrossFileCallSiteBindings(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.dlineage.dynamicsql.RoutineCatalog, int) with its account: the same binding sets in the same order, the
unit and line each came from, and why calls in other units that name the procedure were not bound. |
static DynamicSqlLineageResolver.CallSiteDiscovery |
discoverCrossFileCallSites(TCustomSqlStatement procAst,
RoutineCatalog catalog,
int maxBindingSets,
TSQLEnv sqlEnv,
DynamicLineageOptions options)
discoverCrossFileCallSites(TCustomSqlStatement, RoutineCatalog, int) with the catalog and options a
call whose actuals are not literals needs (discoverCallSites(TCustomSqlStatement, int, TSQLEnv,
RoutineCatalog, DynamicLineageOptions)). |
static List<String> |
foldDbmsSqlTexts(TCustomSqlStatement enclosingRoutine,
TExpression sqlArg,
RoutineCatalog catalog,
int maxVariants)
DBMS_SQL entry point (plan Phase 5 slice 4): fold the SQL-text argument of a
DBMS_SQL.PARSE call into concrete statement texts. |
static String |
joinNotes(String first,
String second)
The non-null notes, joined with "; "; null when there are none.
|
static Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite> |
materializeSites(TCustomSqlStatement procAst,
EDbVendor vendor,
Map<String,SqlValue> bindings,
DynamicLineageOptions options)
Same as
materializeSitesWithoutBindings(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.EDbVendor, gudusoft.gsqlparser.dlineage.dynamicsql.DynamicLineageOptions), but with caller-supplied parameter
bindings (e.g. |
static Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite> |
materializeSitesWithoutBindings(TCustomSqlStatement procAst,
EDbVendor vendor,
DynamicLineageOptions options)
Default-path hook for
DataFlowAnalyzer: abstractly evaluate a procedure's
dynamic-SQL string building with NO call-site bindings — only literal parameter
defaults are seeded — and return the materialized string per EXEC/sp_executesql
statement node (identity-keyed against the SAME parse tree that was passed in). |
static List<Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite>> |
materializeSiteVariants(TCustomSqlStatement procAst,
EDbVendor vendor,
Map<String,SqlValue> bindings,
DynamicLineageOptions options)
Materialize all bounded, row-correlated constant-relation variants for a
procedure.
|
static List<Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite>> |
materializeSiteVariants(TCustomSqlStatement procAst,
EDbVendor vendor,
Map<String,SqlValue> bindings,
DynamicLineageOptions options,
BindingSource source)
materializeSiteVariants(TCustomSqlStatement, EDbVendor, Map, DynamicLineageOptions), each site
stamped with where its bindings came from (Mantis 4962): a site's diagnostic names the binding, and the
default analysis publishes a site some binding reached with the bound variants only. |
static List<TCustomSqlStatement> |
plsqlInterpretationStatements(TStatementList ownStatements,
String ownText,
RoutineCatalog catalog,
int maxForeignCallers)
Oracle analog of cross-file call-site discovery (plan Phase 5): collect
top-level statements from OTHER files (anonymous blocks, CALL statements)
that mention a routine defined in the current file, so the caller can feed
them to
TASTEvaluator together with the file's own statements and
fold parameter-dependent EXECUTE IMMEDIATE templates under the callers'
literal arguments. |
static Map<String,SqlValue> |
presetBindings(TCustomSqlStatement procAst,
TSQLEnv sqlEnv,
String currentDatabase,
String defaultSchema)
The values preset in
sqlEnv for the parameters of the procedure procAst defines (Mantis 4962),
as bindings, or null when none is set. |
static BindingSource |
presetSource(TCustomSqlStatement procAst,
Map<String,SqlValue> presets)
Where the presets of
presetBindings(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.sqlenv.TSQLEnv, java.lang.String, java.lang.String) came from, for a site's diagnostic. |
static DynamicLineageResult |
resolve(TCustomSqlStatement procAst,
EDbVendor vendor,
TSQLEnv sqlEnv,
String currentDatabase,
String defaultSchema,
Map<String,SqlValue> bindings,
DynamicLineageOptions options) |
public static Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite> materializeSitesWithoutBindings(TCustomSqlStatement procAst, EDbVendor vendor, DynamicLineageOptions options)
DataFlowAnalyzer: abstractly evaluate a procedure's
dynamic-SQL string building with NO call-site bindings — only literal parameter
defaults are seeded — and return the materialized string per EXEC/sp_executesql
statement node (identity-keyed against the SAME parse tree that was passed in).
Constant- and template-built strings (REPLACE/QUOTENAME/CONCAT chains over
literals and literal-seeded variables) reduce fully; strings depending on unbound
parameters reduce to placeholder-bearing PARTIAL text; anything else is reported
with a reason. Purely computational — nothing is executed and no model state of
any analyzer is touched.public static Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite> materializeSites(TCustomSqlStatement procAst, EDbVendor vendor, Map<String,SqlValue> bindings, DynamicLineageOptions options)
materializeSitesWithoutBindings(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.EDbVendor, gudusoft.gsqlparser.dlineage.dynamicsql.DynamicLineageOptions), but with caller-supplied parameter
bindings (e.g. extracted from a literal call site) seeded before the walk. Parameters
absent from the bindings fall back to their literal defaults, then to placeholders.public static List<Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite>> materializeSiteVariants(TCustomSqlStatement procAst, EDbVendor vendor, Map<String,SqlValue> bindings, DynamicLineageOptions options)
public static List<Map<TCustomSqlStatement,DynamicSqlLineageResolver.MaterializedSite>> materializeSiteVariants(TCustomSqlStatement procAst, EDbVendor vendor, Map<String,SqlValue> bindings, DynamicLineageOptions options, BindingSource source)
materializeSiteVariants(TCustomSqlStatement, EDbVendor, Map, DynamicLineageOptions), each site
stamped with where its bindings came from (Mantis 4962): a site's diagnostic names the binding, and the
default analysis publishes a site some binding reached with the bound variants only.public static DynamicLineageResult resolve(TCustomSqlStatement procAst, EDbVendor vendor, TSQLEnv sqlEnv, String currentDatabase, String defaultSchema, Map<String,SqlValue> bindings, DynamicLineageOptions options)
public static Map<String,SqlValue> presetBindings(TCustomSqlStatement procAst, TSQLEnv sqlEnv, String currentDatabase, String defaultSchema)
sqlEnv for the parameters of the procedure procAst defines (Mantis 4962),
as bindings, or null when none is set. The procedure is found under the database its definition is in (its
name's, the USE before it, else currentDatabase) and its schema (#presetRoutineNames): a preset
never binds a procedure of the same name in another database. A value supplied but not known is
SqlValue.suppliedUnknown(java.lang.String), never an absent parameter (its default does not apply).public static BindingSource presetSource(TCustomSqlStatement procAst, Map<String,SqlValue> presets)
presetBindings(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.sqlenv.TSQLEnv, java.lang.String, java.lang.String) came from, for a site's diagnostic.public static List<Map<String,SqlValue>> discoverCallSiteBindings(TCustomSqlStatement procAst, int maxBindingSets)
procAst in the same
parsed file: top-level EXEC <proc> 'literal', @p = 'literal', ... statements
whose (unqualified) module name matches the procedure name. Positional and named
arguments are supported; OUTPUT and non-literal arguments are left unbound (they
become placeholders during evaluation). Returns up to maxBindingSets distinct
binding sets in file order.public static DynamicSqlLineageResolver.CallSiteDiscovery discoverCallSites(TCustomSqlStatement procAst, int maxBindingSets)
discoverCallSiteBindings(gudusoft.gsqlparser.TCustomSqlStatement, int) with its account: the same binding sets in the same order, the call each
came from, and the calls in the file that name the procedure but were not bound.public static DynamicSqlLineageResolver.CallSiteDiscovery discoverCallSites(TCustomSqlStatement procAst, int maxBindingSets, TSQLEnv sqlEnv, RoutineCatalog catalog, DynamicLineageOptions options)
discoverCallSites(TCustomSqlStatement, int) with what a call whose actuals are not literals needs
(Mantis 4962): the catalog (sqlEnv, for a calling procedure's presets), the other units
(catalog, for a calling procedure's own calls there) and the evaluation's options. Every call of the
procedure in the file is bound: a call in a batch with its actuals as the batch has them at the call, a call in
another procedure's body with its actuals as that procedure has them, its own parameters bound in turn (its
presets, else its calls, up to levels, else values nobody knows).public static String caseCollision(TCustomSqlStatement procAst, TSQLEnv sqlEnv)
declared under the catalog's rules names: the
evaluation keys variables without their case, so two names the rules keep apart but that differ only in case
would share a value. Null when there are none (SQL Server's default rules ignore case as the evaluation does).public static List<Map<String,SqlValue>> discoverCrossFileCallSiteBindings(TCustomSqlStatement procAst, RoutineCatalog catalog, int maxBindingSets)
procAst located in
OTHER files of the same multi-file analysis (plan Phase 5: cross-file routine
references). otherFileSqlTexts holds the raw SQL text of every analysis
unit; the procedure's own file is skipped by text identity. A text is parsed at
most once per analysis via the caller-owned parseCache (key: the text),
and only when it mentions the procedure's simple name at all.
Never guesses across ambiguity: if any other file defines a procedure with the same simple name in a database-compatible context, there are two candidate owners for a matching call and this method returns no bindings at all. Binding sets are returned in canonical-key order, so the result is independent of the file order of the analysis. Binding sets already surfaced by the same-file discovery above are excluded here, so duplicates never consume the caller's shared cap.
public static DynamicSqlLineageResolver.CallSiteDiscovery discoverCrossFileCallSites(TCustomSqlStatement procAst, RoutineCatalog catalog, int maxBindingSets)
discoverCrossFileCallSiteBindings(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.dlineage.dynamicsql.RoutineCatalog, int) with its account: the same binding sets in the same order, the
unit and line each came from, and why calls in other units that name the procedure were not bound.public static DynamicSqlLineageResolver.CallSiteDiscovery discoverCrossFileCallSites(TCustomSqlStatement procAst, RoutineCatalog catalog, int maxBindingSets, TSQLEnv sqlEnv, DynamicLineageOptions options)
discoverCrossFileCallSites(TCustomSqlStatement, RoutineCatalog, int) with the catalog and options a
call whose actuals are not literals needs (discoverCallSites(TCustomSqlStatement, int, TSQLEnv,
RoutineCatalog, DynamicLineageOptions)).public static List<TCustomSqlStatement> plsqlInterpretationStatements(TStatementList ownStatements, String ownText, RoutineCatalog catalog, int maxForeignCallers)
TASTEvaluator together with the file's own statements and
fold parameter-dependent EXECUTE IMMEDIATE templates under the callers'
literal arguments.
Mirrors the MSSQL rules: a text is parsed at most once per analysis via
parseCache and only when it mentions one of the candidate routine
names; a same-simple-name routine DEFINITION in another file makes that
name ambiguous and drops it from the harvest (never guess between two
candidate owners); foreign definitions themselves are never appended.
Returned statements are ordered by their source text, so evaluation order
is independent of the file order of the analysis.
public static List<String> foldDbmsSqlTexts(TCustomSqlStatement enclosingRoutine, TExpression sqlArg, RoutineCatalog catalog, int maxVariants)
DBMS_SQL.PARSE call into concrete statement texts. Returns the
no-binding fold first (literal or literal-composed locals), then one fold per
literal call-site binding set (same-file callers first, then cross-file via
the catalog), deduplicated, capped at maxVariants. Empty when nothing
folds — the site then keeps its honest unresolved diagnostic. The fold shares
the EXECUTE IMMEDIATE whitelist (literals, parameters bound at vetted call
sites, locals with exactly one literal-composed assignment, || and
parentheses), so a fold can never fabricate object names.