Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
1. Encrypt: Support SqlServer update statement for Specifying a table alias as the target object when use encrypt feature - [#38733](https://github.com/apache/shardingsphere/pull/38733)
1. Encrypt: Support SqlServer update statement for Specifying a view as the target object when use encrypt feature - [#38896](https://github.com/apache/shardingsphere/pull/38896)
1. Encrypt: Support SqlServer for Using the UPDATE statement with information from another table when use encrypt feature - [#38926](https://github.com/apache/shardingsphere/pull/38926)
1. Kernel: Add linked-server infrastructure module for OPENQUERY encrypt rewrite - [#39786](https://github.com/apache/shardingsphere/pull/39786)
1. Sharding: Fix HASH_MOD routing mismatch for same negative numeric values across numeric Java types with compatibility switch `normalize-numeric-int-range` - [#38327](https://github.com/apache/shardingsphere/pull/38327)
1. SQL Parser: Support parsing SYSTEM_USER in SQL92 dialect and bind it as a niladic function instead of a column - [#39102](https://github.com/apache/shardingsphere/pull/39102)

Expand Down
36 changes: 36 additions & 0 deletions kernel/linked-server/api/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-linked-server</artifactId>
<version>5.5.4-SNAPSHOT</version>
</parent>
<artifactId>shardingsphere-linked-server-api</artifactId>
<name>${project.artifactId}</name>

<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-infra-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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.
*/

package org.apache.shardingsphere.linkedserver.config;

import com.cedarsoftware.util.CaseInsensitiveSet;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.infra.config.rule.function.EnhancedRuleConfiguration;
import org.apache.shardingsphere.infra.config.rule.scope.DatabaseRuleConfiguration;
import org.apache.shardingsphere.linkedserver.config.rule.LinkedServerConfiguration;

import java.util.Collection;
import java.util.stream.Collectors;

/**
* Linked server rule configuration.
*/
@RequiredArgsConstructor
@Getter
public final class LinkedServerRuleConfiguration implements DatabaseRuleConfiguration, EnhancedRuleConfiguration {

private final Collection<LinkedServerConfiguration> servers;

@Override
public Collection<String> getLogicTableNames() {
return new CaseInsensitiveSet<>(servers.stream()
.flatMap(each -> each.getTables().values().stream())
.collect(Collectors.toList()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.
*/

package org.apache.shardingsphere.linkedserver.config.rule;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.Map;

/**
* Linked server configuration.
*/
@RequiredArgsConstructor
@Getter
public final class LinkedServerConfiguration {

private final String name;

private final String databaseType;

private final Map<String, String> tables;
}
48 changes: 48 additions & 0 deletions kernel/linked-server/core/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-linked-server</artifactId>
<version>5.5.4-SNAPSHOT</version>
</parent>
<artifactId>shardingsphere-linked-server-core</artifactId>
<name>${project.artifactId}</name>

<dependencies>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-linked-server-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-mode-node</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-test-infra-fixture-database</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.
*/

package org.apache.shardingsphere.linkedserver.constant;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
* Linked server order.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class LinkedServerOrder {

/**
* Linked server order, built before single (order 5) and encrypt (order 10).
*/
public static final int ORDER = 3;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* 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.
*/

package org.apache.shardingsphere.linkedserver.openquery;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.FunctionTableSegment;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
* Utility class for OPENQUERY detection, extraction, and T-SQL escaping.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class OpenQueryUtils {

private static final String OPENQUERY_FUNCTION_NAME = "OPENQUERY";

/**
* Check if a function table segment is an OPENQUERY call.
*
* @param functionTableSegment function table segment
* @return true if OPENQUERY
*/
public static boolean isOpenQuery(final FunctionTableSegment functionTableSegment) {
ExpressionSegment tableFunction = functionTableSegment.getTableFunction();
return tableFunction instanceof FunctionSegment && OPENQUERY_FUNCTION_NAME.equalsIgnoreCase(((FunctionSegment) tableFunction).getFunctionName());
}

/**
* Extract linked server name from OPENQUERY function segment.
*
* @param functionSegment OPENQUERY function segment
* @return linked server name, or empty if parameters are absent
*/
public static Optional<String> extractLinkedServerName(final FunctionSegment functionSegment) {
List<ExpressionSegment> params = new ArrayList<>(functionSegment.getParameters());
if (params.isEmpty()) {
return Optional.empty();
}
ExpressionSegment firstParam = params.get(0);
if (firstParam instanceof ColumnSegment) {
return Optional.of(((ColumnSegment) firstParam).getIdentifier().getValue());
}
return Optional.of(firstParam.getText());
}

/**
* Extract inner SQL literal expression segment from OPENQUERY function segment.
*
* @param functionSegment OPENQUERY function segment
* @return inner SQL literal expression segment
*/
public static Optional<LiteralExpressionSegment> extractInnerSQLSegment(final FunctionSegment functionSegment) {
List<ExpressionSegment> params = new ArrayList<>(functionSegment.getParameters());
if (params.size() < 2) {
return Optional.empty();
}
ExpressionSegment secondParam = params.get(1);
return secondParam instanceof LiteralExpressionSegment ? Optional.of((LiteralExpressionSegment) secondParam) : Optional.empty();
}

/**
* Decode T-SQL escaped single quotes in string literal content.
* Converts {@code ''} to {@code '}.
*
* @param raw raw string with T-SQL escaping
* @return decoded string
*/
public static String decodeTSqlEscaping(final String raw) {
return raw.replace("''", "'");
}

/**
* Encode single quotes for T-SQL string literal context.
* Converts {@code '} to {@code ''}.
*
* @param decoded decoded string
* @return encoded string for T-SQL literal
*/
public static String encodeTSqlEscaping(final String decoded) {
return decoded.replace("'", "''");
}
}
Loading
Loading