def enterGraphQlPair()

in mrs_plugin/lib/MrsDdlListener.py [0:0]


    def enterGraphQlPair(self, ctx):
        objects = self.mrs_object["objects"]
        current_object = (
            objects[-1]
            if (self.mrs_object.get("db_object_type", "") != "FUNCTION")
            else objects[self.mrs_object.get("graph_ql_object_count", 0)]
        )
        fields = current_object["fields"]
        field_name = lib.core.unquote(ctx.graphQlPairKey().getText())
        force_create = self.mrs_object.get("force_create", False)

        # Check if this GraphQlPair is inside a reference, and if so, adjust the ref_fields_offset so that
        # the handling only applies to the referenced fields
        ref_stack = self.mrs_object.get("parent_reference_stack")
        if ref_stack is not None and len(ref_stack) > 0:
            parent_ref = ref_stack[-1]
            ref_fields_offset = parent_ref.get("referenced_fields_offset")
        else:
            parent_ref = None
            ref_fields_offset = 0

        # If there is no graphQlObj for this field, it's a column
        if ctx.graphQlObj() is None:
            db_column_name = ctx.graphQlPairValue().getText().strip("`")

            # Check if this is a REST PROCEDURE RESULT
            graph_ql_object_count = self.mrs_object.get("graph_ql_object_count", 0)
            if graph_ql_object_count == 0:
                # A REST VIEW RESULT or REST PROCEDURE/FUNCTION PARAMETERS
                for i, field in enumerate(fields):
                    # Ignore all higher level fields and only consider referenced fields
                    if i < ref_fields_offset:
                        continue

                    db_column = field.get("db_column")
                    if (
                        db_column is not None
                        and db_column.get("name") == db_column_name
                    ):
                        field["name"] = field_name
                        field["enabled"] = True

                        options_ctx: MRSParser.GraphQlValueOptionsContext = (
                            ctx.graphQlValueOptions()
                        )
                        if options_ctx is not None:
                            # cSpell:ignore NOCHECK NOFILTERING ROWOWNERSHIP
                            if options_ctx.AT_NOCHECK_SYMBOL(0) is not None:
                                field["no_check"] = True
                            if options_ctx.AT_SORTABLE_SYMBOL(0) is not None:
                                field["allow_sorting"] = True
                            if options_ctx.AT_NOFILTERING_SYMBOL(0) is not None:
                                field["allow_filtering"] = False
                            if options_ctx.AT_ROWOWNERSHIP_SYMBOL(0) is not None:
                                current_object["row_ownership_field_id"] = field.get(
                                    "id", None
                                )
                            if options_ctx.AT_KEY_SYMBOL(0) is not None:
                                db_column["is_primary"] = True

                        if (
                            ctx.graphQlCrudOptions() is not None
                            and ctx.graphQlCrudOptions().AT_NOUPDATE_SYMBOL()
                            is not None
                        ):
                            field["no_update"] = True

                        if ctx.AT_DATATYPE_SYMBOL() is not None:
                            db_column["datatype"] = lib.core.unquote(
                                ctx.graphQlDatatypeValue().getText().lower()
                            )
                        if ctx.graphQlValueJsonSchema() is not None:
                            try:
                                field["json_schema"] = json.loads(
                                    ctx.graphQlValueJsonSchema().jsonValue().getText()
                                )
                            except:
                                pass
                        break
                else:
                    if not force_create:
                        raise Exception(
                            f"The column `{db_column_name}` does not exist on "
                            f'`{self.mrs_object.get("schema_name")}`.`{
                                self.mrs_object.get("name")}`.'
                        )
                    else:
                        # Add parameters in case FORCE has been used
                        fields.append(
                            {
                                "id": self.get_uuid(),
                                "object_id": self.mrs_object.get("objects")[0].get(
                                    "id"
                                ),
                                "name": field_name,
                                "position": len(fields),
                                "db_column": {
                                    "name": db_column_name,
                                    "datatype": (
                                        lib.core.unquote(
                                            ctx.graphQlDatatypeValue().getText().lower()
                                        )
                                        if ctx.AT_DATATYPE_SYMBOL()
                                        else "varchar(255)"
                                    ),
                                    "in": ctx.AT_IN_SYMBOL() is not None
                                    or ctx.AT_INOUT_SYMBOL() is not None,
                                    "out": ctx.AT_OUT_SYMBOL() is not None
                                    or ctx.AT_INOUT_SYMBOL() is not None,
                                },
                                "enabled": True,
                                "allow_filtering": True,
                                "allow_sorting": False,
                                "no_check": False,
                                "no_update": False,
                            }
                        )
            else:
                # A REST PROCEDURE RESULT
                if self.mrs_object.get("db_object_type", "") != "FUNCTION":
                    fields.append(
                        {
                            "id": self.get_uuid(),
                            "object_id": self.mrs_object.get("objects")[
                                graph_ql_object_count
                            ].get("id"),
                            "name": field_name,
                            "position": len(fields),
                            "db_column": {
                                "name": db_column_name,
                                "datatype": (
                                    lib.core.unquote(
                                        ctx.graphQlDatatypeValue().getText().lower()
                                    )
                                    if ctx.AT_DATATYPE_SYMBOL()
                                    else "varchar(255)"
                                ),
                            },
                            "enabled": True,
                            "allow_filtering": True,
                            "allow_sorting": False,
                            "no_check": False,
                            "no_update": False,
                        }
                    )

                current_object["fields"] = fields

        else:
            if (
                ctx.graphQlPairValue().qualifiedIdentifier() is None
                or ctx.graphQlPairValue().qualifiedIdentifier().dotIdentifier() is None
            ):
                db_schema_name = self.mrs_object["schema_name"]
                db_object_name = ctx.graphQlPairValue().getText().strip("`")
            else:
                db_schema_name = (
                    ctx.graphQlPairValue()
                    .qualifiedIdentifier()
                    .identifier()
                    .getText()
                    .strip("`")
                )
                db_object_name = (
                    ctx.graphQlPairValue()
                    .qualifiedIdentifier()
                    .dotIdentifier()
                    .identifier()
                    .getText()
                    .strip("`")
                )

            ref_mapping = None
            for field in fields:
                ref_mapping = field.get("reference_mapping")
                if (
                    ref_mapping is not None
                    and ref_mapping.get("referenced_schema") == db_schema_name
                    and ref_mapping.get("referenced_table") == db_object_name
                    and field["enabled"] == False
                ):
                    field["name"] = field_name
                    field["enabled"] = True

                    # Build object_reference
                    obj_reference_id = self.get_uuid()
                    options = self.build_options_list(ctx.graphQlCrudOptions())
                    obj_reference = {
                        "id": obj_reference_id,
                        "reference_mapping": ref_mapping,
                        "options": {
                            "dataMappingViewInsert": "INSERT" in options,
                            "dataMappingViewUpdate": "UPDATE" in options,
                            "dataMappingViewDelete": "DELETE" in options,
                            "dataMappingViewNoCheck": "NOCHECK" in options,
                        },
                        "unnest": self.isUnnestSet(ctx.graphQlValueOptions()),
                    }

                    field["object_reference"] = obj_reference
                    field["represents_reference_id"] = obj_reference_id

                    self.mrs_object.get("parent_reference_stack").append(
                        {
                            "object_reference": obj_reference,
                            "referenced_fields_offset": len(fields),
                        }
                    )

                    # Get referenced fields as well
                    ref_fields = self.get_db_object_fields(
                        object_id=current_object.get("id"),
                        db_schema_name=db_schema_name,
                        db_object_name=db_object_name,
                    )

                    # Append them to the fields list
                    current_object["fields"] = fields + ref_fields

                    break
            else:
                raise Exception(
                    f"The table `{db_schema_name}`.`{db_object_name}` has no reference to "
                    f'`{self.mrs_object.get("schema_name")}`.`{self.mrs_object.get("name")}`.'
                )