[ 
https://issues.apache.org/jira/browse/GROOVY-12724?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18141231#comment-18141231
 ] 

ASF GitHub Bot commented on GROOVY-12724:
-----------------------------------------

daniellansun commented on code in PR #3259:
URL: https://github.com/apache/groovy/pull/3259#discussion_r4512876775


##########
subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/runtime/Queryable.java:
##########
@@ -516,6 +518,42 @@ default Queryable<T> union(Queryable<? extends T> 
queryable) {
      */
     List<T> toList();
 
+    /**
+     * Iterates the materialized elements. A static {@code for} loop calls this
+     * rather than wrapping the query as a single value.
+     *
+     * @return an iterator over the elements
+     * @since 7.0.0
+     */
+    default Iterator<T> iterator() {
+        return toList().iterator();
+    }
+
+    /**
+     * Coerces this query. Implementations that know the target type override 
it.
+     *
+     * @param type the requested type
+     * @return the coerced value
+     * @since 7.0.0
+     */
+    default Object asType(Class<?> type) {
+        if (type == Queryable.class || List.class == type || Collection.class 
== type || Iterable.class == type) {
+            return type == Queryable.class ? this : toList();
+        }
+        return this;

Review Comment:
   Agreed. On the current tip, after the special cases (`Queryable` → this; 
`List` / `Collection` / `Iterable` → `toList()`), every other target (including 
null) goes to `DefaultGroovyMethods.asType`, which throws `GroovyCastException` 
when the value is not compatible. `LazyQueryable` returns this for 
`LazyQueryable` / `Queryable` without building the pipeline; otherwise it 
builds and uses the same rule. Returning `this` for an arbitrary `Foo` is gone.





> GINQ: support static compilation and a fluent query API
> -------------------------------------------------------
>
>                 Key: GROOVY-12724
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12724
>             Project: Groovy
>          Issue Type: Improvement
>          Components: GINQ
>            Reporter: Daniel Sun
>            Assignee: Daniel Sun
>            Priority: Major
>
> Under @CompileStatic / @TypeChecked, GQ, GQL, and @GQ currently rely on 
> dynamic lowering. This improvement makes those entry points usable from a 
> statically checked scope while keeping the SQL-like syntax lowered to the 
> in-memory collection runtime.
> h3. Goals
> * Allow GQ / GQL / @GQ from @CompileStatic and @TypeChecked without forcing 
> the lowered tree through static checking at the expression site.
> * Defer pipeline construction with LazyQueryable until a terminal read 
> (toList, count, etc.), copying locals at the expression site (same binding as 
> dynamic GQ).
> * Add Ginq.from(...) as a deferred, generic fluent chain on the same runtime, 
> with @ClosureParams so where/select/join/aggregate closures can infer element 
> types where inference is sound.
> * Preserve default lazy/deferred evaluation and dynamic GQ behavior for map 
> rows and other intentionally dynamic cases.
> h3. Non-goals / known limits
> * Stored untyped Closure variables still need a SAM target type for parameter 
> inference (same as Java/C#).
> * Raw Query parameters/fields cannot recover a safe element type.
> * Names bound by from inside GQ / GQL / @GQ stay dynamic by design; callers 
> that need checked element types use Ginq.from.
> h3. Related work
> GitHub PR: https://github.com/apache/groovy/pull/3259
> Stacked on GEP-26 SQL window work (PR #3167 / gep26-sql-window).



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to