diff --git a/sqrl-planner/src/main/java/com/datasqrl/graphql/GraphqlSchemaValidator.java b/sqrl-planner/src/main/java/com/datasqrl/graphql/GraphqlSchemaValidator.java index b3fb3908a4..1700235349 100644 --- a/sqrl-planner/src/main/java/com/datasqrl/graphql/GraphqlSchemaValidator.java +++ b/sqrl-planner/src/main/java/com/datasqrl/graphql/GraphqlSchemaValidator.java @@ -205,9 +205,10 @@ private Object validateStructurallyEqualTypes( return null; } else if (inputTypeDef instanceof EnumTypeDefinition) { checkState( - outputTypeDef instanceof EnumTypeDefinition - || outputTypeDef instanceof ScalarTypeDefinition - && inputTypeDef.getName().equals(outputTypeDef.getName()), + (outputTypeDef instanceof EnumTypeDefinition + && inputTypeDef.getName().equals(outputTypeDef.getName())) + || (outputTypeDef instanceof ScalarTypeDefinition + && outputTypeDef.getName().equals("String")), inputType.getSourceLocation(), "Enum types not matching for field %s %s: found %s but wanted %s", outputField.getName(), diff --git a/sqrl-testing/sqrl-testing-integration/src/test/java/com/datasqrl/FullUseCaseIT.java b/sqrl-testing/sqrl-testing-integration/src/test/java/com/datasqrl/FullUseCaseIT.java index 004d3ae8d0..512145088a 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/java/com/datasqrl/FullUseCaseIT.java +++ b/sqrl-testing/sqrl-testing-integration/src/test/java/com/datasqrl/FullUseCaseIT.java @@ -66,7 +66,7 @@ void specificUseCase(UseCaseParam param, TestContainerHook hook) { /** Ad-hoc debugging entry point. Change the path below to run a single use case manually. */ static Stream specificUseCaseProvider() { - return Stream.of(new UseCaseParam(USE_CASES.resolve("repository").resolve("package.json"))); + return Stream.of(new UseCaseParam(USE_CASES.resolve("temporal-join").resolve("package.json"))); } @ParameterizedTest diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/snapshots/com/datasqrl/UseCaseCompileTest/temporal-join-package.txt b/sqrl-testing/sqrl-testing-integration/src/test/resources/snapshots/com/datasqrl/UseCaseCompileTest/temporal-join-package.txt index 45731e8710..d4fcee40a7 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/resources/snapshots/com/datasqrl/UseCaseCompileTest/temporal-join-package.txt +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/snapshots/com/datasqrl/UseCaseCompileTest/temporal-join-package.txt @@ -1,85 +1,3 @@ ->>>inferred_schema.graphqls -"An RFC-3339 compliant Full Date Scalar" -scalar Date - -"A DateTime scalar that handles both full RFC3339 and shorter timestamp formats" -scalar DateTime - -type EnrichedSensorReading { - sensorid: Int! - temperature: Float! - event_time: DateTime! - sensor_name: String -} - -"A JSON scalar" -scalar JSON - -"24-hour clock time value string in the format `hh:mm:ss` or `hh:mm:ss.sss`." -scalar LocalTime - -"A 64-bit signed integer" -scalar Long - -type Mutation { - SensorReading(event: SensorReadingInput!): SensorReadingResultOutput! - SensorUpdates(event: SensorUpdatesInput!): SensorUpdatesResultOutput! -} - -type Query { - EnrichedSensorReading(limit: Int = 10, offset: Int = 0): [EnrichedSensorReading!] - SensorReading(limit: Int = 10, offset: Int = 0): [SensorReading!] - SensorUpdates(limit: Int = 10, offset: Int = 0): [SensorUpdates!] -} - -type SensorReading { - sensorid: Int! - temperature: Float! - event_time: DateTime! -} - -input SensorReadingInput { - sensorid: Int! - temperature: Float! -} - -type SensorReadingResultOutput { - sensorid: Int! - temperature: Float! - event_time: DateTime! -} - -type SensorUpdates { - sensorid: Int! - sensor_name: String! - lastUpdated: DateTime! -} - -input SensorUpdatesInput { - sensorid: Int! - sensor_name: String! -} - -type SensorUpdatesResultOutput { - sensorid: Int! - sensor_name: String! - lastUpdated: DateTime! -} - -enum _McpMethodType { - NONE - TOOL - RESOURCE -} - -enum _RestMethodType { - NONE - GET - POST -} - -directive @api(mcp: _McpMethodType, rest: _RestMethodType, uri: String) on QUERY | MUTATION | FIELD_DEFINITION - >>>pipeline_explain.txt === EnrichedSensorReading ID: default_catalog.default_database.EnrichedSensorReading @@ -91,13 +9,25 @@ Timestamp: event_time Schema: - sensorid: INTEGER NOT NULL - temperature: FLOAT NOT NULL + - placement: VARCHAR(2147483647) CHARACTER SET "UTF-16LE" NOT NULL - event_time: TIMESTAMP_LTZ(3) *ROWTIME* NOT NULL - sensor_name: VARCHAR(2147483647) CHARACTER SET "UTF-16LE" Inputs: - default_catalog.default_database.SensorReading - default_catalog.default_database._SensorDistinct Annotations: - - sort: [2 ASC-nulls-first] + - sort: [3 ASC-nulls-first] + +=== EnrichedSensorReadingByPlacement +ID: default_catalog.default_database.EnrichedSensorReadingByPlacement +Type: query +Stage: postgres +--- +Inputs: + - default_catalog.default_database.EnrichedSensorReading +Annotations: + - parameters: placement + - base-table: EnrichedSensorReading === SensorReading ID: default_catalog.default_database.SensorReading @@ -109,6 +39,7 @@ Timestamp: event_time Schema: - sensorid: INTEGER NOT NULL - temperature: FLOAT NOT NULL + - placement: VARCHAR(2147483647) CHARACTER SET "UTF-16LE" NOT NULL - event_time: TIMESTAMP_LTZ(3) *ROWTIME* NOT NULL Inputs: - default_catalog.default_database.SensorReading__base @@ -171,6 +102,7 @@ Inputs: CREATE TABLE `SensorReading` ( `sensorid` INTEGER NOT NULL, `temperature` FLOAT NOT NULL, + `placement` STRING NOT NULL, `event_time` TIMESTAMP_LTZ(3) NOT NULL METADATA FROM 'timestamp', WATERMARK FOR `event_time` AS `event_time` - INTERVAL '0.0' SECOND ) @@ -204,12 +136,13 @@ FROM (SELECT `sensorid`, `sensor_name`, `lastUpdated`, ROW_NUMBER() OVER (PARTIT WHERE `__sqrlinternal_rownum` = 1; CREATE VIEW `EnrichedSensorReading` AS -SELECT `r`.`sensorid`, `r`.`temperature`, `r`.`event_time`, `u`.`sensor_name` +SELECT `r`.`sensorid`, `r`.`temperature`, `r`.`placement`, `r`.`event_time`, `u`.`sensor_name` FROM `SensorReading` AS `r` LEFT JOIN `_SensorDistinct` FOR SYSTEM_TIME AS OF `r`.`event_time` AS `u` ON `r`.`sensorid` = `u`.`sensorid`; CREATE TABLE `Result_1` ( `sensorid` INTEGER NOT NULL, `temperature` FLOAT NOT NULL, + `placement` VARCHAR(2147483647) CHARACTER SET `UTF-16LE` NOT NULL, `event_time` TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL, `sensor_name` VARCHAR(2147483647) CHARACTER SET `UTF-16LE` ) @@ -220,6 +153,7 @@ WITH ( CREATE TABLE `EnrichedSensorReading_2` ( `sensorid` INTEGER NOT NULL, `temperature` FLOAT NOT NULL, + `placement` VARCHAR(2147483647) CHARACTER SET `UTF-16LE` NOT NULL, `event_time` TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL, `sensor_name` VARCHAR(2147483647) CHARACTER SET `UTF-16LE`, `__pk_hash` CHAR(32) CHARACTER SET `UTF-16LE`, @@ -236,6 +170,7 @@ WITH ( CREATE TABLE `SensorReading_3` ( `sensorid` INTEGER NOT NULL, `temperature` FLOAT NOT NULL, + `placement` VARCHAR(2147483647) CHARACTER SET `UTF-16LE` NOT NULL, `event_time` TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL ) WITH ( @@ -245,6 +180,7 @@ WITH ( CREATE TABLE `SensorReading_4` ( `sensorid` INTEGER NOT NULL, `temperature` FLOAT NOT NULL, + `placement` VARCHAR(2147483647) CHARACTER SET `UTF-16LE` NOT NULL, `event_time` TIMESTAMP(3) WITH LOCAL TIME ZONE NOT NULL, `__pk_hash` CHAR(32) CHARACTER SET `UTF-16LE`, PRIMARY KEY (`__pk_hash`) NOT ENFORCED @@ -287,7 +223,7 @@ SELECT * FROM `default_catalog`.`default_database`.`EnrichedSensorReading` ; INSERT INTO `default_catalog`.`default_database`.`EnrichedSensorReading_2` - SELECT `sensorid`, `temperature`, `event_time`, `sensor_name`, `hash_columns`(`sensorid`, `temperature`, `event_time`, `sensor_name`) AS `__pk_hash` + SELECT `sensorid`, `temperature`, `placement`, `event_time`, `sensor_name`, `hash_columns`(`sensorid`, `temperature`, `placement`, `event_time`, `sensor_name`) AS `__pk_hash` FROM `default_catalog`.`default_database`.`EnrichedSensorReading` ; INSERT INTO `default_catalog`.`default_database`.`SensorReading_3` @@ -295,7 +231,7 @@ INSERT INTO `default_catalog`.`default_database`.`EnrichedSensorReading_2` FROM `default_catalog`.`default_database`.`SensorReading` ; INSERT INTO `default_catalog`.`default_database`.`SensorReading_4` - SELECT `sensorid`, `temperature`, `event_time`, `hash_columns`(`sensorid`, `temperature`, `event_time`) AS `__pk_hash` + SELECT `sensorid`, `temperature`, `placement`, `event_time`, `hash_columns`(`sensorid`, `temperature`, `placement`, `event_time`) AS `__pk_hash` FROM `default_catalog`.`default_database`.`SensorReading` ; INSERT INTO `default_catalog`.`default_database`.`SensorUpdates_5` @@ -336,8 +272,8 @@ INSERT INTO `default_catalog`.`default_database`.`EnrichedSensorReading_2` "testRunnerTopics" : [ ] } >>>postgres-schema.sql -CREATE TABLE IF NOT EXISTS "EnrichedSensorReading" ("sensorid" INTEGER NOT NULL, "temperature" FLOAT NOT NULL, "event_time" TIMESTAMP WITH TIME ZONE NOT NULL, "sensor_name" TEXT, "__pk_hash" TEXT, PRIMARY KEY ("__pk_hash")); -CREATE TABLE IF NOT EXISTS "SensorReading" ("sensorid" INTEGER NOT NULL, "temperature" FLOAT NOT NULL, "event_time" TIMESTAMP WITH TIME ZONE NOT NULL, "__pk_hash" TEXT, PRIMARY KEY ("__pk_hash")); +CREATE TABLE IF NOT EXISTS "EnrichedSensorReading" ("sensorid" INTEGER NOT NULL, "temperature" FLOAT NOT NULL, "placement" TEXT NOT NULL, "event_time" TIMESTAMP WITH TIME ZONE NOT NULL, "sensor_name" TEXT, "__pk_hash" TEXT, PRIMARY KEY ("__pk_hash")); +CREATE TABLE IF NOT EXISTS "SensorReading" ("sensorid" INTEGER NOT NULL, "temperature" FLOAT NOT NULL, "placement" TEXT NOT NULL, "event_time" TIMESTAMP WITH TIME ZONE NOT NULL, "__pk_hash" TEXT, PRIMARY KEY ("__pk_hash")); CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor_name" TEXT NOT NULL, "lastUpdated" TIMESTAMP WITH TIME ZONE NOT NULL, "__pk_hash" TEXT, PRIMARY KEY ("__pk_hash")) >>>postgres-views.sql @@ -363,7 +299,7 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor ], "query" : { "type" : "SqlQuery", - "sql" : "SELECT *\nFROM (SELECT \"sensorid\", \"temperature\", \"event_time\", \"sensor_name\"\n FROM \"EnrichedSensorReading\"\n ORDER BY \"event_time\" NULLS FIRST) AS \"t0\"", + "sql" : "SELECT *\nFROM (SELECT \"sensorid\", \"temperature\", \"placement\", \"event_time\", \"sensor_name\"\n FROM \"EnrichedSensorReading\"\n ORDER BY \"event_time\" NULLS FIRST) AS \"t0\"", "parameters" : [ ], "pagination" : "LIMIT_AND_OFFSET", "cacheDurationMs" : 0, @@ -388,7 +324,7 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor ], "query" : { "type" : "SqlQuery", - "sql" : "SELECT \"sensorid\", \"temperature\", \"event_time\"\nFROM \"SensorReading\"", + "sql" : "SELECT \"sensorid\", \"temperature\", \"placement\", \"event_time\"\nFROM \"SensorReading\"", "parameters" : [ ], "pagination" : "LIMIT_AND_OFFSET", "cacheDurationMs" : 0, @@ -420,6 +356,40 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor "database" : "POSTGRES" } } + }, + { + "type" : "args", + "parentType" : "Query", + "fieldName" : "EnrichedSensorReadingByPlacement", + "exec" : { + "arguments" : [ + { + "type" : "variable", + "path" : "limit" + }, + { + "type" : "variable", + "path" : "offset" + }, + { + "type" : "variable", + "path" : "placement" + } + ], + "query" : { + "type" : "SqlQuery", + "sql" : "SELECT *\nFROM (SELECT \"sensorid\", \"temperature\", \"placement\", \"event_time\", \"sensor_name\"\n FROM \"EnrichedSensorReading\"\n ORDER BY \"event_time\" NULLS FIRST) AS \"t0\"\nWHERE \"placement\" = $1", + "parameters" : [ + { + "type" : "arg", + "path" : "placement" + } + ], + "pagination" : "LIMIT_AND_OFFSET", + "cacheDurationMs" : 0, + "database" : "POSTGRES" + } + } } ], "mutations" : [ @@ -474,7 +444,7 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor }, "format" : "JSON", "apiQuery" : { - "query" : "query EnrichedSensorReading($limit: Int = 10, $offset: Int = 0) {\nEnrichedSensorReading(limit: $limit, offset: $offset) {\nsensorid\ntemperature\nevent_time\nsensor_name\n}\n\n}", + "query" : "query EnrichedSensorReading($limit: Int = 10, $offset: Int = 0) {\nEnrichedSensorReading(limit: $limit, offset: $offset) {\nsensorid\ntemperature\nplacement\nevent_time\nsensor_name\n}\n\n}", "queryName" : "EnrichedSensorReading", "operationType" : "QUERY" }, @@ -500,7 +470,7 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor }, "format" : "JSON", "apiQuery" : { - "query" : "query SensorReading($limit: Int = 10, $offset: Int = 0) {\nSensorReading(limit: $limit, offset: $offset) {\nsensorid\ntemperature\nevent_time\n}\n\n}", + "query" : "query SensorReading($limit: Int = 10, $offset: Int = 0) {\nSensorReading(limit: $limit, offset: $offset) {\nsensorid\ntemperature\nplacement\nevent_time\n}\n\n}", "queryName" : "SensorReading", "operationType" : "QUERY" }, @@ -534,6 +504,41 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor "restMethod" : "GET", "uriTemplate" : "queries/SensorUpdates{?offset,limit}" }, + { + "function" : { + "name" : "GetEnrichedSensorReadingByPlacement", + "parameters" : { + "type" : "object", + "properties" : { + "offset" : { + "type" : "integer" + }, + "limit" : { + "type" : "integer" + }, + "placement" : { + "type" : "string", + "enum" : [ + "DOWNSTAIRS", + "UPSTAIRS" + ] + } + }, + "required" : [ + "placement" + ] + } + }, + "format" : "JSON", + "apiQuery" : { + "query" : "query EnrichedSensorReadingByPlacement($placement: Placements!, $limit: Int = 10, $offset: Int = 0) {\nEnrichedSensorReadingByPlacement(placement: $placement, limit: $limit, offset: $offset) {\nsensorid\ntemperature\nplacement\nevent_time\nsensor_name\n}\n\n}", + "queryName" : "EnrichedSensorReadingByPlacement", + "operationType" : "QUERY" + }, + "mcpMethod" : "TOOL", + "restMethod" : "GET", + "uriTemplate" : "queries/EnrichedSensorReadingByPlacement{?offset,limit,placement}" + }, { "function" : { "name" : "AddSensorReading", @@ -543,19 +548,27 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor "temperature" : { "type" : "number" }, + "placement" : { + "type" : "string", + "enum" : [ + "DOWNSTAIRS", + "UPSTAIRS" + ] + }, "sensorid" : { "type" : "integer" } }, "required" : [ "sensorid", - "temperature" + "temperature", + "placement" ] } }, "format" : "JSON", "apiQuery" : { - "query" : "mutation SensorReading($sensorid: Int!, $temperature: Float!) {\nSensorReading(event: { sensorid: $sensorid, temperature: $temperature }) {\nsensorid\ntemperature\nevent_time\n}\n\n}", + "query" : "mutation SensorReading($sensorid: Int!, $temperature: Float!, $placement: Placements!) {\nSensorReading(event: { sensorid: $sensorid, temperature: $temperature, placement: $placement }) {\nsensorid\ntemperature\nplacement\nevent_time\n}\n\n}", "queryName" : "SensorReading", "operationType" : "MUTATION" }, @@ -595,7 +608,7 @@ CREATE TABLE IF NOT EXISTS "SensorUpdates" ("sensorid" INTEGER NOT NULL, "sensor ], "schema" : { "type" : "string", - "schema" : "\"An RFC-3339 compliant Full Date Scalar\"\nscalar Date\n\n\"A DateTime scalar that handles both full RFC3339 and shorter timestamp formats\"\nscalar DateTime\n\ntype EnrichedSensorReading {\n sensorid: Int!\n temperature: Float!\n event_time: DateTime!\n sensor_name: String\n}\n\n\"A JSON scalar\"\nscalar JSON\n\n\"24-hour clock time value string in the format `hh:mm:ss` or `hh:mm:ss.sss`.\"\nscalar LocalTime\n\n\"A 64-bit signed integer\"\nscalar Long\n\ntype Mutation {\n SensorReading(event: SensorReadingInput!): SensorReadingResultOutput!\n SensorUpdates(event: SensorUpdatesInput!): SensorUpdatesResultOutput!\n}\n\ntype Query {\n EnrichedSensorReading(limit: Int = 10, offset: Int = 0): [EnrichedSensorReading!]\n SensorReading(limit: Int = 10, offset: Int = 0): [SensorReading!]\n SensorUpdates(limit: Int = 10, offset: Int = 0): [SensorUpdates!]\n}\n\ntype SensorReading {\n sensorid: Int!\n temperature: Float!\n event_time: DateTime!\n}\n\ninput SensorReadingInput {\n sensorid: Int!\n temperature: Float!\n}\n\ntype SensorReadingResultOutput {\n sensorid: Int!\n temperature: Float!\n event_time: DateTime!\n}\n\ntype SensorUpdates {\n sensorid: Int!\n sensor_name: String!\n lastUpdated: DateTime!\n}\n\ninput SensorUpdatesInput {\n sensorid: Int!\n sensor_name: String!\n}\n\ntype SensorUpdatesResultOutput {\n sensorid: Int!\n sensor_name: String!\n lastUpdated: DateTime!\n}\n\nenum _McpMethodType {\n NONE\n TOOL\n RESOURCE\n}\n\nenum _RestMethodType {\n NONE\n GET\n POST\n}\n\ndirective @api(mcp: _McpMethodType, rest: _RestMethodType, uri: String) on QUERY | MUTATION | FIELD_DEFINITION\n" + "schema" : "\"An RFC-3339 compliant Full Date Scalar\"\nscalar Date\n\n\"A DateTime scalar that handles both full RFC3339 and shorter timestamp formats\"\nscalar DateTime\n\ntype EnrichedSensorReading {\n sensorid: Int!\n temperature: Float!\n placement: String!\n event_time: DateTime!\n sensor_name: String\n}\n\n\"A JSON scalar\"\nscalar JSON\n\n\"24-hour clock time value string in the format `hh:mm:ss` or `hh:mm:ss.sss`.\"\nscalar LocalTime\n\n\"A 64-bit signed integer\"\nscalar Long\n\ntype Mutation {\n SensorReading(event: SensorReadingInput!): SensorReadingResultOutput!\n SensorUpdates(event: SensorUpdatesInput!): SensorUpdatesResultOutput!\n}\n\ntype Query {\n EnrichedSensorReading(limit: Int = 10, offset: Int = 0): [EnrichedSensorReading!]\n SensorReading(limit: Int = 10, offset: Int = 0): [SensorReading!]\n SensorUpdates(limit: Int = 10, offset: Int = 0): [SensorUpdates!]\n EnrichedSensorReadingByPlacement(placement: Placements!, limit: Int = 10, offset: Int = 0): [EnrichedSensorReading!]\n}\n\nenum Placements {\n DOWNSTAIRS\n UPSTAIRS\n}\n\ntype SensorReading {\n sensorid: Int!\n temperature: Float!\n placement: Placements!\n event_time: DateTime!\n}\n\ninput SensorReadingInput {\n sensorid: Int!\n temperature: Float!\n placement: Placements!\n}\n\ntype SensorReadingResultOutput {\n sensorid: Int!\n temperature: Float!\n placement: Placements!\n event_time: DateTime!\n}\n\ntype SensorUpdates {\n sensorid: Int!\n sensor_name: String!\n lastUpdated: DateTime!\n}\n\ninput SensorUpdatesInput {\n sensorid: Int!\n sensor_name: String!\n}\n\ntype SensorUpdatesResultOutput {\n sensorid: Int!\n sensor_name: String!\n lastUpdated: DateTime!\n}\n\nenum _McpMethodType {\n NONE\n TOOL\n RESOURCE\n}\n\nenum _RestMethodType {\n NONE\n GET\n POST\n}\n\ndirective @api(mcp: _McpMethodType, rest: _RestMethodType, uri: String) on QUERY | MUTATION | FIELD_DEFINITION\n" } } } diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/package.json b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/package.json index 2a9bf73181..1f3d37a6db 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/package.json +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/package.json @@ -2,7 +2,8 @@ "version": "1", "enabled-engines": ["vertx", "postgres", "kafka", "flink"], "script": { - "main": "temporal-join.sqrl" + "main": "temporal-join.sqrl", + "graphql": "temporal-join.graphqls" }, "engines": { "flink" : { @@ -13,6 +14,7 @@ }, "test-runner": { "delay-sec": 30, - "mutation-delay-sec": 1 + "mutation-delay-sec": 1, + "use-inferred-schema": false } } diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/mutation2.snapshot b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/mutation2.snapshot index 55cf20efa5..e83e87e6b9 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/mutation2.snapshot +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/mutation2.snapshot @@ -2,15 +2,18 @@ "data" : { "add1" : { "sensorid" : 101, - "temperature" : 23.5 + "temperature" : 23.5, + "placement" : "DOWNSTAIRS" }, "add2" : { "sensorid" : 101, - "temperature" : 33.5 + "temperature" : 33.5, + "placement" : "DOWNSTAIRS" }, "add3" : { "sensorid" : 111, - "temperature" : 13.5 + "temperature" : 13.5, + "placement" : "UPSTAIRS" } } } \ No newline at end of file diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/query_enriched.snapshot b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/query_enriched.snapshot index dbb1466d9d..0da7048ef8 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/query_enriched.snapshot +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/query_enriched.snapshot @@ -3,14 +3,17 @@ "EnrichedSensorReading" : [ { "sensorid" : 101, "temperature" : 23.5, + "placement" : "DOWNSTAIRS", "sensor_name" : "Living Room Sensor" }, { "sensorid" : 101, "temperature" : 33.5, + "placement" : "DOWNSTAIRS", "sensor_name" : "Living Room Sensor" }, { "sensorid" : 111, "temperature" : 13.5, + "placement" : "UPSTAIRS", "sensor_name" : "Dining Room Sensor" } ] } diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/query_enriched_by_placement.snapshot b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/query_enriched_by_placement.snapshot new file mode 100644 index 0000000000..ae29819bfb --- /dev/null +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/snapshots/query_enriched_by_placement.snapshot @@ -0,0 +1,15 @@ +{ + "data" : { + "EnrichedSensorReadingByPlacement" : [ { + "sensorid" : 101, + "temperature" : 23.5, + "placement" : "DOWNSTAIRS", + "sensor_name" : "Living Room Sensor" + }, { + "sensorid" : 101, + "temperature" : 33.5, + "placement" : "DOWNSTAIRS", + "sensor_name" : "Living Room Sensor" + } ] + } +} \ No newline at end of file diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/temporal-join.graphqls b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/temporal-join.graphqls new file mode 100644 index 0000000000..e47968b4fd --- /dev/null +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/temporal-join.graphqls @@ -0,0 +1,90 @@ +"An RFC-3339 compliant Full Date Scalar" +scalar Date + +"A DateTime scalar that handles both full RFC3339 and shorter timestamp formats" +scalar DateTime + +type EnrichedSensorReading { + sensorid: Int! + temperature: Float! + placement: String! + event_time: DateTime! + sensor_name: String +} + +"A JSON scalar" +scalar JSON + +"24-hour clock time value string in the format `hh:mm:ss` or `hh:mm:ss.sss`." +scalar LocalTime + +"A 64-bit signed integer" +scalar Long + +type Mutation { + SensorReading(event: SensorReadingInput!): SensorReadingResultOutput! + SensorUpdates(event: SensorUpdatesInput!): SensorUpdatesResultOutput! +} + +type Query { + EnrichedSensorReading(limit: Int = 10, offset: Int = 0): [EnrichedSensorReading!] + SensorReading(limit: Int = 10, offset: Int = 0): [SensorReading!] + SensorUpdates(limit: Int = 10, offset: Int = 0): [SensorUpdates!] + EnrichedSensorReadingByPlacement(placement: Placements!, limit: Int = 10, offset: Int = 0): [EnrichedSensorReading!] +} + +enum Placements { + DOWNSTAIRS + UPSTAIRS +} + +type SensorReading { + sensorid: Int! + temperature: Float! + placement: Placements! + event_time: DateTime! +} + +input SensorReadingInput { + sensorid: Int! + temperature: Float! + placement: Placements! +} + +type SensorReadingResultOutput { + sensorid: Int! + temperature: Float! + placement: Placements! + event_time: DateTime! +} + +type SensorUpdates { + sensorid: Int! + sensor_name: String! + lastUpdated: DateTime! +} + +input SensorUpdatesInput { + sensorid: Int! + sensor_name: String! +} + +type SensorUpdatesResultOutput { + sensorid: Int! + sensor_name: String! + lastUpdated: DateTime! +} + +enum _McpMethodType { + NONE + TOOL + RESOURCE +} + +enum _RestMethodType { + NONE + GET + POST +} + +directive @api(mcp: _McpMethodType, rest: _RestMethodType, uri: String) on QUERY | MUTATION | FIELD_DEFINITION diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/temporal-join.sqrl b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/temporal-join.sqrl index 92318184eb..ffca102654 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/temporal-join.sqrl +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/temporal-join.sqrl @@ -2,6 +2,7 @@ CREATE TABLE SensorReading ( sensorid INT NOT NULL, temperature FLOAT NOT NULL, + placement STRING NOT NULL, event_time TIMESTAMP_LTZ(3) NOT NULL METADATA FROM 'timestamp' ); @@ -17,8 +18,11 @@ EXPORT SensorUpdates TO logger.SensorUpdates; _SensorDistinct := DISTINCT SensorUpdates ON sensorid ORDER BY lastUpdated DESC; -EnrichedSensorReading := SELECT r.sensorid, r.temperature, r.event_time, u.sensor_name +EnrichedSensorReading := SELECT r.sensorid, r.temperature, r.placement, r.event_time, u.sensor_name FROM SensorReading r LEFT JOIN _SensorDistinct FOR SYSTEM_TIME AS OF r.event_time u on r.sensorid = u.sensorid ORDER BY r.event_time ASC; +EnrichedSensorReadingByPlacement(placement STRING NOT NULL) := + SELECT * FROM EnrichedSensorReading WHERE placement = :placement; + EXPORT EnrichedSensorReading TO logger.Result; diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/mutation2.graphql b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/mutation2.graphql index 4791a1f364..f3a9e69092 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/mutation2.graphql +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/mutation2.graphql @@ -1,23 +1,29 @@ mutation SensorReadings { add1: SensorReading(event: { sensorid: 101, - temperature: 23.5 + temperature: 23.5, + placement: DOWNSTAIRS }) { sensorid temperature + placement } add2: SensorReading(event: { sensorid: 101, temperature: 33.5 + placement: DOWNSTAIRS }) { sensorid temperature + placement } add3: SensorReading(event: { sensorid: 111, temperature: 13.5 + placement: UPSTAIRS }) { sensorid temperature + placement } -} \ No newline at end of file +} diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/query_enriched.graphql b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/query_enriched.graphql index 9dff5ce50a..c637186069 100644 --- a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/query_enriched.graphql +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/query_enriched.graphql @@ -2,6 +2,7 @@ query GetEnrichedSensorReadings { EnrichedSensorReading(limit: 10, offset: 0) { sensorid temperature + placement sensor_name } -} \ No newline at end of file +} diff --git a/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/query_enriched_by_placement.graphql b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/query_enriched_by_placement.graphql new file mode 100644 index 0000000000..dbfedd0b67 --- /dev/null +++ b/sqrl-testing/sqrl-testing-integration/src/test/resources/usecases/temporal-join/tests/query_enriched_by_placement.graphql @@ -0,0 +1,8 @@ +query GetEnrichedSensorReadingByPlacement { + EnrichedSensorReadingByPlacement(placement: DOWNSTAIRS, limit: 10, offset: 0) { + sensorid + temperature + placement + sensor_name + } +}