vogievetsky commented on code in PR #18126:
URL: https://github.com/apache/druid/pull/18126#discussion_r2159575105


##########
web-console/src/druid-models/native-json-query/native-json-query-completions.ts:
##########
@@ -0,0 +1,1098 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { JsonCompletionRule } from '../../utils';
+
+export const NATIVE_JSON_QUERY_COMPLETIONS: JsonCompletionRule[] = [
+  // Root level - when starting a new query
+  {
+    path: '$',
+    isObject: true,
+    completions: [
+      { value: 'queryType', documentation: 'The type of query to execute' },
+      { value: 'dataSource', documentation: 'The data source to query' },
+    ],
+  },
+
+  // Query type values
+  {
+    path: '$.queryType',
+    completions: [
+      {
+        value: 'timeseries',
+        documentation: 'Timeseries query for time-based aggregations',
+      },
+      {
+        value: 'topN',
+        documentation: 'TopN query to get the top N dimension values',
+      },
+      { value: 'groupBy', documentation: 'GroupBy query for grouped 
aggregations' },
+      { value: 'scan', documentation: 'Scan query to return raw Druid rows' },
+      { value: 'search', documentation: 'Search query to find dimension 
values' },
+      {
+        value: 'timeBoundary',
+        documentation: 'Time boundary query to find data time range',
+      },
+      { value: 'segmentMetadata', documentation: 'Segment metadata query' },
+      { value: 'dataSourceMetadata', documentation: 'Data source metadata 
query' },
+    ],
+  },
+
+  // Common properties for most query types
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType !== 'dataSourceMetadata',
+    completions: [
+      { value: 'intervals', documentation: 'Time intervals to query' },
+      { value: 'filter', documentation: 'Filter to apply to the query' },
+      { value: 'context', documentation: 'Query context parameters' },
+      { value: 'virtualColumns', documentation: 'Virtual columns for computed 
values' },
+    ],
+  },
+
+  // Timeseries query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'timeseries',
+    completions: [
+      { value: 'granularity', documentation: 'Time granularity for bucketing' 
},
+      { value: 'aggregations', documentation: 'Aggregations to compute' },
+      {
+        value: 'postAggregations',
+        documentation: 'Post-aggregations to compute',
+      },
+      {
+        value: 'descending',
+        documentation: 'Whether to sort results in descending order',
+      },
+      { value: 'limit', documentation: 'Maximum number of results to return' },
+    ],
+  },
+
+  // TopN query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'topN',
+    completions: [
+      {
+        value: 'dimension',
+        documentation: 'The dimension to get top values for',
+      },
+      { value: 'threshold', documentation: 'The number of top values to 
return' },
+      { value: 'metric', documentation: 'The metric to sort by' },
+      { value: 'granularity', documentation: 'Time granularity for bucketing' 
},
+      { value: 'aggregations', documentation: 'Aggregations to compute' },
+      {
+        value: 'postAggregations',
+        documentation: 'Post-aggregations to compute',
+      },
+    ],
+  },
+
+  // GroupBy query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'groupBy',
+    completions: [
+      { value: 'dimensions', documentation: 'Dimensions to group by' },
+      { value: 'granularity', documentation: 'Time granularity for bucketing' 
},
+      { value: 'aggregations', documentation: 'Aggregations to compute' },
+      {
+        value: 'postAggregations',
+        documentation: 'Post-aggregations to compute',
+      },
+      { value: 'having', documentation: 'Having clause to filter groups' },
+      { value: 'limitSpec', documentation: 'Limit and ordering specification' 
},
+    ],
+  },
+
+  // Scan query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'scan',
+    completions: [
+      { value: 'columns', documentation: 'Columns to return' },
+      { value: 'limit', documentation: 'Maximum number of rows to return' },
+      { value: 'offset', documentation: 'Number of rows to skip' },
+      { value: 'resultFormat', documentation: 'Format of the result' },
+      { value: 'batchSize', documentation: 'Batch size for streaming' },
+      { value: 'legacy', documentation: 'Use legacy scan query mode' },
+      { value: 'order', documentation: 'Result ordering (none, ascending, 
descending)' },
+    ],
+  },
+
+  // Search query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'search',
+    completions: [
+      { value: 'granularity', documentation: 'Time granularity for bucketing' 
},
+      { value: 'searchDimensions', documentation: 'Dimensions to search' },
+      { value: 'query', documentation: 'Search query specification' },
+      { value: 'sort', documentation: 'Sort specification for results' },
+      { value: 'limit', documentation: 'Maximum number of results to return' },
+    ],
+  },
+
+  // TimeBoundary query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'timeBoundary',
+    completions: [
+      {
+        value: 'bound',
+        documentation: 'Which boundary to return (minTime, maxTime, or null 
for both)',
+      },
+    ],
+  },
+
+  // SegmentMetadata query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'segmentMetadata',
+    completions: [
+      { value: 'toInclude', documentation: 'Columns to include in the result 
(defaults to "all")' },
+      {
+        value: 'merge',
+        documentation: 'Merge all individual segment metadata results into a 
single result',
+      },
+      {
+        value: 'analysisTypes',
+        documentation: 'Column properties to calculate and return (e.g. 
cardinality, size)',
+      },
+      {
+        value: 'aggregatorMergeStrategy',
+        documentation: 'Strategy for merging aggregators: strict, lenient, 
earliest, or latest',
+      },
+      {
+        value: 'lenientAggregatorMerge',
+        documentation: 'Deprecated. Use aggregatorMergeStrategy instead',
+      },
+    ],
+  },
+
+  // SegmentMetadata toInclude properties
+  {
+    path: '$.toInclude',
+    isObject: true,
+    condition: obj => obj.queryType === 'segmentMetadata',
+    completions: [
+      { value: 'type', documentation: 'Type of columns to include: all, none, 
or list' },
+    ],
+  },
+
+  // SegmentMetadata toInclude types
+  {
+    path: '$.toInclude.type',
+    condition: obj => obj.queryType === 'segmentMetadata',
+    completions: [
+      { value: 'all', documentation: 'Include all columns in the result' },
+      { value: 'none', documentation: 'Include no columns in the result' },
+      { value: 'list', documentation: 'Include specific columns listed in the 
columns array' },
+    ],
+  },
+
+  // SegmentMetadata toInclude list properties
+  {
+    path: '$.toInclude',
+    isObject: true,
+    condition: obj => obj.queryType === 'segmentMetadata' && 
obj.toInclude?.type === 'list',
+    completions: [{ value: 'columns', documentation: 'Array of column names to 
include' }],
+  },
+
+  // SegmentMetadata analysisTypes values
+  {
+    path: '$.analysisTypes.[]',
+    condition: obj => obj.queryType === 'segmentMetadata',
+    completions: [
+      { value: 'cardinality', documentation: 'Number of unique values in 
string columns' },
+      { value: 'interval', documentation: 'Time intervals associated with 
queried segments' },
+      { value: 'minmax', documentation: 'Estimated min/max values for string 
columns' },
+      { value: 'size', documentation: 'Estimated byte size as if stored in 
text format' },
+      { value: 'timestampSpec', documentation: 'Timestamp specification of 
data in segments' },
+      { value: 'queryGranularity', documentation: 'Query granularity of data 
in segments' },
+      { value: 'aggregators', documentation: 'List of aggregators usable for 
metric columns' },
+      { value: 'rollup', documentation: 'Whether the segments are rolled up' },
+    ],
+  },
+
+  // SegmentMetadata aggregatorMergeStrategy values
+  {
+    path: '$.aggregatorMergeStrategy',
+    condition: obj => obj.queryType === 'segmentMetadata',
+    completions: [
+      { value: 'strict', documentation: 'Fail if any conflicts or unknown 
aggregators exist' },
+      { value: 'lenient', documentation: 'Ignore unknown aggregators, set 
conflicts to null' },
+      { value: 'earliest', documentation: 'Use aggregator from earliest 
segment in conflicts' },
+      { value: 'latest', documentation: 'Use aggregator from most recent 
segment in conflicts' },
+    ],
+  },
+
+  // DataSourceMetadata query specific properties
+  {
+    path: '$',
+    isObject: true,
+    condition: obj => obj.queryType === 'dataSourceMetadata',
+    completions: [
+      { value: 'dataSource', documentation: 'The data source to get metadata 
for' },
+      { value: 'context', documentation: 'Query context parameters' },
+    ],
+  },
+
+  // Granularity simple values
+  {
+    path: '$.granularity',
+    completions: [
+      { value: 'all', documentation: 'All data in a single bucket' },
+      { value: 'none', documentation: 'No time bucketing' },
+      { value: 'second', documentation: 'Bucket by second' },
+      { value: 'minute', documentation: 'Bucket by minute' },
+      { value: 'fifteen_minute', documentation: 'Bucket by 15 minutes' },
+      { value: 'thirty_minute', documentation: 'Bucket by 30 minutes' },
+      { value: 'hour', documentation: 'Bucket by hour' },
+      { value: 'day', documentation: 'Bucket by day' },
+      { value: 'week', documentation: 'Bucket by week' },
+      { value: 'month', documentation: 'Bucket by month' },
+      { value: 'quarter', documentation: 'Bucket by quarter' },
+      { value: 'year', documentation: 'Bucket by year' },
+    ],
+  },
+
+  // Granularity object properties (when granularity is an object)
+  {
+    path: '$.granularity',
+    isObject: true,
+    condition: obj => typeof obj === 'object' && obj !== null,
+    completions: [
+      { value: 'type', documentation: 'Type of granularity' },
+      { value: 'period', documentation: 'ISO 8601 period' },
+      { value: 'timeZone', documentation: 'Timezone for bucketing' },
+      { value: 'origin', documentation: 'Origin timestamp' },
+    ],
+  },
+
+  // Granularity types
+  {
+    path: '$.granularity.type',
+    completions: [
+      { value: 'duration', documentation: 'Duration-based granularity' },
+      { value: 'period', documentation: 'Period-based granularity' },
+      { value: 'uniform', documentation: 'Uniform granularity' },
+    ],
+  },
+
+  // Duration granularity properties
+  {
+    path: '$.granularity',
+    isObject: true,
+    condition: obj => obj.type === 'duration',
+    completions: [
+      { value: 'duration', documentation: 'Duration in milliseconds' },
+      { value: 'origin', documentation: 'Origin timestamp' },
+    ],
+  },
+
+  // Period granularity properties
+  {
+    path: '$.granularity',
+    isObject: true,
+    condition: obj => obj.type === 'period',
+    completions: [
+      { value: 'period', documentation: 'ISO 8601 period string' },
+      { value: 'timeZone', documentation: 'Timezone for bucketing' },
+      { value: 'origin', documentation: 'Origin timestamp' },
+    ],
+  },
+
+  // Aggregation properties
+  {
+    path: '$.aggregations.[]',
+    isObject: true,
+    completions: [
+      { value: 'type', documentation: 'Type of aggregation' },
+      { value: 'name', documentation: 'Output name for this aggregation' },
+    ],
+  },
+
+  // Aggregation types
+  {
+    path: '$.aggregations.[].type',
+    completions: [
+      { value: 'count', documentation: 'Count aggregator' },
+      { value: 'longSum', documentation: 'Sum aggregator for long values' },
+      { value: 'doubleSum', documentation: 'Sum aggregator for double values' 
},
+      { value: 'floatSum', documentation: 'Sum aggregator for float values' },
+      { value: 'longMin', documentation: 'Min aggregator for long values' },
+      { value: 'doubleMin', documentation: 'Min aggregator for double values' 
},
+      { value: 'floatMin', documentation: 'Min aggregator for float values' },
+      { value: 'longMax', documentation: 'Max aggregator for long values' },
+      { value: 'doubleMax', documentation: 'Max aggregator for double values' 
},
+      { value: 'floatMax', documentation: 'Max aggregator for float values' },
+      { value: 'doubleMean', documentation: 'Mean aggregator for double values 
(query time only)' },
+      { value: 'doubleFirst', documentation: 'First value aggregator for 
doubles' },
+      { value: 'doubleLast', documentation: 'Last value aggregator for 
doubles' },
+      { value: 'floatFirst', documentation: 'First value aggregator for 
floats' },
+      { value: 'floatLast', documentation: 'Last value aggregator for floats' 
},
+      { value: 'longFirst', documentation: 'First value aggregator for longs' 
},
+      { value: 'longLast', documentation: 'Last value aggregator for longs' },
+      { value: 'stringFirst', documentation: 'First value aggregator for 
strings' },
+      { value: 'stringLast', documentation: 'Last value aggregator for 
strings' },
+      { value: 'doubleAny', documentation: 'Any value aggregator for doubles' 
},
+      { value: 'floatAny', documentation: 'Any value aggregator for floats' },
+      { value: 'longAny', documentation: 'Any value aggregator for longs' },
+      { value: 'stringAny', documentation: 'Any value aggregator for strings' 
},
+      {
+        value: 'thetaSketch',
+        documentation: 'Theta sketch for approximate distinct count',
+      },
+      {
+        value: 'HLLSketchBuild',
+        documentation: 'HLL sketch for approximate distinct count',
+      },
+      {
+        value: 'quantilesDoublesSketch',
+        documentation: 'Quantiles sketch for doubles',
+      },
+      {
+        value: 'hyperUnique',
+        documentation: 'HyperLogLog for approximate distinct count',
+      },
+      { value: 'cardinality', documentation: 'Cardinality aggregator' },
+      { value: 'histogram', documentation: 'Approximate histogram aggregator' 
},
+      {
+        value: 'fixedBucketsHistogram',
+        documentation: 'Fixed buckets histogram aggregator',
+      },
+      { value: 'filtered', documentation: 'Filtered aggregator' },
+      { value: 'grouping', documentation: 'Grouping aggregator for subtotals' 
},
+    ],
+  },
+
+  // Aggregation properties for field-based aggregators
+  {
+    path: '$.aggregations.[]',
+    isObject: true,
+    condition: obj =>
+      obj.type &&
+      [
+        'longSum',
+        'doubleSum',
+        'floatSum',
+        'longMin',
+        'doubleMin',
+        'floatMin',
+        'longMax',
+        'doubleMax',
+        'floatMax',
+        'doubleMean',
+      ].includes(obj.type),
+    completions: [
+      { value: 'fieldName', documentation: 'The field to aggregate' },
+      { value: 'expression', documentation: 'Expression to evaluate instead of 
fieldName' },
+    ],
+  },
+
+  // Aggregation properties for first/last aggregators
+  {
+    path: '$.aggregations.[]',
+    isObject: true,
+    condition: obj =>
+      obj.type &&
+      [
+        'doubleFirst',
+        'doubleLast',
+        'floatFirst',
+        'floatLast',
+        'longFirst',
+        'longLast',
+        'stringFirst',
+        'stringLast',
+        'doubleAny',
+        'floatAny',
+        'longAny',
+        'stringAny',
+      ].includes(obj.type),
+    completions: [
+      { value: 'fieldName', documentation: 'The field to aggregate' },
+      {
+        value: 'timeColumn',
+        documentation: 'Time column to use for ordering (defaults to __time)',
+      },
+    ],
+  },
+
+  // Filtered aggregator properties
+  {
+    path: '$.aggregations.[]',
+    isObject: true,
+    condition: obj => obj.type === 'filtered',
+    completions: [
+      { value: 'filter', documentation: 'Filter to apply before aggregation' },
+      { value: 'aggregator', documentation: 'The aggregator to apply to 
filtered data' },
+    ],
+  },
+
+  // Filter types
+  {
+    path: '$.filter',
+    isObject: true,
+    completions: [{ value: 'type', documentation: 'Type of filter' }],
+  },
+
+  {
+    path: '$.filter.type',
+    completions: [
+      { value: 'selector', documentation: 'Matches a specific dimension value' 
},

Review Comment:
   I am sticking only to the documented stuff for now



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to