| 144 |
144 |
** 063 DDF 20250424 Replaced file with artifact.
|
| 145 |
145 |
** 064 SP 20260802 Accept the word indexed field on either side of CONTAINS, normalizing
|
| 146 |
146 |
** a reversed expression to field-first.
|
| 147 |
|
** 20260804 Reject a CONTAINS the 4GL will not carry, with its own error number:
|
|
147 |
** SP 20260804 Reject a CONTAINS the 4GL will not carry, with its own error number:
|
| 148 |
148 |
** negated or non-word-indexed (3398), non-character operand (223), chained (247)
|
| 149 |
149 |
** and, in a prepared query text only, USE-INDEX (3316), CAN-FIND (3541), a leading
|
| 150 |
150 |
** FIRST/LAST (3322), and a subsequent LAST or a FIND (3318).
|
| 151 |
|
** 20260814 Moved the 3322 refusal of a leading record phrase not opened by EACH to
|
|
151 |
** SP 20260814 Moved the 3322 refusal of a leading record phrase not opened by EACH to
|
| 152 |
152 |
** DynamicQueryHelper, as the rule is not specific to a CONTAINS.
|
|
153 |
** OM 20260807 Additional expression validations for CONTAINS operator.
|
| 153 |
154 |
-->
|
| 154 |
155 |
|
| 155 |
156 |
<!--
|
| ... | ... | |
| 1060 |
1061 |
<action>ch1 = this.firstChild</action>
|
| 1061 |
1062 |
<action>ch2 = this.getChildAt(1)</action>
|
| 1062 |
1063 |
|
|
1064 |
<rule>ch1 == null or ch1.type != prog.field_char
|
|
1065 |
<rule>isRuntimeQueryMode()
|
|
1066 |
<action>
|
|
1067 |
compileError(223, "** Incompatible data types in expression or assignment", this)
|
|
1068 |
</action>
|
|
1069 |
<action on="false">
|
|
1070 |
printfln("WARNING: (%d:%d) Incompatible data types in expression or assignment. (223)",
|
|
1071 |
this.line, this.column)
|
|
1072 |
</action>
|
|
1073 |
</rule>
|
|
1074 |
</rule>
|
|
1075 |
|
| 1063 |
1076 |
<!-- a chained CONTAINS is a syntax error, not a complaint about its operands, so the
|
| 1064 |
1077 |
checks below are skipped for it -->
|
| 1065 |
1078 |
<rule>ch1 != null and ch1.type == prog.kw_contains
|
| ... | ... | |
| 1072 |
1085 |
</rule>
|
| 1073 |
1086 |
</rule>
|
| 1074 |
1087 |
|
|
1088 |
<!-- a non-character operand is refused before the query opens; a LONGCHAR is not
|
|
1089 |
character here, as a large object may not appear in a where clause at all -->
|
|
1090 |
<rule>ch2 == null or
|
|
1091 |
ch2.type == prog.unknown_val or
|
|
1092 |
((ch2.type > prog.begin_vartypes and ch2.type < prog.end_vartypes) and
|
|
1093 |
ch2.type != prog.var_char) or
|
|
1094 |
((ch2.type > prog.begin_fieldtypes and ch2.type < prog.end_fieldtypes) and
|
|
1095 |
ch2.type != prog.field_char)
|
|
1096 |
<rule>isRuntimeQueryMode()
|
|
1097 |
<action>
|
|
1098 |
compileError(223, "** Incompatible data types in expression or assignment", this)
|
|
1099 |
</action>
|
|
1100 |
<action on="false">
|
|
1101 |
printfln("WARNING: (%d:%d) Incompatible data types in expression or assignment. (223)",
|
|
1102 |
this.line, this.column)
|
|
1103 |
</action>
|
|
1104 |
</rule>
|
|
1105 |
</rule>
|
|
1106 |
|
| 1075 |
1107 |
<rule>ch1 == null or ch1.type != prog.kw_contains
|
| 1076 |
1108 |
<variable name="badfld" type="java.lang.Boolean" />
|
| 1077 |
1109 |
<variable name="recph" type="com.goldencode.ast.Aast" />
|
| 1078 |
1110 |
<variable name="lead" type="com.goldencode.ast.Aast" />
|
| 1079 |
1111 |
<variable name="inFind" type="java.lang.Boolean" />
|
| 1080 |
|
|
| 1081 |
|
<!-- a non-character operand is refused before the query opens; a LONGCHAR is not
|
| 1082 |
|
character here, as a large object may not appear in a where clause at all -->
|
| 1083 |
|
<rule>ch2 != null and
|
| 1084 |
|
(ch2.type == prog.unknown_val or
|
| 1085 |
|
((ch2.type > prog.begin_vartypes and ch2.type < prog.end_vartypes) and
|
| 1086 |
|
ch2.type != prog.var_char))
|
| 1087 |
|
<rule>isRuntimeQueryMode()
|
| 1088 |
|
<action>
|
| 1089 |
|
compileError(223, "** Incompatible data types in expression or assignment",
|
| 1090 |
|
this)
|
| 1091 |
|
</action>
|
| 1092 |
|
<action on="false">
|
| 1093 |
|
printfln(
|
| 1094 |
|
"WARNING: (%d:%d) Incompatible data types in expression or assignment. (223)",
|
| 1095 |
|
this.line, this.column)
|
| 1096 |
|
</action>
|
| 1097 |
|
</rule>
|
| 1098 |
|
</rule>
|
| 1099 |
|
|
|
1112 |
|
| 1100 |
1113 |
<!-- a negated CONTAINS and a non-word-indexed one share error 3398, so they are
|
| 1101 |
1114 |
decided together and reported once -->
|
| 1102 |
|
<action>badfld = ch1 == null or !ch1.isAnnotation("word-indexed")</action>
|
|
1115 |
<action>badfld = (ch1 == null) or !ch1.isAnnotation("word-indexed")</action>
|
| 1103 |
1116 |
<rule>badfld and ch2 != null and ch2.isAnnotation("word-indexed")
|
| 1104 |
1117 |
<action>badfld = false</action>
|
| 1105 |
1118 |
<action>copy.getChildAt(1).move(null, 0)</action>
|
| ... | ... | |
| 1111 |
1124 |
<rule>badfld
|
| 1112 |
1125 |
<rule>isRuntimeQueryMode()
|
| 1113 |
1126 |
<action>
|
| 1114 |
|
compileError(3398, "CONTAINS allowed only for word indexed field references",
|
| 1115 |
|
this)
|
|
1127 |
compileError(3398, "CONTAINS allowed only for word indexed field references", this)
|
| 1116 |
1128 |
</action>
|
| 1117 |
1129 |
<action on="false">
|
| 1118 |
1130 |
printfln(
|