forked from sqlancer/sqlancer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQLite3Case.java
More file actions
151 lines (126 loc) · 5.13 KB
/
SQLite3Case.java
File metadata and controls
151 lines (126 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package sqlancer.sqlite3.ast;
import java.util.Optional;
import sqlancer.sqlite3.schema.SQLite3Schema.SQLite3Column.SQLite3CollateSequence;
public abstract class SQLite3Case extends SQLite3Expression {
protected final CasePair[] pairs;
protected final SQLite3Expression elseExpr;
public SQLite3Case(CasePair[] pairs, SQLite3Expression elseExpr) {
this.pairs = pairs;
this.elseExpr = elseExpr;
}
public static class CasePair {
private final SQLite3Expression cond;
private final SQLite3Expression then;
public CasePair(SQLite3Expression cond, SQLite3Expression then) {
this.cond = cond;
this.then = then;
}
public SQLite3Expression getCond() {
return cond;
}
public SQLite3Expression getThen() {
return then;
}
}
public CasePair[] getPairs() {
return pairs;
}
public SQLite3Expression getElseExpr() {
return elseExpr;
}
protected SQLite3CollateSequence getExplicitCasePairAndElseCollate() {
for (CasePair c : pairs) {
if (c.getCond().getExplicitCollateSequence() != null) {
return c.getCond().getExplicitCollateSequence();
} else if (c.getThen().getExplicitCollateSequence() != null) {
return c.getThen().getExplicitCollateSequence();
}
}
if (elseExpr == null) {
return null;
} else {
return elseExpr.getExplicitCollateSequence();
}
}
public static class SQLite3CaseWithoutBaseExpression extends SQLite3Case {
public SQLite3CaseWithoutBaseExpression(CasePair[] pairs, SQLite3Expression elseExpr) {
super(pairs, elseExpr);
}
@Override
public SQLite3CollateSequence getExplicitCollateSequence() {
return getExplicitCasePairAndElseCollate();
}
@Override
public SQLite3Constant getExpectedValue() {
for (CasePair c : pairs) {
SQLite3Constant expectedValue = c.getCond().getExpectedValue();
if (expectedValue == null) {
return null;
}
Optional<Boolean> isTrue = SQLite3Cast.isTrue(expectedValue);
if (isTrue.isPresent() && isTrue.get()) {
return c.getThen().getExpectedValue();
}
}
if (elseExpr == null) {
return SQLite3Constant.createNullConstant();
} else {
return elseExpr.getExpectedValue();
}
}
}
public static class SQLite3CaseWithBaseExpression extends SQLite3Case {
private final SQLite3Expression baseExpr;
public SQLite3CaseWithBaseExpression(SQLite3Expression baseExpr, CasePair[] pairs, SQLite3Expression elseExpr) {
super(pairs, elseExpr);
this.baseExpr = baseExpr;
}
@Override
public SQLite3CollateSequence getExplicitCollateSequence() {
if (baseExpr.getExplicitCollateSequence() != null) {
return baseExpr.getExplicitCollateSequence();
} else {
return getExplicitCasePairAndElseCollate();
}
}
public SQLite3Expression getBaseExpr() {
return baseExpr;
}
@Override
public SQLite3Constant getExpectedValue() {
SQLite3Constant baseExprValue = baseExpr.getExpectedValue();
if (baseExprValue == null) {
return null;
}
for (CasePair c : pairs) {
SQLite3Constant whenComparisonValue = c.getCond().getExpectedValue();
if (whenComparisonValue == null) {
return null;
} // TODO collate
SQLite3CollateSequence seq;
if (baseExpr.getExplicitCollateSequence() != null) {
seq = baseExpr.getExplicitCollateSequence();
} else if (whenComparisonValue.getExplicitCollateSequence() != null) {
seq = whenComparisonValue.getExplicitCollateSequence();
} else if (c.getCond().getImplicitCollateSequence() != null) {
seq = c.getCond().getImplicitCollateSequence();
} else if (whenComparisonValue.getImplicitCollateSequence() != null) {
seq = c.getCond().getImplicitCollateSequence();
} else {
seq = SQLite3CollateSequence.BINARY;
}
ConstantTuple newVals = applyAffinities(baseExpr.getAffinity(), c.getCond().getAffinity(),
baseExpr.getExpectedValue(), c.getCond().getExpectedValue());
SQLite3Constant equals = newVals.left.applyEquals(newVals.right, seq);
if (!equals.isNull() && equals.asInt() == 1) {
return c.getThen().getExpectedValue();
}
}
if (elseExpr == null) {
return SQLite3Constant.createNullConstant();
} else {
return elseExpr.getExpectedValue();
}
}
}
}