001package gudusoft.gsqlparser.dlineage.dynamicsql;
002
003/**
004 * Resource bounds for {@code resolveDynamicSqlLineage}.
005 *
006 * <p>The evaluated dynamic-SQL string is effectively attacker-controlled (it is
007 * built from runtime parameter values), so every dimension that an adversarial
008 * or pathological procedure could blow up is capped. When a bound is exceeded
009 * the affected site fails <em>closed</em> to an unresolved diagnostic — never a
010 * hang, never an OOM, never a fabricated edge.
011 */
012public final class DynamicLineageOptions {
013
014    private int maxResolvedSqlLength = 1_000_000;   // chars in a single materialized statement string
015    private int maxSites = 256;                     // dynamic-SQL EXEC sites resolved per call
016    private int maxBindings = 1024;                 // parameter bindings accepted per call
017    private int maxValueSetSize = 8;                // correlated constant-relation variants
018    private int maxConstRelationRows = 64;          // literal rows retained per table variable
019    private int maxExpansionDepth = 256;            // function/CASE nesting depth before failing closed
020    private long timeoutMillis = 10_000;            // wall-clock budget for the whole resolve call
021    private boolean showImplicitSchema = true;      // qualify unqualified names with currentDatabase/defaultSchema
022    private DynamicSqlTrustMode trustMode = DynamicSqlTrustMode.LEGACY;
023
024    public static DynamicLineageOptions createDefault() {
025        return new DynamicLineageOptions();
026    }
027
028    public int getMaxResolvedSqlLength() {
029        return maxResolvedSqlLength;
030    }
031
032    public DynamicLineageOptions setMaxResolvedSqlLength(int v) {
033        this.maxResolvedSqlLength = v;
034        return this;
035    }
036
037    public int getMaxSites() {
038        return maxSites;
039    }
040
041    public DynamicLineageOptions setMaxSites(int v) {
042        this.maxSites = v;
043        return this;
044    }
045
046    public int getMaxBindings() {
047        return maxBindings;
048    }
049
050    public DynamicLineageOptions setMaxBindings(int v) {
051        this.maxBindings = v;
052        return this;
053    }
054
055    /**
056     * Maximum number of distinct statically-enumerated values (or correlated
057     * row tuples) retained by the dynamic-SQL evaluator. An attempted union or
058     * product above this bound widens to today's UNKNOWN result; it is never
059     * silently truncated.
060     */
061    public int getMaxValueSetSize() {
062        return maxValueSetSize;
063    }
064
065    public DynamicLineageOptions setMaxValueSetSize(int v) {
066        this.maxValueSetSize = v;
067        return this;
068    }
069
070    /** Maximum number of literal rows retained for one T-SQL table variable. */
071    public int getMaxConstRelationRows() {
072        return maxConstRelationRows;
073    }
074
075    public DynamicLineageOptions setMaxConstRelationRows(int v) {
076        this.maxConstRelationRows = v;
077        return this;
078    }
079
080    /** Compatibility alias for callers that use the longer relation-cap name. */
081    public int getMaxConstantRelationRows() {
082        return getMaxConstRelationRows();
083    }
084
085    public DynamicLineageOptions setMaxConstantRelationRows(int v) {
086        return setMaxConstRelationRows(v);
087    }
088
089    public int getMaxExpansionDepth() {
090        return maxExpansionDepth;
091    }
092
093    public DynamicLineageOptions setMaxExpansionDepth(int v) {
094        this.maxExpansionDepth = v;
095        return this;
096    }
097
098    public long getTimeoutMillis() {
099        return timeoutMillis;
100    }
101
102    public DynamicLineageOptions setTimeoutMillis(long v) {
103        this.timeoutMillis = v;
104        return this;
105    }
106
107    public boolean isShowImplicitSchema() {
108        return showImplicitSchema;
109    }
110
111    public DynamicLineageOptions setShowImplicitSchema(boolean v) {
112        this.showImplicitSchema = v;
113        return this;
114    }
115
116    /**
117     * Controls observation of edges from a materialized string that still has
118     * unresolved fragments. Both modes preserve publication; SHADOW adds
119     * diagnostics. The default is {@link DynamicSqlTrustMode#LEGACY} for
120     * backwards compatibility.
121     */
122    public DynamicSqlTrustMode getTrustMode() {
123        return trustMode;
124    }
125
126    public DynamicLineageOptions setTrustMode(DynamicSqlTrustMode v) {
127        this.trustMode = v == null ? DynamicSqlTrustMode.LEGACY : v;
128        return this;
129    }
130}